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

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

 



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

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


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