1 /*
2  * Copyright (c) 2015 PLUMgrid, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #include <fcntl.h>
17 #include <stdlib.h>
18 #include <iostream>
19 #include "kbuild_helper.h"
20 
21 namespace ebpf {
22 
23 using std::string;
24 using std::vector;
25 
KBuildHelper(const std::string & kdir,bool has_source_dir)26 KBuildHelper::KBuildHelper(const std::string &kdir, bool has_source_dir) : kdir_(kdir),
27                                                                            has_source_dir_(has_source_dir) {
28 }
29 
30 // read the flags from cache or learn
get_flags(const char * uname_machine,vector<string> * cflags)31 int KBuildHelper::get_flags(const char *uname_machine, vector<string> *cflags) {
32   //uname -m | sed -e s/i.86/x86/ -e s/x86_64/x86/ -e s/sun4u/sparc64/ -e s/arm.*/arm/
33   //               -e s/sa110/arm/ -e s/s390x/s390/ -e s/parisc64/parisc/
34   //               -e s/ppc.*/powerpc/ -e s/mips.*/mips/ -e s/sh[234].*/sh/
35   //               -e s/aarch64.*/arm64/
36 
37   string arch;
38   const char *archenv = getenv("ARCH");
39   // If ARCH env is defined, use it over uname
40   if (archenv)
41     arch = string(archenv);
42   else
43     arch = string(uname_machine);
44 
45   if (!arch.compare(0, 6, "x86_64")) {
46     arch = "x86";
47   } else if (arch[0] == 'i' && !arch.compare(2, 2, "86")) {
48     arch = "x86";
49   } else if (!arch.compare(0, 3, "arm")) {
50     arch = "arm";
51   } else if (!arch.compare(0, 5, "sa110")) {
52     arch = "arm";
53   } else if (!arch.compare(0, 5, "s390x")) {
54     arch = "s390";
55   } else if (!arch.compare(0, 8, "parisc64")) {
56     arch = "parisc";
57   } else if (!arch.compare(0, 3, "ppc")) {
58     arch = "powerpc";
59   } else if (!arch.compare(0, 4, "mips")) {
60     arch = "mips";
61   } else if (!arch.compare(0, 2, "sh")) {
62     arch = "sh";
63   } else if (!arch.compare(0, 7, "aarch64")) {
64     arch = "arm64";
65   }
66 
67   cflags->push_back("-nostdinc");
68   cflags->push_back("-isystem");
69   cflags->push_back("/virtual/lib/clang/include");
70 
71   // some module build directories split headers between source/ and build/
72   if (has_source_dir_) {
73     cflags->push_back("-I" + kdir_ + "/build/arch/"+arch+"/include");
74     cflags->push_back("-I" + kdir_ + "/build/arch/"+arch+"/include/generated/uapi");
75     cflags->push_back("-I" + kdir_ + "/build/arch/"+arch+"/include/generated");
76     cflags->push_back("-I" + kdir_ + "/build/include");
77     cflags->push_back("-I" + kdir_ + "/build/./arch/"+arch+"/include/uapi");
78     cflags->push_back("-I" + kdir_ + "/build/arch/"+arch+"/include/generated/uapi");
79     cflags->push_back("-I" + kdir_ + "/build/include/uapi");
80     cflags->push_back("-I" + kdir_ + "/build/include/generated");
81     cflags->push_back("-I" + kdir_ + "/build/include/generated/uapi");
82   }
83 
84   cflags->push_back("-I./arch/"+arch+"/include");
85   cflags->push_back("-Iarch/"+arch+"/include/generated/uapi");
86   cflags->push_back("-Iarch/"+arch+"/include/generated");
87   cflags->push_back("-Iinclude");
88   cflags->push_back("-I./arch/"+arch+"/include/uapi");
89   cflags->push_back("-Iarch/"+arch+"/include/generated/uapi");
90   cflags->push_back("-I./include/uapi");
91   cflags->push_back("-Iinclude/generated/uapi");
92   cflags->push_back("-include");
93   cflags->push_back("./include/linux/kconfig.h");
94   cflags->push_back("-D__KERNEL__");
95   cflags->push_back("-D__HAVE_BUILTIN_BSWAP16__");
96   cflags->push_back("-D__HAVE_BUILTIN_BSWAP32__");
97   cflags->push_back("-D__HAVE_BUILTIN_BSWAP64__");
98 
99   // If ARCH env variable is set, pass this along.
100   if (archenv)
101 	cflags->push_back("-D__TARGET_ARCH_" + arch);
102 
103   cflags->push_back("-Wno-unused-value");
104   cflags->push_back("-Wno-pointer-sign");
105   cflags->push_back("-fno-stack-protector");
106 
107   return 0;
108 }
109 
110 }  // namespace ebpf
111