]>
Commit | Line | Data |
---|---|---|
b26e2ae7 JM |
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], 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 |