Re: [RFC bpf-next 8/9] libbpf: support llvm-generated indirect jumps

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

 



On 25/07/07 12:07PM, Eduard Zingerman wrote:
> On Thu, 2025-07-03 at 11:21 -0700, Eduard Zingerman wrote:
> 
> [...]
> 
> > > > >   .jumptables
> > > > >     <subprog-rel-off-0>
> > > > >     <subprog-rel-off-1> | <--- jump table #1 symbol:
> > > > >     <subprog-rel-off-2> |        .size = 2   // number of entries in the jump table
> > > > >     ...                          .value = 1  // offset within .jumptables
> > > > >     <subprog-rel-off-N>                          ^
> > > > >                                                  |
> > > > >   .text                                          |
> > > > >     ...                                          |
> > > > >     <insn-N>     <------ relocation referencing -'
> > > > >     ...                  jump table #1 symbol
> 
> [...]
> 
> I think I got it working in:
> https://github.com/eddyz87/llvm-project/tree/separate-jumptables-section

Awesome! I will try to use it tomorrow.

> Changes on top of Yonghong's work.
> An example is in the attachment the gist is:
> 
> -------------------------------
> 
> $ clang --target=bpf -c -o jump-table-test.o jump-table-test.c
> There are 8 section headers, starting at offset 0xaa0:
> 
> Section Headers:
>   [Nr] Name              Type            Address          Off    Size   ES Flg Lk Inf Al
>   ...
>   [ 4] .jumptables       PROGBITS        0000000000000000 000220 000260 00      0   0  1
>   ...
> 
> Symbol table '.symtab' contains 8 entries:
>    Num:    Value          Size Type    Bind   Vis       Ndx Name
>      ...
>      3: 0000000000000000   256 NOTYPE  LOCAL  DEFAULT     4 .BPF.JT.0.0
>      4: 0000000000000100   352 NOTYPE  LOCAL  DEFAULT     4 .BPF.JT.0.1
>      ...
> 
> $ llvm-objdump --no-show-raw-insn -Sdr jump-table-test.o
> jump-table-test.o:      file format elf64-bpf
> 
> Disassembly of section .text:
> 
> 0000000000000000 <foo>:
>        ...
>        6:       r2 <<= 0x3
>        7:       r1 = 0x0 ll
>                 0000000000000038:  R_BPF_64_64  .jumptables
>        9:       r1 += r2
>       10:       r1 = *(u64 *)(r1 + 0x0)
>       11:       gotox r1
>       ...
>       34:       r2 <<= 0x3
>       35:       r1 = 0x100 ll
>                 0000000000000118:  R_BPF_64_64  .jumptables
>       37:       r1 += r2
>       38:       r1 = *(u64 *)(r1 + 0x0)
>       39:       gotox r1
>       ...
> 
> -------------------------------
> 
> The changes only touch BPF backend. Can be simplified a bit if I move
> MachineFunction::getJTISymbol to TargetLowering in the shared LLVM
> parts.

