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 = uname_machine;
38 const char *archenv;
39
40 if (!strncmp(uname_machine, "x86_64", 6)) {
41 arch = "x86";
42 } else if (uname_machine[0] == 'i' && !strncmp(&uname_machine[2], "86", 2)) {
43 arch = "x86";
44 } else if (!strncmp(uname_machine, "arm", 3)) {
45 arch = "arm";
46 } else if (!strncmp(uname_machine, "sa110", 5)) {
47 arch = "arm";
48 } else if (!strncmp(uname_machine, "s390x", 5)) {
49 arch = "s390";
50 } else if (!strncmp(uname_machine, "parisc64", 8)) {
51 arch = "parisc";
52 } else if (!strncmp(uname_machine, "ppc", 3)) {
53 arch = "powerpc";
54 } else if (!strncmp(uname_machine, "mips", 4)) {
55 arch = "mips";
56 } else if (!strncmp(uname_machine, "sh", 2)) {
57 arch = "sh";
58 } else if (!strncmp(uname_machine, "aarch64", 7)) {
59 arch = "arm64";
60 }
61
62 // If ARCH env is defined, use it over uname
63 archenv = getenv("ARCH");
64 if (archenv)
65 arch = string(archenv);
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