[PATCH] D155894: [BPF] allow external calls

Yonghong Song via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 26 19:52:32 PDT 2023


yonghong-song added a comment.

I applied this patch and did an experiment with bpftool linker functionality. The following are details.

First let us try one example with func mmemset which is not a builtin function.

  $ cat t1.c                                                                                                                                  
  #define __hidden __attribute__((visibility("hidden")))                                                                                                                      
  __hidden extern void *mmemset(void *s, int c, unsigned long n);                                                                                                             
  void do_memset(char *x, unsigned long l) {                                                                                                                                  
    mmemset(x, 0, l);                                                                                                                                                         
  }                                                                                                                                                                           
  $ cat t2.c                                                                                                                                  
  void *mmemset(void *s, int c, unsigned long n);                                                                                                                             
  void *mmemset(void *x, int c, unsigned long n) {
    // custom memset, I am using step of 2, otherwise the
    // compiler is smart enough and may transform
    // the code back to memset!
    char *ch = x;
    for (int i = 0; i < n; i+=2) ch[i] = c;
    return 0;
  }
  $ clang --target=bpf -O2 -g -c t1.c                    
  $ clang --target=bpf -O2 -g -c t2.c                    
  $ bpftool gen object final.o t1.o t2.o                 
  $ llvm-readelf -s t1.o
     
  Symbol table '.symtab' contains 13 entries: 
     Num:    Value          Size Type    Bind   Vis       Ndx Name
       0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT   UND 
       1: 0000000000000000     0 FILE    LOCAL  DEFAULT   ABS t1.c
       2: 0000000000000000     0 SECTION LOCAL  DEFAULT     2 .text
       3: 0000000000000000     0 SECTION LOCAL  DEFAULT     4 .debug_loclists
       4: 0000000000000000     0 SECTION LOCAL  DEFAULT     5 .debug_abbrev
       5: 0000000000000000     0 SECTION LOCAL  DEFAULT     8 .debug_str_offsets
       6: 0000000000000000     0 SECTION LOCAL  DEFAULT    10 .debug_str
       7: 0000000000000000     0 SECTION LOCAL  DEFAULT    11 .debug_addr               
       8: 0000000000000000     0 SECTION LOCAL  DEFAULT    16 .debug_frame
       9: 0000000000000000     0 SECTION LOCAL  DEFAULT    18 .debug_line               
      10: 0000000000000000     0 SECTION LOCAL  DEFAULT    20 .debug_line_str
      11: 0000000000000000    32 FUNC    GLOBAL DEFAULT     2 do_memset                 
      12: 0000000000000000     0 NOTYPE  GLOBAL HIDDEN    UND mmemset
  $ llvm-readelf -s t2.o                                 
      
  Symbol table '.symtab' contains 14 entries: 
     Num:    Value          Size Type    Bind   Vis       Ndx Name                      
       0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT   UND 
       1: 0000000000000000     0 FILE    LOCAL  DEFAULT   ABS t2.c
       2: 0000000000000000     0 SECTION LOCAL  DEFAULT     2 .text
       3: 0000000000000038     0 NOTYPE  LOCAL  DEFAULT     2 LBB0_3
       4: 0000000000000010     0 NOTYPE  LOCAL  DEFAULT     2 LBB0_2
       5: 0000000000000000     0 SECTION LOCAL  DEFAULT     3 .debug_loclists
       6: 0000000000000000     0 SECTION LOCAL  DEFAULT     4 .debug_abbrev
       7: 0000000000000000     0 SECTION LOCAL  DEFAULT     7 .debug_str_offsets
       8: 0000000000000000     0 SECTION LOCAL  DEFAULT     9 .debug_str
       9: 0000000000000000     0 SECTION LOCAL  DEFAULT    10 .debug_addr
      10: 0000000000000000     0 SECTION LOCAL  DEFAULT    15 .debug_frame
      11: 0000000000000000     0 SECTION LOCAL  DEFAULT    17 .debug_line
      12: 0000000000000000     0 SECTION LOCAL  DEFAULT    19 .debug_line_str
      13: 0000000000000000    72 FUNC    GLOBAL DEFAULT     2 mmemset
  $ llvm-readelf -s final.o
  
  Symbol table '.symtab' contains 8 entries:
     Num:    Value          Size Type    Bind   Vis       Ndx Name
       0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT   UND 
       1: 0000000000000000     0 FILE    LOCAL  DEFAULT   ABS t1.c
       2: 0000000000000000     0 SECTION LOCAL  DEFAULT     3 .text
       3: 0000000000000000    32 FUNC    GLOBAL DEFAULT     3 do_memset
       4: 0000000000000020    72 FUNC    GLOBAL HIDDEN      3 mmemset
       5: 0000000000000000     0 FILE    LOCAL  DEFAULT   ABS t2.c
       6: 0000000000000058     0 NOTYPE  LOCAL  DEFAULT     3 LBB0_3
       7: 0000000000000030     0 NOTYPE  LOCAL  DEFAULT     3 LBB0_2

