X-Git-Url: https://git.distorted.org.uk/~mdw/catacomb/blobdiff_plain/1a517bb3785891ff6940c73af7c5a136d0250ebf..0923a413958b0e778a3f059c76355ab58e5be414:/base/asm-common.h diff --git a/base/asm-common.h b/base/asm-common.h index fdd7fad1..22bb44d6 100644 --- a/base/asm-common.h +++ b/base/asm-common.h @@ -66,6 +66,7 @@ #define INTFUNC(name) \ TYPE_FUNC(name); \ .macro ENDFUNC; _ENDFUNC(name); .endm; \ + .L$_prologue_p = 0; .L$_frameptr_p = 0; \ FUNC_PREHOOK(name); \ name: \ FUNC_POSTHOOK(name) @@ -77,6 +78,8 @@ INTFUNC(F(name)) // Marking the end of a function. #define _ENDFUNC(name) \ + .if ~ .L$_prologue_p; .error "Missing `endprologue'"; .endif; \ + .if .L$_frameptr_p; .purgem dropfp; .endif; \ .purgem ENDFUNC; \ SIZE_OBJ(name); \ ENDFUNC_HOOK(name); \ @@ -147,6 +150,11 @@ name: // `.seh_pushreg' and friends, and `.seh_endprologue'. #endif +#if __ELF__ +# define FUNC_POSTHOOK(_) .cfi_startproc +# define ENDFUNC_HOOK(_) .cfi_endproc +#endif + // Don't use the wretched AT&T syntax. It's festooned with pointless // punctuation, and all of the data movement is backwards. Ugh! .intel_syntax noprefix @@ -427,6 +435,101 @@ name: #endif #define WHOLE(reg) _REGFORM(reg, r) +// Stack management and unwinding. +.macro setfp fp, offset = 0 + .if \offset == 0 + mov \fp, R_sp(r) +#if __ELF__ + .cfi_def_cfa_register \fp +#endif +#if ABI_WIN && CPUFAM_AMD64 + .seh_setframe \fp, 0 +#endif + .else + lea \fp, [R_sp(r) + \offset] +#if __ELF__ + .cfi_def_cfa_register \fp + .cfi_adjust_cfa_offset -\offset +#endif +#if ABI_WIN && CPUFAM_AMD64 + .seh_setframe \fp, \offset +#endif + .endif + .L$_frameptr_p = -1 + .macro dropfp; _dropfp \fp, \offset; .endm +.endm + +.macro _dropfp fp, offset = 0 + .if \offset == 0 + mov R_sp(r), \fp +#if __ELF__ + .cfi_def_cfa_register R_sp(r) +#endif + .else + lea R_sp(r), [\fp - \offset] +#if __ELF__ + .cfi_def_cfa_register R_sp(r) + .cfi_adjust_cfa_offset +\offset +#endif + .endif + .L$_frameptr_p = 0 + .purgem dropfp +.endm + +.macro stalloc n + sub R_sp(r), \n +#if __ELF__ + .cfi_adjust_cfa_offset +\n +#endif +#if ABI_WIN && CPUFAM_AMD64 + .seh_stackalloc \n +#endif +.endm + +.macro stfree n + add R_sp(r), \n +#if __ELF__ + .cfi_adjust_cfa_offset -\n +#endif +.endm + +.macro pushreg r + push \r +#if __ELF__ + .cfi_adjust_cfa_offset +WORDSZ + .cfi_rel_offset \r, 0 +#endif +#if ABI_WIN && CPUFAM_AMD64 + .seh_pushreg \r +#endif +.endm + +.macro popreg r + pop \r +#if __ELF__ + .cfi_adjust_cfa_offset -WORDSZ + .cfi_restore \r +#endif +.endm + +.macro savexmm r, offset + movdqa [R_sp(r) + \offset], \r +#if ABI_WIN && CPUFAM_AMD64 + .seh_savexmm \r, \offset +#endif +.endm + +.macro rstrxmm r, offset + movdqa \r, [R_sp(r) + \offset] +.endm + +.macro endprologue +#if ABI_WIN && CPUFAM_AMD64 + .seh_endprologue +#endif + .L$_prologue_p = -1 +.endm + #endif #if CPUFAM_X86 @@ -551,8 +654,8 @@ name: ARM // Set the function hooks. -#define FUNC_PREHOOK(_) .balign 4 -#define ENDFUNC_HOOK(name) .ltorg +#define FUNC_PREHOOK(_) .balign 4; .fnstart +#define ENDFUNC_HOOK(_) .fnend; .ltorg // Call external subroutine at ADDR, possibly via PLT. .macro callext addr, cond= @@ -868,6 +971,63 @@ name: // Macros for converting vldm/vstm ranges. #define QQ(qlo, qhi) D0(qlo)-D1(qhi) +// Stack management and unwinding. +.macro setfp fp, offset = 0 + .if \offset == 0 + mov \fp, sp + .setfp \fp, sp + .else + add \fp, sp, #\offset + .setfp \fp, sp, #\offset + .endif + .macro dropfp; _dropfp \fp, \offset; .endm + .L$_frameptr_p = -1 +.endm + +.macro _dropfp fp, offset = 0 + .if \offset == 0 + mov sp, \fp + .else + sub sp, \fp, #\offset + .endif + .purgem dropfp + .L$_frameptr_p = 0 +.endm + +.macro stalloc n + sub sp, sp, #\n + .pad #\n +.endm + +.macro stfree n + add sp, sp, #\n + .pad #-\n +.endm + +.macro pushreg rr:vararg + stmfd sp!, {\rr} + .save {\rr} +.endm + +.macro popreg rr:vararg + ldmfd sp!, {\rr} +.endm + +.macro pushvfp rr:vararg + vstmdb sp!, {\rr} + .vsave {\rr} +.endm + +.macro popvfp rr:vararg + vldmia sp!, {\rr} +.endm + +.macro endprologue +.endm + +// No need for prologue markers on ARM. +#define FUNC_POSTHOOK(_) .L$_prologue_p = -1 + #endif ///--------------------------------------------------------------------------