Commit 13e74d30 authored by 4ast's avatar 4ast

Merge pull request #396 from iovisor/fix_333

Embed runtime header files in libbcc.so
parents aaeea7bb c597c29c
...@@ -107,8 +107,6 @@ Python bindings for BPF Compiler Collection (BCC) ...@@ -107,8 +107,6 @@ Python bindings for BPF Compiler Collection (BCC)
%files -n libbcc %files -n libbcc
/usr/lib64/* /usr/lib64/*
/usr/share/bcc/include/*
/usr/share/bcc/lib/*
/usr/include/bcc/* /usr/include/bcc/*
%files -n libbcc-examples %files -n libbcc-examples
......
...@@ -107,8 +107,6 @@ Python bindings for BPF Compiler Collection (BCC) ...@@ -107,8 +107,6 @@ Python bindings for BPF Compiler Collection (BCC)
%files -n libbcc %files -n libbcc
/usr/lib64/* /usr/lib64/*
/usr/share/bcc/include/*
/usr/share/bcc/lib/*
/usr/include/bcc/* /usr/include/bcc/*
%files -n libbcc-examples %files -n libbcc-examples
......
...@@ -76,8 +76,6 @@ Python bindings for BPF Compiler Collection (BCC) ...@@ -76,8 +76,6 @@ Python bindings for BPF Compiler Collection (BCC)
%files -n libbcc %files -n libbcc
/usr/lib64/* /usr/lib64/*
/usr/share/bcc/include/*
/usr/share/bcc/lib/*
/usr/include/bcc/* /usr/include/bcc/*
%files -n libbcc-examples %files -n libbcc-examples
......
...@@ -76,8 +76,6 @@ Python bindings for BPF Compiler Collection (BCC) ...@@ -76,8 +76,6 @@ Python bindings for BPF Compiler Collection (BCC)
%files -n libbcc %files -n libbcc
/usr/lib64/* /usr/lib64/*
/usr/share/bcc/include/*
/usr/share/bcc/lib/*
/usr/include/bcc/* /usr/include/bcc/*
%files -n libbcc-examples %files -n libbcc-examples
......
...@@ -76,8 +76,6 @@ Python bindings for BPF Compiler Collection (BCC) ...@@ -76,8 +76,6 @@ Python bindings for BPF Compiler Collection (BCC)
%files -n libbcc %files -n libbcc
/usr/lib64/* /usr/lib64/*
/usr/share/bcc/include/*
/usr/share/bcc/lib/*
/usr/include/bcc/* /usr/include/bcc/*
%files -n libbcc-examples %files -n libbcc-examples
......
...@@ -76,8 +76,6 @@ Python bindings for BPF Compiler Collection (BCC) ...@@ -76,8 +76,6 @@ Python bindings for BPF Compiler Collection (BCC)
%files -n libbcc %files -n libbcc
/usr/lib64/* /usr/lib64/*
/usr/share/bcc/include/*
/usr/share/bcc/lib/*
/usr/include/bcc/* /usr/include/bcc/*
%files -n libbcc-examples %files -n libbcc-examples
......
...@@ -71,8 +71,6 @@ Command line tools for BPF Compiler Collection (BCC) ...@@ -71,8 +71,6 @@ Command line tools for BPF Compiler Collection (BCC)
%files -n libbcc %files -n libbcc
/usr/lib64/* /usr/lib64/*
/usr/share/bcc/include/*
/usr/share/bcc/lib/*
/usr/include/bcc/* /usr/include/bcc/*
%files -n libbcc-examples %files -n libbcc-examples
......
usr/include/bcc/* usr/include/bcc/*
usr/lib/x86_64-linux-gnu/libbcc* usr/lib/x86_64-linux-gnu/libbcc*
usr/share/bcc/include/*
usr/share/bcc/lib/*
...@@ -32,10 +32,7 @@ if (CMAKE_COMPILER_IS_GNUCC) ...@@ -32,10 +32,7 @@ if (CMAKE_COMPILER_IS_GNUCC)
endif() endif()
endif() endif()
# tell the shared library where it is being installed so it can find shared header files add_library(bcc SHARED bpf_common.cc bpf_module.cc libbpf.c perf_reader.c shared_table.cc exported_files.cc)
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)
set_target_properties(bcc PROPERTIES VERSION ${REVISION_LAST} SOVERSION 0) set_target_properties(bcc PROPERTIES VERSION ${REVISION_LAST} SOVERSION 0)
# BPF is still experimental otherwise it should be available # BPF is still experimental otherwise it should be available
...@@ -52,9 +49,6 @@ target_link_libraries(bcc b_frontend clang_frontend ${clang_libs} ${llvm_libs} L ...@@ -52,9 +49,6 @@ target_link_libraries(bcc b_frontend clang_frontend ${clang_libs} ${llvm_libs} L
install(TARGETS bcc LIBRARY COMPONENT libbcc install(TARGETS bcc LIBRARY COMPONENT libbcc
DESTINATION ${CMAKE_INSTALL_LIBDIR}) 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 install(FILES bpf_common.h bpf_module.h ../libbpf.h COMPONENT libbcc
DESTINATION include/bcc) DESTINATION include/bcc)
install(DIRECTORY compat/linux/ COMPONENT libbcc install(DIRECTORY compat/linux/ COMPONENT libbcc
...@@ -62,8 +56,5 @@ install(DIRECTORY compat/linux/ COMPONENT libbcc ...@@ -62,8 +56,5 @@ install(DIRECTORY compat/linux/ COMPONENT libbcc
FILES_MATCHING PATTERN "*.h") FILES_MATCHING PATTERN "*.h")
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libbcc.pc COMPONENT libbcc install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libbcc.pc COMPONENT libbcc
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
install(DIRECTORY clang COMPONENT libbcc
DESTINATION share/bcc/lib
FILES_MATCHING PATTERN "*.h")
add_subdirectory(frontends) add_subdirectory(frontends)
...@@ -48,6 +48,7 @@ ...@@ -48,6 +48,7 @@
#include "frontends/clang/loader.h" #include "frontends/clang/loader.h"
#include "frontends/clang/b_frontend_action.h" #include "frontends/clang/b_frontend_action.h"
#include "bpf_module.h" #include "bpf_module.h"
#include "exported_files.h"
#include "kbuild_helper.h" #include "kbuild_helper.h"
#include "shared_table.h" #include "shared_table.h"
#include "libbpf.h" #include "libbpf.h"
...@@ -331,9 +332,9 @@ int BPFModule::load_cfile(const string &file, bool in_memory, const char *cflags ...@@ -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 // Load in a pre-built list of functions into the initial Module object, then
// build an ExecutionEngine. // build an ExecutionEngine.
int BPFModule::load_includes(const string &tmpfile) { int BPFModule::load_includes(const string &text) {
clang_loader_ = make_unique<ClangLoader>(&*ctx_, flags_); 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 -1;
return 0; return 0;
} }
...@@ -683,7 +684,12 @@ int BPFModule::load_b(const string &filename, const string &proto_filename) { ...@@ -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 // Helpers are inlined in the following file (C). Load the definitions and
// 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")) 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; return rc;
b_loader_.reset(new BLoader(flags_)); b_loader_.reset(new BLoader(flags_));
......
...@@ -47,7 +47,7 @@ class BPFModule { ...@@ -47,7 +47,7 @@ class BPFModule {
llvm::Function * make_writer(llvm::Module *mod, llvm::Type *type); llvm::Function * make_writer(llvm::Module *mod, llvm::Type *type);
void dump_ir(llvm::Module &mod); 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_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 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 kbuild_flags(const char *uname_release, std::vector<std::string> *cflags);
int run_pass_manager(llvm::Module &mod); int run_pass_manager(llvm::Module &mod);
......
R"********(
/*===---- stdarg.h - Variable argument handling ----------------------------=== /*===---- stdarg.h - Variable argument handling ----------------------------===
* *
* Copyright (c) 2008 Eli Friedman * Copyright (c) 2008 Eli Friedman
...@@ -50,3 +51,4 @@ typedef __builtin_va_list va_list; ...@@ -50,3 +51,4 @@ typedef __builtin_va_list va_list;
typedef __builtin_va_list __gnuc_va_list; typedef __builtin_va_list __gnuc_va_list;
#endif /* __STDARG_H */ #endif /* __STDARG_H */
)********"
R"********(
/* /*
* Copyright (c) 2015 PLUMgrid, Inc. * Copyright (c) 2015 PLUMgrid, Inc.
* *
...@@ -392,3 +393,4 @@ int bpf_num_cpus() asm("llvm.bpf.extra"); ...@@ -392,3 +393,4 @@ int bpf_num_cpus() asm("llvm.bpf.extra");
#define lock_xadd(ptr, val) ((void)__sync_fetch_and_add(ptr, val)) #define lock_xadd(ptr, val) ((void)__sync_fetch_and_add(ptr, val))
#endif #endif
)********"
R"********(
/* /*
* Copyright (c) 2015 PLUMgrid, Inc. * Copyright (c) 2015 PLUMgrid, Inc.
* *
...@@ -95,3 +96,4 @@ struct vxlan_t { ...@@ -95,3 +96,4 @@ struct vxlan_t {
unsigned int key:24; unsigned int key:24;
unsigned int rsv4:8; unsigned int rsv4:8;
} BPF_PACKET_HEADER; } BPF_PACKET_HEADER;
)********"
/*
* 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://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://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"
},
};
}
/*
* 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://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_; }
};
}
...@@ -57,7 +57,7 @@ int KBuildHelper::get_flags(const char *uname_machine, vector<string> *cflags) { ...@@ -57,7 +57,7 @@ int KBuildHelper::get_flags(const char *uname_machine, vector<string> *cflags) {
cflags->push_back("-nostdinc"); cflags->push_back("-nostdinc");
cflags->push_back("-isystem"); 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("-I./arch/"+arch+"/include");
cflags->push_back("-Iarch/"+arch+"/include/generated/uapi"); cflags->push_back("-Iarch/"+arch+"/include/generated/uapi");
cflags->push_back("-Iarch/"+arch+"/include/generated"); cflags->push_back("-Iarch/"+arch+"/include/generated");
......
...@@ -47,6 +47,7 @@ ...@@ -47,6 +47,7 @@
#include "common.h" #include "common.h"
#include "exception.h" #include "exception.h"
#include "exported_files.h"
#include "kbuild_helper.h" #include "kbuild_helper.h"
#include "b_frontend_action.h" #include "b_frontend_action.h"
#include "loader.h" #include "loader.h"
...@@ -58,9 +59,16 @@ using std::vector; ...@@ -58,9 +59,16 @@ using std::vector;
namespace ebpf { namespace ebpf {
map<string, unique_ptr<llvm::MemoryBuffer>> ClangLoader::remapped_files_;
ClangLoader::ClangLoader(llvm::LLVMContext *ctx, unsigned flags) ClangLoader::ClangLoader(llvm::LLVMContext *ctx, unsigned flags)
: ctx_(ctx), flags_(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() {} ClangLoader::~ClangLoader() {}
...@@ -68,6 +76,10 @@ int ClangLoader::parse(unique_ptr<llvm::Module> *mod, unique_ptr<vector<TableDes ...@@ -68,6 +76,10 @@ int ClangLoader::parse(unique_ptr<llvm::Module> *mod, unique_ptr<vector<TableDes
const string &file, bool in_memory, const char *cflags[], int ncflags) { const string &file, bool in_memory, const char *cflags[], int ncflags) {
using namespace clang; 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; struct utsname un;
uname(&un); uname(&un);
char kdir[256]; char kdir[256];
...@@ -80,7 +92,8 @@ int ClangLoader::parse(unique_ptr<llvm::Module> *mod, unique_ptr<vector<TableDes ...@@ -80,7 +92,8 @@ int ClangLoader::parse(unique_ptr<llvm::Module> *mod, unique_ptr<vector<TableDes
string abs_file; string abs_file;
if (in_memory) { if (in_memory) {
abs_file = "<bcc-memory-buffer>"; abs_file = main_path;
main_buf = llvm::MemoryBuffer::getMemBuffer(file);
} else { } else {
if (file.substr(0, 1) == "/") if (file.substr(0, 1) == "/")
abs_file = file; abs_file = file;
...@@ -98,9 +111,9 @@ int ClangLoader::parse(unique_ptr<llvm::Module> *mod, unique_ptr<vector<TableDes ...@@ -98,9 +111,9 @@ int ClangLoader::parse(unique_ptr<llvm::Module> *mod, unique_ptr<vector<TableDes
if (kbuild_helper.get_flags(un.machine, &kflags)) if (kbuild_helper.get_flags(un.machine, &kflags))
return -1; return -1;
kflags.push_back("-include"); kflags.push_back("-include");
kflags.push_back(BCC_INSTALL_PREFIX "/share/bcc/include/bcc/helpers.h"); kflags.push_back("/virtual/include/bcc/helpers.h");
kflags.push_back("-I"); kflags.push_back("-isystem");
kflags.push_back(BCC_INSTALL_PREFIX "/share/bcc/include"); kflags.push_back("/virtual/include");
for (auto it = kflags.begin(); it != kflags.end(); ++it) for (auto it = kflags.begin(); it != kflags.end(); ++it)
flags_cstr.push_back(it->c_str()); flags_cstr.push_back(it->c_str());
if (cflags) { if (cflags) {
...@@ -156,11 +169,17 @@ int ClangLoader::parse(unique_ptr<llvm::Module> *mod, unique_ptr<vector<TableDes ...@@ -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)) const_cast<const char **>(ccargs.data()) + ccargs.size(), diags))
return -1; 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) { if (in_memory) {
invocation1->getPreprocessorOpts().addRemappedFile("<bcc-memory-buffer>", invocation1->getPreprocessorOpts().addRemappedFile(main_path, &*main_buf);
llvm::MemoryBuffer::getMemBuffer(file).release());
invocation1->getFrontendOpts().Inputs.clear(); 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; invocation1->getFrontendOpts().DisableFree = false;
...@@ -174,6 +193,7 @@ int ClangLoader::parse(unique_ptr<llvm::Module> *mod, unique_ptr<vector<TableDes ...@@ -174,6 +193,7 @@ int ClangLoader::parse(unique_ptr<llvm::Module> *mod, unique_ptr<vector<TableDes
BFrontendAction bact(os, flags_); BFrontendAction bact(os, flags_);
if (!compiler1.ExecuteAction(bact)) if (!compiler1.ExecuteAction(bact))
return -1; return -1;
unique_ptr<llvm::MemoryBuffer> out_buf = llvm::MemoryBuffer::getMemBuffer(out_str);
// this contains the open FDs // this contains the open FDs
*tables = bact.take_tables(); *tables = bact.take_tables();
...@@ -183,10 +203,12 @@ int ClangLoader::parse(unique_ptr<llvm::Module> *mod, unique_ptr<vector<TableDes ...@@ -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)) const_cast<const char **>(ccargs.data()) + ccargs.size(), diags))
return -1; return -1;
CompilerInstance compiler2; CompilerInstance compiler2;
invocation2->getPreprocessorOpts().addRemappedFile("<bcc-memory-buffer>", invocation2->getPreprocessorOpts().RetainRemappedFileBuffers = true;
llvm::MemoryBuffer::getMemBuffer(out_str).release()); 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.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; invocation2->getFrontendOpts().DisableFree = false;
// suppress warnings in the 2nd pass, but bail out on errors (our fault) // suppress warnings in the 2nd pass, but bail out on errors (our fault)
invocation2->getDiagnosticOpts().IgnoreWarnings = true; invocation2->getDiagnosticOpts().IgnoreWarnings = true;
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
namespace llvm { namespace llvm {
class Module; class Module;
class LLVMContext; class LLVMContext;
class MemoryBuffer;
} }
namespace ebpf { namespace ebpf {
...@@ -41,6 +42,7 @@ class ClangLoader { ...@@ -41,6 +42,7 @@ class ClangLoader {
int parse(std::unique_ptr<llvm::Module> *mod, std::unique_ptr<std::vector<TableDesc>> *tables, 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); const std::string &file, bool in_memory, const char *cflags[], int ncflags);
private: private:
static std::map<std::string, std::unique_ptr<llvm::MemoryBuffer>> remapped_files_;
llvm::LLVMContext *ctx_; llvm::LLVMContext *ctx_;
unsigned flags_; unsigned flags_;
}; };
......
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