bcc: Add some basic support for MIPS
authorTiezhu Yang <yangtiezhu@loongson.cn>
Sat, 20 Mar 2021 01:42:35 +0000 (09:42 +0800)
committeryonghong-song <ys114321@gmail.com>
Sat, 20 Mar 2021 16:07:00 +0000 (09:07 -0700)
In order to fix the following errors when running bpf program
on the MIPS Loongson64 platform, add some basic support, with
this patch, running hello_world.py can get the expected result.

 root@linux:/home/loongson/bcc# python examples/hello_world.py
 In file included from <built-in>:3:
 In file included from /virtual/include/bcc/helpers.h:51:
 In file included from include/uapi/linux/if_packet.h:5:
 arch/mips/include/uapi/asm/byteorder.h:17:3: error: "MIPS, but neither __MIPSEB__, nor __MIPSEL__???"
 # error "MIPS, but neither __MIPSEB__, nor __MIPSEL__???"
   ^
 In file included from <built-in>:3:
 In file included from /virtual/include/bcc/helpers.h:53:
 In file included from include/linux/log2.h:12:
 In file included from include/linux/bitops.h:32:
 In file included from arch/mips/include/asm/bitops.h:19:
 In file included from arch/mips/include/asm/barrier.h:11:
 arch/mips/include/asm/addrspace.h:13:10: fatal error: 'spaces.h' file not found
 #include <spaces.h>
         ^~~~~~~~~~
 2 errors generated.
 Traceback (most recent call last):
   File "examples/hello_world.py", line 12, in <module>
     BPF(text='int kprobe__sys_clone(void *ctx) { bpf_trace_printk("Hello, World!\\n"); return 0; }').trace_print()
   File "/usr/lib/python2.7/site-packages/bcc/__init__.py", line 364, in __init__
     raise Exception("Failed to compile BPF module %s" % (src_file or "<text>"))
 Exception: Failed to compile BPF module <text>

 root@linux:/home/loongson/bcc# python examples/hello_world.py
 In file included from <built-in>:3:
 In file included from /virtual/include/bcc/helpers.h:53:
 In file included from include/linux/log2.h:12:
 In file included from include/linux/bitops.h:32:
 arch/mips/include/asm/bitops.h:101:3: error: invalid output constraint '+ZC' in asm
                 __bit_op(*m, __INS "%0, %3, %2, 1", "i"(bit), "r"(~0));
                 ^
 arch/mips/include/asm/bitops.h:40:19: note: expanded from macro '__bit_op'
         : "=&r"(__temp), "+" GCC_OFF_SMALL_ASM()(mem)           \
                          ^
 [...]
 arch/mips/include/asm/atomic.h:154:1: error: invalid output constraint '+ZC' in asm
 arch/mips/include/asm/atomic.h:151:2: note: expanded from macro 'ATOMIC_OPS'
         ATOMIC_FETCH_OP(pfx, op, type, c_op, asm_op, ll, sc)
         ^
 arch/mips/include/asm/atomic.h:141:4: note: expanded from macro 'ATOMIC_FETCH_OP'
           "+" GCC_OFF_SMALL_ASM() (v->counter)                          \
           ^
 fatal error: too many errors emitted, stopping now [-ferror-limit=]
 20 errors generated.
 Traceback (most recent call last):
   File "examples/hello_world.py", line 12, in <module>
     BPF(text='int kprobe__sys_clone(void *ctx) { bpf_trace_printk("Hello, World!\\n"); return 0; }').trace_print()
   File "/usr/lib/python2.7/site-packages/bcc/__init__.py", line 364, in __init__
     raise Exception("Failed to compile BPF module %s" % (src_file or "<text>"))
 Exception: Failed to compile BPF module <text>

Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn>
libbpf-tools/Makefile
src/cc/export/helpers.h
src/cc/frontends/clang/arch_helper.h
src/cc/frontends/clang/b_frontend_action.cc
src/cc/frontends/clang/kbuild_helper.cc
src/cc/frontends/clang/loader.cc

