File bcc-kernel-header-search.patch of Package bcc
From 8206974677d7376c33f131d7767dc719d798b52d Mon Sep 17 00:00:00 2001
From: Brenden Blanco <bblanco@plumgrid.com>
Date: Mon, 7 Mar 2016 23:27:59 -0800
Subject: [PATCH 1/2] Add option to change kernel build search paths
Some linux distributions structure the /lib/modules directories
differently, causing complexities. Add cmake overrides to be able to
compile different behavior.
If your distro sets up `/lib/modules/$(uname -r)/{source,build}` with
header files split between the two (debian does this), then add
-DBCC_KERNEL_HAS_SOURCE_DIR=1 to the cmake command line.
If your distro just has something other than build/, but things are
still in one subdirectory, then add -DBCC_KERNEL_MODULES_SUFFIX=foo to
the cmake command line.
Also, fix one implicit declaration warning introduced by the new
bpf_get_stackid() helper.
Fixes: #397
Signed-off-by: Brenden Blanco <bblanco@plumgrid.com>
---
CMakeLists.txt | 16 ++++++++++++++++
src/cc/frontends/clang/CMakeLists.txt | 2 ++
src/cc/frontends/clang/loader.cc | 9 ++++++++-
3 files changed, 26 insertions(+), 1 deletion(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 94172b0..f79a2cb 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -39,6 +39,22 @@ FOREACH(DIR ${LLVM_INCLUDE_DIRS})
include_directories("${DIR}/../tools/clang/include")
ENDFOREACH()
+# Set to non-zero if system installs kernel headers with split source and build
+# directories in /lib/modules/`uname -r`/. This is the case for debian and
+# suse, to the best of my knowledge.
+if(BCC_KERNEL_HAS_SOURCE_DIR)
+ set(BCC_KERNEL_HAS_SOURCE_DIR 1)
+ set(BCC_KERNEL_MODULES_SUFFIX "source")
+else()
+ set(BCC_KERNEL_HAS_SOURCE_DIR 0)
+endif()
+
+# Similar to above, set to custom value if kernel headers in
+# /lib/modules/`uname -r` sit in a different location than build/.
+if(NOT DEFINED BCC_KERNEL_MODULES_SUFFIX)
+ set(BCC_KERNEL_MODULES_SUFFIX "build")
+endif()
+
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall")
endif()
diff --git a/src/cc/frontends/clang/CMakeLists.txt b/src/cc/frontends/clang/CMakeLists.txt
index 514df49..6e01bc0 100644
--- a/src/cc/frontends/clang/CMakeLists.txt
+++ b/src/cc/frontends/clang/CMakeLists.txt
@@ -1,4 +1,6 @@
# Copyright (c) PLUMgrid, Inc.
# Licensed under the Apache License, Version 2.0 (the "License")
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DKERNEL_MODULES_SUFFIX='\"${BCC_KERNEL_MODULES_SUFFIX}\"'")
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DKERNEL_HAS_SOURCE_DIR=${BCC_KERNEL_HAS_SOURCE_DIR}")
add_library(clang_frontend loader.cc b_frontend_action.cc kbuild_helper.cc)
diff --git a/src/cc/frontends/clang/loader.cc b/src/cc/frontends/clang/loader.cc
index a138d93..af21a4f 100644
--- a/src/cc/frontends/clang/loader.cc
+++ b/src/cc/frontends/clang/loader.cc
@@ -83,7 +83,7 @@ int ClangLoader::parse(unique_ptr<llvm::Module> *mod, unique_ptr<vector<TableDes
struct utsname un;
uname(&un);
char kdir[256];
- snprintf(kdir, sizeof(kdir), "%s/%s/build", KERNEL_MODULES_DIR, un.release);
+ snprintf(kdir, sizeof(kdir), "%s/%s/%s", KERNEL_MODULES_DIR, un.release, KERNEL_MODULES_SUFFIX);
// clang needs to run inside the kernel dir
DirStack dstack(kdir);
@@ -110,6 +110,13 @@ int ClangLoader::parse(unique_ptr<llvm::Module> *mod, unique_ptr<vector<TableDes
vector<string> kflags;
if (kbuild_helper.get_flags(un.machine, &kflags))
return -1;
+ // some module build directories split headers between source/ and build/
+ if (KERNEL_HAS_SOURCE_DIR) {
+ kflags.push_back("-isystem");
+ kflags.push_back(string(KERNEL_MODULES_DIR "/") + un.release + "/build/include");
+ kflags.push_back("-isystem");
+ kflags.push_back(string(KERNEL_MODULES_DIR "/") + un.release + "/build/include/generated/uapi");
+ }
kflags.push_back("-include");
kflags.push_back("/virtual/include/bcc/helpers.h");
kflags.push_back("-isystem");
--
2.7.2
From 902bdb9d6554c8d4286a7a64076b90bca32b3232 Mon Sep 17 00:00:00 2001
From: Brenden Blanco <bblanco@plumgrid.com>
Date: Tue, 8 Mar 2016 08:32:29 -0800
Subject: [PATCH 2/2] When in KERNEL_HAS_SOURCE_DIR mode, include everything
Include all of the paths in the build/ directory when kernel headers are
split.
Signed-off-by: Brenden Blanco <bblanco@plumgrid.com>
---
src/cc/frontends/clang/kbuild_helper.cc | 16 +++++++++++++++-
src/cc/frontends/clang/kbuild_helper.h | 10 ++++++----
src/cc/frontends/clang/loader.cc | 14 +++-----------
3 files changed, 24 insertions(+), 16 deletions(-)
diff --git a/src/cc/frontends/clang/kbuild_helper.cc b/src/cc/frontends/clang/kbuild_helper.cc
index dc1675b..3cb55df 100644
--- a/src/cc/frontends/clang/kbuild_helper.cc
+++ b/src/cc/frontends/clang/kbuild_helper.cc
@@ -22,7 +22,7 @@ namespace ebpf {
using std::string;
using std::vector;
-KBuildHelper::KBuildHelper() {
+KBuildHelper::KBuildHelper(const std::string &kdir) : kdir_(kdir) {
}
// read the flags from cache or learn
@@ -58,6 +58,19 @@ int KBuildHelper::get_flags(const char *uname_machine, vector<string> *cflags) {
cflags->push_back("-nostdinc");
cflags->push_back("-isystem");
cflags->push_back("/virtual/lib/clang/include");
+
+ // some module build directories split headers between source/ and build/
+ if (KERNEL_HAS_SOURCE_DIR) {
+ cflags->push_back("-I" + kdir_ + "/build/arch/"+arch+"/include");
+ cflags->push_back("-I" + kdir_ + "/build/arch/"+arch+"/include/generated/uapi");
+ cflags->push_back("-I" + kdir_ + "/build/arch/"+arch+"/include/generated");
+ cflags->push_back("-I" + kdir_ + "/build/include");
+ cflags->push_back("-I" + kdir_ + "/build/./arch/"+arch+"/include/uapi");
+ cflags->push_back("-I" + kdir_ + "/build/arch/"+arch+"/include/generated/uapi");
+ cflags->push_back("-I" + kdir_ + "/build/include/uapi");
+ cflags->push_back("-I" + kdir_ + "/build/include/generated/uapi");
+ }
+
cflags->push_back("-I./arch/"+arch+"/include");
cflags->push_back("-Iarch/"+arch+"/include/generated/uapi");
cflags->push_back("-Iarch/"+arch+"/include/generated");
@@ -71,6 +84,7 @@ int KBuildHelper::get_flags(const char *uname_machine, vector<string> *cflags) {
cflags->push_back("-D__KERNEL__");
cflags->push_back("-Wno-unused-value");
cflags->push_back("-Wno-pointer-sign");
+
return 0;
}
diff --git a/src/cc/frontends/clang/kbuild_helper.h b/src/cc/frontends/clang/kbuild_helper.h
index 6f93dec..3cbc0f6 100644
--- a/src/cc/frontends/clang/kbuild_helper.h
+++ b/src/cc/frontends/clang/kbuild_helper.h
@@ -33,13 +33,13 @@ typedef std::unique_ptr<FILE, FileDeleter> FILEPtr;
// Helper with pushd/popd semantics
class DirStack {
public:
- explicit DirStack(const char *dst) : ok_(false) {
+ explicit DirStack(const std::string &dst) : ok_(false) {
if (getcwd(cwd_, sizeof(cwd_)) == NULL) {
::perror("getcwd");
return;
}
- if (::chdir(dst)) {
- fprintf(stderr, "chdir(%s): %s\n", dst, strerror(errno));
+ if (::chdir(dst.c_str())) {
+ fprintf(stderr, "chdir(%s): %s\n", dst.c_str(), strerror(errno));
return;
}
ok_ = true;
@@ -94,8 +94,10 @@ class TmpDir {
// case we eventually support non-root user programs, cache in $HOME.
class KBuildHelper {
public:
- KBuildHelper();
+ explicit KBuildHelper(const std::string &kdir);
int get_flags(const char *uname_machine, std::vector<std::string> *cflags);
+ private:
+ std::string kdir_;
};
} // namespace ebpf
diff --git a/src/cc/frontends/clang/loader.cc b/src/cc/frontends/clang/loader.cc
index af21a4f..6a0d025 100644
--- a/src/cc/frontends/clang/loader.cc
+++ b/src/cc/frontends/clang/loader.cc
@@ -82,11 +82,10 @@ int ClangLoader::parse(unique_ptr<llvm::Module> *mod, unique_ptr<vector<TableDes
unique_ptr<llvm::MemoryBuffer> main_buf;
struct utsname un;
uname(&un);
- char kdir[256];
- snprintf(kdir, sizeof(kdir), "%s/%s/%s", KERNEL_MODULES_DIR, un.release, KERNEL_MODULES_SUFFIX);
+ string kdir = string(KERNEL_MODULES_DIR) + "/" + un.release;
// clang needs to run inside the kernel dir
- DirStack dstack(kdir);
+ DirStack dstack(kdir + "/" + KERNEL_MODULES_SUFFIX);
if (!dstack.ok())
return -1;
@@ -106,17 +105,10 @@ int ClangLoader::parse(unique_ptr<llvm::Module> *mod, unique_ptr<vector<TableDes
"-Wno-gnu-variable-sized-type-not-at-end",
"-x", "c", "-c", abs_file.c_str()});
- KBuildHelper kbuild_helper;
+ KBuildHelper kbuild_helper(kdir);
vector<string> kflags;
if (kbuild_helper.get_flags(un.machine, &kflags))
return -1;
- // some module build directories split headers between source/ and build/
- if (KERNEL_HAS_SOURCE_DIR) {
- kflags.push_back("-isystem");
- kflags.push_back(string(KERNEL_MODULES_DIR "/") + un.release + "/build/include");
- kflags.push_back("-isystem");
- kflags.push_back(string(KERNEL_MODULES_DIR "/") + un.release + "/build/include/generated/uapi");
- }
kflags.push_back("-include");
kflags.push_back("/virtual/include/bcc/helpers.h");
kflags.push_back("-isystem");
--
2.7.2