mirror of
https://github.com/cirosantilli/linux-kernel-module-cheat.git
synced 2026-01-25 19:21:35 +01:00
88 lines
1.7 KiB
C
88 lines
1.7 KiB
C
/* https://github.com/cirosantilli/linux-kernel-module-cheat#userland-assembly-c-standard-library */
|
|
|
|
#ifndef COMMON_ARCH_H
|
|
#define COMMON_ARCH_H
|
|
|
|
#define ASSERT_EQ(reg, const) \
|
|
push %rax; \
|
|
push %rbx; \
|
|
mov reg, %rax; \
|
|
mov const, %rbx; \
|
|
cmp %rax, %rbx; \
|
|
pop %rbx; \
|
|
pop %rax; \
|
|
ASSERT(je); \
|
|
;
|
|
|
|
# TODO
|
|
##define ASSERT_MEMCMP(s1, s2, n) \
|
|
# MEMCMP(s1, s2, n); \
|
|
# ASSERT_EQ(x0, 0); \
|
|
#;
|
|
|
|
/* Program entry point.
|
|
*
|
|
* Return with EXIT.
|
|
*
|
|
* Basically implements an x86_64 prologue:
|
|
*
|
|
* - save callee saved registers
|
|
* x86_64 explained at: https://stackoverflow.com/questions/18024672/what-registers-are-preserved-through-a-linux-x86-64-function-call/55207335#55207335
|
|
* - save register arguments for later usage
|
|
*/
|
|
#define ENTRY \
|
|
.text; \
|
|
.global asm_main; \
|
|
asm_main: \
|
|
push %rbp; \
|
|
mov %rsp, %rbp; \
|
|
push %r15; \
|
|
push %r14; \
|
|
push %r13; \
|
|
push %r12; \
|
|
push %rbx; \
|
|
push %rdi; \
|
|
sub $8, %rsp; \
|
|
asm_main_after_prologue: \
|
|
;
|
|
|
|
/* Meant to be called at the end of ENTRY.*
|
|
*
|
|
* Branching to "fail" makes tests fail with exit status 1.
|
|
*
|
|
* If EXIT is reached, the program ends successfully.
|
|
*/
|
|
#define EXIT \
|
|
mov $0, %rax; \
|
|
jmp pass; \
|
|
fail: \
|
|
/* -0x30(%rbp) is argument 1 which we pushed at prologue */ \
|
|
mov -0x30(%rbp), %rbx; \
|
|
movl %eax, (%rbx); \
|
|
mov $1, %rax; \
|
|
pass: \
|
|
add $16, %rsp; \
|
|
pop %rbx; \
|
|
pop %r12; \
|
|
pop %r13; \
|
|
pop %r14; \
|
|
pop %r15; \
|
|
pop %rbp; \
|
|
ret; \
|
|
;
|
|
|
|
#define FAIL \
|
|
mov $__LINE__, %eax; \
|
|
jmp fail; \
|
|
;
|
|
|
|
# TODO
|
|
##define MEMCMP(s1, s2, n) \
|
|
# adr x0, s1; \
|
|
# adr x1, s2; \
|
|
# ldr x2, =n; \
|
|
# bl memcmp; \
|
|
#;
|
|
|
|
#endif
|