| # mach: bpf |
| # sim: --skb-data-offset=0x20 |
| # output: pass\nexit 0 (0x0)\n |
| ;;; ldabs.s |
| ;;; Tests for non-generic BPF load instructions in simulator. |
| ;;; These instructions (ld{abs,ind}{b,h,w,dw}) are used to access |
| ;;; kernel socket data from BPF programs for high performance filters. |
| ;;; |
| ;;; Register r6 is an implicit input holding a pointer to a struct sk_buff. |
| ;;; Register r0 is an implicit output, holding the fetched data. |
| ;;; |
| ;;; e.g. |
| ;;; ldabsw means: |
| ;;; r0 = ntohl (*(u32 *) (((struct sk_buff *)r6)->data + imm32)) |
| ;;; |
| ;;; ldindw means |
| ;;; r0 = ntohl (*(u32 *) (((struct sk_buff *)r6)->data + src_reg + imm32)) |
| |
| .include "testutils.inc" |
| |
| .text |
| .global main |
| .type main, @function |
| main: |
| ;; R6 holds a pointer to a struct sk_buff, which we pretend |
| ;; exists at 0x1000 |
| mov %r6, 0x1000 |
| |
| ;; We configure skb-data-offset=0x20 |
| ;; This specifies offsetof(struct sk_buff, data), where the field 'data' |
| ;; is a pointer a data buffer, in this case at 0x2000 |
| stw [%r6+0x20], 0x2000 |
| |
| ;; Write the value 0x7eadbeef into memory at 0x2004 |
| ;; i.e. offset 4 within the data buffer pointed to by |
| ;; ((struct sk_buff *)r6)->data |
| stw [%r6+0x1004], 0xdeadbeef |
| |
| ;; Now load data[4] into r0 using the ldabsw instruction |
| ldabsw 0x4 |
| |
| ;; ...and compare to what we expect |
| fail_ne32 %r0, 0xdeadbeef |
| |
| ;; Repeat for a half-word (2-bytes) |
| sth [%r6+0x1008], 0x1234 |
| ldabsh 0x8 |
| fail_ne32 %r0, 0x1234 |
| |
| ;; Repeat for a single byte |
| stb [%r6+0x1010], 0x5a |
| ldabsb 0x10 |
| fail_ne32 %r0, 0x5a |
| |
| ;; Repeat for a double-word (8-byte) |
| ;; (note: fail_ne macro uses r0, so copy to another r1 to compare) |
| lddw %r2, 0x1234deadbeef5678 |
| stxdw [%r6+0x1018], %r2 |
| ldabsdw 0x18 |
| mov %r1, %r0 |
| fail_ne %r1, 0x1234deadbeef5678 |
| |
| ;; Now, we do the same for the indirect loads |
| mov %r7, 0x100 |
| stw [%r6+0x1100], 0xfeedbeef |
| |
| ldindw %r7, 0x0 |
| fail_ne32 %r0, 0xfeedbeef |
| |
| ;; half-word |
| sth [%r6+0x1104], 0x6789 |
| ldindh %r7, 0x4 |
| fail_ne32 %r0, 0x6789 |
| |
| ;; byte |
| stb [%r6+0x1108], 0x5f |
| ldindb %r7, 0x8 |
| fail_ne32 %r0, 0x5f |
| |
| ;; double-word |
| lddw %r2, 0xcafe12345678d00d |
| stxdw [%r6+0x1110], %r2 |
| ldinddw %r7, 0x10 |
| mov %r1, %r0 |
| fail_ne %r1, 0xcafe12345678d00d |
| |
| pass |