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 24main: 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], 0xdeadbeef 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, 0xdeadbeef 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 ;; Repeat for a double-word (8-byte) 56 ;; (note: fail_ne macro uses r0, so copy to another r1 to compare) 57 lddw %r2, 0x1234deadbeef5678 58 stxdw [%r6+0x1018], %r2 59 ldabsdw 0x18 60 mov %r1, %r0 61 fail_ne %r1, 0x1234deadbeef5678 62 63 ;; Now, we do the same for the indirect loads 64 mov %r7, 0x100 65 stw [%r6+0x1100], 0xfeedbeef 66 67 ldindw %r7, 0x0 68 fail_ne32 %r0, 0xfeedbeef 69 70 ;; half-word 71 sth [%r6+0x1104], 0x6789 72 ldindh %r7, 0x4 73 fail_ne32 %r0, 0x6789 74 75 ;; byte 76 stb [%r6+0x1108], 0x5f 77 ldindb %r7, 0x8 78 fail_ne32 %r0, 0x5f 79 80 ;; double-word 81 lddw %r2, 0xcafe12345678d00d 82 stxdw [%r6+0x1110], %r2 83 ldinddw %r7, 0x10 84 mov %r1, %r0 85 fail_ne %r1, 0xcafe12345678d00d 86 87 pass 88