Skip to content

Commit

Permalink
Merge pull request iovisor#396 from iovisor/fix_333
Browse files Browse the repository at this point in the history
Embed runtime header files in libbcc.so
  • Loading branch information
4ast committed Feb 18, 2016
2 parents aaeea7b + c597c29 commit 13e74d3
Show file tree
Hide file tree
Showing 19 changed files with 125 additions and 42 deletions.
2 changes: 0 additions & 2 deletions SPECS/bcc.el6.spec
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,6 @@ Python bindings for BPF Compiler Collection (BCC)

%files -n libbcc
/usr/lib64/*
/usr/share/bcc/include/*
/usr/share/bcc/lib/*
/usr/include/bcc/*

%files -n libbcc-examples
Expand Down
2 changes: 0 additions & 2 deletions SPECS/bcc.el6.spec.in
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,6 @@ Python bindings for BPF Compiler Collection (BCC)

%files -n libbcc
/usr/lib64/*
/usr/share/bcc/include/*
/usr/share/bcc/lib/*
/usr/include/bcc/*

%files -n libbcc-examples
Expand Down
2 changes: 0 additions & 2 deletions SPECS/bcc.el7.spec
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,6 @@ Python bindings for BPF Compiler Collection (BCC)

%files -n libbcc
/usr/lib64/*
/usr/share/bcc/include/*
/usr/share/bcc/lib/*
/usr/include/bcc/*

%files -n libbcc-examples
Expand Down
2 changes: 0 additions & 2 deletions SPECS/bcc.el7.spec.in
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,6 @@ Python bindings for BPF Compiler Collection (BCC)

%files -n libbcc
/usr/lib64/*
/usr/share/bcc/include/*
/usr/share/bcc/lib/*
/usr/include/bcc/*

%files -n libbcc-examples
Expand Down
2 changes: 0 additions & 2 deletions SPECS/bcc.f22.spec
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,6 @@ Python bindings for BPF Compiler Collection (BCC)

%files -n libbcc
/usr/lib64/*
/usr/share/bcc/include/*
/usr/share/bcc/lib/*
/usr/include/bcc/*

%files -n libbcc-examples
Expand Down
2 changes: 0 additions & 2 deletions SPECS/bcc.f22.spec.in
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,6 @@ Python bindings for BPF Compiler Collection (BCC)

%files -n libbcc
/usr/lib64/*
/usr/share/bcc/include/*
/usr/share/bcc/lib/*
/usr/include/bcc/*

%files -n libbcc-examples
Expand Down
2 changes: 0 additions & 2 deletions SPECS/bcc.spec
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,6 @@ Command line tools for BPF Compiler Collection (BCC)

%files -n libbcc
/usr/lib64/*
/usr/share/bcc/include/*
/usr/share/bcc/lib/*
/usr/include/bcc/*

%files -n libbcc-examples
Expand Down
2 changes: 0 additions & 2 deletions debian/libbcc.install
Original file line number Diff line number Diff line change
@@ -1,4 +1,2 @@
usr/include/bcc/*
usr/lib/x86_64-linux-gnu/libbcc*
usr/share/bcc/include/*
usr/share/bcc/lib/*
11 changes: 1 addition & 10 deletions src/cc/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,7 @@ if (CMAKE_COMPILER_IS_GNUCC)
endif()
endif()

# tell the shared library where it is being installed so it can find shared header files
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DBCC_INSTALL_PREFIX='\"${CMAKE_INSTALL_PREFIX}\"'")

add_library(bcc SHARED bpf_common.cc bpf_module.cc libbpf.c perf_reader.c shared_table.cc)
add_library(bcc SHARED bpf_common.cc bpf_module.cc libbpf.c perf_reader.c shared_table.cc exported_files.cc)
set_target_properties(bcc PROPERTIES VERSION ${REVISION_LAST} SOVERSION 0)

# BPF is still experimental otherwise it should be available
Expand All @@ -52,18 +49,12 @@ target_link_libraries(bcc b_frontend clang_frontend ${clang_libs} ${llvm_libs} L

install(TARGETS bcc LIBRARY COMPONENT libbcc
DESTINATION ${CMAKE_INSTALL_LIBDIR})
install(DIRECTORY export/ COMPONENT libbcc
DESTINATION share/bcc/include/bcc
FILES_MATCHING PATTERN "*.h")
install(FILES bpf_common.h bpf_module.h ../libbpf.h COMPONENT libbcc
DESTINATION include/bcc)
install(DIRECTORY compat/linux/ COMPONENT libbcc
DESTINATION include/bcc/compat/linux
FILES_MATCHING PATTERN "*.h")
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libbcc.pc COMPONENT libbcc
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
install(DIRECTORY clang COMPONENT libbcc
DESTINATION share/bcc/lib
FILES_MATCHING PATTERN "*.h")

add_subdirectory(frontends)
12 changes: 9 additions & 3 deletions src/cc/bpf_module.cc
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
#include "frontends/clang/loader.h"
#include "frontends/clang/b_frontend_action.h"
#include "bpf_module.h"
#include "exported_files.h"
#include "kbuild_helper.h"
#include "shared_table.h"
#include "libbpf.h"
Expand Down Expand Up @@ -331,9 +332,9 @@ int BPFModule::load_cfile(const string &file, bool in_memory, const char *cflags

// Load in a pre-built list of functions into the initial Module object, then
// build an ExecutionEngine.
int BPFModule::load_includes(const string &tmpfile) {
int BPFModule::load_includes(const string &text) {
clang_loader_ = make_unique<ClangLoader>(&*ctx_, flags_);
if (clang_loader_->parse(&mod_, &tables_, tmpfile, false, nullptr, 0))
if (clang_loader_->parse(&mod_, &tables_, text, true, nullptr, 0))
return -1;
return 0;
}
Expand Down Expand Up @@ -683,7 +684,12 @@ int BPFModule::load_b(const string &filename, const string &proto_filename) {

// Helpers are inlined in the following file (C). Load the definitions and
// 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"))
auto helpers_h = ExportedFiles::headers().find("/virtual/include/bcc/helpers.h");
if (helpers_h == ExportedFiles::headers().end()) {
fprintf(stderr, "Internal error: missing bcc/helpers.h");
return -1;
}
if (int rc = load_includes(helpers_h->second))
return rc;

b_loader_.reset(new BLoader(flags_));
Expand Down
2 changes: 1 addition & 1 deletion src/cc/bpf_module.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ class BPFModule {
llvm::Function * make_writer(llvm::Module *mod, llvm::Type *type);
void dump_ir(llvm::Module &mod);
int load_file_module(std::unique_ptr<llvm::Module> *mod, const std::string &file, bool in_memory);
int load_includes(const std::string &tmpfile);
int load_includes(const std::string &text);
int load_cfile(const std::string &file, bool in_memory, const char *cflags[], int ncflags);
int kbuild_flags(const char *uname_release, std::vector<std::string> *cflags);
int run_pass_manager(llvm::Module &mod);
Expand Down
2 changes: 2 additions & 0 deletions src/cc/clang/include/stdarg.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
R"********(
/*===---- stdarg.h - Variable argument handling ----------------------------===
*
* Copyright (c) 2008 Eli Friedman
Expand Down Expand Up @@ -50,3 +51,4 @@ typedef __builtin_va_list va_list;
typedef __builtin_va_list __gnuc_va_list;
#endif /* __STDARG_H */
)********"
2 changes: 2 additions & 0 deletions src/cc/export/helpers.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
R"********(
/*
* Copyright (c) 2015 PLUMgrid, Inc.
*
Expand Down Expand Up @@ -392,3 +393,4 @@ int bpf_num_cpus() asm("llvm.bpf.extra");
#define lock_xadd(ptr, val) ((void)__sync_fetch_and_add(ptr, val))

#endif
)********"
2 changes: 2 additions & 0 deletions src/cc/export/proto.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
R"********(
/*
* Copyright (c) 2015 PLUMgrid, Inc.
*
Expand Down Expand Up @@ -95,3 +96,4 @@ struct vxlan_t {
unsigned int key:24;
unsigned int rsv4:8;
} BPF_PACKET_HEADER;
)********"
42 changes: 42 additions & 0 deletions src/cc/exported_files.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Copyright (c) 2016 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:https://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 "exported_files.h"

using std::map;
using std::string;

namespace ebpf {

// c++11 feature for including raw string literals
// see http:https://www.stroustrup.com/C++11FAQ.html#raw-strings

map<string, const char *> ExportedFiles::headers_ = {
{
"/virtual/include/bcc/proto.h",
#include "export/proto.h"
},
{
"/virtual/include/bcc/helpers.h",
#include "export/helpers.h"
},
{
"/virtual/lib/clang/include/stdarg.h",
#include "clang/include/stdarg.h"
},
};

}
30 changes: 30 additions & 0 deletions src/cc/exported_files.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright (c) 2016 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:https://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.
*/

