1 # mach: bpf 2 # sim: --skb-data-offset=0x20 3 # output: pass\nexit 0 (0x0)\n 4 /* ldabs.s 5 Tests for non-generic BPF load instructions in simulator. 6 These instructions (ld{abs,ind}{b,h,w,dw}) are used to access 7 kernel socket data from BPF programs for high performance filters. 8 9 Register r6 is an implicit input holding a pointer to a struct sk_buff. 10 Register r0 is an implicit output, holding the fetched data. 11 12 e.g. 13 ldabsw means: 14 r0 = ntohl (*(u32 *) (((struct sk_buff *)r6)->data + imm32)) 15 16 ldindw means 17 r0 = ntohl (*(u32 *) (((struct sk_buff *)r6)->data + src_reg + imm32)) */ 18 19 .include "testutils.inc" 20 21 .text 22 .global main 23 .type main, @function 24 main: 25 /* R6 holds a pointer to a struct sk_buff, which we pretend 26 exists at 0x1000 */ 27 mov %r6, 0x1000 28 29 /* We configure skb-data-offset=0x20 30 This specifies offsetof(struct sk_buff, data), where the field 'data' 31 is a pointer a data buffer, in this case at 0x2000 */ 32 stw [%r6+0x20], 0x2000 33 34 /* Write the value 0x7eadbeef into memory at 0x2004 35 i.e. offset 4 within the data buffer pointed to by 36 ((struct sk_buff *)r6)->data */ 37 stw [%r6+0x1004], 0x0eadbeef 38 39 /* Now load data[4] into r0 using the ldabsw instruction */ 40 ldabsw 0x4 41 42 /* ...and compare to what we expect */ 43 fail_ne32 %r0, 0x0eadbeef 44 45 /* Repeat for a half-word (2-bytes) */ 46 sth [%r6+0x1008], 0x1234 47 ldabsh 0x8 48 fail_ne32 %r0, 0x1234 49 50 /* Repeat for a single byte */ 51 stb [%r6+0x1010], 0x5a 52 ldabsb 0x10 53 fail_ne32 %r0, 0x5a 54 55 /* Now, we do the same for the indirect loads */ 56 mov %r7, 0x100 57 stw [%r6+0x1100], 0x0eedbeef 58 59 ldindw %r7, 0x0 60 fail_ne32 %r0, 0x0eedbeef 61 62 /* half-word */ 63 sth [%r6+0x1104], 0x6789 64 ldindh %r7, 0x4 65 fail_ne32 %r0, 0x6789 66 67 /* byte */ 68 stb [%r6+0x1108], 0x5f 69 ldindb %r7, 0x8 70 fail_ne32 %r0, 0x5f 71 72 pass 73