lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Thu, 27 Apr 2017 19:06:14 -0700
From:   Alexei Starovoitov <ast@...com>
To:     David Miller <davem@...emloft.net>, <daniel@...earbox.net>
CC:     <netdev@...r.kernel.org>, <xdp-newbies@...r.kernel.org>
Subject: Re: assembler mnenomics for call/tailcall plus maps...

On 4/27/17 1:42 PM, David Miller wrote:
>
> Can you guys give me some kind of idea of how it might be nice to
> represent calls and tailcalls in assembler files?

llvm prints them as 'call 1' for bpf_map_lookup
and 'call 12' for bpf_tail_call.
In the instruction stream bpf_tail_call is no different
than regular call. Only after verifier it becomes special instruction.
This 'call 1234' is obviously not readable.
We probably should allow both 'call 123' to make sure that
we don't need to change assembler/compiler with every new
helper added and allow more sane
'call bpf_map_lookup_elem'
for helpers with known func_id.

> And also the emission of maps.
>
> Right now I just have the assembler looking for 32-bit immediate
> values for call and tailcall instructions.
>
> Looking at samples/bpf/sockex3_kern.c we have:
>
> struct bpf_map_def SEC("maps") jmp_table = {
> 	.type = BPF_MAP_TYPE_PROG_ARRAY,
> 	.key_size = sizeof(u32),
> 	.value_size = sizeof(u32),
> 	.max_entries = 8,
> };

yeah. this one is tricky.
Currently there is a protocol between C file section name
and user space bpf_loader.
The above 'struct bpf_map_def' is recognized by
samples/bpf/bpf_load.c
and by tools/lib/bpf/libbpf.c which is used by perf.
iproute2 allows extended format with two extra fields
for pinning.

So if we write the same stuff in assembler, the existing
loaders will understand it.
The tricky part is in relocations.
To do bpf_map_lookup_elem() the R1 needs to point to map,
so in assembler we need to be able to say something like:

ldimm64 r1, jmp_table

where jmp_table will be in data section named 'maps'.

So in asm the map lookup will look like:
	.section        maps,"aw",@progbits
         .globl  hashmap_def
hashmap_def:
         .long   1  # type
         .long   24 # key_size
         .long   40 # value_size
         .long   256 # max_entries

         .text
         .section        xdp_tx_iptunnel,"ax",@progbits
         .globl  _xdp_prog
_xdp_prog:
          ldimm64 r1, hashmap_def
          mov r2, r10
          add r2, -8
          call bpf_map_lookup_elem

this is 64-bit relo for ldimm64 insn

This is how it's defined in llvm:
ELF_RELOC(R_BPF_NONE,        0)
ELF_RELOC(R_BPF_64_64,       1)
ELF_RELOC(R_BPF_64_32,      10)

The R_BPF_64_64 is the only relocation against .text
The other one is used for relo into dwarf sections.

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