index 5bbd0c42044002b8cd5c4a92904131c8c887267a..87df7e486d2526172269060bb43d8eee0d627b11 100644 (file)
@@ -9,7 +9,7 @@ INCLUDES := -I$(OUTPUT)
 CFLAGS := -g -O2 -Wall
 INSTALL ?= install
 prefix ?= /usr/local
-ARCH := $(shell uname -m | sed 's/x86_64/x86/' | sed 's/aarch64/arm64/' | sed 's/ppc64le/powerpc/')
+ARCH := $(shell uname -m | sed 's/x86_64/x86/' | sed 's/aarch64/arm64/' | sed 's/ppc64le/powerpc/' | sed 's/mips.*/mips/')
 
 ifeq ($(wildcard $(ARCH)/),)
 $(error Architecture $(ARCH) is not supported yet. Please open an issue)
index c232441516ccd8e7b71e4cb0058e7a7f7ba08a8f..4aeeb3370d93e230df651cb529f225d67a38a322 100644 (file)
@@ -1099,6 +1099,9 @@ int bpf_usdt_readarg_p(int argc, struct pt_regs *ctx, void *buf, u64 len) asm("l
 #elif defined(__TARGET_ARCH_powerpc)
 #define bpf_target_powerpc
 #define bpf_target_defined
+#elif defined(__TARGET_ARCH_mips)
+#define bpf_target_mips
+#define bpf_target_defined
 #else
 #undef bpf_target_defined
 #endif
@@ -1113,6 +1116,8 @@ int bpf_usdt_readarg_p(int argc, struct pt_regs *ctx, void *buf, u64 len) asm("l
 #define bpf_target_arm64
 #elif defined(__powerpc__)
 #define bpf_target_powerpc
+#elif defined(__mips__)
+#define bpf_target_mips
 #endif
 #endif
 
@@ -1161,6 +1166,18 @@ int bpf_usdt_readarg_p(int argc, struct pt_regs *ctx, void *buf, u64 len) asm("l
 #define PT_REGS_RC(x)          ((x)->regs[0])
 #define PT_REGS_SP(x)          ((x)->sp)
 #define PT_REGS_IP(x)          ((x)->pc)
+#elif defined(bpf_target_mips)
+#define PT_REGS_PARM1(x) ((x)->regs[4])
+#define PT_REGS_PARM2(x) ((x)->regs[5])
+#define PT_REGS_PARM3(x) ((x)->regs[6])
+#define PT_REGS_PARM4(x) ((x)->regs[7])
+#define PT_REGS_PARM5(x) ((x)->regs[8])
+#define PT_REGS_PARM6(x) ((x)->regs[9])
+#define PT_REGS_RET(x) ((x)->regs[31])
+#define PT_REGS_FP(x) ((x)->regs[30]) /* Works only with CONFIG_FRAME_POINTER */
+#define PT_REGS_RC(x) ((x)->regs[2])
+#define PT_REGS_SP(x) ((x)->regs[29])
+#define PT_REGS_IP(x) ((x)->cp0_epc)
 #else
 #error "bcc does not support this platform yet"
 #endif
index d02feff0212a1f22b40720a41b98cc1b42f6148e..7704fd02d7e8fe810928e790fe5d87d143416d6a 100644 (file)
@@ -22,6 +22,7 @@ typedef enum {
   BCC_ARCH_PPC_LE,
   BCC_ARCH_S390X,
   BCC_ARCH_ARM64,
+  BCC_ARCH_MIPS,
   BCC_ARCH_X86
 } bcc_arch_t;
 
@@ -43,6 +44,8 @@ static void *run_arch_callback(arch_callback_t fn, bool for_syscall = false)
     return fn(BCC_ARCH_S390X, for_syscall);
 #elif defined(__aarch64__)
     return fn(BCC_ARCH_ARM64, for_syscall);
+#elif defined(__mips__)
+    return fn(BCC_ARCH_MIPS, for_syscall);
 #else
     return fn(BCC_ARCH_X86, for_syscall);
 #endif
@@ -59,6 +62,8 @@ static void *run_arch_callback(arch_callback_t fn, bool for_syscall = false)
     return fn(BCC_ARCH_S390X, for_syscall);
   } else if (!strcmp(archenv, "arm64")) {
     return fn(BCC_ARCH_ARM64, for_syscall);
+  } else if (!strcmp(archenv, "mips")) {
+    return fn(BCC_ARCH_MIPS, for_syscall);
   } else {
     return fn(BCC_ARCH_X86, for_syscall);
   }
index da9b8ed9c0fd11e7eb3eb87b4945ab30f2f94f5f..9b3c24893e0b68d5caf375518109ba7abeea356f 100644 (file)
@@ -57,6 +57,9 @@ const char *calling_conv_regs_s390x[] = {"gprs[2]", "gprs[3]", "gprs[4]",
 const char *calling_conv_regs_arm64[] = {"regs[0]", "regs[1]", "regs[2]",
                                        "regs[3]", "regs[4]", "regs[5]"};
 
+const char *calling_conv_regs_mips[] = {"regs[4]", "regs[5]", "regs[6]",
+                                       "regs[7]", "regs[8]", "regs[9]"};
+
 void *get_call_conv_cb(bcc_arch_t arch, bool for_syscall)
 {
   const char **ret;
@@ -72,6 +75,9 @@ void *get_call_conv_cb(bcc_arch_t arch, bool for_syscall)
     case BCC_ARCH_ARM64:
       ret = calling_conv_regs_arm64;
       break;
+    case BCC_ARCH_MIPS:
+      ret = calling_conv_regs_mips;
+      break;
     default:
       if (for_syscall)
         ret = calling_conv_syscall_regs_x86;
index c4e0f074a50e76b667901b3ab4a2b161874fc98b..5bed2721b6c4dd5280c13d898411f19b14dde733 100644 (file)
@@ -115,6 +115,11 @@ int KBuildHelper::get_flags(const char *uname_machine, vector<string> *cflags) {
     cflags->push_back("-Iinclude/generated/uapi");
   }
 
+  if (arch == "mips") {
+    cflags->push_back("-Iarch/mips/include/asm/mach-loongson64");
+    cflags->push_back("-Iarch/mips/include/asm/mach-generic");
+  }
+
   cflags->push_back("-include");
   cflags->push_back("./include/linux/kconfig.h");
   cflags->push_back("-D__KERNEL__");
index a274f0fe687765a2cee6e7442f41afda95078144..9bd8a65044d4c32b9ca3f81aa4f5b077a1a8d57f 100644 (file)
@@ -195,6 +195,15 @@ int ClangLoader::parse(unique_ptr<llvm::Module> *mod, TableStorage &ts,
                                    "-fno-asynchronous-unwind-tables",
                                    "-x", "c", "-c", abs_file.c_str()});
 
+  const char *arch = getenv("ARCH");
+  if (!arch)
+    arch = un.machine;
+
+  if (!strncmp(arch, "mips", 4)) {
+    flags_cstr.push_back("-D__MIPSEL__");
+    flags_cstr.push_back("-D_MIPS_SZLONG=64");
+  }
+
   KBuildHelper kbuild_helper(kpath_env ? kpath : kdir, has_kpath_source);
 
   vector<string> kflags;
@@ -270,6 +279,9 @@ void *get_clang_target_cb(bcc_arch_t arch, bool for_syscall)
     case BCC_ARCH_ARM64:
       ret = "aarch64-unknown-linux-gnu";
       break;
+    case BCC_ARCH_MIPS:
+      ret = "mips64el-unknown-linux-gnuabi64";
+      break;
     default:
       ret = "x86_64-unknown-linux-gnu";
   }