Commit 269c7388 authored by Alastair Robertson's avatar Alastair Robertson

clang_parser: Use BCC's KBuildHelper

To get full arguments to pass into Clang for reading kernel headers
parent c3b69149
......@@ -20,6 +20,7 @@ target_include_directories(bpftrace PUBLIC ${source_dir}/src/cc)
target_link_libraries(bpftrace ${binary_dir}/src/cc/libbpf.a)
target_link_libraries(bpftrace ${binary_dir}/src/cc/libbcc-loader-static.a)
target_link_libraries(bpftrace ${binary_dir}/src/cc/libbcc.a)
target_link_libraries(bpftrace ${binary_dir}/src/cc/frontends/clang/libclang_frontend.a)
target_link_libraries(bpftrace ${LIBELF_LIBRARIES})
install(TARGETS bpftrace DESTINATION bin)
......@@ -3,6 +3,8 @@
#include <string.h>
#include <sys/utsname.h>
#include "frontends/clang/kbuild_helper.h"
#include "ast.h"
#include "bpftrace.h"
#include "clang_parser.h"
......@@ -88,16 +90,28 @@ static SizedType get_sized_type(CXType clang_type)
// TODO add support for arrays
return SizedType(Type::none, 0);
}
case CXType_LongDouble:
return SizedType(Type::none, 0);
default:
// TODO just return Type::none?
auto unknown_type = get_clang_string(clang_getTypeKindSpelling(clang_type.kind));
std::cerr << "Error: unknown clang CXType '" << unknown_type << "'" << std::endl;
abort();
return SizedType(Type::none, 0);
}
}
static bool is_dir(const std::string& path)
{
struct stat buf;
if (::stat(path.c_str(), &buf) < 0)
return false;
return S_ISDIR(buf.st_mode);
}
static std::pair<bool, std::string> get_kernel_path_info(const std::string kdir)
{
if (is_dir(kdir + "/build") && is_dir(kdir + "/source"))
return std::make_pair (true, "source");
return std::make_pair(false, "build");
}
void ClangParser::parse(ast::Program *program, StructMap &structs)
{
auto input = program->c_definitions;
......@@ -145,18 +159,34 @@ void ClangParser::parse(ast::Program *program, StructMap &structs)
struct utsname utsname;
uname(&utsname);
std::string kernel_header_include_flag = std::string("/lib/modules/") + utsname.release + "/build/include";
std::string kernel_modules_dir = std::string("/lib/modules/") + utsname.release;
auto kpath_info = get_kernel_path_info(kernel_modules_dir);
auto kpath = kernel_modules_dir + "/" + kpath_info.second;
bool has_kpath_source = kpath_info.first;
CXIndex index = clang_createIndex(1, 1);
CXTranslationUnit translation_unit;
const char * const args[] = {
ebpf::DirStack dstack(kpath);
if (!dstack.ok())
return;
ebpf::KBuildHelper kbuild_helper(kpath, has_kpath_source);
std::vector<std::string> kflags;
kbuild_helper.get_flags(utsname.machine, &kflags);
std::vector<const char *> args =
{
"-I", "/bpftrace/include",
"-I", kernel_header_include_flag.c_str(),
};
for (auto &flag : kflags)
{
args.push_back(flag.c_str());
}
CXIndex index = clang_createIndex(1, 1);
CXTranslationUnit translation_unit;
CXErrorCode error = clang_parseTranslationUnit2(
index,
"definitions.h",
args, sizeof(args)/sizeof(char*),
&args[0], args.size(),
unsaved_files, sizeof(unsaved_files)/sizeof(CXUnsavedFile),
CXTranslationUnit_None,
&translation_unit);
......
......@@ -31,6 +31,7 @@ target_include_directories(bpftrace_test PUBLIC ${source_dir}/src/cc)
target_link_libraries(bpftrace_test ${binary_dir}/src/cc/libbpf.a)
target_link_libraries(bpftrace_test ${binary_dir}/src/cc/libbcc-loader-static.a)
target_link_libraries(bpftrace_test ${binary_dir}/src/cc/libbcc.a)
target_link_libraries(bpftrace_test ${binary_dir}/src/cc/frontends/clang/libclang_frontend.a)
target_link_libraries(bpftrace_test ${LIBELF_LIBRARIES})
find_package(Threads REQUIRED)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment