Skip to content

Commit

Permalink
Merge pull request iovisor#1332 from iovisor/ast_dev
Browse files Browse the repository at this point in the history
annotate program tag
  • Loading branch information
yonghong-song committed Sep 8, 2017
2 parents 6aec309 + 4f47e3b commit d56fff0
Show file tree
Hide file tree
Showing 11 changed files with 255 additions and 9 deletions.
4 changes: 4 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ if(NOT DEFINED BCC_KERNEL_MODULES_DIR)
set(BCC_KERNEL_MODULES_DIR "/lib/modules")
endif()

if(NOT DEFINED BCC_PROG_TAG_DIR)
set(BCC_PROG_TAG_DIR "/var/tmp/bcc")
endif()

# As reported in issue #735, GCC 6 has some behavioral problems when
# dealing with -isystem. Hence, skip the warning optimization
# altogether on that compiler.
Expand Down
2 changes: 1 addition & 1 deletion src/cc/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR}/compat)
add_definitions(${LLVM_DEFINITIONS})
configure_file(libbcc.pc.in ${CMAKE_CURRENT_BINARY_DIR}/libbcc.pc @ONLY)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC -DBCC_PROG_TAG_DIR='\"${BCC_PROG_TAG_DIR}\"'")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")

include(static_libstdc++)
Expand Down
4 changes: 4 additions & 0 deletions src/cc/api/BPF.cc
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,10 @@ StatusTuple BPF::load_func(const std::string& func_name,

if (fd < 0)
return StatusTuple(-1, "Failed to load %s: %d", func_name.c_str(), fd);

bpf_module_->annotate_prog_tag(func_name, fd,
reinterpret_cast<struct bpf_insn*>(func_start),
func_size);
funcs_[func_name] = fd;
return StatusTuple(0);
}
Expand Down
68 changes: 66 additions & 2 deletions src/cc/bpf_module.cc
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ BPFModule::BPFModule(unsigned flags, TableStorage *ts)
local_ts_ = createSharedTableStorage();
ts_ = &*local_ts_;
}
func_src_ = ebpf::make_unique<FuncSource>();
}

