Dumping instructions from an eBPF object file

How to see the instruction opcodes from an eBPF object file

llvm-objdump

You can take an eBPF object file and get a dump of its instructions through llvm-objdump:

$ llvm-objdump -d ./.output/minimal.bpf.o

./.output/minimal.bpf.o:	file format elf64-bpf

Disassembly of section tp/syscalls/sys_enter_write:

0000000000000000 <handle_tp>:
       0:	85 00 00 00 0e 00 00 00	call 14
       1:	77 00 00 00 20 00 00 00	r0 >>= 32
       2:	18 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00	r1 = 0 ll
       4:	61 11 00 00 00 00 00 00	r1 = *(u32 *)(r1 + 0)
       5:	5d 01 10 00 00 00 00 00	if r1 != r0 goto +16 <LBB0_2>
       6:	b7 01 00 00 64 2e 0a 00	r1 = 667236
       7:	63 1a f8 ff 00 00 00 00	*(u32 *)(r10 - 8) = r1
       8:	18 01 00 00 6f 6d 20 50 00 00 00 00 49 44 20 25	r1 = 2675213260325678447 ll
      10:	7b 1a f0 ff 00 00 00 00	*(u64 *)(r10 - 16) = r1
      11:	18 01 00 00 67 65 72 65 00 00 00 00 64 20 66 72	r1 = 8243311783519085927 ll
      13:	7b 1a e8 ff 00 00 00 00	*(u64 *)(r10 - 24) = r1
      14:	18 01 00 00 42 50 46 20 00 00 00 00 74 72 69 67	r1 = 7451612901544448066 ll
      16:	7b 1a e0 ff 00 00 00 00	*(u64 *)(r10 - 32) = r1
      17:	bf a1 00 00 00 00 00 00	r1 = r10
      18:	07 01 00 00 e0 ff ff ff	r1 += -32
      19:	b7 02 00 00 1c 00 00 00	r2 = 28
      20:	bf 03 00 00 00 00 00 00	r3 = r0
      21:	85 00 00 00 06 00 00 00	call 6

00000000000000b0 <LBB0_2>:
      22:	b7 00 00 00 00 00 00 00	r0 = 0
      23:	95 00 00 00 00 00 00 00	exit

This object file is the minimal example from libbpf-bootstrap.

The instructions are displayed in little endian hex output. The first byte you see in each row represents the entire opcode of a bpf instruction.

Those 85s are bpf helper function calls. You can tell because 0x05 is a 64-bit jump instruction class (BPF_JMP), and 0x80 is the function call op (BPF_CALL). Use the bit-and operation on these (technically, you're supposed to bit-and another bit in the middle but in this specific case it's just another 0x0) and you'll get 0x85.

There's also another new jump class: BPF_JMP32. Can you combine this with the BPF_CALL op to do another form of helper function call? It doesn't seem so.

Written by