Re: can't get BTF: type .rodata.cst32: not found

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, Feb 4, 2022 at 10:04 AM Yonghong Song <yhs@xxxxxx> wrote:
>
>
>
> On 2/4/22 3:11 AM, Timo Beckers wrote:
> > On 2/3/22 03:11, Yonghong Song wrote:
> >>
> >>
> >> On 2/2/22 5:47 AM, Timo Beckers wrote:
> >>> On 2/2/22 08:17, Yonghong Song wrote:
> >>>>
> >>>>
> >>>> On 2/1/22 10:07 AM, Vincent Li wrote:
> >>>>> On Fri, Jan 28, 2022 at 10:27 AM Vincent Li <vincent.mc.li@xxxxxxxxx> wrote:
> >>>>>>
> >>>>>> On Thu, Jan 27, 2022 at 5:50 PM Yonghong Song <yhs@xxxxxx> wrote:
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>> On 1/25/22 12:32 PM, Vincent Li wrote:
> >>>>>>>> On Tue, Jan 25, 2022 at 9:52 AM Vincent Li <vincent.mc.li@xxxxxxxxx> wrote:
> >>>>>>>>>
> >>>>>>>>> this is macro I suspected in my implementation that could cause issue with BTF
> >>>>>>>>>
> >>>>>>>>> #define ENABLE_VTEP 1
> >>>>>>>>> #define VTEP_ENDPOINT (__u32[]){0xec48a90a, 0xee48a90a, 0x1f48a90a,
> >>>>>>>>> 0x2048a90a, }
> >>>>>>>>> #define VTEP_MAC (__u64[]){0x562e984c3682, 0x582e984c3682,
> >>>>>>>>> 0x5eaaed93fdf2, 0x5faaed93fdf2, }
> >>>>>>>>> #define VTEP_NUMS 4
> >>>>>>>>>
> >>>>>>>>> On Tue, Jan 25, 2022 at 9:38 AM Vincent Li <vincent.mc.li@xxxxxxxxx> wrote:
> >>>>>>>>>>
> >>>>>>>>>> Hi
> >>>>>>>>>>
> >>>>>>>>>> While developing Cilium VTEP integration feature
> >>>>>>>>>> https://github.com/cilium/cilium/pull/17370, I found a strange issue
> >>>>>>>>>> that seems related to BTF and probably caused by my specific
> >>>>>>>>>> implementation, the issue is described in
> >>>>>>>>>> https://github.com/cilium/cilium/issues/18616, I don't know much about
> >>>>>>>>>> BTF and not sure if my implementation is seriously flawed or just some
> >>>>>>>>>> implementation bug or maybe not compatible with BTF. Strangely, the
> >>>>>>>>>> issue appears related to number of VTEPs I use, no problem with 1 or 2
> >>>>>>>>>> VTEP, 3, 4 VTEPs will have problem with BTF, any guidance from BTF
> >>>>>>>>>> experts  are appreciated :-).
> >>>>>>>>>>
> >>>>>>>>>> Thanks
> >>>>>>>>>>
> >>>>>>>>>> Vincent
> >>>>>>>>
> >>>>>>>> Sorry for previous top post
> >>>>>>>>
> >>>>>>>> it looks the compiler compiles the cilium bpf_lxc.c to bpf_lxc.o
> >>>>>>>> differently and added " [21] .rodata.cst32     PROGBITS
> >>>>>>>> 0000000000000000  00011e68" when  following macro exceeded 2 members
> >>>>>>>>
> >>>>>>>> #define VTEP_ENDPOINT (__u32[]){0xec48a90a, 0xee48a90a, 0x1f48a90a,
> >>>>>>>> 0x2048a90a, }
> >>>>>>>>
> >>>>>>>> no ".rodata.cst32" compiled in bpf_lxc.o  when above VTEP_ENDPOINT
> >>>>>>>> member <=2. any reason why compiler would do that?
> >>>>>>>
> >>>>>>> Regarding to why compiler generates .rodata.cst32, the reason is
> >>>>>>> you have some 32-byte constants which needs to be saved somewhere.
> >>>>>>> For example,
> >>>>>>>
> >>>>>>> $ cat t.c
> >>>>>>> struct t {
> >>>>>>>       long c[2];
> >>>>>>>       int d[4];
> >>>>>>> };
> >>>>>>> struct t g;
> >>>>>>> int test()
> >>>>>>> {
> >>>>>>>        struct t tmp  = {.c = {1, 2}, .d = {3, 4}};
> >>>>>>>        g = tmp;
> >>>>>>>        return 0;
> >>>>>>> }
> >>>>>>>
> >>>>>>> $ clang -target bpf -O2 -c t.c
> >>>>>>> $ llvm-readelf -S t.o
> >>>>>>> ...
> >>>>>>>       [ 4] .rodata.cst32     PROGBITS        0000000000000000 0000a8 000020
> >>>>>>> 20  AM  0   0  8
> >>>>>>> ...
> >>>>>>>
> >>>>>>> In the above code, if you change the struct size, say from 32 bytes to
> >>>>>>> 40 bytes, the rodata.cst32 will go away.
> >>>>>>
> >>>>>> Thanks Yonghong! I guess it is cilium/ebpf needs to recognize rodata.cst32 then
> >>>>>
> >>>>> Hi Yonghong,
> >>>>>
> >>>>> Here is a follow-up question, it looks cilium/ebpf parse vmlinux and
> >>>>> stores BTF type info in btf.Spec.namedTypes, but the elf object file
> >>>>> provided by user may have section like rodata.cst32 generated by
> >>>>> compiler that does not have accompanying BTF type info stored in
> >>>>> btf.Spec.NamedTypes for the rodata.cst32, how vmlinux can be
> >>>>> guaranteed to  have every BTF type info from application/user provided
> >>>>> elf object file ? I guess there is no guarantee.
> >>>>
> >>>> vmlinux holds kernel types. rodata.cst32 holds data. If the type of
> >>>> rodata.cst32 needs to be emitted, the type will be encoded in bpf
> >>>> program BTF.
> >>>>
> >>>> Did you actually find an issue with .rodata.cst32 section? Such a
> >>>> section is typically generated by the compiler for initial data
> >>>> inside the function and llvm bpf backend tries to inline the
> >>>> values through a bunch of load instructions. So even you see
> >>>> .rodata.cst32, typically you can safely ignore it.
> >>>>
> >>>>>
> >>>>> Vincent
> >>>>
> >>>
> >>> Hi Yonghong,
> >>>
> >>> Thanks for the reproducer. Couldn't figure out what to do with .rodata.cst32,
> >>> since there are no symbols and no BTF info for that section.
> >>>
> >>> The values found in .rodata.cst32 are indeed inlined in the bytecode as you
> >>> mentioned, so it seems like we can ignore it.
> >>>
> >>> Why does the compiler emit these sections? cilium/ebpf assumed up until now
> >>> that all sections starting with '.rodata' are datasecs and must be loaded into
> >>> the kernel, which of course needs accompanying BTF.
> >>
> >> The clang frontend emits these .rodata.* sections. In early days, kernel
> >> doesn't support global data so llvm bpf backend implements an
> >> optimization to inline these values. But llvm bpf backend didn't completely remove them as the backend doesn't have a global view
> >> whether these .rodata.* are being used in other places or not.
> >>
> >> Now, llvm bpf backend has better infrastructure and we probably can
> >> implement an IR pass to detect all uses of .rodata.*, inline these
> >> uses, and remove the .rodata.* global variable.
> >>
> >> You can check relocation section of the program text. If the .rodata.*
> >> section is referenced, you should preserve it. Otherwise, you can
> >> ignore that .rodata.* section.
> >>
> >>>
> >>> What other .rodata.* should we expect?
> >>
> >> Glancing through llvm code, you may see .rodata.{4,8,16,32},
> >> .rodata.str*.
> >>
> >>>
> >>> Thanks,
> >>>
> >>> Timo
> >
> > Thanks for the replies all, very insightful. We were already doing things mostly
> > right wrt. .rodata.*, but found a few subtle bugs walking through the code again.
> >
> > I've gotten a hold of the ELF Vincent was trying to load, and I saw a few things
> > that I found unusual. In his case, the values in cst32 are not inlined. Instead,
> > this ELF has a .Lconstinit symbol pointing at the start of .rodata.cst32, and it's
> > an STT_OBJECT with STB_LOCAL. Our relocation handler is fairly strict and requires
> > STT_OBJECTs to be global (for supporting non-static consts).
>
> There are two ways to resolve the issue. First, extend the loader
> support to handle STB_LOCAL as well. Or Second, change the code like
>      struct t v = {1, 5, 29, ...};
> to
>      struct t v;
>      __builtin_memset(&v, 0, sizeof(struct t));
>      v.field1 = ...;
>      v.field2 = ...;
>
>
> >
> > ---
> > ~ llvm-readelf -ar bpf_lxc.o
> >
> > Symbol table '.symtab' contains 606 entries:
> >     Num:    Value          Size Type    Bind   Vis       Ndx Name
> >       2: 0000000000000000    32 OBJECT  LOCAL  DEFAULT    21 .Lconstinit
> >
> > Relocation section '.rel2/7' at offset 0x6bdf0 contains 173 entries:
> >      Offset             Info             Type               Symbol's Value  Symbol's Name
> > 0000000000007300  0000000200000001 R_BPF_64_64            0000000000000000 .Lconstinit
> > ---
> >
> > ---
> > ~ llvm-objdump -S -r -j 2/7 -j .rodata.cst32 bpf_lxc.o
> > warning: failed to compute relocation: R_BPF_64_64, Invalid data was encountered while parsing the file
> > ... <2 more of these> ...
> >
> > Disassembly of section 2/7:
> >
> > 00000000000072f8 <LBB1_476>:
> >      3679:       67 08 00 00 03 00 00 00 r8 <<= 3
> >      3680:       18 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 r2 = 0 ll
> >                  0000000000007300:  R_BPF_64_64  .Lconstinit
> >      3682:       0f 82 00 00 00 00 00 00 r2 += r8
> >      3683:       79 22 00 00 00 00 00 00 r2 = *(u64 *)(r2 + 0)
> >      3684:       7b 2a 58 ff 00 00 00 00 *(u64 *)(r10 - 168) = r2
> >
> > Disassembly of section .rodata.cst32:
> >
> > 0000000000000000 <.Lconstinit>:
> >         0:       82 36 4c 98 2e 56 00 00 <unknown>
> >         1:       82 36 4c 98 2e 55 00 00 <unknown>
> > ---
> >
> >
> > This symbol doesn't exist in the program. Worth noting is that the code that accesses
> > this static data sits within a subscope, but not sure what the effect of this would be.
> >
> > Vincent, maybe try removing the enclosing {} to see if that changes anything?
> >
> > ---
> > static __always_inline int foo(struct __ctx_buff *ctx,
> >
> > ... <snip> ...
> >
> >       {
> >               int i;
> >
> >               for (i = 0; i < VTEP_NUMS; i) {
> >                       if (tunnel_endpoint == VTEP_ENDPOINT[i]) {
> >                               vtep_mac = VTEP_MAC[i];
> >                               break;
> >                       }
> >               }
> >       }
> > ---
> >
> > Is this perhaps something that needs to be addressed in the compiler?
>
> If you can give a reproducible test (with .c or .i file), I can take a
> look at what is missing in llvm compiler and improve it.
>

not sure if it would help, here is my step to generate the bpf_lxc.o
object file with the .rodata.cst32

git clone https://github.com/f5devcentral/cilium.git
cd cilium; git checkout vli-vxlan; KERNEL=54 make -C bpf
llvm-objdump -S -r -j 2/7 -j .rodata.cst32 bpf/bpf_lxc.o

> >
> >
> > Thanks again,
> >
> > Timo



[Index of Archives]     [Linux Samsung SoC]     [Linux Rockchip SoC]     [Linux Actions SoC]     [Linux for Synopsys ARC Processors]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]


  Powered by Linux