Commit 74155c5b authored by 4ast's avatar 4ast Committed by GitHub

Merge pull request #957 from iovisor/misc_fixes

Fixes for LLVM4+, python3
parents 3a3b0f98 dacb8ad1
...@@ -147,7 +147,7 @@ static u32 (*bpf_get_prandom_u32)(void) = ...@@ -147,7 +147,7 @@ static u32 (*bpf_get_prandom_u32)(void) =
static int (*bpf_trace_printk_)(const char *fmt, u64 fmt_size, ...) = static int (*bpf_trace_printk_)(const char *fmt, u64 fmt_size, ...) =
(void *) BPF_FUNC_trace_printk; (void *) BPF_FUNC_trace_printk;
int bpf_trace_printk(const char *fmt, ...) asm("llvm.bpf.extra"); int bpf_trace_printk(const char *fmt, ...) asm("llvm.bpf.extra");
static void bpf_tail_call_(u64 map_fd, void *ctx, int index) { static inline void bpf_tail_call_(u64 map_fd, void *ctx, int index) {
((void (*)(void *, u64, int))BPF_FUNC_tail_call)(ctx, map_fd, index); ((void (*)(void *, u64, int))BPF_FUNC_tail_call)(ctx, map_fd, index);
} }
static int (*bpf_clone_redirect)(void *ctx, int ifindex, u32 flags) = static int (*bpf_clone_redirect)(void *ctx, int ifindex, u32 flags) =
......
...@@ -1163,6 +1163,8 @@ StatusTuple CodegenLLVM::visit_func_decl_stmt_node(FuncDeclStmtNode *n) { ...@@ -1163,6 +1163,8 @@ StatusTuple CodegenLLVM::visit_func_decl_stmt_node(FuncDeclStmtNode *n) {
Function *fn = mod_->getFunction(n->id_->name_); Function *fn = mod_->getFunction(n->id_->name_);
if (fn) return mkstatus_(n, "Function %s already defined", n->id_->c_str()); if (fn) return mkstatus_(n, "Function %s already defined", n->id_->c_str());
fn = Function::Create(fn_type, GlobalValue::ExternalLinkage, n->id_->name_, mod_); fn = Function::Create(fn_type, GlobalValue::ExternalLinkage, n->id_->name_, mod_);
fn->setCallingConv(CallingConv::C);
fn->addFnAttr(Attribute::NoUnwind);
fn->setSection(BPF_FN_PREFIX + n->id_->name_); fn->setSection(BPF_FN_PREFIX + n->id_->name_);
BasicBlock *label_entry = BasicBlock::Create(ctx(), "entry", fn); BasicBlock *label_entry = BasicBlock::Create(ctx(), "entry", fn);
......
...@@ -211,24 +211,25 @@ int ClangLoader::parse(unique_ptr<llvm::Module> *mod, unique_ptr<vector<TableDes ...@@ -211,24 +211,25 @@ int ClangLoader::parse(unique_ptr<llvm::Module> *mod, unique_ptr<vector<TableDes
} }
// pre-compilation pass for generating tracepoint structures // pre-compilation pass for generating tracepoint structures
auto invocation0 = make_unique<CompilerInvocation>(); CompilerInstance compiler0;
if (!CompilerInvocation::CreateFromArgs(*invocation0, const_cast<const char **>(ccargs.data()), CompilerInvocation &invocation0 = compiler0.getInvocation();
const_cast<const char **>(ccargs.data()) + ccargs.size(), diags)) if (!CompilerInvocation::CreateFromArgs(
invocation0, const_cast<const char **>(ccargs.data()),
const_cast<const char **>(ccargs.data()) + ccargs.size(), diags))
return -1; return -1;
invocation0->getPreprocessorOpts().RetainRemappedFileBuffers = true; invocation0.getPreprocessorOpts().RetainRemappedFileBuffers = true;
for (const auto &f : remapped_files_) for (const auto &f : remapped_files_)
invocation0->getPreprocessorOpts().addRemappedFile(f.first, &*f.second); invocation0.getPreprocessorOpts().addRemappedFile(f.first, &*f.second);
if (in_memory) { if (in_memory) {
invocation0->getPreprocessorOpts().addRemappedFile(main_path, &*main_buf); invocation0.getPreprocessorOpts().addRemappedFile(main_path, &*main_buf);
invocation0->getFrontendOpts().Inputs.clear(); invocation0.getFrontendOpts().Inputs.clear();
invocation0->getFrontendOpts().Inputs.push_back(FrontendInputFile(main_path, IK_C)); invocation0.getFrontendOpts().Inputs.push_back(
FrontendInputFile(main_path, IK_C));
} }
invocation0->getFrontendOpts().DisableFree = false; invocation0.getFrontendOpts().DisableFree = false;
CompilerInstance compiler0;
compiler0.setInvocation(invocation0.release());
compiler0.createDiagnostics(new IgnoringDiagConsumer()); compiler0.createDiagnostics(new IgnoringDiagConsumer());
// capture the rewritten c file // capture the rewritten c file
...@@ -239,24 +240,25 @@ int ClangLoader::parse(unique_ptr<llvm::Module> *mod, unique_ptr<vector<TableDes ...@@ -239,24 +240,25 @@ int ClangLoader::parse(unique_ptr<llvm::Module> *mod, unique_ptr<vector<TableDes
unique_ptr<llvm::MemoryBuffer> out_buf = llvm::MemoryBuffer::getMemBuffer(out_str); unique_ptr<llvm::MemoryBuffer> out_buf = llvm::MemoryBuffer::getMemBuffer(out_str);
// first pass // first pass
auto invocation1 = make_unique<CompilerInvocation>(); CompilerInstance compiler1;
if (!CompilerInvocation::CreateFromArgs(*invocation1, const_cast<const char **>(ccargs.data()), CompilerInvocation &invocation1 = compiler1.getInvocation();
const_cast<const char **>(ccargs.data()) + ccargs.size(), diags)) if (!CompilerInvocation::CreateFromArgs(
invocation1, const_cast<const char **>(ccargs.data()),
const_cast<const char **>(ccargs.data()) + ccargs.size(), diags))
return -1; return -1;
// This option instructs clang whether or not to free the file buffers that we // This option instructs clang whether or not to free the file buffers that we
// give to it. Since the embedded header files should be copied fewer times // give to it. Since the embedded header files should be copied fewer times
// and reused if possible, set this flag to true. // and reused if possible, set this flag to true.
invocation1->getPreprocessorOpts().RetainRemappedFileBuffers = true; invocation1.getPreprocessorOpts().RetainRemappedFileBuffers = true;
for (const auto &f : remapped_files_) for (const auto &f : remapped_files_)
invocation1->getPreprocessorOpts().addRemappedFile(f.first, &*f.second); invocation1.getPreprocessorOpts().addRemappedFile(f.first, &*f.second);
invocation1->getPreprocessorOpts().addRemappedFile(main_path, &*out_buf); invocation1.getPreprocessorOpts().addRemappedFile(main_path, &*out_buf);
invocation1->getFrontendOpts().Inputs.clear(); invocation1.getFrontendOpts().Inputs.clear();
invocation1->getFrontendOpts().Inputs.push_back(FrontendInputFile(main_path, IK_C)); invocation1.getFrontendOpts().Inputs.push_back(
invocation1->getFrontendOpts().DisableFree = false; FrontendInputFile(main_path, IK_C));
invocation1.getFrontendOpts().DisableFree = false;
CompilerInstance compiler1;
compiler1.setInvocation(invocation1.release());
compiler1.createDiagnostics(); compiler1.createDiagnostics();
// capture the rewritten c file // capture the rewritten c file
...@@ -270,21 +272,22 @@ int ClangLoader::parse(unique_ptr<llvm::Module> *mod, unique_ptr<vector<TableDes ...@@ -270,21 +272,22 @@ int ClangLoader::parse(unique_ptr<llvm::Module> *mod, unique_ptr<vector<TableDes
*tables = bact.take_tables(); *tables = bact.take_tables();
// second pass, clear input and take rewrite buffer // second pass, clear input and take rewrite buffer
auto invocation2 = make_unique<CompilerInvocation>();
if (!CompilerInvocation::CreateFromArgs(*invocation2, const_cast<const char **>(ccargs.data()),
const_cast<const char **>(ccargs.data()) + ccargs.size(), diags))
return -1;
CompilerInstance compiler2; CompilerInstance compiler2;
invocation2->getPreprocessorOpts().RetainRemappedFileBuffers = true; CompilerInvocation &invocation2 = compiler2.getInvocation();
if (!CompilerInvocation::CreateFromArgs(
invocation2, const_cast<const char **>(ccargs.data()),
const_cast<const char **>(ccargs.data()) + ccargs.size(), diags))
return -1;
invocation2.getPreprocessorOpts().RetainRemappedFileBuffers = true;
for (const auto &f : remapped_files_) for (const auto &f : remapped_files_)
invocation2->getPreprocessorOpts().addRemappedFile(f.first, &*f.second); invocation2.getPreprocessorOpts().addRemappedFile(f.first, &*f.second);
invocation2->getPreprocessorOpts().addRemappedFile(main_path, &*out_buf1); invocation2.getPreprocessorOpts().addRemappedFile(main_path, &*out_buf1);
invocation2->getFrontendOpts().Inputs.clear(); invocation2.getFrontendOpts().Inputs.clear();
invocation2->getFrontendOpts().Inputs.push_back(FrontendInputFile(main_path, IK_C)); invocation2.getFrontendOpts().Inputs.push_back(
invocation2->getFrontendOpts().DisableFree = false; FrontendInputFile(main_path, IK_C));
invocation2.getFrontendOpts().DisableFree = false;
// suppress warnings in the 2nd pass, but bail out on errors (our fault) // suppress warnings in the 2nd pass, but bail out on errors (our fault)
invocation2->getDiagnosticOpts().IgnoreWarnings = true; invocation2.getDiagnosticOpts().IgnoreWarnings = true;
compiler2.setInvocation(invocation2.release());
compiler2.createDiagnostics(); compiler2.createDiagnostics();
EmitLLVMOnlyAction ir_act(&*ctx_); EmitLLVMOnlyAction ir_act(&*ctx_);
......
...@@ -764,7 +764,7 @@ class BPF(object): ...@@ -764,7 +764,7 @@ class BPF(object):
fn = self.load_func(fn_name, BPF.KPROBE) fn = self.load_func(fn_name, BPF.KPROBE)
ev_name = "p_%s_0x%x" % (self._probe_repl.sub("_", path), addr) ev_name = "p_%s_0x%x" % (self._probe_repl.sub("_", path), addr)
res = lib.bpf_attach_uprobe(fn.fd, 0, ev_name.encode("ascii"), res = lib.bpf_attach_uprobe(fn.fd, 0, ev_name.encode("ascii"),
path, addr, pid, cpu, group_fd, path.encode("ascii"), addr, pid, cpu, group_fd,
self._reader_cb_impl, ct.cast(id(self), ct.py_object)) self._reader_cb_impl, ct.cast(id(self), ct.py_object))
res = ct.cast(res, ct.c_void_p) res = ct.cast(res, ct.c_void_p)
if not res: if not res:
...@@ -814,7 +814,7 @@ class BPF(object): ...@@ -814,7 +814,7 @@ class BPF(object):
fn = self.load_func(fn_name, BPF.KPROBE) fn = self.load_func(fn_name, BPF.KPROBE)
ev_name = "r_%s_0x%x" % (self._probe_repl.sub("_", path), addr) ev_name = "r_%s_0x%x" % (self._probe_repl.sub("_", path), addr)
res = lib.bpf_attach_uprobe(fn.fd, 1, ev_name.encode("ascii"), res = lib.bpf_attach_uprobe(fn.fd, 1, ev_name.encode("ascii"),
path, addr, pid, cpu, group_fd, path.encode("ascii"), addr, pid, cpu, group_fd,
self._reader_cb_impl, ct.cast(id(self), ct.py_object)) self._reader_cb_impl, ct.cast(id(self), ct.py_object))
res = ct.cast(res, ct.c_void_p) res = ct.cast(res, ct.c_void_p)
if not res: if not res:
...@@ -1046,7 +1046,8 @@ class BPF(object): ...@@ -1046,7 +1046,8 @@ class BPF(object):
for k, v in self.open_tracepoints.items(): for k, v in self.open_tracepoints.items():
lib.perf_reader_free(v) lib.perf_reader_free(v)
(tp_category, tp_name) = k.split(':') (tp_category, tp_name) = k.split(':')
lib.bpf_detach_tracepoint(tp_category, tp_name) lib.bpf_detach_tracepoint(tp_category.encode("ascii"),
tp_name.encode("ascii"))
self.open_tracepoints.clear() self.open_tracepoints.clear()
for (ev_type, ev_config) in list(self.open_perf_events.keys()): for (ev_type, ev_config) in list(self.open_perf_events.keys()):
self.detach_perf_event(ev_type, ev_config) self.detach_perf_event(ev_type, ev_config)
......
...@@ -17,7 +17,7 @@ endif() ...@@ -17,7 +17,7 @@ endif()
add_test(NAME py_test_stat1_b WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} add_test(NAME py_test_stat1_b WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMAND ${TEST_WRAPPER} py_stat1_b namespace ${CMAKE_CURRENT_SOURCE_DIR}/test_stat1.py test_stat1.b proto.b) COMMAND ${TEST_WRAPPER} py_stat1_b namespace ${CMAKE_CURRENT_SOURCE_DIR}/test_stat1.py test_stat1.b proto.b)
add_test(NAME py_test_bpf_log WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} add_test(NAME py_test_bpf_log WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMAND ${TEST_WRAPPER} py_bpf_prog namespace ${CMAKE_CURRENT_SOURCE_DIR}/test_bpf_log.py) COMMAND ${TEST_WRAPPER} py_bpf_prog sudo ${CMAKE_CURRENT_SOURCE_DIR}/test_bpf_log.py)
add_test(NAME py_test_stat1_c WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} add_test(NAME py_test_stat1_c WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMAND ${TEST_WRAPPER} py_stat1_c namespace ${CMAKE_CURRENT_SOURCE_DIR}/test_stat1.py test_stat1.c) COMMAND ${TEST_WRAPPER} py_stat1_c namespace ${CMAKE_CURRENT_SOURCE_DIR}/test_stat1.py test_stat1.c)
#add_test(NAME py_test_xlate1_b WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} #add_test(NAME py_test_xlate1_b WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
......
...@@ -51,7 +51,7 @@ class TestBPFProgLoad(TestCase): ...@@ -51,7 +51,7 @@ class TestBPFProgLoad(TestCase):
except Exception: except Exception:
self.fp.flush() self.fp.flush()
self.fp.seek(0) self.fp.seek(0)
self.assertEqual(error_msg in self.fp.read(), True) self.assertEqual(error_msg in self.fp.read().decode(), True)
def test_log_no_debug(self): def test_log_no_debug(self):
...@@ -61,7 +61,7 @@ class TestBPFProgLoad(TestCase): ...@@ -61,7 +61,7 @@ class TestBPFProgLoad(TestCase):
except Exception: except Exception:
self.fp.flush() self.fp.flush()
self.fp.seek(0) self.fp.seek(0)
self.assertEqual(error_msg in self.fp.read(), True) self.assertEqual(error_msg in self.fp.read().decode(), True)
if __name__ == "__main__": if __name__ == "__main__":
......
...@@ -61,10 +61,8 @@ class TestTracepointDataLoc(unittest.TestCase): ...@@ -61,10 +61,8 @@ class TestTracepointDataLoc(unittest.TestCase):
b = bcc.BPF(text=text) b = bcc.BPF(text=text)
subprocess.check_output(["/bin/ls"]) subprocess.check_output(["/bin/ls"])
sleep(1) sleep(1)
found = False self.assertTrue("/bin/ls" in [v.filename.decode()
for k, v in b["execs"].items(): for v in b["execs"].values()])
found = "ls" in v.filename
self.assertTrue(found, "'ls' was not found in map")
if __name__ == "__main__": if __name__ == "__main__":
unittest.main() unittest.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