bpf.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
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

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