Commit aa7b2797 authored by Brenden Blanco's avatar Brenden Blanco

Add BPFModule::table_storage() helper

Adds a reference to the ts_ member, for use by BPF class to access the
storage object and perform lookups.

Note that get_hash_table/get_stack_table don't have an error return, so
failure to lookup the table name will result in undefined behavior
(which is actually the case prior to this commit as well).

Also update indentation per clang-format
Signed-off-by: default avatarBrenden Blanco <bblanco@gmail.com>
parent faea8c84
......@@ -395,8 +395,14 @@ StatusTuple BPF::detach_perf_event(uint32_t ev_type, uint32_t ev_config) {
StatusTuple BPF::open_perf_buffer(const std::string& name,
perf_reader_raw_cb cb, void* cb_cookie,
int page_cnt) {
if (perf_buffers_.find(name) == perf_buffers_.end())
perf_buffers_[name] = new BPFPerfBuffer(bpf_module_.get(), name);
if (perf_buffers_.find(name) == perf_buffers_.end()) {
TableStorage::iterator it;
if (!bpf_module_->table_storage().Find(Path({bpf_module_->id(), name}), it))
return StatusTuple(-1,
"open_perf_buffer: unable to find table_storage %s",
name.c_str());
perf_buffers_[name] = new BPFPerfBuffer(it->second);
}
if ((page_cnt & (page_cnt - 1)) != 0)
return StatusTuple(-1, "open_perf_buffer page_cnt must be a power of two");
auto table = perf_buffers_[name];
......
......@@ -46,7 +46,7 @@ public:
static const int BPF_MAX_STACK_DEPTH = 127;
explicit BPF(unsigned int flag = 0, TableStorage* ts = nullptr)
: bpf_module_(new BPFModule(flag, ts)), ts_(ts) {}
: bpf_module_(new BPFModule(flag, ts)) {}
StatusTuple init(const std::string& bpf_program,
std::vector<std::string> cflags = {},
std::vector<USDT> usdt = {});
......@@ -93,16 +93,17 @@ public:
template <class KeyType, class ValueType>
BPFHashTable<KeyType, ValueType> get_hash_table(const std::string& name) {
if (ts_) {
TableStorage::iterator it;
if (ts_->Find(Path({name}), it))
if (bpf_module_->table_storage().Find(Path({bpf_module_->id(), name}), it))
return BPFHashTable<KeyType, ValueType>(it->second);
}
return BPFHashTable<KeyType, ValueType>(bpf_module_.get(), name);
return BPFHashTable<KeyType, ValueType>({});
}
BPFStackTable get_stack_table(const std::string& name) {
return BPFStackTable(bpf_module_.get(), name);
TableStorage::iterator it;
if (bpf_module_->table_storage().Find(Path({bpf_module_->id(), name}), it))
return BPFStackTable(it->second);
return BPFStackTable({});
}
StatusTuple open_perf_buffer(const std::string& name, perf_reader_raw_cb cb,
......@@ -160,7 +161,6 @@ private:
uint64_t symbol_addr, bcc_symbol* output);
std::unique_ptr<BPFModule> bpf_module_;
TableStorage* ts_;
std::map<std::string, int> funcs_;
......
......@@ -34,17 +34,10 @@ namespace ebpf {
template <class KeyType, class ValueType>
class BPFTableBase {
public:
public:
size_t capacity() { return capacity_; }
protected:
BPFTableBase(BPFModule* bpf_module, const std::string& name) {
size_t id_ = bpf_module->table_id(name);
if (id_ >= bpf_module->num_tables())
throw std::invalid_argument("Table " + name + " does not exist");
fd_ = bpf_module->table_fd(id_);
capacity_ = bpf_module->table_max_entries(id_);
};
protected:
explicit BPFTableBase(const TableDesc& desc) {
fd_ = desc.fd;
capacity_ = desc.max_entries;
......@@ -76,9 +69,8 @@ protected:
template <class KeyType, class ValueType>
class BPFHashTable : protected BPFTableBase<KeyType, ValueType> {
public:
explicit BPFHashTable(const TableDesc& desc) : BPFTableBase<KeyType, ValueType>(desc) {}
BPFHashTable(BPFModule* bpf_module, const std::string& name)
: BPFTableBase<KeyType, ValueType>(bpf_module, name) {}
explicit BPFHashTable(const TableDesc& desc)
: BPFTableBase<KeyType, ValueType>(desc) {}
ValueType get_value(const KeyType& key) {
ValueType res;
......@@ -115,22 +107,22 @@ struct stacktrace_t {
};
class BPFStackTable : protected BPFTableBase<int, stacktrace_t> {
public:
BPFStackTable(BPFModule* bpf_module, const std::string& name)
: BPFTableBase<int, stacktrace_t>(bpf_module, name) {}
public:
BPFStackTable(const TableDesc& desc)
: BPFTableBase<int, stacktrace_t>(desc) {}
~BPFStackTable();
std::vector<intptr_t> get_stack_addr(int stack_id);
std::vector<std::string> get_stack_symbol(int stack_id, int pid);
private:
private:
std::map<int, void*> pid_sym_;
};
class BPFPerfBuffer : protected BPFTableBase<int, int> {
public:
BPFPerfBuffer(BPFModule* bpf_module, const std::string& name)
: BPFTableBase<int, int>(bpf_module, name), epfd_(-1) {}
public:
BPFPerfBuffer(const TableDesc& desc)
: BPFTableBase<int, int>(desc), epfd_(-1) {}
~BPFPerfBuffer();
StatusTuple open_all_cpu(perf_reader_raw_cb cb, void* cb_cookie,
......@@ -138,7 +130,7 @@ public:
StatusTuple close_all_cpu();
void poll(int timeout);
private:
private:
StatusTuple open_on_cpu(perf_reader_raw_cb cb, int cpu, void* cb_cookie,
int page_cnt);
StatusTuple close_on_cpu(int cpu);
......
......@@ -102,7 +102,10 @@ class MyMemoryManager : public SectionMemoryManager {
};
BPFModule::BPFModule(unsigned flags, TableStorage *ts)
: flags_(flags), ctx_(new LLVMContext), ts_(ts) {
: flags_(flags),
ctx_(new LLVMContext),
id_(std::to_string((uintptr_t)this)),
ts_(ts) {
InitializeNativeTarget();
InitializeNativeTargetAsmPrinter();
LLVMInitializeBPFTarget();
......@@ -120,7 +123,7 @@ BPFModule::~BPFModule() {
engine_.reset();
rw_engine_.reset();
ctx_.reset();
ts_->DeletePrefix(Path({std::to_string((uintptr_t)this)}));
ts_->DeletePrefix(Path({id_}));
}
static void debug_printf(Module *mod, IRBuilder<> &B, const string &fmt, vector<Value *> args) {
......@@ -322,8 +325,7 @@ 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, const char *cflags[], int ncflags) {
clang_loader_ = make_unique<ClangLoader>(&*ctx_, flags_);
if (clang_loader_->parse(&mod_, *ts_, file, in_memory, cflags, ncflags,
std::to_string((uintptr_t)this)))
if (clang_loader_->parse(&mod_, *ts_, file, in_memory, cflags, ncflags, id_))
return -1;
return 0;
}
......@@ -349,7 +351,7 @@ int BPFModule::annotate() {
auto m = make_unique<Module>("sscanf", *ctx_);
size_t id = 0;
Path path({std::to_string((uintptr_t)this)});
Path path({id_});
for (auto it = ts_->lower_bound(path), up = ts_->upper_bound(path); it != up; ++it) {
TableDesc &table = it->second;
tables_.push_back(&it->second);
......@@ -725,8 +727,7 @@ int BPFModule::load_b(const string &filename, const string &proto_filename) {
return rc;
b_loader_.reset(new BLoader(flags_));
if (int rc =
b_loader_->parse(&*mod_, filename, proto_filename, *ts_, std::to_string((uintptr_t)this)))
if (int rc = b_loader_->parse(&*mod_, filename, proto_filename, *ts_, id_))
return rc;
if (int rc = annotate())
return rc;
......
......@@ -58,6 +58,7 @@ class BPFModule {
int load_b(const std::string &filename, const std::string &proto_filename);
int load_c(const std::string &filename, const char *cflags[], int ncflags);
int load_string(const std::string &text, const char *cflags[], int ncflags);
std::string id() const { return id_; }
size_t num_functions() const;
uint8_t * function_start(size_t id) const;
uint8_t * function_start(const std::string &name) const;
......@@ -89,6 +90,8 @@ class BPFModule {
int table_leaf_scanf(size_t id, const char *buf, void *leaf);
char * license() const;
unsigned kern_version() const;
TableStorage &table_storage() { return *ts_; }
private:
unsigned flags_; // 0x1 for printing
std::string filename_;
......@@ -105,6 +108,7 @@ class BPFModule {
std::vector<std::string> function_names_;
std::map<llvm::Type *, llvm::Function *> readers_;
std::map<llvm::Type *, llvm::Function *> writers_;
std::string id_;
TableStorage *ts_;
std::unique_ptr<TableStorage> local_ts_;
};
......
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