1 1.8 rillig /* $NetBSD: frame_regs.h,v 1.8 2021/04/17 20:12:55 rillig Exp $ */ 2 1.1 dsl 3 1.1 dsl #ifndef _AMD64_FRAME_REGS_H_ 4 1.1 dsl #define _AMD64_FRAME_REGS_H_ 5 1.1 dsl 6 1.1 dsl /* 7 1.1 dsl * amd64 registers (and friends) ordered as in a trap/interrupt/syscall frame. 8 1.1 dsl * Also the indexes into the 'general register state' (__greg_t) passed to 9 1.1 dsl * userland. 10 1.1 dsl * Historically they were in the same order, but the order in the frames 11 1.3 dsl * has been changed to improve syscall efficiency. 12 1.1 dsl * 13 1.1 dsl * Notes: 14 1.8 rillig * 1) gdb (amd64nbsd-tdep.c) has a lookup table that assumes the __greg_t 15 1.7 mrg * ordering. 16 1.1 dsl * 2) src/lib/libc/arch/x86_64/gen/makecontext.c assumes that the first 17 1.1 dsl * 6 entries in the __greg_t array match the registers used to pass 18 1.1 dsl * function arguments. 19 1.4 dsl * 3) The 'struct reg' from machine/reg.h has to match __greg_t. 20 1.4 dsl * Since they are both arrays and indexed with the same tokens this 21 1.4 dsl * shouldn't be a problem, but is rather confusing. 22 1.4 dsl * This assumption is made in a lot of places! 23 1.1 dsl * 4) There might be other code out there that relies on the ordering. 24 1.3 dsl * 25 1.3 dsl * The first entries below match the registers used for syscall arguments 26 1.4 dsl * (%rcx is destroyed by the syscall instruction, the libc system call 27 1.4 dsl * stubs copy %rcx to %r10). 28 1.3 dsl * arg6-arg9 are copied from the user stack for system calls with more 29 1.3 dsl * than 6 args (SYS_MAXSYSARGS is 8, + 2 entries for SYS___SYSCALL). 30 1.1 dsl */ 31 1.1 dsl #define _FRAME_REG(greg, freg) \ 32 1.5 uebayasi greg(rdi, RDI, 0) /* tf_rdi */ \ 33 1.5 uebayasi greg(rsi, RSI, 1) /* tf_rsi */ \ 34 1.5 uebayasi greg(rdx, RDX, 2) /* tf_rdx */ \ 35 1.5 uebayasi greg(r10, R10, 6) /* tf_r10 */ \ 36 1.5 uebayasi greg(r8, R8, 4) /* tf_r8 */ \ 37 1.5 uebayasi greg(r9, R9, 5) /* tf_r9 */ \ 38 1.5 uebayasi freg(arg6, @, @) /* tf_arg6: syscall arg from stack */ \ 39 1.5 uebayasi freg(arg7, @, @) /* tf_arg7: syscall arg from stack */ \ 40 1.5 uebayasi freg(arg8, @, @) /* tf_arg8: syscall arg from stack */ \ 41 1.5 uebayasi freg(arg9, @, @) /* tf_arg9: syscall arg from stack */ \ 42 1.5 uebayasi greg(rcx, RCX, 3) /* tf_rcx */ \ 43 1.5 uebayasi greg(r11, R11, 7) /* tf_r11 */ \ 44 1.5 uebayasi greg(r12, R12, 8) /* tf_r12 */ \ 45 1.5 uebayasi greg(r13, R13, 9) /* tf_r13 */ \ 46 1.5 uebayasi greg(r14, R14, 10) /* tf_r14 */ \ 47 1.5 uebayasi greg(r15, R15, 11) /* tf_r15 */ \ 48 1.5 uebayasi greg(rbp, RBP, 12) /* tf_rbp */ \ 49 1.5 uebayasi greg(rbx, RBX, 13) /* tf_rbx */ \ 50 1.5 uebayasi greg(rax, RAX, 14) /* tf_rax */ \ 51 1.5 uebayasi greg(gs, GS, 15) /* tf_gs */ \ 52 1.5 uebayasi greg(fs, FS, 16) /* tf_fs */ \ 53 1.5 uebayasi greg(es, ES, 17) /* tf_es */ \ 54 1.5 uebayasi greg(ds, DS, 18) /* tf_ds */ \ 55 1.5 uebayasi greg(trapno, TRAPNO, /* tf_trapno */ \ 56 1.5 uebayasi 19) \ 57 1.5 uebayasi /* Below portion defined in hardware */ \ 58 1.5 uebayasi greg(err, ERR, 20) /* tf_err: Dummy inserted if not defined */ \ 59 1.5 uebayasi greg(rip, RIP, 21) /* tf_rip */ \ 60 1.5 uebayasi greg(cs, CS, 22) /* tf_cs */ \ 61 1.5 uebayasi greg(rflags, RFLAGS, /* tf_rflags */ \ 62 1.5 uebayasi 23) \ 63 1.1 dsl /* These are pushed unconditionally on the x86-64 */ \ 64 1.5 uebayasi greg(rsp, RSP, 24) /* tf_rsp */ \ 65 1.5 uebayasi greg(ss, SS, 25) /* tf_ss */ 66 1.1 dsl 67 1.1 dsl #define _FRAME_NOREG(reg, REG, idx) 68 1.1 dsl 69 1.1 dsl #define _FRAME_GREG(greg) _FRAME_REG(greg, _FRAME_NOREG) 70 1.1 dsl 71 1.1 dsl #endif 72