Skip to content

Commit

Permalink
Add BTF tests
Browse files Browse the repository at this point in the history
Adding BTF test to clang_parser modules
with generated BTF data.
  • Loading branch information
olsajiri committed Sep 4, 2019
1 parent b71def5 commit 56068cd
Show file tree
Hide file tree
Showing 2 changed files with 138 additions and 2 deletions.
48 changes: 48 additions & 0 deletions tests/btf_data.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#pragma once

#if 0
The data consists of following source file objects:

struct Foo1 {
int a;
char b;
long c;
};

struct Foo2 {
int a;
struct Foo1 f;
};

struct Foo3 {
struct Foo1 *foo1;
struct Foo2 *foo2;
};
#endif

unsigned char btf_data[] = {
0x9f, 0xeb, 0x01, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xc0, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x04, 0x10, 0x00, 0x00, 0x00,
0x10, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x12, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
0x14, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00, 0x00,
0x20, 0x00, 0x00, 0x01, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x01,
0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x04, 0x18, 0x00, 0x00, 0x00,
0x10, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x1b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
0x0b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x04, 0x10, 0x00, 0x00, 0x00,
0x1d, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x22, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, 0x00,
0x00, 0x46, 0x6f, 0x6f, 0x31, 0x00, 0x46, 0x6f, 0x6f, 0x32, 0x00, 0x46,
0x6f, 0x6f, 0x33, 0x00, 0x61, 0x00, 0x62, 0x00, 0x63, 0x00, 0x63, 0x68,
0x61, 0x72, 0x00, 0x66, 0x00, 0x66, 0x6f, 0x6f, 0x31, 0x00, 0x66, 0x6f,
0x6f, 0x32, 0x00, 0x69, 0x6e, 0x74, 0x00, 0x6c, 0x6f, 0x6e, 0x67, 0x20,
0x69, 0x6e, 0x74, 0x00
};
unsigned int btf_data_len = 268;
92 changes: 90 additions & 2 deletions tests/clang_parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@ namespace clang_parser {

using StructMap = std::map<std::string, Struct>;

static void parse(const std::string &input, BPFtrace &bpftrace, bool result = true)
static void parse(const std::string &input, BPFtrace &bpftrace, bool result = true,
const std::string& probe = "kprobe:sys_read { 1 }")
{
auto extended_input = input + "kprobe:sys_read { 1 }";
auto extended_input = input + probe;
Driver driver(bpftrace);
ASSERT_EQ(driver.parse_str(extended_input), 0);

Expand Down Expand Up @@ -380,6 +381,93 @@ TEST(clang_parser, parse_fail)
parse("struct a { int a; struct b b; };", bpftrace, false);
}

#ifdef HAVE_LIBBPF_BTF_DUMP

#include "btf_data.h"

TEST(clang_parser, btf)
{
char *path = strdup("/tmp/XXXXXX");
ASSERT_TRUE(path != NULL);

int fd = mkstemp(path);
ASSERT_TRUE(fd >= 0);

EXPECT_EQ(write(fd, btf_data, btf_data_len), btf_data_len);
close(fd);

ASSERT_EQ(setenv("BPFTRACE_BTF_TEST", path, true), 0);

BPFtrace bpftrace;
parse("", bpftrace, true,
"kprobe:sys_read {\n"
" @x1 = (struct Foo1 *) curtask;\n"
" @x2 = (struct Foo2 *) curtask;\n"
" @x3 = (struct Foo3 *) curtask;\n"
"}");

// clear the environment
unsetenv("BPFTRACE_BTF_TEST");
std::remove(path);

StructMap &structs = bpftrace.structs_;

ASSERT_EQ(structs.size(), 3U);
ASSERT_EQ(structs.count("Foo1"), 1U);
ASSERT_EQ(structs.count("Foo2"), 1U);
ASSERT_EQ(structs.count("Foo3"), 1U);

EXPECT_EQ(structs["Foo1"].size, 16);
ASSERT_EQ(structs["Foo1"].fields.size(), 3U);
ASSERT_EQ(structs["Foo1"].fields.count("a"), 1U);
ASSERT_EQ(structs["Foo1"].fields.count("b"), 1U);
ASSERT_EQ(structs["Foo1"].fields.count("c"), 1U);

EXPECT_EQ(structs["Foo1"].fields["a"].type.type, Type::integer);
EXPECT_EQ(structs["Foo1"].fields["a"].type.size, 4U);
EXPECT_EQ(structs["Foo1"].fields["a"].offset, 0);

EXPECT_EQ(structs["Foo1"].fields["b"].type.type, Type::integer);
EXPECT_EQ(structs["Foo1"].fields["b"].type.size, 1U);
EXPECT_EQ(structs["Foo1"].fields["b"].offset, 4);

EXPECT_EQ(structs["Foo1"].fields["c"].type.type, Type::integer);
EXPECT_EQ(structs["Foo1"].fields["c"].type.size, 8U);
EXPECT_EQ(structs["Foo1"].fields["c"].offset, 8);

EXPECT_EQ(structs["Foo2"].size, 24);
ASSERT_EQ(structs["Foo2"].fields.size(), 2U);
ASSERT_EQ(structs["Foo2"].fields.count("a"), 1U);
ASSERT_EQ(structs["Foo2"].fields.count("f"), 1U);

EXPECT_EQ(structs["Foo2"].fields["a"].type.type, Type::integer);
EXPECT_EQ(structs["Foo2"].fields["a"].type.size, 4U);
EXPECT_EQ(structs["Foo2"].fields["a"].offset, 0);

EXPECT_EQ(structs["Foo2"].fields["f"].type.type, Type::cast);
EXPECT_EQ(structs["Foo2"].fields["f"].type.size, 16U);
EXPECT_EQ(structs["Foo2"].fields["f"].offset, 8);

EXPECT_EQ(structs["Foo3"].size, 16);
ASSERT_EQ(structs["Foo3"].fields.size(), 2U);
ASSERT_EQ(structs["Foo3"].fields.count("foo1"), 1U);
ASSERT_EQ(structs["Foo3"].fields.count("foo2"), 1U);

EXPECT_EQ(structs["Foo3"].fields["foo1"].type.type, Type::cast);
EXPECT_EQ(structs["Foo3"].fields["foo1"].type.size, 8U);
EXPECT_EQ(structs["Foo3"].fields["foo1"].type.is_pointer, true);
EXPECT_EQ(structs["Foo3"].fields["foo1"].type.cast_type, "Foo1");
EXPECT_EQ(structs["Foo3"].fields["foo1"].offset, 0);

EXPECT_EQ(structs["Foo3"].fields["foo2"].type.type, Type::cast);
EXPECT_EQ(structs["Foo3"].fields["foo2"].type.size, 8U);
EXPECT_EQ(structs["Foo3"].fields["foo2"].type.is_pointer, true);
EXPECT_EQ(structs["Foo3"].fields["foo2"].type.cast_type, "Foo2");
EXPECT_EQ(structs["Foo3"].fields["foo2"].offset, 8);
}

#endif // HAVE_LIBBPF_BTF_DUMP

} // namespace clang_parser
} // namespace test
} // namespace bpftrace

0 comments on commit 56068cd

Please sign in to comment.