export/helpers: only put helpers in special section for B lang
authorDave Marchevsky <davemarchevsky@fb.com>
Mon, 18 Oct 2021 00:25:48 +0000 (20:25 -0400)
committeryonghong-song <ys114321@gmail.com>
Mon, 18 Oct 2021 21:44:07 +0000 (14:44 -0700)
B's code generation needs these functions to exist in the object as it
emits some calls to these functions at IR stage, where 'always_inline'
directive results in no symbol for the function being emitted otherwise
as all uses are inlined.

For C, stop putting these helpers in a "helpers" section in object file.
For B, add a `B_WORKAROUND` ifdef check so the "helpers" section is
populated as expected.

There is almost certainly a more elegant way to fix this but would
require digging deep in the b frontend and potentially breaking other
things. Since B frontend hasn't been touched in many years and still
works, let's take the safer but uglier route.

src/cc/bpf_module.cc
src/cc/export/helpers.h

index 007d6ad..80d3fc6 100644 (file)
@@ -175,7 +175,8 @@ int BPFModule::load_cfile(const string &file, bool in_memory, const char *cflags
 // build an ExecutionEngine.
 int BPFModule::load_includes(const string &text) {
   ClangLoader clang_loader(&*ctx_, flags_);
-  if (clang_loader.parse(&mod_, *ts_, text, true, nullptr, 0, "", *func_src_,
+  const char *cflags[] = {"-DB_WORKAROUND"};
+  if (clang_loader.parse(&mod_, *ts_, text, true, cflags, 1, "", *func_src_,
                          mod_src_, "", fake_fd_map_, perf_events_))
     return -1;
   return 0;
index 5314bca..e4044aa 100644 (file)
@@ -69,6 +69,12 @@ R"********(
  */
 #define BCC_SEC(NAME) __attribute__((section(NAME), used))
 
+#ifdef B_WORKAROUND
+#define BCC_SEC_HELPERS BCC_SEC("helpers")
+#else
+#define BCC_SEC_HELPERS
+#endif
+
 // Associate map with its key/value types
 #define BPF_ANNOTATE_KV_PAIR(name, type_key, type_val) \
         struct ____btf_map_##name {                    \
@@ -1020,7 +1026,7 @@ unsigned int bpf_log2l(unsigned long v)
 struct bpf_context;
 
 static inline __attribute__((always_inline))
-BCC_SEC("helpers")
+BCC_SEC_HELPERS
 u64 bpf_dext_pkt(void *pkt, u64 off, u64 bofs, u64 bsz) {
   if (bofs == 0 && bsz == 8) {
     return load_byte(pkt, off);
@@ -1043,7 +1049,7 @@ u64 bpf_dext_pkt(void *pkt, u64 off, u64 bofs, u64 bsz) {
 }
 
 static inline __attribute__((always_inline))
-BCC_SEC("helpers")
+BCC_SEC_HELPERS
 void bpf_dins_pkt(void *pkt, u64 off, u64 bofs, u64 bsz, u64 val) {
   // The load_xxx function does a bswap before returning the short/word/dword,
   // so the value in register will always be host endian. However, the bytes
@@ -1086,25 +1092,25 @@ void bpf_dins_pkt(void *pkt, u64 off, u64 bofs, u64 bsz, u64 val) {
 }
 
 static inline __attribute__((always_inline))
-BCC_SEC("helpers")
+BCC_SEC_HELPERS
 void * bpf_map_lookup_elem_(uintptr_t map, void *key) {
   return bpf_map_lookup_elem((void *)map, key);
 }
 
 static inline __attribute__((always_inline))
-BCC_SEC("helpers")
+BCC_SEC_HELPERS
 int bpf_map_update_elem_(uintptr_t map, void *key, void *value, u64 flags) {
   return bpf_map_update_elem((void *)map, key, value, flags);
 }
 
 static inline __attribute__((always_inline))
-BCC_SEC("helpers")
+BCC_SEC_HELPERS
 int bpf_map_delete_elem_(uintptr_t map, void *key) {
   return bpf_map_delete_elem((void *)map, key);
 }
 
 static inline __attribute__((always_inline))
-BCC_SEC("helpers")
+BCC_SEC_HELPERS
 int bpf_l3_csum_replace_(void *ctx, u64 off, u64 from, u64 to, u64 flags) {
   switch (flags & 0xf) {
     case 2:
@@ -1120,7 +1126,7 @@ int bpf_l3_csum_replace_(void *ctx, u64 off, u64 from, u64 to, u64 flags) {
 }
 
 static inline __attribute__((always_inline))
-BCC_SEC("helpers")
+BCC_SEC_HELPERS
 int bpf_l4_csum_replace_(void *ctx, u64 off, u64 from, u64 to, u64 flags) {
   switch (flags & 0xf) {
     case 2: