frame_regs.h revision 1.4.56.1 1 1.4.56.1 jdolecek /* $NetBSD: frame_regs.h,v 1.4.56.1 2017/12/03 11:35:47 jdolecek 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.4.56.1 jdolecek * 1) gdb (amd64nbsd-tdep.c) has a lookup table that assumes the __greg_t
15 1.4.56.1 jdolecek * 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.4.56.1 jdolecek greg(rdi, RDI, 0) /* tf_rdi */ \
33 1.4.56.1 jdolecek greg(rsi, RSI, 1) /* tf_rsi */ \
34 1.4.56.1 jdolecek greg(rdx, RDX, 2) /* tf_rdx */ \
35 1.4.56.1 jdolecek greg(r10, R10, 6) /* tf_r10 */ \
36 1.4.56.1 jdolecek greg(r8, R8, 4) /* tf_r8 */ \
37 1.4.56.1 jdolecek greg(r9, R9, 5) /* tf_r9 */ \
38 1.4.56.1 jdolecek freg(arg6, @, @) /* tf_arg6: syscall arg from stack */ \
39 1.4.56.1 jdolecek freg(arg7, @, @) /* tf_arg7: syscall arg from stack */ \
40 1.4.56.1 jdolecek freg(arg8, @, @) /* tf_arg8: syscall arg from stack */ \
41 1.4.56.1 jdolecek freg(arg9, @, @) /* tf_arg9: syscall arg from stack */ \
42 1.4.56.1 jdolecek greg(rcx, RCX, 3) /* tf_rcx */ \
43 1.4.56.1 jdolecek greg(r11, R11, 7) /* tf_r11 */ \
44 1.4.56.1 jdolecek greg(r12, R12, 8) /* tf_r12 */ \
45 1.4.56.1 jdolecek greg(r13, R13, 9) /* tf_r13 */ \
46 1.4.56.1 jdolecek greg(r14, R14, 10) /* tf_r14 */ \
47 1.4.56.1 jdolecek greg(r15, R15, 11) /* tf_r15 */ \
48 1.4.56.1 jdolecek greg(rbp, RBP, 12) /* tf_rbp */ \
49 1.4.56.1 jdolecek greg(rbx, RBX, 13) /* tf_rbx */ \
50 1.4.56.1 jdolecek greg(rax, RAX, 14) /* tf_rax */ \
51 1.4.56.1 jdolecek greg(gs, GS, 15) /* tf_gs */ \
52 1.4.56.1 jdolecek greg(fs, FS, 16) /* tf_fs */ \
53 1.4.56.1 jdolecek greg(es, ES, 17) /* tf_es */ \
54 1.4.56.1 jdolecek greg(ds, DS, 18) /* tf_ds */ \
55 1.4.56.1 jdolecek greg(trapno, TRAPNO, /* tf_trapno */ \
56 1.4.56.1 jdolecek 19) \
57 1.4.56.1 jdolecek /* Below portion defined in hardware */ \
58 1.4.56.1 jdolecek greg(err, ERR, 20) /* tf_err: Dummy inserted if not defined */ \
59 1.4.56.1 jdolecek greg(rip, RIP, 21) /* tf_rip */ \
60 1.4.56.1 jdolecek greg(cs, CS, 22) /* tf_cs */ \
61 1.4.56.1 jdolecek greg(rflags, RFLAGS, /* tf_rflags */ \
62 1.4.56.1 jdolecek 23) \
63 1.1 dsl /* These are pushed unconditionally on the x86-64 */ \
64 1.4.56.1 jdolecek greg(rsp, RSP, 24) /* tf_rsp */ \
65 1.4.56.1 jdolecek 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