static StatusTuple unimplemented_sscanf(const char *, void *) {
Expand All @@ -133,6 +134,7 @@ BPFModule::~BPFModule() {
engine_.reset();
rw_engine_.reset();
ctx_.reset();
func_src_.reset();

ts_->DeletePrefix(Path({id_}));
}
Expand Down Expand Up @@ -456,7 +458,7 @@ unique_ptr<ExecutionEngine> BPFModule::finalize_rw(unique_ptr<Module> m) {
// load an entire c file as a module
int BPFModule::load_cfile(const string &file, bool in_memory, const char *cflags[], int ncflags) {
clang_loader_ = ebpf::make_unique<ClangLoader>(&*ctx_, flags_);
if (clang_loader_->parse(&mod_, *ts_, file, in_memory, cflags, ncflags, id_))
if (clang_loader_->parse(&mod_, *ts_, file, in_memory, cflags, ncflags, id_, *func_src_))
return -1;
return 0;
}
Expand All @@ -468,7 +470,7 @@ int BPFModule::load_cfile(const string &file, bool in_memory, const char *cflags
// build an ExecutionEngine.
int BPFModule::load_includes(const string &text) {
clang_loader_ = ebpf::make_unique<ClangLoader>(&*ctx_, flags_);
if (clang_loader_->parse(&mod_, *ts_, text, true, nullptr, 0, ""))
if (clang_loader_->parse(&mod_, *ts_, text, true, nullptr, 0, "", *func_src_))
return -1;
return 0;
}
Expand Down Expand Up @@ -632,6 +634,68 @@ uint8_t * BPFModule::function_start(const string &name) const {
return get<0>(section->second);
}

const char * BPFModule::function_source(const string &name) const {
return func_src_->src(name);
}

const char * BPFModule::function_source_rewritten(const string &name) const {
return func_src_->src_rewritten(name);
}

int BPFModule::annotate_prog_tag(const string &name, int prog_fd,
struct bpf_insn *insns, int prog_len) {
unsigned long long tag1, tag2;
int err;

err = bpf_prog_compute_tag(insns, prog_len, &tag1);
if (err)
return err;
err = bpf_prog_get_tag(prog_fd, &tag2);
if (err)
return err;
if (tag1 != tag2) {
fprintf(stderr, "prog tag mismatch %llx %llx\n", tag1, tag2);
return -1;
}

err = mkdir(BCC_PROG_TAG_DIR, 0777);
if (err && errno != EEXIST) {
fprintf(stderr, "cannot create " BCC_PROG_TAG_DIR "\n");
return -1;
}

char buf[128];
::snprintf(buf, sizeof(buf), BCC_PROG_TAG_DIR "/bpf_prog_%llx", tag1);
err = mkdir(buf, 0777);
if (err && errno != EEXIST) {
fprintf(stderr, "cannot create %s\n", buf);
return -1;
}

::snprintf(buf, sizeof(buf), BCC_PROG_TAG_DIR "/bpf_prog_%llx/%s.c",
tag1, name.data());
FileDesc fd(open(buf, O_CREAT | O_WRONLY | O_TRUNC, 0644));
if (fd < 0) {
fprintf(stderr, "cannot create %s\n", buf);
return -1;
}

const char *src = function_source(name);
write(fd, src, strlen(src));

::snprintf(buf, sizeof(buf), BCC_PROG_TAG_DIR "/bpf_prog_%llx/%s.rewritten.c",
tag1, name.data());
fd = open(buf, O_CREAT | O_WRONLY | O_TRUNC, 0644);
if (fd < 0) {
fprintf(stderr, "cannot create %s\n", buf);
return -1;
}

src = function_source_rewritten(name);
write(fd, src, strlen(src));
return 0;
}

size_t BPFModule::function_size(size_t id) const {
if (id >= function_names_.size())
return 0;
Expand Down
6 changes: 6 additions & 0 deletions src/cc/bpf_module.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class TableDesc;
class TableStorage;
class BLoader;
class ClangLoader;
class FuncSource;

class BPFModule {
private:
Expand Down Expand Up @@ -68,6 +69,10 @@ class BPFModule {
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_source(const std::string &name) const;
const char * function_source_rewritten(const std::string &name) const;
int annotate_prog_tag(const std::string &name, int fd,
struct bpf_insn *insn, int prog_len);
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;
Expand Down Expand Up @@ -108,6 +113,7 @@ class BPFModule {
std::unique_ptr<llvm::Module> mod_;
std::unique_ptr<BLoader> b_loader_;
std::unique_ptr<ClangLoader> clang_loader_;
std::unique_ptr<FuncSource> func_src_;
std::map<std::string, std::tuple<uint8_t *, uintptr_t>> sections_;
std::vector<TableDesc *> tables_;
std::map<std::string, size_t> table_names_;
Expand Down
14 changes: 12 additions & 2 deletions src/cc/frontends/clang/b_frontend_action.cc
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include <clang/Rewrite/Core/Rewriter.h>

#include "b_frontend_action.h"
#include "loader.h"
#include "common.h"
#include "table_storage.h"

Expand Down Expand Up @@ -222,6 +223,9 @@ bool BTypeVisitor::VisitFunctionDecl(FunctionDecl *D) {
auto real_start_loc = rewriter_.getSourceMgr().getFileLoc(D->getLocStart());
if (D->isExternallyVisible() && D->hasBody()) {
current_fn_ = D->getName();
string bd = rewriter_.getRewrittenText(expansionRange(D->getSourceRange()));
fe_.func_src_.set_src(current_fn_, bd);
fe_.func_range_[current_fn_] = expansionRange(D->getSourceRange());
string attr = string("__attribute__((section(\"") + BPF_FN_PREFIX + D->getName().str() + "\")))\n";
rewriter_.InsertText(real_start_loc, attr);
if (D->param_size() > MAX_CALLING_CONV_REGS + 1) {
Expand Down Expand Up @@ -776,12 +780,18 @@ bool ProbeConsumer::HandleTopLevelDecl(DeclGroupRef Group) {
}

BFrontendAction::BFrontendAction(llvm::raw_ostream &os, unsigned flags, TableStorage &ts,
const std::string &id)
: os_(os), flags_(flags), ts_(ts), id_(id), rewriter_(new Rewriter) {}
const std::string &id, FuncSource& func_src)
: os_(os), flags_(flags), ts_(ts), id_(id), rewriter_(new Rewriter), func_src_(func_src) {}

void BFrontendAction::EndSourceFileAction() {
if (flags_ & DEBUG_PREPROCESSOR)
rewriter_->getEditBuffer(rewriter_->getSourceMgr().getMainFileID()).write(llvm::errs());

for (auto func : func_range_) {
auto f = func.first;
string bd = rewriter_->getRewrittenText(func_range_[f]);
func_src_.set_src_rewritten(f, bd);
}
rewriter_->getEditBuffer(rewriter_->getSourceMgr().getMainFileID()).write(os_);
os_.flush();
}
Expand Down
7 changes: 6 additions & 1 deletion src/cc/frontends/clang/b_frontend_action.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ class StringRef;
namespace ebpf {

class BFrontendAction;
class FuncSource;

// Type visitor and rewriter for B programs.
// It will look for B-specific features and rewrite them into a valid
Expand Down Expand Up @@ -122,7 +123,8 @@ class BFrontendAction : public clang::ASTFrontendAction {
public:
// Initialize with the output stream where the new source file contents
// should be written.
BFrontendAction(llvm::raw_ostream &os, unsigned flags, TableStorage &ts, const std::string &id);
BFrontendAction(llvm::raw_ostream &os, unsigned flags, TableStorage &ts, const std::string &id,
FuncSource& func_src);

// Called by clang when the AST has been completed, here the output stream
// will be flushed.
Expand All @@ -141,6 +143,9 @@ class BFrontendAction : public clang::ASTFrontendAction {
TableStorage &ts_;
std::string id_;
std::unique_ptr<clang::Rewriter> rewriter_;
friend class BTypeVisitor;
std::map<std::string, clang::SourceRange> func_range_;
FuncSource& func_src_;
};

} // namespace visitor
26 changes: 24 additions & 2 deletions src/cc/frontends/clang/loader.cc
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,8 @@ std::pair<bool, string> get_kernel_path_info(const string kdir)
}

int ClangLoader::parse(unique_ptr<llvm::Module> *mod, TableStorage &ts, const string &file,
bool in_memory, const char *cflags[], int ncflags, const std::string &id) {
bool in_memory, const char *cflags[], int ncflags, const std::string &id,
FuncSource& func_src) {
using namespace clang;

string main_path = "/virtual/main.c";
Expand Down Expand Up @@ -276,7 +277,7 @@ int ClangLoader::parse(unique_ptr<llvm::Module> *mod, TableStorage &ts, const st
// capture the rewritten c file
string out_str1;
llvm::raw_string_ostream os1(out_str1);
BFrontendAction bact(os1, flags_, ts, id);
BFrontendAction bact(os1, flags_, ts, id, func_src);
if (!compiler1.ExecuteAction(bact))
return -1;
unique_ptr<llvm::MemoryBuffer> out_buf1 = llvm::MemoryBuffer::getMemBuffer(out_str1);
Expand Down Expand Up @@ -312,5 +313,26 @@ int ClangLoader::parse(unique_ptr<llvm::Module> *mod, TableStorage &ts, const st
return 0;
}

const char * FuncSource::src(const std::string& name) {
auto src = funcs_.find(name);
if (src == funcs_.end())
return "";
return src->second.src_.data();
}

const char * FuncSource::src_rewritten(const std::string& name) {
auto src = funcs_.find(name);
if (src == funcs_.end())
return "";
return src->second.src_rewritten_.data();
}

void FuncSource::set_src(const std::string& name, const std::string& src) {
funcs_[name].src_ = src;
}

void FuncSource::set_src_rewritten(const std::string& name, const std::string& src) {
funcs_[name].src_rewritten_ = src;
}

} // namespace ebpf
19 changes: 18 additions & 1 deletion src/cc/frontends/clang/loader.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,29 @@ class MemoryBuffer;

namespace ebpf {

class FuncSource {
class SourceCode {
public:
SourceCode(const std::string& s1 = "", const std::string& s2 = ""): src_(s1), src_rewritten_(s2) {}
std::string src_;
std::string src_rewritten_;
};
std::map<std::string, SourceCode> funcs_;
public:
FuncSource() {}
const char * src(const std::string& name);
const char * src_rewritten(const std::string& name);
void set_src(const std::string& name, const std::string& src);
void set_src_rewritten(const std::string& name, const std::string& src);
};

class ClangLoader {
public:
explicit ClangLoader(llvm::LLVMContext *ctx, unsigned flags);
~ClangLoader();
int parse(std::unique_ptr<llvm::Module> *mod, TableStorage &ts, const std::string &file,
bool in_memory, const char *cflags[], int ncflags, const std::string &id);
bool in_memory, const char *cflags[], int ncflags, const std::string &id,
FuncSource& func_src);

private:
static std::map<std::string, std::unique_ptr<llvm::MemoryBuffer>> remapped_files_;
Expand Down
Loading

0 comments on commit d56fff0

Please sign in to comment.