Skip to content

Commit

Permalink
Add ability to set custom cflags when loading programs
Browse files Browse the repository at this point in the history
Example:
b = bcc.BPF("myprog.c", cflags=["-DMYCUSTOMFLAG1", ...])

Signed-off-by: Brenden Blanco <[email protected]>
  • Loading branch information
Brenden Blanco committed Jan 6, 2016
1 parent 4386195 commit 9358850
Show file tree
Hide file tree
Showing 8 changed files with 40 additions and 23 deletions.
8 changes: 4 additions & 4 deletions src/cc/bpf_common.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
4 changes: 2 additions & 2 deletions src/cc/bpf_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
14 changes: 7 additions & 7 deletions src/cc/bpf_module.cc
Original file line number Diff line number Diff line change
Expand Up @@ -299,9 +299,9 @@ unique_ptr<ExecutionEngine> BPFModule::finalize_rw(unique_ptr<Module> 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<ClangLoader>(&*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;
}
Expand All @@ -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<ClangLoader>(&*ctx_, flags_);
if (clang_loader_->parse(&mod_, &tables_, tmpfile, false))
if (clang_loader_->parse(&mod_, &tables_, tmpfile, false, nullptr, 0))
return -1;
return 0;
}
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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;
Expand Down
6 changes: 3 additions & 3 deletions src/cc/bpf_module.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,15 @@ class BPFModule {
void dump_ir(llvm::Module &mod);
int load_file_module(std::unique_ptr<llvm::Module> *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<std::string> *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;
Expand Down
6 changes: 5 additions & 1 deletion src/cc/frontends/clang/loader.cc
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ ClangLoader::ClangLoader(llvm::LLVMContext *ctx, unsigned flags)
ClangLoader::~ClangLoader() {}

int ClangLoader::parse(unique_ptr<llvm::Module> *mod, unique_ptr<vector<TableDesc>> *tables,
const string &file, bool in_memory) {
const string &file, bool in_memory, const char *cflags[], int ncflags) {
using namespace clang;

struct utsname un;
Expand Down Expand Up @@ -103,6 +103,10 @@ int ClangLoader::parse(unique_ptr<llvm::Module> *mod, unique_ptr<vector<TableDes
kflags.push_back(BCC_INSTALL_PREFIX "/share/bcc/include");
for (auto it = kflags.begin(); it != kflags.end(); ++it)
flags_cstr.push_back(it->c_str());
if (cflags) {
for (auto i = 0; i < ncflags; ++i)
flags_cstr.push_back(cflags[i]);
}

// set up the error reporting class
IntrusiveRefCntPtr<DiagnosticOptions> diag_opts(new DiagnosticOptions());
Expand Down
2 changes: 1 addition & 1 deletion src/cc/frontends/clang/loader.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class ClangLoader {
explicit ClangLoader(llvm::LLVMContext *ctx, unsigned flags);
~ClangLoader();
int parse(std::unique_ptr<llvm::Module> *mod, std::unique_ptr<std::vector<TableDesc>> *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_;
Expand Down
15 changes: 10 additions & 5 deletions src/python/bcc/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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:
Expand All @@ -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)
Expand All @@ -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)
Expand Down
8 changes: 8 additions & 0 deletions tests/cc/test_clang.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()

0 comments on commit 9358850

Please sign in to comment.