Commit 5a19f90a authored by Brenden Blanco's avatar Brenden Blanco

Extract table types from B programs as well

Signed-off-by: default avatarBrenden Blanco <bblanco@plumgrid.com>
parent 52b0a903
...@@ -41,8 +41,8 @@ FOREACH(DIR ${LLVM_INCLUDE_DIRS}) ...@@ -41,8 +41,8 @@ FOREACH(DIR ${LLVM_INCLUDE_DIRS})
include_directories("${DIR}/../tools/clang/include") include_directories("${DIR}/../tools/clang/include")
ENDFOREACH() ENDFOREACH()
set(CMAKE_C_FLAGS "-Wall") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
set(CMAKE_CXX_FLAGS "-std=c++11 -Wall") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall")
endif() endif()
add_subdirectory(scripts) add_subdirectory(scripts)
......
...@@ -157,6 +157,12 @@ int BPFModule::annotate() { ...@@ -157,6 +157,12 @@ int BPFModule::annotate() {
for (auto fn = mod_->getFunctionList().begin(); fn != mod_->getFunctionList().end(); ++fn) for (auto fn = mod_->getFunctionList().begin(); fn != mod_->getFunctionList().end(); ++fn)
fn->addFnAttr(Attribute::AlwaysInline); 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()) { //for (auto s : mod_->getIdentifiedStructTypes()) {
// llvm::errs() << "struct " << s->getName() << "\n"; // llvm::errs() << "struct " << s->getName() << "\n";
// for (auto e : s->elements()) { // for (auto e : s->elements()) {
...@@ -229,9 +235,6 @@ int BPFModule::finalize() { ...@@ -229,9 +235,6 @@ int BPFModule::finalize() {
if (!strncmp(FN_PREFIX.c_str(), section.first.c_str(), FN_PREFIX.size())) if (!strncmp(FN_PREFIX.c_str(), section.first.c_str(), FN_PREFIX.size()))
function_names_.push_back(section.first); function_names_.push_back(section.first);
for (auto table : *tables_)
table_names_.push_back(table.first);
return 0; return 0;
} }
...@@ -377,11 +380,11 @@ int BPFModule::load_b(const string &filename, const string &proto_filename) { ...@@ -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. // 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")) if (int rc = load_includes(BCC_INSTALL_PREFIX "/share/bcc/include/bcc/helpers.h"))
return rc; return rc;
if (int rc = annotate())
return rc;
b_loader_.reset(new BLoader); 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; return rc;
if (int rc = finalize()) if (int rc = finalize())
return rc; return rc;
......
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#include "exception.h" #include "exception.h"
#include "codegen_llvm.h" #include "codegen_llvm.h"
#include "lexer.h" #include "lexer.h"
#include "table_desc.h"
#include "type_helper.h" #include "type_helper.h"
#include "linux/bpf.h" #include "linux/bpf.h"
#include "libbpf.h" #include "libbpf.h"
...@@ -47,6 +48,7 @@ using namespace llvm; ...@@ -47,6 +48,7 @@ using namespace llvm;
using std::for_each; using std::for_each;
using std::make_tuple; using std::make_tuple;
using std::map;
using std::pair; using std::pair;
using std::set; using std::set;
using std::string; using std::string;
...@@ -1219,7 +1221,7 @@ StatusTuple CodegenLLVM::visit_func_decl_stmt_node(FuncDeclStmtNode *n) { ...@@ -1219,7 +1221,7 @@ StatusTuple CodegenLLVM::visit_func_decl_stmt_node(FuncDeclStmtNode *n) {
return mkstatus(0); 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_state());
scopes_->set_current(scopes_->top_var()); scopes_->set_current(scopes_->top_var());
...@@ -1232,6 +1234,15 @@ StatusTuple CodegenLLVM::visit(Node* root) { ...@@ -1232,6 +1234,15 @@ StatusTuple CodegenLLVM::visit(Node* root) {
TRY2((*it)->accept(this)); TRY2((*it)->accept(this));
//TRY2(print_parser()); //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); return mkstatus(0);
} }
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#pragma once #pragma once
#include <map>
#include <stdio.h> #include <stdio.h>
#include <vector> #include <vector>
#include <string> #include <string>
...@@ -40,6 +41,8 @@ class GlobalVariable; ...@@ -40,6 +41,8 @@ class GlobalVariable;
} }
namespace ebpf { namespace ebpf {
class BPFTable;
namespace cc { namespace cc {
class BlockStack; class BlockStack;
...@@ -60,7 +63,7 @@ class CodegenLLVM : public Visitor { ...@@ -60,7 +63,7 @@ class CodegenLLVM : public Visitor {
EXPAND_NODES(VISIT) EXPAND_NODES(VISIT)
#undef 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; int get_table_fd(const std::string &name) const;
......
...@@ -18,9 +18,12 @@ ...@@ -18,9 +18,12 @@
#include "type_check.h" #include "type_check.h"
#include "codegen_llvm.h" #include "codegen_llvm.h"
#include "loader.h" #include "loader.h"
#include "table_desc.h"
using std::get; using std::get;
using std::map;
using std::string; using std::string;
using std::unique_ptr;
namespace ebpf { namespace ebpf {
...@@ -30,7 +33,8 @@ BLoader::BLoader() { ...@@ -30,7 +33,8 @@ BLoader::BLoader() {
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; int rc;
proto_parser_ = make_unique<ebpf::cc::Parser>(proto_filename); 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 ...@@ -57,8 +61,10 @@ int BLoader::parse(llvm::Module *mod, const string &filename, const string &prot
return -1; return -1;
} }
*tables = make_unique<map<string, BPFTable>>();
codegen_ = ebpf::make_unique<ebpf::cc::CodegenLLVM>(mod, parser_->scopes_.get(), proto_parser_->scopes_.get()); 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()) { 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()); fprintf(stderr, "Codegen error @line=%d: %s\n", get<0>(ret), get<1>(ret).c_str());
return get<0>(ret); return get<0>(ret);
......
...@@ -16,6 +16,8 @@ ...@@ -16,6 +16,8 @@
#pragma once #pragma once
#include <map>
#include <memory>
#include <string> #include <string>
namespace llvm { namespace llvm {
...@@ -24,6 +26,8 @@ class Module; ...@@ -24,6 +26,8 @@ class Module;
namespace ebpf { namespace ebpf {
class BPFTable;
namespace cc { namespace cc {
class Parser; class Parser;
class CodegenLLVM; class CodegenLLVM;
...@@ -33,7 +37,8 @@ class BLoader { ...@@ -33,7 +37,8 @@ class BLoader {
public: public:
BLoader(); BLoader();
~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; int get_table_fd(const std::string &name) const;
private: private:
std::unique_ptr<cc::Parser> parser_; std::unique_ptr<cc::Parser> parser_;
......
...@@ -23,6 +23,8 @@ ...@@ -23,6 +23,8 @@
#include <clang/Frontend/FrontendAction.h> #include <clang/Frontend/FrontendAction.h>
#include <clang/Rewrite/Core/Rewriter.h> #include <clang/Rewrite/Core/Rewriter.h>
#include "table_desc.h"
namespace clang { namespace clang {
class ASTConsumer; class ASTConsumer;
class ASTContext; class ASTContext;
...@@ -36,17 +38,6 @@ class StringRef; ...@@ -36,17 +38,6 @@ class StringRef;
namespace ebpf { 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 // Helper visitor for constructing a string representation of a key/leaf decl
class BMapDeclVisitor : public clang::RecursiveASTVisitor<BMapDeclVisitor> { class BMapDeclVisitor : public clang::RecursiveASTVisitor<BMapDeclVisitor> {
public: public:
......
/*
* 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
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