// put each non-static non-inline function decl in its own section, to be
// extracted by the MemoryManager
if (D->isExternallyVisible() && D->hasBody()) {
- string attr = string("__attribute__((section(\".") + D->getName().str() + "\")))\n";
+ string attr = string("__attribute__((section(\".bpf.fn.") + D->getName().str() + "\")))\n";
rewriter_.InsertText(D->getLocStart(), attr);
// remember the arg names of the current function...first one is the ctx
fn_args_.clear();
delete mod;
}
+size_t bpf_num_functions(void *program) {
+ auto mod = static_cast<ebpf::BPFModule *>(program);
+ if (!mod) return 0;
+ return mod->num_functions();
+}
+
+const char * bpf_function_name(void *program, size_t id) {
+ auto mod = static_cast<ebpf::BPFModule *>(program);
+ if (!mod) return nullptr;
+ return mod->function_name(id);
+}
+
void * bpf_function_start(void *program, const char *name) {
auto mod = static_cast<ebpf::BPFModule *>(program);
if (!mod) return nullptr;
- return mod->start(name);
+ return mod->function_start(name);
+}
+
+void * bpf_function_start_id(void *program, size_t id) {
+ auto mod = static_cast<ebpf::BPFModule *>(program);
+ if (!mod) return nullptr;
+ return mod->function_start(id);
}
size_t bpf_function_size(void *program, const char *name) {
auto mod = static_cast<ebpf::BPFModule *>(program);
if (!mod) return 0;
- return mod->size(name);
+ return mod->function_size(name);
+}
+
+size_t bpf_function_size_id(void *program, size_t id) {
+ auto mod = static_cast<ebpf::BPFModule *>(program);
+ if (!mod) return 0;
+ return mod->function_size(id);
}
char * bpf_module_license(void *program) {
return mod->kern_version();
}
+size_t bpf_num_tables(void *program) {
+ auto mod = static_cast<ebpf::BPFModule *>(program);
+ if (!mod) return -1;
+ return mod->num_tables();
+}
+
int bpf_table_fd(void *program, const char *table_name) {
auto mod = static_cast<ebpf::BPFModule *>(program);
if (!mod) return -1;
return mod->table_fd(table_name);
}
+int bpf_table_fd_id(void *program, size_t id) {
+ auto mod = static_cast<ebpf::BPFModule *>(program);
+ if (!mod) return -1;
+ return mod->table_fd(id);
+}
+
+const char * bpf_table_name(void *program, size_t id) {
+ auto mod = static_cast<ebpf::BPFModule *>(program);
+ if (!mod) return nullptr;
+ return mod->table_name(id);
+}
+
const char * bpf_table_key_desc(void *program, const char *table_name) {
auto mod = static_cast<ebpf::BPFModule *>(program);
if (!mod) return nullptr;
return mod->table_key_desc(table_name);
}
+const char * bpf_table_key_desc_id(void *program, size_t id) {
+ auto mod = static_cast<ebpf::BPFModule *>(program);
+ if (!mod) return nullptr;
+ return mod->table_key_desc(id);
+}
+
const char * bpf_table_leaf_desc(void *program, const char *table_name) {
auto mod = static_cast<ebpf::BPFModule *>(program);
if (!mod) return nullptr;
return mod->table_leaf_desc(table_name);
}
+const char * bpf_table_leaf_desc_id(void *program, size_t id) {
+ auto mod = static_cast<ebpf::BPFModule *>(program);
+ if (!mod) return nullptr;
+ return mod->table_leaf_desc(id);
+}
+
}
void bpf_module_destroy(void *program);
char * bpf_module_license(void *program);
unsigned bpf_module_kern_version(void *program);
+size_t bpf_num_functions(void *program);
+const char * bpf_function_name(void *program, size_t id);
+void * bpf_function_start_id(void *program, size_t id);
void * bpf_function_start(void *program, const char *name);
+size_t bpf_function_size_id(void *program, size_t id);
size_t bpf_function_size(void *program, const char *name);
+size_t bpf_num_tables(void *program);
int bpf_table_fd(void *program, const char *table_name);
+int bpf_table_fd_id(void *program, size_t id);
+const char * bpf_table_name(void *program, size_t id);
const char * bpf_table_key_desc(void *program, const char *table_name);
+const char * bpf_table_key_desc_id(void *program, size_t id);
const char * bpf_table_leaf_desc(void *program, const char *table_name);
+const char * bpf_table_leaf_desc_id(void *program, size_t id);
#ifdef __cplusplus
}
using std::vector;
using namespace llvm;
+const string BPFModule::FN_PREFIX = ".bpf.fn.";
+
// Snooping class to remember the sections as the JIT creates them
class MyMemoryManager : public SectionMemoryManager {
public:
engine_->finalizeObject();
+ // give functions an id
+ for (auto section : sections_)
+ if (!strncmp(FN_PREFIX.c_str(), section.first.c_str(), FN_PREFIX.size()))
+ function_names_.push_back(section.first);
+
+ for (auto table : *tables_)
+ table_names_.push_back(table.first);
+
return 0;
}
-uint8_t * BPFModule::start(const string &name) const {
- auto section = sections_.find("." + name);
+size_t BPFModule::num_functions() const {
+ return function_names_.size();
+}
+
+const char * BPFModule::function_name(size_t id) const {
+ if (id >= function_names_.size())
+ return nullptr;
+ return function_names_[id].c_str() + FN_PREFIX.size();
+}
+
+uint8_t * BPFModule::function_start(size_t id) const {
+ if (id >= function_names_.size())
+ return nullptr;
+ auto section = sections_.find(function_names_[id]);
+ if (section == sections_.end())
+ return nullptr;
+ return get<0>(section->second);
+}
+
+uint8_t * BPFModule::function_start(const string &name) const {
+ auto section = sections_.find(FN_PREFIX + name);
if (section == sections_.end())
return nullptr;
return get<0>(section->second);
}
-size_t BPFModule::size(const string &name) const {
- auto section = sections_.find("." + name);
+size_t BPFModule::function_size(size_t id) const {
+ if (id >= function_names_.size())
+ return 0;
+ auto section = sections_.find(function_names_[id]);
+ if (section == sections_.end())
+ return 0;
+ return get<1>(section->second);
+}
+
+size_t BPFModule::function_size(const string &name) const {
+ auto section = sections_.find(FN_PREFIX + name);
if (section == sections_.end())
return 0;
return *(unsigned *)get<0>(section->second);
}
+size_t BPFModule::num_tables() const {
+ return table_names_.size();
+}
+
int BPFModule::table_fd(const string &name) const {
int fd = codegen_ ? codegen_->get_table_fd(name) : -1;
if (fd >= 0) return fd;
return table_it->second.fd;
}
+int BPFModule::table_fd(size_t id) const {
+ if (id >= table_names_.size()) return -1;
+ return table_fd(table_names_[id]);
+}
+
+const char * BPFModule::table_name(size_t id) const {
+ if (id >= table_names_.size()) return nullptr;
+ return table_names_[id].c_str();
+}
+
+const char * BPFModule::table_key_desc(size_t id) const {
+ if (id >= table_names_.size()) return nullptr;
+ return table_key_desc(table_names_[id]);
+}
+
const char * BPFModule::table_key_desc(const string &name) const {
if (codegen_) return nullptr;
auto table_it = tables_->find(name);
return table_it->second.key_desc.c_str();
}
+const char * BPFModule::table_leaf_desc(size_t id) const {
+ if (id >= table_names_.size()) return nullptr;
+ return table_leaf_desc(table_names_[id]);
+}
+
const char * BPFModule::table_leaf_desc(const string &name) const {
if (codegen_) return nullptr;
auto table_it = tables_->find(name);
class BPFModule {
private:
+ static const std::string FN_PREFIX;
int init_engine();
int parse();
int finalize();
~BPFModule();
int load(const std::string &filename, const std::string &proto_filename);
int load_string(const std::string &text);
- uint8_t * start(const std::string &name) const;
- size_t size(const std::string &name) const;
+ size_t num_functions() const;
+ uint8_t * function_start(size_t id) const;
+ uint8_t * function_start(const std::string &name) const;
+ const char * function_name(size_t id) const;
+ size_t function_size(size_t id) const;
+ size_t function_size(const std::string &name) const;
+ size_t num_tables() const;
+ int table_fd(size_t id) const;
int table_fd(const std::string &name) const;
+ const char * table_name(size_t id) const;
+ const char * table_key_desc(size_t id) const;
const char * table_key_desc(const std::string &name) const;
+ const char * table_leaf_desc(size_t id) const;
const char * table_leaf_desc(const std::string &name) const;
char * license() const;
unsigned kern_version() const;
std::unique_ptr<ebpf::cc::CodegenLLVM> codegen_;
std::map<std::string, std::tuple<uint8_t *, uintptr_t>> sections_;
std::unique_ptr<std::map<std::string, BPFTable>> tables_;
+ std::vector<std::string> table_names_;
+ std::vector<std::string> function_names_;
};
} // namespace ebpf
Function *fn = mod_->getFunction(n->id_->name_);
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->setSection("." + n->id_->name_);
+ fn->setSection(".bpf.fn." + n->id_->name_);
BasicBlock *label_entry = BasicBlock::Create(ctx(), "entry", fn);
B.SetInsertPoint(label_entry);