> $ cat jump-table-test.c
> struct simple_ctx { int x; };
> 
> int bar(int v);
> 
> int foo(struct simple_ctx *ctx)
> {
> 	int ret_user;
> 
>         switch (ctx->x) {
>         case 0:
>                 ret_user = 2;
>                 break;
>         case 11:
>                 ret_user = 3;
>                 break;
>         case 27:
>                 ret_user = 4;
>                 break;
>         case 31:
>                 ret_user = 5;
>                 break;
>         default:
>                 ret_user = 19;
>                 break;
>         }
> 
>         switch (bar(ret_user)) {
>         case 1:
>                 ret_user = 5;
>                 break;
>         case 12:
>                 ret_user = 7;
>                 break;
>         case 27:
>                 ret_user = 23;
>                 break;
>         case 32:
>                 ret_user = 37;
>                 break;
>         case 44:
>                 ret_user = 77;
>                 break;
>         default:
>                 ret_user = 11;
>                 break;
>         }
> 
>         return ret_user;
> }
> 
> $ clang --target=bpf -c -o jump-table-test.o jump-table-test.c
> There are 8 section headers, starting at offset 0xaa0:
> 
> Section Headers:
>   [Nr] Name              Type            Address          Off    Size   ES Flg Lk Inf Al
>   [ 0]                   NULL            0000000000000000 000000 000000 00      0   0  0
>   [ 1] .strtab           STRTAB          0000000000000000 000a31 00006b 00      0   0  1
>   [ 2] .text             PROGBITS        0000000000000000 000040 0001e0 00  AX  0   0  8
>   [ 3] .rel.text         REL             0000000000000000 000540 000030 10   I  7   2  8
>   [ 4] .jumptables       PROGBITS        0000000000000000 000220 000260 00      0   0  1
>   [ 5] .rel.jumptables   REL             0000000000000000 000570 0004c0 10   I  7   4  8
>   [ 6] .llvm_addrsig     LLVM_ADDRSIG    0000000000000000 000a30 000001 00   E  7   0  1
>   [ 7] .symtab           SYMTAB          0000000000000000 000480 0000c0 18      1   6  8
> Key to Flags:
>   W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
>   L (link order), O (extra OS processing required), G (group), T (TLS),
>   C (compressed), x (unknown), o (OS specific), E (exclude),
>   R (retain), p (processor specific)
> 
> 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 jump-table-test.c
>      2: 0000000000000000     0 SECTION LOCAL  DEFAULT     2 .text
>      3: 0000000000000000   256 NOTYPE  LOCAL  DEFAULT     4 .BPF.JT.0.0
>      4: 0000000000000100   352 NOTYPE  LOCAL  DEFAULT     4 .BPF.JT.0.1
>      5: 0000000000000000     0 SECTION LOCAL  DEFAULT     4 .jumptables
>      6: 0000000000000000   480 FUNC    GLOBAL DEFAULT     2 foo
>      7: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT   UND bar
> 
> $ llvm-objdump --no-show-raw-insn -Sdr jump-table-test.o
> jump-table-test.o:	file format elf64-bpf
> 
> Disassembly of section .text:
> 
> 0000000000000000 <foo>:
>        0:	*(u64 *)(r10 - 0x8) = r1
>        1:	r1 = *(u64 *)(r10 - 0x8)
>        2:	w1 = *(u32 *)(r1 + 0x0)
>        3:	*(u64 *)(r10 - 0x18) = r1
>        4:	if w1 > 0x1f goto +0x13 <foo+0xc0>
>        5:	r2 = *(u64 *)(r10 - 0x18)
>        6:	r2 <<= 0x3
>        7:	r1 = 0x0 ll
> 		0000000000000038:  R_BPF_64_64	.jumptables
>        9:	r1 += r2
>       10:	r1 = *(u64 *)(r1 + 0x0)
>       11:	gotox r1
>       12:	w1 = 0x2
>       13:	*(u32 *)(r10 - 0xc) = w1
>       14:	goto +0xc <foo+0xd8>
>       15:	w1 = 0x3
>       16:	*(u32 *)(r10 - 0xc) = w1
>       17:	goto +0x9 <foo+0xd8>
>       18:	w1 = 0x4
>       19:	*(u32 *)(r10 - 0xc) = w1
>       20:	goto +0x6 <foo+0xd8>
>       21:	w1 = 0x5
>       22:	*(u32 *)(r10 - 0xc) = w1
>       23:	goto +0x3 <foo+0xd8>
>       24:	w1 = 0x13
>       25:	*(u32 *)(r10 - 0xc) = w1
>       26:	goto +0x0 <foo+0xd8>
>       27:	w1 = *(u32 *)(r10 - 0xc)
>       28:	call -0x1
> 		00000000000000e0:  R_BPF_64_32	bar
>       29:	w0 += -0x1
>       30:	w1 = w0
>       31:	*(u64 *)(r10 - 0x20) = r1
>       32:	if w0 > 0x2b goto +0x16 <foo+0x1b8>
>       33:	r2 = *(u64 *)(r10 - 0x20)
>       34:	r2 <<= 0x3
>       35:	r1 = 0x100 ll
> 		0000000000000118:  R_BPF_64_64	.jumptables
>       37:	r1 += r2
>       38:	r1 = *(u64 *)(r1 + 0x0)
>       39:	gotox r1
>       40:	w1 = 0x5
>       41:	*(u32 *)(r10 - 0xc) = w1
>       42:	goto +0xf <foo+0x1d0>
>       43:	w1 = 0x7
>       44:	*(u32 *)(r10 - 0xc) = w1
>       45:	goto +0xc <foo+0x1d0>
>       46:	w1 = 0x17
>       47:	*(u32 *)(r10 - 0xc) = w1
>       48:	goto +0x9 <foo+0x1d0>
>       49:	w1 = 0x25
>       50:	*(u32 *)(r10 - 0xc) = w1
>       51:	goto +0x6 <foo+0x1d0>
>       52:	w1 = 0x4d
>       53:	*(u32 *)(r10 - 0xc) = w1
>       54:	goto +0x3 <foo+0x1d0>
>       55:	w1 = 0xb
>       56:	*(u32 *)(r10 - 0xc) = w1
>       57:	goto +0x0 <foo+0x1d0>
>       58:	w0 = *(u32 *)(r10 - 0xc)
>       59:	exit
> 





[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