Commit 1a6ee5ac authored by 4ast's avatar 4ast

Merge pull request #308 from iovisor/cflags

Add ability to set custom cflags when loading programs
parents 43861954 93588503
......@@ -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;
}
......
......@@ -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);
......
......@@ -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;
}
......@@ -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;
}
......@@ -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;
......
......@@ -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;
......
......@@ -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;
......@@ -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());
......
......@@ -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_;
......
......@@ -30,9 +30,11 @@ lib = ct.CDLL("libbcc.so")
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 @@ class BPF(object):
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 @@ class BPF(object):
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 @@ class BPF(object):
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)
......
......@@ -287,5 +287,13 @@ BPF_TABLE("array", int, union emptyu, t3, 1);
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()
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