So bpftool linking succeeded with global function mmemset.

Now let rename the mmemset to memset in the above t1.c and t2.c.

  $ cat t1.c
  #define __hidden __attribute__((visibility("hidden")))
  __hidden extern void *memset(void *s, int c, unsigned long n);
  void do_memset(char *x, unsigned long l) {
    memset(x, 0, l);
  }
  $ cat t2.c
  void *memset(void *s, int c, unsigned long n);
  void *memset(void *x, int c, unsigned long n) {
    // custom memset, I am using step of 2, otherwise the
    // compiler is smart enough and may transform
    // the code back to memset!
    char *ch = x;
    for (int i = 0; i < n; i+=2) ch[i] = c;
    return 0;
  }
  $ clang --target=bpf -O2 -g -c t1.c
  $ clang --target=bpf -O2 -g -c t2.c
  $ bpftool gen object final.o t1.o t2.o
  libbpf: failed to find BTF info for global/extern symbol 'memset'
  Error: failed to link 't1.o': No such file or directory (2)
  $ llvm-readelf -s t1.o
  
  Symbol table '.symtab' contains 13 entries:
     Num:    Value          Size Type    Bind   Vis       Ndx Name
       0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT   UND 
       1: 0000000000000000     0 FILE    LOCAL  DEFAULT   ABS t1.c
       2: 0000000000000000     0 SECTION LOCAL  DEFAULT     2 .text
       3: 0000000000000000     0 SECTION LOCAL  DEFAULT     4 .debug_loclists
       4: 0000000000000000     0 SECTION LOCAL  DEFAULT     5 .debug_abbrev
       5: 0000000000000000     0 SECTION LOCAL  DEFAULT     8 .debug_str_offsets
       6: 0000000000000000     0 SECTION LOCAL  DEFAULT    10 .debug_str
       7: 0000000000000000     0 SECTION LOCAL  DEFAULT    11 .debug_addr
       8: 0000000000000000     0 SECTION LOCAL  DEFAULT    16 .debug_frame
       9: 0000000000000000     0 SECTION LOCAL  DEFAULT    18 .debug_line
      10: 0000000000000000     0 SECTION LOCAL  DEFAULT    20 .debug_line_str
      11: 0000000000000000    32 FUNC    GLOBAL DEFAULT     2 do_memset
      12: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT   UND memset
  $ llvm-readelf -s t2.o
  
  Symbol table '.symtab' contains 14 entries:
     Num:    Value          Size Type    Bind   Vis       Ndx Name
       0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT   UND 
       1: 0000000000000000     0 FILE    LOCAL  DEFAULT   ABS t2.c
       2: 0000000000000000     0 SECTION LOCAL  DEFAULT     2 .text
       3: 0000000000000038     0 NOTYPE  LOCAL  DEFAULT     2 LBB0_3
       4: 0000000000000010     0 NOTYPE  LOCAL  DEFAULT     2 LBB0_2
       5: 0000000000000000     0 SECTION LOCAL  DEFAULT     3 .debug_loclists
       6: 0000000000000000     0 SECTION LOCAL  DEFAULT     4 .debug_abbrev
       7: 0000000000000000     0 SECTION LOCAL  DEFAULT     7 .debug_str_offsets
       8: 0000000000000000     0 SECTION LOCAL  DEFAULT     9 .debug_str
       9: 0000000000000000     0 SECTION LOCAL  DEFAULT    10 .debug_addr
      10: 0000000000000000     0 SECTION LOCAL  DEFAULT    15 .debug_frame
      11: 0000000000000000     0 SECTION LOCAL  DEFAULT    17 .debug_line
      12: 0000000000000000     0 SECTION LOCAL  DEFAULT    19 .debug_line_str
      13: 0000000000000000    72 FUNC    GLOBAL DEFAULT     2 memset

The major difference is in t1.o,

      12: 0000000000000000     0 NOTYPE  GLOBAL HIDDEN    UND mmemset
  vs.
      12: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT   UND memset

So for builtin function memset, the 'visibility' is not set to HIDDEN although
we have an attribute for it.

I would like to have more study for this to understand why and how to fix it
before we lift the error message.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D155894/new/

https://reviews.llvm.org/D155894



More information about the llvm-commits mailing list