From: Eduard Zingerman <eddyz87@gmail.com>
To: Anton Protopopov <a.s.protopopov@gmail.com>
Cc: Alexei Starovoitov <alexei.starovoitov@gmail.com>,
bpf <bpf@vger.kernel.org>, Alexei Starovoitov <ast@kernel.org>,
Andrii Nakryiko <andrii@kernel.org>,
Anton Protopopov <aspsk@isovalent.com>,
Daniel Borkmann <daniel@iogearbox.net>,
Quentin Monnet <qmo@kernel.org>,
Yonghong Song <yonghong.song@linux.dev>
Subject: Re: [RFC bpf-next 8/9] libbpf: support llvm-generated indirect jumps
Date: Wed, 09 Jul 2025 01:38:06 -0700 [thread overview]
Message-ID: <f38d1a6ff69991230b929f2cad5776f500a2a57c.camel@gmail.com> (raw)
In-Reply-To: <f90ea7ec00265ab842e373a69f0ffdbb374f7614.camel@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 1145 bytes --]
On Tue, 2025-07-08 at 22:58 -0700, Eduard Zingerman wrote:
[...]
> This seems to work:
> https://github.com/eddyz87/llvm-project/tree/separate-jumptables-section.1
Pushed an update:
- correct offsets computation;
- avoid relocations in the .jumptables section.
Here is how it looks now (updated session.log attached):
foo: # @foo
# %bb.0: # %entry
w1 = *(u32 *)(r1 + 0)
if w1 > 31 goto LBB0_2
# %bb.1: # %entry
.LJTI0_0:
.reloc 0, FK_SecRel_8, .BPF.JT.0.0
gotox r1
goto LBB0_2
LBB0_7:
w1 = 2
goto LBB0_3
...
.Lfunc_end0:
.size foo, .Lfunc_end0-foo
.section .jumptables,"",@progbits
.L0_0_set_7 = LBB0_7-.LJTI0_0
.L0_0_set_2 = LBB0_2-.LJTI0_0
.L0_0_set_8 = LBB0_8-.LJTI0_0
.L0_0_set_9 = LBB0_9-.LJTI0_0
.L0_0_set_10 = LBB0_10-.LJTI0_0
.BPF.JT.0.0:
.long .L0_0_set_7
.long .L0_0_set_2
.long .L0_0_set_2
.long .L0_0_set_2
.long .L0_0_set_2
...
I think this is a correct form, further changes should be LLVM
internal.
[-- Attachment #2: session.log --]
[-- Type: text/x-log, Size: 7532 bytes --]
$ cat jump-table-test.c
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 -O2 -S -o - jump-table-test.c
.text
.globl foo # -- Begin function foo
.p2align 3
.type foo,@function
foo: # @foo
# %bb.0: # %entry
w1 = *(u32 *)(r1 + 0)
if w1 > 31 goto LBB0_2
# %bb.1: # %entry
.LJTI0_0:
.reloc 0, FK_SecRel_8, .BPF.JT.0.0
gotox r1
goto LBB0_2
LBB0_7:
w1 = 2
goto LBB0_3
LBB0_9: # %sw.bb2
w1 = 4
goto LBB0_3
LBB0_8: # %sw.bb1
w1 = 3
goto LBB0_3
LBB0_10: # %sw.bb3
w1 = 5
goto LBB0_3
LBB0_2: # %sw.default
w1 = 19
LBB0_3: # %sw.epilog
call bar
# kill: def $w0 killed $w0 def $r0
w0 += -1
if w0 > 43 goto LBB0_5
# %bb.4: # %sw.epilog
.LJTI0_1:
.reloc 0, FK_SecRel_8, .BPF.JT.0.1
gotox r0
goto LBB0_5
LBB0_11:
w0 = 5
goto LBB0_6
LBB0_5: # %sw.default9
w0 = 11
goto LBB0_6
LBB0_13: # %sw.bb6
w0 = 23
goto LBB0_6
LBB0_12: # %sw.bb5
w0 = 7
goto LBB0_6
LBB0_14: # %sw.bb7
w0 = 37
goto LBB0_6
LBB0_15: # %sw.bb8
w0 = 77
LBB0_6: # %sw.epilog10
exit
.Lfunc_end0:
.size foo, .Lfunc_end0-foo
.section .jumptables,"",@progbits
.L0_0_set_7 = LBB0_7-.LJTI0_0
.L0_0_set_2 = LBB0_2-.LJTI0_0
.L0_0_set_8 = LBB0_8-.LJTI0_0
.L0_0_set_9 = LBB0_9-.LJTI0_0
.L0_0_set_10 = LBB0_10-.LJTI0_0
.BPF.JT.0.0:
.long .L0_0_set_7
.long .L0_0_set_2
.long .L0_0_set_2
.long .L0_0_set_2
.long .L0_0_set_2
.long .L0_0_set_2
.long .L0_0_set_2
.long .L0_0_set_2
.long .L0_0_set_2
.long .L0_0_set_2
.long .L0_0_set_2
.long .L0_0_set_8
.long .L0_0_set_2
.long .L0_0_set_2
.long .L0_0_set_2
.long .L0_0_set_2
.long .L0_0_set_2
.long .L0_0_set_2
.long .L0_0_set_2
.long .L0_0_set_2
.long .L0_0_set_2
.long .L0_0_set_2
.long .L0_0_set_2
.long .L0_0_set_2
.long .L0_0_set_2
.long .L0_0_set_2
.long .L0_0_set_2
.long .L0_0_set_9
.long .L0_0_set_2
.long .L0_0_set_2
.long .L0_0_set_2
.long .L0_0_set_10
.size .BPF.JT.0.0, 128
.L0_1_set_11 = LBB0_11-.LJTI0_1
.L0_1_set_5 = LBB0_5-.LJTI0_1
.L0_1_set_12 = LBB0_12-.LJTI0_1
.L0_1_set_13 = LBB0_13-.LJTI0_1
.L0_1_set_14 = LBB0_14-.LJTI0_1
.L0_1_set_15 = LBB0_15-.LJTI0_1
.BPF.JT.0.1:
.long .L0_1_set_11
.long .L0_1_set_5
.long .L0_1_set_5
.long .L0_1_set_5
.long .L0_1_set_5
.long .L0_1_set_5
.long .L0_1_set_5
.long .L0_1_set_5
.long .L0_1_set_5
.long .L0_1_set_5
.long .L0_1_set_5
.long .L0_1_set_12
.long .L0_1_set_5
.long .L0_1_set_5
.long .L0_1_set_5
.long .L0_1_set_5
.long .L0_1_set_5
.long .L0_1_set_5
.long .L0_1_set_5
.long .L0_1_set_5
.long .L0_1_set_5
.long .L0_1_set_5
.long .L0_1_set_5
.long .L0_1_set_5
.long .L0_1_set_5
.long .L0_1_set_5
.long .L0_1_set_13
.long .L0_1_set_5
.long .L0_1_set_5
.long .L0_1_set_5
.long .L0_1_set_5
.long .L0_1_set_14
.long .L0_1_set_5
.long .L0_1_set_5
.long .L0_1_set_5
.long .L0_1_set_5
.long .L0_1_set_5
.long .L0_1_set_5
.long .L0_1_set_5
.long .L0_1_set_5
.long .L0_1_set_5
.long .L0_1_set_5
.long .L0_1_set_5
.long .L0_1_set_15
.size .BPF.JT.0.1, 176
# -- End function
.addrsig
$ clang --target=bpf -O2 -c -o jump-table-test.o jump-table-test.c
$ llvm-readelf -r --symbols --sections jump-table-test.o
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 000320 000067 00 0 0 1
[ 2] .text PROGBITS 0000000000000000 000040 0000f0 00 AX 0 0 8
[ 3] .rel.text REL 0000000000000000 0002f0 000030 10 I 6 2 8
[ 4] .jumptables PROGBITS 0000000000000000 000130 000130 00 0 0 1
[ 5] .llvm_addrsig LLVM_ADDRSIG 0000000000000000 000320 000000 00 E 6 0 1
[ 6] .symtab SYMTAB 0000000000000000 000260 000090 18 1 2 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)
Relocation section '.rel.text' at offset 0x2f0 contains 3 entries:
Offset Info Type Symbol's Value Symbol's Name
0000000000000010 0000000300000001 R_BPF_64_64 0000000000000000 .BPF.JT.0.0
0000000000000068 000000040000000a R_BPF_64_32 0000000000000000 bar
0000000000000080 0000000500000001 R_BPF_64_64 0000000000000080 .BPF.JT.0.1
Symbol table '.symtab' contains 6 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 240 FUNC GLOBAL DEFAULT 2 foo
3: 0000000000000000 128 NOTYPE GLOBAL DEFAULT 4 .BPF.JT.0.0
4: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND bar
5: 0000000000000080 176 NOTYPE GLOBAL 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>:
0: w1 = *(u32 *)(r1 + 0x0)
1: if w1 > 0x1f goto +0xa <foo+0x60>
2: gotox r1
0000000000000010: R_BPF_64_64 .BPF.JT.0.0
3: goto +0x8 <foo+0x60>
4: w1 = 0x2
5: goto +0x7 <foo+0x68>
6: w1 = 0x4
7: goto +0x5 <foo+0x68>
8: w1 = 0x3
9: goto +0x3 <foo+0x68>
10: w1 = 0x5
11: goto +0x1 <foo+0x68>
12: w1 = 0x13
13: call -0x1
0000000000000068: R_BPF_64_32 bar
14: w0 += -0x1
15: if w0 > 0x2b goto +0x4 <foo+0xa0>
16: gotox r0
0000000000000080: R_BPF_64_64 .BPF.JT.0.1
17: goto +0x2 <foo+0xa0>
18: w0 = 0x5
19: goto +0x9 <foo+0xe8>
20: w0 = 0xb
21: goto +0x7 <foo+0xe8>
22: w0 = 0x17
23: goto +0x5 <foo+0xe8>
24: w0 = 0x7
25: goto +0x3 <foo+0xe8>
26: w0 = 0x25
27: goto +0x1 <foo+0xe8>
28: w0 = 0x4d
29: exit
next prev parent reply other threads:[~2025-07-09 8:38 UTC|newest]
Thread overview: 63+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-06-15 8:59 [RFC bpf-next 0/9] BPF indirect jumps Anton Protopopov
2025-06-15 8:59 ` [RFC bpf-next 1/9] bpf: save the start of functions in bpf_prog_aux Anton Protopopov
2025-06-15 8:59 ` [RFC bpf-next 2/9] bpf, x86: add new map type: instructions set Anton Protopopov
2025-06-18 0:57 ` Eduard Zingerman
2025-06-18 2:16 ` Alexei Starovoitov
2025-06-19 18:57 ` Anton Protopopov
2025-06-19 18:55 ` Anton Protopopov
2025-06-19 18:55 ` Eduard Zingerman
2025-06-15 8:59 ` [RFC bpf-next 3/9] selftests/bpf: add selftests for new insn_set map Anton Protopopov
2025-06-18 11:04 ` Eduard Zingerman
2025-06-18 15:16 ` Anton Protopopov
2025-06-15 8:59 ` [RFC bpf-next 4/9] bpf, x86: allow indirect jumps to r8...r15 Anton Protopopov
2025-06-17 19:41 ` Alexei Starovoitov
2025-06-18 14:28 ` Anton Protopopov
2025-06-15 8:59 ` [RFC bpf-next 5/9] bpf, x86: add support for indirect jumps Anton Protopopov
2025-06-18 3:06 ` Alexei Starovoitov
2025-06-19 19:57 ` Anton Protopopov
2025-06-19 19:58 ` Anton Protopopov
2025-06-18 11:03 ` Eduard Zingerman
2025-06-19 20:13 ` Anton Protopopov
2025-06-15 8:59 ` [RFC bpf-next 6/9] bpf: workaround llvm behaviour with " Anton Protopopov
2025-06-18 11:04 ` Eduard Zingerman
2025-06-18 13:59 ` Alexei Starovoitov
2025-06-15 8:59 ` [RFC bpf-next 7/9] bpf: disasm: add support for BPF_JMP|BPF_JA|BPF_X Anton Protopopov
2025-06-15 8:59 ` [RFC bpf-next 8/9] libbpf: support llvm-generated indirect jumps Anton Protopopov
2025-06-18 3:22 ` Alexei Starovoitov
2025-06-18 15:08 ` Anton Protopopov
2025-07-07 23:45 ` Eduard Zingerman
2025-07-07 23:49 ` Alexei Starovoitov
2025-07-08 0:01 ` Eduard Zingerman
2025-07-08 0:12 ` Alexei Starovoitov
2025-07-08 0:18 ` Eduard Zingerman
2025-07-08 0:49 ` Alexei Starovoitov
2025-07-08 0:51 ` Eduard Zingerman
2025-07-08 20:59 ` Eduard Zingerman
2025-07-08 21:25 ` Alexei Starovoitov
2025-07-08 21:29 ` Eduard Zingerman
2025-07-09 5:33 ` Anton Protopopov
2025-07-09 5:58 ` Eduard Zingerman
2025-07-09 8:38 ` Eduard Zingerman [this message]
2025-07-10 5:11 ` Eduard Zingerman
2025-07-10 6:10 ` Anton Protopopov
2025-07-10 6:13 ` Eduard Zingerman
2025-06-18 19:49 ` Eduard Zingerman
2025-06-27 2:28 ` Eduard Zingerman
2025-06-27 10:18 ` Anton Protopopov
2025-07-03 18:21 ` Eduard Zingerman
2025-07-03 19:03 ` Anton Protopopov
2025-07-07 19:07 ` Eduard Zingerman
2025-07-07 19:34 ` Anton Protopopov
2025-07-07 21:44 ` Yonghong Song
2025-07-08 5:58 ` Yonghong Song
2025-07-08 8:30 ` Eduard Zingerman
2025-07-08 10:42 ` Eduard Zingerman
2025-06-15 8:59 ` [RFC bpf-next 9/9] selftests/bpf: add selftests for " Anton Protopopov
2025-06-18 3:24 ` Alexei Starovoitov
2025-06-18 14:49 ` Anton Protopopov
2025-06-18 16:01 ` Alexei Starovoitov
2025-06-18 16:36 ` Anton Protopopov
2025-06-18 16:43 ` Alexei Starovoitov
2025-06-18 20:25 ` Anton Protopopov
2025-06-18 21:59 ` Alexei Starovoitov
2025-06-19 5:05 ` Anton Protopopov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=f38d1a6ff69991230b929f2cad5776f500a2a57c.camel@gmail.com \
--to=eddyz87@gmail.com \
--cc=a.s.protopopov@gmail.com \
--cc=alexei.starovoitov@gmail.com \
--cc=andrii@kernel.org \
--cc=aspsk@isovalent.com \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=qmo@kernel.org \
--cc=yonghong.song@linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).