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