X-Git-Url: https://git.distorted.org.uk/~mdw/catacomb/blobdiff_plain/82d064a1d4fc1486200d94dae7234dbdbe8fc76c..818bad9b1b5e68bdd26595a0ec5f513fe56ba174:/base/regdump.h diff --git a/base/regdump.h b/base/regdump.h index bbbd5bd1..3a6d59cb 100644 --- a/base/regdump.h +++ b/base/regdump.h @@ -135,6 +135,7 @@ union gp64 { uint64 u64; int64 i64; PTR64 }; #define REGSRC_SIMD 0x04000000 /* SIMD vector register */ #define REGSRC_STMMX 0x05000000 /* x86-specific: x87/MMX register */ #define REGSRC_SEG 0x06000000 /* x86-specific: segment register */ +#define REGSRC_NONE 0x0f000000 /* just a message */ /* Where to find the values. */ #define REGF_WDMASK 0xf0000000 @@ -271,11 +272,11 @@ struct regmap { regmap_avx = 2*WORDSZ regmap_size = 3*WORDSZ -#define REGDEF_GPX86_COMMON(rn, RN) \ - regsrc.e##rn = REGSRC_GP | REGIX_##RN; \ +#define REGDEF_GPX86_COMMON(rn, ix) \ + regsrc.e##rn = REGSRC_GP | ix; \ regty.e##rn = REGF_32; \ regfmt.e##rn = REGF_HEX; \ - regsrc.r##rn = REGSRC_GP | REGIX_##RN; \ + regsrc.r##rn = REGSRC_GP | ix; \ regty.r##rn = REGF_64; \ regfmt.r##rn = REGF_HEX @@ -289,7 +290,7 @@ struct regmap { regsrc.rn##x = REGSRC_GP | REGIX_##RN##X; \ regty.rn##x = REGF_16; \ regfmt.rn##x = REGF_HEX; \ - REGDEF_GPX86_COMMON(rn##x, RN##X) + REGDEF_GPX86_COMMON(rn##x, REGIX_##RN##X) REGDEF_GPX86_ABCD(a, A) REGDEF_GPX86_ABCD(b, B) REGDEF_GPX86_ABCD(c, C) @@ -312,7 +313,7 @@ REGDEF_GPX86_ABCD(d, D) regsrc.rn = REGSRC_GP | REGIX_##RN; \ regty.rn = REGF_16; \ regfmt.rn = REGF_HEX; \ - REGDEF_GPX86_COMMON(rn, RN) + REGDEF_GPX86_COMMON(rn, REGIX_##RN) REGDEF_GPX86_XP(ip, IP) REGDEF_GPX86_XP(si, SI) REGDEF_GPX86_XP(di, DI) @@ -381,32 +382,32 @@ DO8(REGDEF_SIMD) // Stash r/eax. This is bletcherous: hope we don't get a signal in // the next few instructions. - mov [R_sp(r) - REGDUMP_SPADJ + (REGIX_AX - 1)*WORDSZ], R_a(r) + mov [SP - REGDUMP_SPADJ + (REGIX_AX - 1)*WORDSZ], AX .ifnes "\addr", "nil" // Collect the effective address for the following dump, leaving it // in the `addr' slot of the dump. - lea R_a(r), \addr - mov [R_sp(r) - REGDUMP_SPADJ + (REGIX_ADDR - 1)*WORDSZ], R_a(r) + lea AX, \addr + mov [SP - REGDUMP_SPADJ + (REGIX_ADDR - 1)*WORDSZ], AX .endif // Make space for the register save area. On AMD64 with System/V // ABI, also skip the red zone. Use `lea' here to preserve the // flags. - lea R_sp(r), [R_sp(r) - REGDUMP_SPADJ] + lea SP, [SP - REGDUMP_SPADJ] // Save flags and general-purpose registers. On 32-bit x86, we save // ebx here and establish a GOT pointer here for the benefit of the // PLT-indirect calls made later on. pushf # if CPUFAM_X86 - mov [esp + 4*REGIX_BX], ebx + mov [SP + 4*REGIX_BX], ebx ldgot # endif callext F(regdump_gpsave) // Make space for the extended registers. - sub R_sp(r), R_c(r) + sub SP, CX callext F(regdump_xtsave) // Prepare for calling back into C. On 32-bit x86, leave space for @@ -414,11 +415,11 @@ DO8(REGDEF_SIMD) // the `shadow space' for the called-function's arguments. Also, // forcibly align the stack pointer to a 16-byte boundary. # if CPUFAM_X86 - sub esp, 16 + sub SP, 16 # elif ABI_WIN - sub rsp, 32 + sub SP, 32 # endif - and R_sp(r), ~15 + and SP, ~15 .endm .macro _rstrregs @@ -426,27 +427,38 @@ DO8(REGDEF_SIMD) // We assume r/ebp still points to the register map. callext F(regdump_xtrstr) - mov R_sp(r), R_bp(r) + mov SP, BP callext F(regdump_gprstr) popf - lea R_sp(r), [R_sp(r) + REGDUMP_SPADJ] + lea SP, [SP + REGDUMP_SPADJ] +.endm + +.macro _nilbase +# if CPUFAM_X86 + xor eax, eax + mov [SP + 0], eax +# elif ABI_SYSV + xor edi, edi +# elif ABI_WIN + xor ecx, ecx +# endif .endm .macro _regbase # if CPUFAM_X86 - mov [esp + 0], ebp + mov [SP + 0], BP # elif ABI_SYSV - mov rdi, rbp + mov rdi, BP # elif ABI_WIN - mov rcx, rbp + mov rcx, BP # endif .endm .macro _membase - mov R_a(r), [R_bp(r) + regmap_gp] + mov AX, [BP + regmap_gp] # if CPUFAM_X86 mov eax, [eax + REGIX_ADDR*WORDSZ] - mov [esp + 0], eax + mov [SP + 0], eax # elif ABI_SYSV mov rdi, [rax + REGIX_ADDR*WORDSZ] # elif ABI_WIN @@ -457,7 +469,7 @@ DO8(REGDEF_SIMD) .macro _reglbl msg .ifeqs "\msg", "" # if CPUFAM_X86 - mov dword ptr [esp + 4], 0 + mov dword ptr [SP + 4], 0 # elif ABI_SYSV xor esi, esi # elif ABI_WIN @@ -466,7 +478,7 @@ DO8(REGDEF_SIMD) .else # if CPUFAM_X86 lea eax, [INTADDR(.L$_reglbl$\@)] - mov [esp + 4], eax + mov [SP + 4], eax # elif ABI_SYSV lea rsi, [INTADDR(.L$_reglbl$\@)] # elif ABI_WIN @@ -481,7 +493,7 @@ DO8(REGDEF_SIMD) .macro _regfmt arg # if CPUFAM_X86 - mov dword ptr [esp + 8], \arg + mov dword ptr [SP + 8], \arg # elif ABI_SYSV mov edx, \arg # elif ABI_WIN @@ -600,6 +612,8 @@ DO16(REGDEF_NEONQ) sub r13, r13, #REGDUMP_GPSIZE // Save flags and general-purpose registers. + mrs r14, cpsr + str r14, [r13, #4*REGIX_CPSR] str r12, [r13, #4*12] bl regdump_gpsave @@ -625,6 +639,10 @@ DO16(REGDEF_NEONQ) add r13, r13, #REGDUMP_GPSIZE .endm +.macro _nilbase + mov r0, #0 +.endm + .macro _regbase mov r0, r5 .endm @@ -643,8 +661,8 @@ DO16(REGDEF_NEONQ) .endm .macro _regfmt arg - movw r2, #\arg&0xffff - movt r2, #(\arg >> 16)&0xffff + movw r2, #(\arg)&0xffff + movt r2, #((\arg) >> 16)&0xffff .endm #endif @@ -756,8 +774,15 @@ DO32(REGDEF_FP) // Make space for the register save area. sub sp, sp, #REGDUMP_GPSIZE - // Save flags and general-purpose registers. - stp x16, x17, [sp, #8*16] + // Save flags and general-purpose registers. The PLT linkage code + // makes free with x8--x17, so we must save those here. + mrs x30, nzcv + str x30, [sp, #8*REGIX_NZCV] + stp x8, x9, [sp, #64] + stp x10, x11, [sp, #80] + stp x12, x13, [sp, #96] + stp x14, x15, [sp, #112] + stp x16, x17, [sp, #128] bl regdump_gpsave // Make space for the extended registers. @@ -776,6 +801,10 @@ DO32(REGDEF_FP) add sp, sp, #REGDUMP_GPSIZE .endm +.macro _nilbase + mov x0, #0 +.endm + .macro _regbase mov x0, x21 .endm @@ -794,8 +823,8 @@ DO32(REGDEF_FP) .endm .macro _regfmt arg - movz w2, #\arg&0xffff - movk w2, #(\arg >> 16)&0xffff, lsl #16 + movz w2, #(\arg)&0xffff + movk w2, #((\arg) >> 16)&0xffff, lsl #16 .endm #endif @@ -889,6 +918,15 @@ extern void regdump_freshline(void); _rstrregs .endm +.macro msg lbl + _saveregs + _nilbase + _reglbl "\lbl" + _regfmt REGSRC_NONE | (1 << REGF_WDSHIFT) + callext F(regdump) + _rstrregs +.endm + .macro reg lbl, rn, fmt=0 _saveregs _regbase