mirror of
https://github.com/cirosantilli/linux-kernel-module-cheat.git
synced 2026-01-29 04:54:27 +01:00
userland: start refactor to show failing values on failure!
aarch64 basically done, but missing: - other archs - maybe convert main.c into C++ to use templates? - full review of ASSERT_EQ calling convention issues not seen by tests by chance - documentation
This commit is contained in:
@@ -4,31 +4,55 @@
|
||||
#define COMMON_ARCH_H
|
||||
|
||||
#define ASSERT_EQ(reg, const) \
|
||||
ldr x11, =const; \
|
||||
cmp reg, x11; \
|
||||
mov x0, reg; \
|
||||
ldr x1, =const; \
|
||||
ASSERT_EQ_DO(64); \
|
||||
;
|
||||
|
||||
#define ASSERT_EQ_DO(bits) \
|
||||
bl assert_eq_ ## bits; \
|
||||
cmp x0, 0; \
|
||||
ASSERT(beq); \
|
||||
;
|
||||
|
||||
#define ASSERT_MEMCMP(s1, s2, n) \
|
||||
MEMCMP(s1, s2, n); \
|
||||
ASSERT_EQ(x0, 0); \
|
||||
#define ASSERT_EQ_REG(reg1, reg2) \
|
||||
str reg2, [sp, -8]!; \
|
||||
mov x0, reg1; \
|
||||
ldr x1, [sp], 8; \
|
||||
ASSERT_EQ_DO(64); \
|
||||
;
|
||||
|
||||
#define ASSERT_EQ_REG_32(reg1, reg2) \
|
||||
str reg2, [sp, -4]!; \
|
||||
mov w0, reg1; \
|
||||
ldr w1, [sp], 4; \
|
||||
ASSERT_EQ_DO(32); \
|
||||
;
|
||||
|
||||
#define ASSERT_MEMCMP(label1, label2, const_size) \
|
||||
adr x0, label1; \
|
||||
adr x1, label2; \
|
||||
ldr x2, =const_size; \
|
||||
bl assert_memcmp; \
|
||||
cmp x0, 0; \
|
||||
ASSERT(beq); \
|
||||
;
|
||||
|
||||
#define ENTRY \
|
||||
.text; \
|
||||
.global asm_main; \
|
||||
asm_main: \
|
||||
sub sp, sp, 0xA0; \
|
||||
stp x29, x30, [sp]; \
|
||||
stp x27, x28, [sp, 0x10]; \
|
||||
stp x25, x26, [sp, 0x20]; \
|
||||
stp x23, x24, [sp, 0x30]; \
|
||||
stp x21, x22, [sp, 0x40]; \
|
||||
stp x19, x20, [sp, 0x50]; \
|
||||
stp x6, x7, [sp, 0x60]; \
|
||||
stp x4, x5, [sp, 0x70]; \
|
||||
stp x2, x3, [sp, 0x80]; \
|
||||
stp x0, x1, [sp, 0x90]; \
|
||||
sub sp, sp, 0xA0; \
|
||||
stp x29, x30, [sp]; \
|
||||
stp x27, x28, [sp, 0x10]; \
|
||||
stp x25, x26, [sp, 0x20]; \
|
||||
stp x23, x24, [sp, 0x30]; \
|
||||
stp x21, x22, [sp, 0x40]; \
|
||||
stp x19, x20, [sp, 0x50]; \
|
||||
stp x6, x7, [sp, 0x60]; \
|
||||
stp x4, x5, [sp, 0x70]; \
|
||||
stp x2, x3, [sp, 0x80]; \
|
||||
stp x0, x1, [sp, 0x90]; \
|
||||
asm_main_after_prologue: \
|
||||
;
|
||||
|
||||
@@ -56,11 +80,4 @@ pass: \
|
||||
b fail; \
|
||||
;
|
||||
|
||||
#define MEMCMP(s1, s2, n) \
|
||||
adr x0, s1; \
|
||||
adr x1, s2; \
|
||||
ldr x2, =n; \
|
||||
bl memcmp; \
|
||||
;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -4,25 +4,25 @@
|
||||
|
||||
ENTRY
|
||||
/* Test values. */
|
||||
mov x0, 0
|
||||
mov x1, 1
|
||||
mov x19, 0
|
||||
mov x20, 1
|
||||
|
||||
/* eq is true, set x2 = 1. */
|
||||
cmp x0, x0
|
||||
cset x2, eq
|
||||
ASSERT_EQ(x2, 1)
|
||||
/* eq is true, set x21 = 1. */
|
||||
cmp x19, x19
|
||||
cset x21, eq
|
||||
ASSERT_EQ(x21, 1)
|
||||
|
||||
/* eq is false, set x2 = 0. */
|
||||
cmp x0, x1
|
||||
cset x2, eq
|
||||
ASSERT_EQ(x2, 0)
|
||||
/* eq is false, set x21 = 0. */
|
||||
cmp x19, x20
|
||||
cset x21, eq
|
||||
ASSERT_EQ(x21, 0)
|
||||
|
||||
/* Same for ne. */
|
||||
cmp x0, x0
|
||||
cset x2, ne
|
||||
ASSERT_EQ(x2, 0)
|
||||
cmp x19, x19
|
||||
cset x21, ne
|
||||
ASSERT_EQ(x21, 0)
|
||||
|
||||
cmp x0, x1
|
||||
cset x2, ne
|
||||
ASSERT_EQ(x2, 1)
|
||||
cmp x19, x20
|
||||
cset x21, ne
|
||||
ASSERT_EQ(x21, 1)
|
||||
EXIT
|
||||
|
||||
@@ -3,26 +3,26 @@
|
||||
#include "common.h"
|
||||
|
||||
ENTRY
|
||||
mov x0, 1
|
||||
mov x19, 1
|
||||
bl inc
|
||||
ASSERT_EQ(x0, 2)
|
||||
ASSERT_EQ(x19, 2)
|
||||
bl inc2
|
||||
ASSERT_EQ(x0, 3)
|
||||
ASSERT_EQ(x19, 3)
|
||||
bl inc3
|
||||
ASSERT_EQ(x0, 4)
|
||||
ASSERT_EQ(x19, 4)
|
||||
EXIT
|
||||
|
||||
/* void inc(uint64_t *i) { (*i)++ } */
|
||||
inc:
|
||||
add x0, x0, 1
|
||||
add x19, x19, 1
|
||||
ret
|
||||
|
||||
/* Same but explicit return register. */
|
||||
inc2:
|
||||
add x0, x0, 1
|
||||
add x19, x19, 1
|
||||
ret x30
|
||||
|
||||
/* Same but with br. */
|
||||
inc3:
|
||||
add x0, x0, 1
|
||||
add x19, x19, 1
|
||||
br x30
|
||||
|
||||
@@ -3,15 +3,15 @@
|
||||
#include "common.h"
|
||||
|
||||
ENTRY
|
||||
ldr x0, =0x1122334455667788
|
||||
ldr x19, =0x1122334455667788
|
||||
|
||||
// lsr alias: imms == 63
|
||||
|
||||
ldr x1, =0xFFFFFFFFFFFFFFFF
|
||||
ubfm x1, x0, 16, 63
|
||||
ASSERT_EQ(x1, 0x0000112233445566)
|
||||
ldr x20, =0xFFFFFFFFFFFFFFFF
|
||||
ubfm x20, x19, 16, 63
|
||||
ASSERT_EQ(x20, 0x0000112233445566)
|
||||
|
||||
ldr x1, =0xFFFFFFFFFFFFFFFF
|
||||
ubfm x1, x0, 32, 63
|
||||
ASSERT_EQ(x1, 0x0000000011223344)
|
||||
ldr x20, =0xFFFFFFFFFFFFFFFF
|
||||
ubfm x20, x19, 32, 63
|
||||
ASSERT_EQ(x20, 0x0000000011223344)
|
||||
EXIT
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
#include "common.h"
|
||||
|
||||
ENTRY
|
||||
ldr x0, =0x1122334455667788
|
||||
ldr x19, =0x1122334455667788
|
||||
|
||||
ldr x1, =0xFFFFFFFFFFFFFFFF
|
||||
ubfx x1, x0, 8, 16
|
||||
ASSERT_EQ(x1, 0x0000000000006677)
|
||||
ldr x20, =0xFFFFFFFFFFFFFFFF
|
||||
ubfx x20, x19, 8, 16
|
||||
ASSERT_EQ(x20, 0x0000000000006677)
|
||||
|
||||
ldr x1, =0xFFFFFFFFFFFFFFFF
|
||||
ubfx x1, x0, 8, 32
|
||||
ASSERT_EQ(x1, 0x0000000044556677)
|
||||
ldr x20, =0xFFFFFFFFFFFFFFFF
|
||||
ubfx x20, x19, 8, 32
|
||||
ASSERT_EQ(x20, 0x0000000044556677)
|
||||
EXIT
|
||||
|
||||
@@ -9,14 +9,14 @@ ENTRY
|
||||
#endif
|
||||
|
||||
/* mov (register) is an alias for ORR, which accepts xzr. */
|
||||
mov x0, 1
|
||||
mov x0, xzr
|
||||
ASSERT_EQ(x0, 0)
|
||||
mov x19, 1
|
||||
mov x19, xzr
|
||||
ASSERT_EQ(x19, 0)
|
||||
|
||||
/* Same encoding as the mov version. */
|
||||
mov x0, 1
|
||||
orr x0, xzr, xzr
|
||||
ASSERT_EQ(x0, 0)
|
||||
mov x19, 1
|
||||
orr x19, xzr, xzr
|
||||
ASSERT_EQ(x19, 0)
|
||||
|
||||
/* So, orr, which is not an alias, can only take xzr, not sp. */
|
||||
#if 0
|
||||
@@ -24,19 +24,19 @@ ENTRY
|
||||
#endif
|
||||
|
||||
/* Zero register discards result if written to. */
|
||||
mov x0, 1
|
||||
orr xzr, x0, x0
|
||||
mov x19, 1
|
||||
orr xzr, x19, x19
|
||||
ASSERT_EQ(xzr, 0)
|
||||
|
||||
/* MOV (to/from SP) is an alias for ADD (immediate). */
|
||||
mov x0, sp
|
||||
mov x19, sp
|
||||
mov sp, 1
|
||||
/* Alias to add. */
|
||||
mov x1, sp
|
||||
mov x20, sp
|
||||
/* Exact same encoding as above. */
|
||||
add x1, sp, 0
|
||||
ASSERT_EQ(x1, 1)
|
||||
mov sp, x0
|
||||
add x20, sp, 0
|
||||
mov sp, x19
|
||||
ASSERT_EQ(x20, 1)
|
||||
|
||||
/* So, ADD (immediate), which is not an alias, can only take sp, not xzr. */
|
||||
#if 0
|
||||
|
||||
Reference in New Issue
Block a user