#pragma once

#include <map>
#include <string>

namespace ebpf {

class ExportedFiles {
static std::map<std::string, const char *> headers_;
public:
static const std::map<std::string, const char *> & headers() { return headers_; }
};

}
2 changes: 1 addition & 1 deletion src/cc/frontends/clang/kbuild_helper.cc
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ int KBuildHelper::get_flags(const char *uname_machine, vector<string> *cflags) {

cflags->push_back("-nostdinc");
cflags->push_back("-isystem");
cflags->push_back(BCC_INSTALL_PREFIX "/share/bcc/lib/clang/include");
cflags->push_back("/virtual/lib/clang/include");
cflags->push_back("-I./arch/"+arch+"/include");
cflags->push_back("-Iarch/"+arch+"/include/generated/uapi");
cflags->push_back("-Iarch/"+arch+"/include/generated");
Expand Down
44 changes: 33 additions & 11 deletions src/cc/frontends/clang/loader.cc
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@

#include "common.h"
#include "exception.h"
#include "exported_files.h"
#include "kbuild_helper.h"
#include "b_frontend_action.h"
#include "loader.h"
Expand All @@ -58,16 +59,27 @@ using std::vector;

namespace ebpf {

map<string, unique_ptr<llvm::MemoryBuffer>> ClangLoader::remapped_files_;

ClangLoader::ClangLoader(llvm::LLVMContext *ctx, unsigned flags)
: ctx_(ctx), flags_(flags)
{}
{
if (remapped_files_.empty()) {
for (auto f : ExportedFiles::headers())
remapped_files_[f.first] = llvm::MemoryBuffer::getMemBuffer(f.second);
}
}

ClangLoader::~ClangLoader() {}

int ClangLoader::parse(unique_ptr<llvm::Module> *mod, unique_ptr<vector<TableDesc>> *tables,
const string &file, bool in_memory, const char *cflags[], int ncflags) {
using namespace clang;

string main_path = "/virtual/main.c";
string proto_path = "/virtual/include/bcc/proto.h";
string helpers_path = "/virtual/include/bcc/helpers.h";
unique_ptr<llvm::MemoryBuffer> main_buf;
struct utsname un;
uname(&un);
char kdir[256];
Expand All @@ -80,7 +92,8 @@ int ClangLoader::parse(unique_ptr<llvm::Module> *mod, unique_ptr<vector<TableDes

string abs_file;
if (in_memory) {
abs_file = "<bcc-memory-buffer>";
abs_file = main_path;
main_buf = llvm::MemoryBuffer::getMemBuffer(file);
} else {
if (file.substr(0, 1) == "/")
abs_file = file;
Expand All @@ -98,9 +111,9 @@ int ClangLoader::parse(unique_ptr<llvm::Module> *mod, unique_ptr<vector<TableDes
if (kbuild_helper.get_flags(un.machine, &kflags))
return -1;
kflags.push_back("-include");
kflags.push_back(BCC_INSTALL_PREFIX "/share/bcc/include/bcc/helpers.h");
kflags.push_back("-I");
kflags.push_back(BCC_INSTALL_PREFIX "/share/bcc/include");
kflags.push_back("/virtual/include/bcc/helpers.h");
kflags.push_back("-isystem");
kflags.push_back("/virtual/include");
for (auto it = kflags.begin(); it != kflags.end(); ++it)
flags_cstr.push_back(it->c_str());
if (cflags) {
Expand Down Expand Up @@ -156,11 +169,17 @@ int ClangLoader::parse(unique_ptr<llvm::Module> *mod, unique_ptr<vector<TableDes
const_cast<const char **>(ccargs.data()) + ccargs.size(), diags))
return -1;

// This option instructs clang whether or not to free the file buffers that we
// give to it. Since the embedded header files should be copied fewer times
// and reused if possible, set this flag to true.
invocation1->getPreprocessorOpts().RetainRemappedFileBuffers = true;
for (const auto &f : remapped_files_)
invocation1->getPreprocessorOpts().addRemappedFile(f.first, &*f.second);

if (in_memory) {
invocation1->getPreprocessorOpts().addRemappedFile("<bcc-memory-buffer>",
llvm::MemoryBuffer::getMemBuffer(file).release());
invocation1->getPreprocessorOpts().addRemappedFile(main_path, &*main_buf);
invocation1->getFrontendOpts().Inputs.clear();
invocation1->getFrontendOpts().Inputs.push_back(FrontendInputFile("<bcc-memory-buffer>", IK_C));
invocation1->getFrontendOpts().Inputs.push_back(FrontendInputFile(main_path, IK_C));
}
invocation1->getFrontendOpts().DisableFree = false;

Expand All @@ -174,6 +193,7 @@ int ClangLoader::parse(unique_ptr<llvm::Module> *mod, unique_ptr<vector<TableDes
BFrontendAction bact(os, flags_);
if (!compiler1.ExecuteAction(bact))
return -1;
unique_ptr<llvm::MemoryBuffer> out_buf = llvm::MemoryBuffer::getMemBuffer(out_str);
// this contains the open FDs
*tables = bact.take_tables();

Expand All @@ -183,10 +203,12 @@ int ClangLoader::parse(unique_ptr<llvm::Module> *mod, unique_ptr<vector<TableDes
const_cast<const char **>(ccargs.data()) + ccargs.size(), diags))
return -1;
CompilerInstance compiler2;
invocation2->getPreprocessorOpts().addRemappedFile("<bcc-memory-buffer>",
llvm::MemoryBuffer::getMemBuffer(out_str).release());
invocation2->getPreprocessorOpts().RetainRemappedFileBuffers = true;
for (const auto &f : remapped_files_)
invocation2->getPreprocessorOpts().addRemappedFile(f.first, &*f.second);
invocation2->getPreprocessorOpts().addRemappedFile(main_path, &*out_buf);
invocation2->getFrontendOpts().Inputs.clear();
invocation2->getFrontendOpts().Inputs.push_back(FrontendInputFile("<bcc-memory-buffer>", IK_C));
invocation2->getFrontendOpts().Inputs.push_back(FrontendInputFile(main_path, IK_C));
invocation2->getFrontendOpts().DisableFree = false;
// suppress warnings in the 2nd pass, but bail out on errors (our fault)
invocation2->getDiagnosticOpts().IgnoreWarnings = true;
Expand Down
2 changes: 2 additions & 0 deletions src/cc/frontends/clang/loader.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
namespace llvm {
class Module;
class LLVMContext;
class MemoryBuffer;
}

namespace ebpf {
Expand All @@ -41,6 +42,7 @@ class ClangLoader {
int parse(std::unique_ptr<llvm::Module> *mod, std::unique_ptr<std::vector<TableDesc>> *tables,
const std::string &file, bool in_memory, const char *cflags[], int ncflags);
private:
static std::map<std::string, std::unique_ptr<llvm::MemoryBuffer>> remapped_files_;
llvm::LLVMContext *ctx_;
unsigned flags_;
};
Expand Down

0 comments on commit 13e74d3

Please sign in to comment.