Extract table types from B programs as well
authorBrenden Blanco <bblanco@plumgrid.com>
Fri, 7 Aug 2015 16:56:46 +0000 (09:56 -0700)
committerBrenden Blanco <bblanco@plumgrid.com>
Fri, 7 Aug 2015 16:56:46 +0000 (09:56 -0700)
Signed-off-by: Brenden Blanco <bblanco@plumgrid.com>
CMakeLists.txt
src/cc/bpf_module.cc
src/cc/frontends/b/codegen_llvm.cc
src/cc/frontends/b/codegen_llvm.h
src/cc/frontends/b/loader.cc
src/cc/frontends/b/loader.h
src/cc/frontends/clang/b_frontend_action.h
src/cc/table_desc.h [new file with mode: 0644]

index 1dc4280..a8bb4f6 100644 (file)
@@ -41,8 +41,8 @@ FOREACH(DIR ${LLVM_INCLUDE_DIRS})
   include_directories("${DIR}/../tools/clang/include")
 ENDFOREACH()
 
-set(CMAKE_C_FLAGS "-Wall")
-set(CMAKE_CXX_FLAGS "-std=c++11 -Wall")
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall")
 endif()
 
 add_subdirectory(scripts)
index 3fb5653..95e6bbd 100644 (file)
@@ -157,6 +157,12 @@ int BPFModule::annotate() {
   for (auto fn = mod_->getFunctionList().begin(); fn != mod_->getFunctionList().end(); ++fn)
     fn->addFnAttr(Attribute::AlwaysInline);
 
+  for (auto table : *tables_) {
+    table_names_.push_back(table.first);
+    GlobalValue *gvar = mod_->getNamedValue(table.first);
+    if (!gvar) continue;
+    llvm::errs() << "table " << gvar->getName() << "\n";
+  }
   //for (auto s : mod_->getIdentifiedStructTypes()) {
   //  llvm::errs() << "struct " << s->getName() << "\n";
   //  for (auto e : s->elements()) {
@@ -229,9 +235,6 @@ int BPFModule::finalize() {
     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;
 }
 
@@ -377,11 +380,11 @@ int BPFModule::load_b(const string &filename, const string &proto_filename) {
   // pass the partially compiled module to the B frontend to continue with.
   if (int rc = load_includes(BCC_INSTALL_PREFIX "/share/bcc/include/bcc/helpers.h"))
     return rc;
-  if (int rc = annotate())
-    return rc;
 
   b_loader_.reset(new BLoader);
-  if (int rc = b_loader_->parse(&*mod_, filename, proto_filename))
+  if (int rc = b_loader_->parse(&*mod_, filename, proto_filename, &tables_))
+    return rc;
+  if (int rc = annotate())
     return rc;
   if (int rc = finalize())
     return rc;
index f4dee19..4b1c734 100644 (file)
@@ -36,6 +36,7 @@
 #include "exception.h"
 #include "codegen_llvm.h"
 #include "lexer.h"
+#include "table_desc.h"
 #include "type_helper.h"
 #include "linux/bpf.h"
 #include "libbpf.h"
@@ -47,6 +48,7 @@ using namespace llvm;
 
 using std::for_each;
 using std::make_tuple;
+using std::map;
 using std::pair;
 using std::set;
 using std::string;
@@ -1219,7 +1221,7 @@ StatusTuple CodegenLLVM::visit_func_decl_stmt_node(FuncDeclStmtNode *n) {
   return mkstatus(0);
 }
 
-StatusTuple CodegenLLVM::visit(Node* root) {
+StatusTuple CodegenLLVM::visit(Node* root, map<string, BPFTable> &tables) {
   scopes_->set_current(scopes_->top_state());
   scopes_->set_current(scopes_->top_var());
 
@@ -1232,6 +1234,15 @@ StatusTuple CodegenLLVM::visit(Node* root) {
     TRY2((*it)->accept(this));
   //TRY2(print_parser());
 
+  for (auto table : tables_) {
+    BPFTable desc = {
+      table_fds_[table.first],
+      table.first->key_type_->bit_width_ >> 3,
+      table.first->leaf_type_->bit_width_ >> 3,
+      table.first->size_,
+    };
+    tables[table.first->id_->name_] = desc;
+  }
   return mkstatus(0);
 }
 
index 3705404..f256e28 100644 (file)
@@ -16,6 +16,7 @@
 
 #pragma once
 
+#include <map>
 #include <stdio.h>
 #include <vector>
 #include <string>
@@ -40,6 +41,8 @@ class GlobalVariable;
 }
 
 namespace ebpf {
+class BPFTable;
+
 namespace cc {
 
 class BlockStack;
@@ -60,7 +63,7 @@ class CodegenLLVM : public Visitor {
   EXPAND_NODES(VISIT)
 #undef VISIT
 
-  virtual STATUS_RETURN visit(Node* n);
+  virtual STATUS_RETURN visit(Node* n, std::map<string, BPFTable> &tables);
 
   int get_table_fd(const std::string &name) const;
 
index 24a4318..75d3d53 100644 (file)
 #include "type_check.h"
 #include "codegen_llvm.h"
 #include "loader.h"
+#include "table_desc.h"
 
 using std::get;
+using std::map;
 using std::string;
+using std::unique_ptr;
 
 namespace ebpf {
 
@@ -30,7 +33,8 @@ BLoader::BLoader() {
 BLoader::~BLoader() {
 }
 
-int BLoader::parse(llvm::Module *mod, const string &filename, const string &proto_filename) {
+int BLoader::parse(llvm::Module *mod, const string &filename, const string &proto_filename,
+                   unique_ptr<map<string, BPFTable>> *tables) {
   int rc;
 
   proto_parser_ = make_unique<ebpf::cc::Parser>(proto_filename);
@@ -57,8 +61,10 @@ int BLoader::parse(llvm::Module *mod, const string &filename, const string &prot
     return -1;
   }
 
+  *tables = make_unique<map<string, BPFTable>>();
+
   codegen_ = ebpf::make_unique<ebpf::cc::CodegenLLVM>(mod, parser_->scopes_.get(), proto_parser_->scopes_.get());
-  ret = codegen_->visit(parser_->root_node_);
+  ret = codegen_->visit(parser_->root_node_, **tables);
   if (get<0>(ret) != 0 || get<1>(ret).size()) {
     fprintf(stderr, "Codegen error @line=%d: %s\n", get<0>(ret), get<1>(ret).c_str());
     return get<0>(ret);
index 80ee874..82a89ae 100644 (file)
@@ -16,6 +16,8 @@
 
 #pragma once
 
+#include <map>
+#include <memory>
 #include <string>
 
 namespace llvm {
@@ -24,6 +26,8 @@ class Module;
 
 namespace ebpf {
 
+class BPFTable;
+
 namespace cc {
 class Parser;
 class CodegenLLVM;
@@ -33,7 +37,8 @@ class BLoader {
  public:
   BLoader();
   ~BLoader();
-  int parse(llvm::Module *mod, const std::string &filename, const std::string &proto_filename);
+  int parse(llvm::Module *mod, const std::string &filename, const std::string &proto_filename,
+            std::unique_ptr<std::map<std::string, BPFTable>> *tables);
   int get_table_fd(const std::string &name) const;
  private:
   std::unique_ptr<cc::Parser> parser_;
index ff17adc..61bccee 100644 (file)
@@ -23,6 +23,8 @@
 #include <clang/Frontend/FrontendAction.h>
 #include <clang/Rewrite/Core/Rewriter.h>
 
+#include "table_desc.h"
+
 namespace clang {
 class ASTConsumer;
 class ASTContext;
@@ -36,17 +38,6 @@ class StringRef;
 
 namespace ebpf {
 
-struct BPFTable {
-  int fd;
-  size_t key_size;
-  size_t leaf_size;
-  size_t max_entries;
-  std::string key_desc;
-  std::string leaf_desc;
-  std::string key_reader;
-  std::string leaf_reader;
-};
-
 // Helper visitor for constructing a string representation of a key/leaf decl
 class BMapDeclVisitor : public clang::RecursiveASTVisitor<BMapDeclVisitor> {
  public:
diff --git a/src/cc/table_desc.h b/src/cc/table_desc.h
new file mode 100644 (file)
index 0000000..795b61f
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2015 PLUMgrid, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <cstdint>
+#include <string>
+
+namespace ebpf {
+
+struct BPFTable {
+  int fd;
+  size_t key_size;  // sizes are in bytes
+  size_t leaf_size;
+  size_t max_entries;
+  std::string key_desc;
+  std::string leaf_desc;
+  std::string key_reader;
+  std::string leaf_reader;
+};
+
+}  // namespace ebpf