On Mon, 6 Mar 2017 16:14:06 -0800 Alexei Starovoitov via iovisor-dev <[email protected]> wrote:
> On Mon, Mar 6, 2017 at 10:29 AM, Jesper Dangaard Brouer > <[email protected]> wrote: > > On Mon, 6 Mar 2017 09:11:46 -0800 > > Alexei Starovoitov via iovisor-dev <[email protected]> wrote: > > > >> On Mon, Mar 6, 2017 at 3:53 AM, Jesper Dangaard Brouer > >> <[email protected]> wrote: > >> > Hi All, > >> > > >> > I've added a section to my eBPF documentation, about how to read the > >> > eBPF generated ELF binary, and deduct the size of the compiled program > >> > (mostly for kernel/samples/bpf). > >> > > >> > https://prototype-kernel.readthedocs.io/en/latest/bpf/troubleshooting.html#elf-binary > >> > https://github.com/netoptimizer/prototype-kernel/commit/079352102cb0ba > >> > > >> > Can someone validate what I've saying is true? (commit inlined below > >> > sign, to make is as easy as possible for people to correct me). > >> > > >> > And anything else users can use the readelf output for? > >> > > >> > -- > >> > Best regards, > >> > Jesper Dangaard Brouer > >> > MSc.CS, Principal Kernel Engineer at Red Hat > >> > LinkedIn: http://www.linkedin.com/in/brouer > >> > > >> > commit 079352102cb0ba12141ecd28c216ec5ac5290192 > >> > Author: Jesper Dangaard Brouer <[email protected]> > >> > Date: Fri Feb 24 12:10:45 2017 +0100 > >> > > >> > doc: eBPF describe howto read the eBPF generated ELF binary > >> > > >> > Signed-off-by: Jesper Dangaard Brouer <[email protected]> > >> > > >> > diff --git a/kernel/Documentation/bpf/troubleshooting.rst > >> > b/kernel/Documentation/bpf/troubleshooting.rst > >> > index b6f3b6fe9501..39ebffae4142 100644 > >> > --- a/kernel/Documentation/bpf/troubleshooting.rst > >> > +++ b/kernel/Documentation/bpf/troubleshooting.rst > >> > @@ -15,6 +15,41 @@ see system call `setrlimit(2)`_. > >> > The ``bpf_create_map`` call will return errno EPERM (Operation not > >> > permitted) when the RLIMIT_MEMLOCK memory size limit is exceeded. > >> > > >> > - > >> > .. _setrlimit(2): http://man7.org/linux/man-pages/man2/setrlimit.2.html > >> > > >> > +ELF binary > >> > +========== > >> > + > >> > +The binary containing the eBPF program, which got generated by the > >> > +LLVM compiler, is an ELF binary. For samples/bpf/ this is the file > >> > +named xxx_kern.o. > >> > + > >> > +To answer questions like how big is my eBPF program, it is possible to > >> > +use a tool like ``readelf``. :: > >> > + > >> > + $ readelf -SW xdp_ddos01_blacklist_kern.o > >> > + There are 8 section headers, starting at offset 0x398: > >> > + > >> > + 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 000072 00 > >> > 0 0 1 > >> > + [ 2] .text PROGBITS 0000000000000000 000040 000000 00 AX > >> > 0 0 4 > >> > + [ 3] xdp_prog PROGBITS 0000000000000000 000040 0001b8 00 AX > >> > 0 0 8 > >> > + [ 4] .relxdp_prog REL 0000000000000000 000300 000020 10 > >> > 7 3 8 > >> > + [ 5] maps PROGBITS 0000000000000000 0001f8 000028 00 WA > >> > 0 0 4 > >> > + [ 6] license PROGBITS 0000000000000000 000220 000004 00 WA > >> > 0 0 1 > >> > + [ 7] .symtab SYMTAB 0000000000000000 000228 0000d8 18 > >> > 1 5 8 > >> > + Key to Flags: > >> > + W (write), A (alloc), X (execute), M (merge), S (strings) > >> > + I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown) > >> > + O (extra OS processing required) o (OS specific), p (processor > >> > specific) > >> > + > >> > +From the output, we can see the programmer choose to name the XDP > >> > +program section "xdp_prog". From this line ([ 3]) the size column > >> > +shows the size 0001b8 in hex, which is easily converted on the cmdline > >> > +to 440 bytes:: > >> > + > >> > + $ echo $((0x0001b8)) > >> > + 440 > >> > >> hmm. i think instead of clarifying bpf elf output is doing the opposite. > >> at least i'm completely lost in the above text. > >> What all of the above suppose to mean? > > > > That what I'm implicit asking you ;-) > > > >> why is it useful to do readelf? and look at hex ? > > > > What other tools exists to help me understand the contents of the LLVM > > compiled binary _kern.o ? > > The best is to use > llvm-objdump -S prog_kern.o Hmmm, what version of LLVM have the -S option? $ llvm-objdump -S xdp_ddos01_blacklist_kern.o llvm-objdump: Unknown command line argument '-S'. Try: 'llvm-objdump -help' llvm-objdump: Did you mean '-D'? $ llvm-objdump --version | egrep 'version|bpf' LLVM version 3.8.1 bpf - BPF (host endian) bpfeb - BPF (big endian) bpfel - BPF (little endian) I would really like some command tool, to inspect eBPF-ELF program with, available in a distro version, in this case Fedora 25. > it will show section names, asm code and original C code > if compiled with -g And the option -g is supplied to the CLANG program (not LLC). > It's important to mention that .o is a normal elf file, > but the doc doesn't need to go into elf details. Okay. > > Is there an easier way to answer my question: > > Q: how big is my eBPF program? > > in llvm-objdump output you'll see something like: > 139: 85 00 00 00 01 00 00 00 call 1 > 140: b7 00 00 00 00 00 00 00 r0 = 0 > 141: 95 00 00 00 00 00 00 00 exit > > so this particular program has 141 instructions. > > > I would actually (also) like to know the size of the JIT'ed asm code? > > that's practically impossible to know in advance, since hardening and > start address randomization will play a role. > Or use sysctl net.core.bpf_jit_enable=2 > at load time which gives raw x86 hex. The sysctl adjusting sounds interesting: sysctl net.core.bpf_jit_enable=2 What is below "proglen=335" the JIT'ed asm-code size? flen=55 proglen=335 pass=4 image=ffffffffa0006820 from=xdp_ddos01_blac pid=13333 JIT code: 00000000: 55 48 89 e5 48 81 ec 28 02 00 00 48 89 9d d8 fd JIT code: 00000010: ff ff 4c 89 ad e0 fd ff ff 4c 89 b5 e8 fd ff ff JIT code: 00000020: 4c 89 bd f0 fd ff ff 31 c0 48 89 85 f8 fd ff ff JIT code: 00000030: bb 02 00 00 00 48 8b 77 08 48 8b 7f 00 48 89 fa JIT code: 00000040: 48 83 c2 0e 48 39 f2 0f 87 e1 00 00 00 48 0f b6 JIT code: 00000050: 4f 0c 48 0f b6 57 0d 48 c1 e2 08 48 09 ca 48 89 JIT code: 00000060: d1 48 81 e1 ff 00 00 00 41 b8 06 00 00 00 49 39 JIT code: 00000070: c8 0f 87 b7 00 00 00 48 81 fa 88 a8 00 00 74 0e JIT code: 00000080: b9 0e 00 00 00 48 81 fa 81 00 00 00 75 1a 48 89 JIT code: 00000090: fa 48 83 c2 12 48 39 f2 0f 87 90 00 00 00 b9 12 JIT code: 000000a0: 00 00 00 48 0f b7 57 10 bb 02 00 00 00 48 81 e2 JIT code: 000000b0: ff ff 00 00 48 83 fa 08 75 49 48 01 cf 31 db 48 JIT code: 000000c0: 89 fa 48 83 c2 14 48 39 f2 77 38 8b 7f 0c 89 7d JIT code: 000000d0: fc 48 89 ee 48 83 c6 fc 48 bf 00 9c 24 5f 07 88 JIT code: 000000e0: ff ff e8 29 cd 13 e1 bb 02 00 00 00 48 83 f8 00 JIT code: 000000f0: 74 11 48 8b 78 00 48 83 c7 01 48 89 78 00 bb 01 JIT code: 00000100: 00 00 00 89 5d f8 48 89 ee 48 83 c6 f8 48 bf c0 JIT code: 00000110: 76 12 13 04 88 ff ff e8 f4 cc 13 e1 48 83 f8 00 JIT code: 00000120: 74 0c 48 8b 78 00 48 83 c7 01 48 89 78 00 48 89 JIT code: 00000130: d8 48 8b 9d d8 fd ff ff 4c 8b ad e0 fd ff ff 4c JIT code: 00000140: 8b b5 e8 fd ff ff 4c 8b bd f0 fd ff ff c9 c3 $ echo $((0x140)) 320 $ echo $((0x140 + 15)) 335 Using same example code, thus BPF instructions-size was 440 bytes, so the JIT'ed code size does get smaller. -- Best regards, Jesper Dangaard Brouer MSc.CS, Principal Kernel Engineer at Red Hat LinkedIn: http://www.linkedin.com/in/brouer _______________________________________________ iovisor-dev mailing list [email protected] https://lists.iovisor.org/mailman/listinfo/iovisor-dev
