Commit 62cc8b76 authored by 4ast's avatar 4ast

Merge pull request #92 from iovisor/bblanco_dev

Add index-based function references to c api
parents aacef040 32109bf9
......@@ -25,9 +25,7 @@
#include "b_frontend_action.h"
extern "C"
int bpf_create_map(enum bpf_map_type map_type, int key_size, int value_size,
int max_entries);
#include "libbpf.h"
namespace ebpf {
......@@ -90,7 +88,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_PREFIX + 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();
......
......@@ -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);
}
}
......@@ -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
}
......
......@@ -63,6 +63,7 @@
#include "b_frontend_action.h"
#include "bpf_module.h"
#include "kbuild_helper.h"
#include "libbpf.h"
namespace ebpf {
......@@ -76,6 +77,8 @@ using std::unique_ptr;
using std::vector;
using namespace llvm;
const string BPFModule::FN_PREFIX = BPF_FN_PREFIX;
// Snooping class to remember the sections as the JIT creates them
class MyMemoryManager : public SectionMemoryManager {
public:
......@@ -365,19 +368,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 +439,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 +451,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 +473,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);
......
......@@ -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
......@@ -38,9 +38,7 @@
#include "cc/lexer.h"
#include "cc/type_helper.h"
#include "linux/bpf.h"
extern "C"
int bpf_create_map(int map_type, int key_size, int value_size, int max_entries);
#include "libbpf.h"
namespace ebpf {
namespace cc {
......@@ -801,7 +799,7 @@ StatusTuple CodegenLLVM::visit_table_index_expr_node(TableIndexExprNode *n) {
// result = lookup(key)
Value *lookup1 = B.CreateBitCast(B.CreateCall(lookup_fn, vector<Value *>({pseudo_map_fd, key_ptr})), leaf_ptype);
Value *result;
Value *result = nullptr;
if (n->table_->policy_id()->name_ == "AUTO") {
Function *parent = B.GetInsertBlock()->getParent();
BasicBlock *label_start = B.GetInsertBlock();
......@@ -1079,7 +1077,7 @@ StatusTuple CodegenLLVM::visit_table_decl_stmt_node(TableDeclStmtNode *n) {
auto leaf = scopes_->top_struct()->lookup(n->leaf_id()->name_, /*search_local*/true);
if (!leaf) return mkstatus_(n, "cannot find leaf %s", n->leaf_id()->name_.c_str());
int map_type = BPF_MAP_TYPE_UNSPEC;
bpf_map_type map_type = BPF_MAP_TYPE_UNSPEC;
if (n->type_id()->name_ == "FIXED_MATCH")
map_type = BPF_MAP_TYPE_HASH;
else if (n->type_id()->name_ == "INDEXED")
......@@ -1166,7 +1164,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_PREFIX + n->id_->name_);
BasicBlock *label_entry = BasicBlock::Create(ctx(), "entry", fn);
B.SetInsertPoint(label_entry);
......
......@@ -49,6 +49,10 @@ int bpf_detach_kprobe(const char *event_desc);
#define LOG_BUF_SIZE 65536
extern char bpf_log_buf[LOG_BUF_SIZE];
// Put non-static/inline functions in their own section with this prefix +
// fn_name to enable discovery by the bcc library.
#define BPF_FN_PREFIX ".bpf.fn."
/* ALU ops on registers, bpf_add|sub|...: dst_reg += src_reg */
#define BPF_ALU64_REG(OP, DST, SRC) \
......
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