Add index-based function references to c api
authorBrenden Blanco <bblanco@plumgrid.com>
Tue, 28 Jul 2015 03:29:25 +0000 (20:29 -0700)
committerBrenden Blanco <bblanco@plumgrid.com>
Tue, 28 Jul 2015 03:29:25 +0000 (20:29 -0700)
* Add the index based API so that an external api (bcc-fuse) can iterate
  through the maps and functions that were compiled in this program.
* Add a more unique section prefix to disambiguate exportable functions.

Signed-off-by: Brenden Blanco <bblanco@plumgrid.com>
src/cc/b_frontend_action.cc
src/cc/bpf_common.cc
src/cc/bpf_common.h
src/cc/bpf_module.cc
src/cc/bpf_module.h
src/cc/codegen_llvm.cc

index 899949d..b41d4d1 100644 (file)
@@ -90,7 +90,7 @@ bool BTypeVisitor::VisitFunctionDecl(FunctionDecl *D) {
   // 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();
index 746a789..79f2b54 100644 (file)
@@ -41,16 +41,40 @@ void bpf_module_destroy(void *program) {
   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) {
@@ -65,22 +89,52 @@ unsigned bpf_module_kern_version(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);
+}
+
 }
index 51a5614..68e567b 100644 (file)
@@ -29,11 +29,20 @@ void * bpf_module_create_from_string(const char *text, unsigned flags);
 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
 }
index 528abdb..b5f84c4 100644 (file)
@@ -76,6 +76,8 @@ using std::unique_ptr;
 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:
@@ -365,19 +367,55 @@ int BPFModule::finalize() {
 
   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;
 
@@ -400,6 +438,10 @@ unsigned BPFModule::kern_version() const {
   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;
@@ -408,6 +450,21 @@ int BPFModule::table_fd(const string &name) const {
   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);
@@ -415,6 +472,11 @@ const char * BPFModule::table_key_desc(const string &name) const {
   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);
index de847f7..77b454d 100644 (file)
@@ -38,6 +38,7 @@ class Parser;
 
 class BPFModule {
  private:
+  static const std::string FN_PREFIX;
   int init_engine();
   int parse();
   int finalize();
@@ -51,10 +52,19 @@ class BPFModule {
   ~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;
@@ -70,6 +80,8 @@ class BPFModule {
   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
index 25f6476..cae49ea 100644 (file)
@@ -1166,7 +1166,7 @@ StatusTuple CodegenLLVM::visit_func_decl_stmt_node(FuncDeclStmtNode *n) {
   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);