Re: [PATCH bpf-next v3 6/8] bpftool: Add LLVM as default library for disassembling JIT-ed programs

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

 



2022-10-20 10:49 UTC-0700 ~ Alexei Starovoitov
<alexei.starovoitov@xxxxxxxxx>
> On Thu, Oct 20, 2022 at 5:37 AM Quentin Monnet <quentin@xxxxxxxxxxxxx> wrote:
>>
>> +
>> +/* This callback to set the ref_type is necessary to have the LLVM disassembler
>> + * print PC-relative addresses instead of byte offsets for branch instruction
>> + * targets.
>> + */
>> +static const char *
>> +symbol_lookup_callback(__maybe_unused void *disasm_info,
>> +                      __maybe_unused uint64_t ref_value,
>> +                      uint64_t *ref_type, __maybe_unused uint64_t ref_PC,
>> +                      __maybe_unused const char **ref_name)
>> +{
>> +       *ref_type = LLVMDisassembler_ReferenceType_InOut_None;
>> +       return NULL;
>> +}
> 
> Could you give an example before/after for asm
> that contains 'call foo' instructions?
> I'm not sure that above InOut_None will not break
> symbolization.

Hi Alexei, I ran a quick test and it doesn't seem we lose any
information. Building from:

	#include <linux/bpf.h>
	#include "bpf_helper_defs.h"

	#define SEC(name) __attribute__((section(name), used))

	static __attribute__((noinline))
	int bar(int b) {
		return bpf_get_prandom_u32() > b;
	}

	SEC("xdp")
	int foo(struct xdp_md *ctx) {
		void *data = (void *)(long)ctx->data;
		void *data_end = (void *)(long)ctx->data_end;

		return bar(data_end - data);
	}

Here is the output from the existing version (using libbfd):

	# bpftool version
	bpftool v7.1.0
	using libbpf v1.1
	features: libbfd, libbpf_strict, skeletons

	# bpftool prog dump jited name foo
	int foo(struct xdp_md * ctx):
	bpf_prog_65e359e7b0251046_foo:
	; void *data = (void *)(long)ctx->data;
	   0:   nopl   0x0(%rax,%rax,1)
	   5:   xchg   %ax,%ax
	   7:   push   %rbp
	   8:   mov    %rsp,%rbp
	   b:   mov    0x0(%rdi),%rsi
	; void *data_end = (void *)(long)ctx->data_end;
	   f:   mov    0x8(%rdi),%rdi
	; return bar(data_end - data);
	  13:   sub    %esi,%edi
	; return bar(data_end - data);
	  15:   call   0x0000000000000038
	; return bar(data_end - data);
	  1a:   leave
	  1b:   ret

	int bar(int b):
	bpf_prog_9b001d67a67f01cc_bar:
	; int bar(int b) {
	   0:   nopl   0x0(%rax,%rax,1)
	   5:   xchg   %ax,%ax
	   7:   push   %rbp
	   8:   mov    %rsp,%rbp
	   b:   push   %rbx
	   c:   mov    %edi,%ebx
	; return bpf_get_prandom_u32() > b;
	   e:   call   0xffffffffcab00454
	  13:   mov    %eax,%edi
	  15:   mov    $0x1,%eax
	; return bpf_get_prandom_u32() > b;
	  1a:   cmp    %ebx,%edi
	  1c:   ja     0x0000000000000020
	  1e:   xor    %eax,%eax
	; return bpf_get_prandom_u32() > b;
	  20:   pop    %rbx
	  21:   leave
	  22:   ret

Did you expect "bar" to appear on insn '15:'? I don't think we get this
from bpftool at the moment? Or did I misunderstand your question?

The output from LLVM's disassembler comes below:

	# ./bpftool version
	bpftool v7.1.0
	using libbpf v1.1
	features: llvm, libbpf_strict, skeletons

	# ./bpftool prog dump jited name foo
	int foo(struct xdp_md * ctx):
	bpf_prog_65e359e7b0251046_foo:
	; void *data = (void *)(long)ctx->data;
	   0:   nopl    (%rax,%rax)
	   5:   nop
	   7:   pushq   %rbp
	   8:   movq    %rsp, %rbp
	   b:   movq    (%rdi), %rsi
	; void *data_end = (void *)(long)ctx->data_end;
	   f:   movq    8(%rdi), %rdi
	; return bar(data_end - data);
	  13:   subl    %esi, %edi
	; return bar(data_end - data);
	  15:   callq   0x38
	; return bar(data_end - data);
	  1a:   leave
	  1b:   retq

	int bar(int b):
	bpf_prog_9b001d67a67f01cc_bar:
	; int bar(int b) {
	   0:   nopl    (%rax,%rax)
	   5:   nop
	   7:   pushq   %rbp
	   8:   movq    %rsp, %rbp
	   b:   pushq   %rbx
	   c:   movl    %edi, %ebx
	; return bpf_get_prandom_u32() > b;
	   e:   callq   0xffffffffcab00454
	  13:   movl    %eax, %edi
	  15:   movl    $1, %eax
	; return bpf_get_prandom_u32() > b;
	  1a:   cmpl    %ebx, %edi
	  1c:   ja      0x20
	  1e:   xorl    %eax, %eax
	; return bpf_get_prandom_u32() > b;
	  20:   popq    %rbx
	  21:   leave
	  22:   retq

LLVM, but _without_ the LLVMDisassembler_ReferenceType_InOut_None:

	int foo(struct xdp_md * ctx):
	bpf_prog_65e359e7b0251046_foo:
	; void *data = (void *)(long)ctx->data;
	   0:   nopl    (%rax,%rax)
	   5:   nop
	   7:   pushq   %rbp
	   8:   movq    %rsp, %rbp
	   b:   movq    (%rdi), %rsi
	; void *data_end = (void *)(long)ctx->data_end;
	   f:   movq    8(%rdi), %rdi
	; return bar(data_end - data);
	  13:   subl    %esi, %edi
	; return bar(data_end - data);
	  15:   callq   30
	; return bar(data_end - data);
	  1a:   leave
	  1b:   retq

	int bar(int b):
	bpf_prog_9b001d67a67f01cc_bar:
	; int bar(int b) {
	   0:   nopl    (%rax,%rax)
	   5:   nop
	   7:   pushq   %rbp
	   8:   movq    %rsp, %rbp
	   b:   pushq   %rbx
	   c:   movl    %edi, %ebx
	; return bpf_get_prandom_u32() > b;
	   e:   callq   -894434239
	  13:   movl    %eax, %edi
	  15:   movl    $1, %eax
	; return bpf_get_prandom_u32() > b;
	  1a:   cmpl    %ebx, %edi
	  1c:   ja      2
	  1e:   xorl    %eax, %eax
	; return bpf_get_prandom_u32() > b;
	  20:   popq    %rbx
	  21:   leave
	  22:   retq




[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