diff --git a/src/cc/bpf_common.cc b/src/cc/bpf_common.cc index 029da49bb329..f68372ce36b2 100644 --- a/src/cc/bpf_common.cc +++ b/src/cc/bpf_common.cc @@ -26,18 +26,18 @@ void * bpf_module_create_b(const char *filename, const char *proto_filename, uns return mod; } -void * bpf_module_create_c(const char *filename, unsigned flags) { +void * bpf_module_create_c(const char *filename, unsigned flags, const char *cflags[], int ncflags) { auto mod = new ebpf::BPFModule(flags); - if (mod->load_c(filename) != 0) { + if (mod->load_c(filename, cflags, ncflags) != 0) { delete mod; return nullptr; } return mod; } -void * bpf_module_create_c_from_string(const char *text, unsigned flags) { +void * bpf_module_create_c_from_string(const char *text, unsigned flags, const char *cflags[], int ncflags) { auto mod = new ebpf::BPFModule(flags); - if (mod->load_string(text) != 0) { + if (mod->load_string(text, cflags, ncflags) != 0) { delete mod; return nullptr; } diff --git a/src/cc/bpf_common.h b/src/cc/bpf_common.h index e066c584b477..9d02d9b442cf 100644 --- a/src/cc/bpf_common.h +++ b/src/cc/bpf_common.h @@ -25,8 +25,8 @@ extern "C" { #endif void * bpf_module_create_b(const char *filename, const char *proto_filename, unsigned flags); -void * bpf_module_create_c(const char *filename, unsigned flags); -void * bpf_module_create_c_from_string(const char *text, unsigned flags); +void * bpf_module_create_c(const char *filename, unsigned flags, const char *cflags[], int ncflags); +void * bpf_module_create_c_from_string(const char *text, unsigned flags, const char *cflags[], int ncflags); void bpf_module_destroy(void *program); char * bpf_module_license(void *program); unsigned bpf_module_kern_version(void *program); diff --git a/src/cc/bpf_module.cc b/src/cc/bpf_module.cc index bd55a0ebbe7c..767adee5341a 100644 --- a/src/cc/bpf_module.cc +++ b/src/cc/bpf_module.cc @@ -299,9 +299,9 @@ unique_ptr BPFModule::finalize_rw(unique_ptr m) { } // load an entire c file as a module -int BPFModule::load_cfile(const string &file, bool in_memory) { +int BPFModule::load_cfile(const string &file, bool in_memory, const char *cflags[], int ncflags) { clang_loader_ = make_unique(&*ctx_, flags_); - if (clang_loader_->parse(&mod_, &tables_, file, in_memory)) + if (clang_loader_->parse(&mod_, &tables_, file, in_memory, cflags, ncflags)) return -1; return 0; } @@ -313,7 +313,7 @@ int BPFModule::load_cfile(const string &file, bool in_memory) { // build an ExecutionEngine. int BPFModule::load_includes(const string &tmpfile) { clang_loader_ = make_unique(&*ctx_, flags_); - if (clang_loader_->parse(&mod_, &tables_, tmpfile, false)) + if (clang_loader_->parse(&mod_, &tables_, tmpfile, false, nullptr, 0)) return -1; return 0; } @@ -668,7 +668,7 @@ int BPFModule::load_b(const string &filename, const string &proto_filename) { } // load a C file -int BPFModule::load_c(const string &filename) { +int BPFModule::load_c(const string &filename, const char *cflags[], int ncflags) { if (!sections_.empty()) { fprintf(stderr, "Program already initialized\n"); return -1; @@ -677,7 +677,7 @@ int BPFModule::load_c(const string &filename) { fprintf(stderr, "Invalid filename\n"); return -1; } - if (int rc = load_cfile(filename, false)) + if (int rc = load_cfile(filename, false, cflags, ncflags)) return rc; if (int rc = annotate()) return rc; @@ -687,12 +687,12 @@ int BPFModule::load_c(const string &filename) { } // load a C text string -int BPFModule::load_string(const string &text) { +int BPFModule::load_string(const string &text, const char *cflags[], int ncflags) { if (!sections_.empty()) { fprintf(stderr, "Program already initialized\n"); return -1; } - if (int rc = load_cfile(text, true)) + if (int rc = load_cfile(text, true, cflags, ncflags)) return rc; if (int rc = annotate()) return rc; diff --git a/src/cc/bpf_module.h b/src/cc/bpf_module.h index 541341df3995..f79a9386cadb 100644 --- a/src/cc/bpf_module.h +++ b/src/cc/bpf_module.h @@ -48,15 +48,15 @@ class BPFModule { void dump_ir(llvm::Module &mod); int load_file_module(std::unique_ptr *mod, const std::string &file, bool in_memory); int load_includes(const std::string &tmpfile); - int load_cfile(const std::string &file, bool in_memory); + int load_cfile(const std::string &file, bool in_memory, const char *cflags[], int ncflags); int kbuild_flags(const char *uname_release, std::vector *cflags); int run_pass_manager(llvm::Module &mod); public: BPFModule(unsigned flags); ~BPFModule(); int load_b(const std::string &filename, const std::string &proto_filename); - int load_c(const std::string &filename); - int load_string(const std::string &text); + int load_c(const std::string &filename, const char *cflags[], int ncflags); + int load_string(const std::string &text, const char *cflags[], int ncflags); size_t num_functions() const; uint8_t * function_start(size_t id) const; uint8_t * function_start(const std::string &name) const; diff --git a/src/cc/frontends/clang/loader.cc b/src/cc/frontends/clang/loader.cc index 45fda7d4282b..7b2de839448e 100644 --- a/src/cc/frontends/clang/loader.cc +++ b/src/cc/frontends/clang/loader.cc @@ -65,7 +65,7 @@ ClangLoader::ClangLoader(llvm::LLVMContext *ctx, unsigned flags) ClangLoader::~ClangLoader() {} int ClangLoader::parse(unique_ptr *mod, unique_ptr> *tables, - const string &file, bool in_memory) { + const string &file, bool in_memory, const char *cflags[], int ncflags) { using namespace clang; struct utsname un; @@ -103,6 +103,10 @@ int ClangLoader::parse(unique_ptr *mod, unique_ptrc_str()); + if (cflags) { + for (auto i = 0; i < ncflags; ++i) + flags_cstr.push_back(cflags[i]); + } // set up the error reporting class IntrusiveRefCntPtr diag_opts(new DiagnosticOptions()); diff --git a/src/cc/frontends/clang/loader.h b/src/cc/frontends/clang/loader.h index 2f45b6496013..22c64e1ba811 100644 --- a/src/cc/frontends/clang/loader.h +++ b/src/cc/frontends/clang/loader.h @@ -39,7 +39,7 @@ class ClangLoader { explicit ClangLoader(llvm::LLVMContext *ctx, unsigned flags); ~ClangLoader(); int parse(std::unique_ptr *mod, std::unique_ptr> *tables, - const std::string &file, bool in_memory); + const std::string &file, bool in_memory, const char *cflags[], int ncflags); private: llvm::LLVMContext *ctx_; unsigned flags_; diff --git a/src/python/bcc/__init__.py b/src/python/bcc/__init__.py index b34614612d20..01fd08a59859 100644 --- a/src/python/bcc/__init__.py +++ b/src/python/bcc/__init__.py @@ -30,9 +30,11 @@ lib.bpf_module_create_b.restype = ct.c_void_p lib.bpf_module_create_b.argtypes = [ct.c_char_p, ct.c_char_p, ct.c_uint] lib.bpf_module_create_c.restype = ct.c_void_p -lib.bpf_module_create_c.argtypes = [ct.c_char_p, ct.c_uint] +lib.bpf_module_create_c.argtypes = [ct.c_char_p, ct.c_uint, + ct.POINTER(ct.c_char_p), ct.c_int] lib.bpf_module_create_c_from_string.restype = ct.c_void_p -lib.bpf_module_create_c_from_string.argtypes = [ct.c_char_p, ct.c_uint] +lib.bpf_module_create_c_from_string.argtypes = [ct.c_char_p, ct.c_uint, + ct.POINTER(ct.c_char_p), ct.c_int] lib.bpf_module_destroy.restype = None lib.bpf_module_destroy.argtypes = [ct.c_void_p] lib.bpf_module_license.restype = ct.c_char_p @@ -395,7 +397,7 @@ def _find_file(filename): raise Exception("Could not find file %s" % filename) return filename - def __init__(self, src_file="", hdr_file="", text=None, cb=None, debug=0): + def __init__(self, src_file="", hdr_file="", text=None, cb=None, debug=0, cflags=[]): """Create a a new BPF module with the given source code. Note: @@ -416,8 +418,11 @@ def __init__(self, src_file="", hdr_file="", text=None, cb=None, debug=0): self.debug = debug self.funcs = {} self.tables = {} + cflags_array = (ct.c_char_p * len(cflags))() + for i, s in enumerate(cflags): cflags_array[i] = s.encode("ascii") if text: - self.module = lib.bpf_module_create_c_from_string(text.encode("ascii"), self.debug) + self.module = lib.bpf_module_create_c_from_string(text.encode("ascii"), + self.debug, cflags_array, len(cflags_array)) else: src_file = BPF._find_file(src_file) hdr_file = BPF._find_file(hdr_file) @@ -426,7 +431,7 @@ def __init__(self, src_file="", hdr_file="", text=None, cb=None, debug=0): hdr_file.encode("ascii"), self.debug) else: self.module = lib.bpf_module_create_c(src_file.encode("ascii"), - self.debug) + self.debug, cflags_array, len(cflags_array)) if self.module == None: raise Exception("Failed to compile BPF module %s" % src_file) diff --git a/tests/cc/test_clang.py b/tests/cc/test_clang.py index 1b4664838a9f..d701b65ab012 100755 --- a/tests/cc/test_clang.py +++ b/tests/cc/test_clang.py @@ -287,5 +287,13 @@ def test_complex_leaf_types(self): import ctypes self.assertEqual(ctypes.sizeof(b["t3"].Leaf), 8) + def test_cflags(self): + text = """ +#ifndef MYFLAG +#error "MYFLAG not set as expected" +#endif +""" + b = BPF(text=text, cflags=["-DMYFLAG"]) + if __name__ == "__main__": main()