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

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

 



On Sat, Feb 5, 2022 at 2:38 AM Yonghong Song <yhs@xxxxxx> wrote:
>
>
>
> On 2/4/22 11:39 AM, Vincent Li wrote:
> > 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. I can reproduce the issue now. Will take a look
> and get back to you as soon as I got any concrete results.
>

All the emails are arriving heavily out of order, it's confusing to
follow. Does this affect cilium/ebpf library or libbpf can't handle
this as well?

> >
> >>>
> >>>
> >>> 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