/***************************************************************/ /* mgdb: midipix-specific bits for gdb */ /* Copyright (C) 2019 Z. Gilboa */ /* Released under GPLv2 and GPLv3; see COPYING.MGDB. */ /***************************************************************/ #include "defs.h" #include "osabi.h" #include "regcache.h" #include "amd64-tdep.h" #include "winnt-nat.h" #include #include #define AMD64_KNOWN_REG_CAP AMD64_MXCSR_REGNUM struct regcache; static unsigned regoffs[AMD64_NUM_REGS]; static void amd64_winnt_supply_reg( struct regcache * rcache, int regnum, uintptr_t regval) { regcache_raw_supply(rcache,regnum,®val); } static void amd64_winnt_supply_pc_regs( struct regcache * rcache, mcontext_t * regctx) { amd64_winnt_supply_reg(rcache,AMD64_RIP_REGNUM,regctx->uc_rip); } static void amd64_winnt_supply_core_regs( struct regcache * rcache, mcontext_t * regctx) { amd64_winnt_supply_reg(rcache,AMD64_RAX_REGNUM,regctx->uc_rax); amd64_winnt_supply_reg(rcache,AMD64_RBX_REGNUM,regctx->uc_rbx); amd64_winnt_supply_reg(rcache,AMD64_RCX_REGNUM,regctx->uc_rcx); amd64_winnt_supply_reg(rcache,AMD64_RDX_REGNUM,regctx->uc_rdx); amd64_winnt_supply_reg(rcache,AMD64_RSI_REGNUM,regctx->uc_rsi); amd64_winnt_supply_reg(rcache,AMD64_RDI_REGNUM,regctx->uc_rdi); amd64_winnt_supply_reg(rcache,AMD64_RBP_REGNUM,regctx->uc_rbp); amd64_winnt_supply_reg(rcache,AMD64_RSP_REGNUM,regctx->uc_rsp); amd64_winnt_supply_reg(rcache,AMD64_R8_REGNUM, regctx->uc_r8); amd64_winnt_supply_reg(rcache,AMD64_R9_REGNUM, regctx->uc_r9); amd64_winnt_supply_reg(rcache,AMD64_R10_REGNUM,regctx->uc_r10); amd64_winnt_supply_reg(rcache,AMD64_R11_REGNUM,regctx->uc_r11); amd64_winnt_supply_reg(rcache,AMD64_R12_REGNUM,regctx->uc_r12); amd64_winnt_supply_reg(rcache,AMD64_R13_REGNUM,regctx->uc_r13); amd64_winnt_supply_reg(rcache,AMD64_R14_REGNUM,regctx->uc_r14); amd64_winnt_supply_reg(rcache,AMD64_R15_REGNUM,regctx->uc_r15); amd64_winnt_supply_reg(rcache,AMD64_CS_REGNUM,regctx->uc_seg_cs); amd64_winnt_supply_reg(rcache,AMD64_SS_REGNUM,regctx->uc_seg_ss); amd64_winnt_supply_reg(rcache,AMD64_DS_REGNUM,regctx->uc_seg_ds); amd64_winnt_supply_reg(rcache,AMD64_ES_REGNUM,regctx->uc_seg_es); amd64_winnt_supply_reg(rcache,AMD64_FS_REGNUM,regctx->uc_seg_fs); amd64_winnt_supply_reg(rcache,AMD64_GS_REGNUM,regctx->uc_seg_gs); amd64_winnt_supply_reg(rcache,AMD64_EFLAGS_REGNUM,regctx->uc_eflags); } void amd64_winnt_fetch_registers( struct regcache * rcache, int regnum, struct winnt_thread * thread) { int pfd; pid_t tid; mcontext_t * regctx; pfd = thread->process->pfd; tid = thread->tid; regctx = &thread->regctx; if (regctx->uc_context_flags) if (__dbg_regs_fetch(pfd,tid,regctx) < 0) return; if (regnum == AMD64_RIP_REGNUM) { amd64_winnt_supply_pc_regs(rcache,regctx); } else { amd64_winnt_supply_core_regs(rcache,regctx); } regctx->uc_context_flags = WINNT_THREAD_CONTEXT_READY; } void amd64_winnt_store_registers( const struct regcache * rcache, int regnum, struct winnt_thread * thread) { int pfd; pid_t tid; int rmin; int rmax; char * mark; mcontext_t * regctx; if (regnum > AMD64_KNOWN_REG_CAP) return; if (regnum < 0) { rmin = 0; rmax = AMD64_KNOWN_REG_CAP; } else { rmin = regnum; rmax = regnum; } pfd = thread->process->pfd; tid = thread->tid; regctx = &thread->regctx; mark = (char *)regctx; for (regnum=rmin; regnum<=rmax; regnum++) regcache_raw_collect( rcache,regnum, mark + regoffs[regnum]); if (!__dbg_regs_store(pfd,tid,regctx)) regctx->uc_context_flags = WINNT_THREAD_CONTEXT_READY; } #define AMD64_WINNT_INIT_REG_OFFSET(regnum,regmem) \ regoffs[regnum] = offsetof(mcontext_t,regmem) #define AMD64_WINNT_INIT_MX_REG_OFFSET(regidx,regmem) \ regoffs[regidx] = offsetof(mcontext_t,\ uc_flt.uc_flt_save.regmem) #define AMD64_WINNT_INIT_XSAVE_REG_OFFSET(ctrlidx,regmem) \ regoffs[AMD64_FCTRL_REGNUM+ctrlidx] = offsetof(mcontext_t,\ uc_flt.uc_flt_save.regmem) #define AMD64_WINNT_INIT_ST_REG_OFFSET(regnum,stidx) \ regoffs[AMD64_ST0_REGNUM+stidx] = offsetof(mcontext_t, \ uc_flt.uc_flt_save.uc_float_registers[stidx]) #define AMD64_WINNT_INIT_XMM_REG_OFFSET(regnum,stidx) \ regoffs[AMD64_XMM0_REGNUM+stidx] = offsetof(mcontext_t, \ uc_flt.uc_flt_save.uc_float_registers[stidx]) void amd64_winnt_init_reg_offsets(void) { AMD64_WINNT_INIT_REG_OFFSET(AMD64_RAX_REGNUM,uc_rax); AMD64_WINNT_INIT_REG_OFFSET(AMD64_RBX_REGNUM,uc_rbx); AMD64_WINNT_INIT_REG_OFFSET(AMD64_RCX_REGNUM,uc_rcx); AMD64_WINNT_INIT_REG_OFFSET(AMD64_RDX_REGNUM,uc_rdx); AMD64_WINNT_INIT_REG_OFFSET(AMD64_RSI_REGNUM,uc_rsi); AMD64_WINNT_INIT_REG_OFFSET(AMD64_RDI_REGNUM,uc_rdi); AMD64_WINNT_INIT_REG_OFFSET(AMD64_RBP_REGNUM,uc_rbp); AMD64_WINNT_INIT_REG_OFFSET(AMD64_RSP_REGNUM,uc_rsp); AMD64_WINNT_INIT_REG_OFFSET(AMD64_R8_REGNUM, uc_r8); AMD64_WINNT_INIT_REG_OFFSET(AMD64_R9_REGNUM, uc_r9); AMD64_WINNT_INIT_REG_OFFSET(AMD64_R10_REGNUM,uc_r10); AMD64_WINNT_INIT_REG_OFFSET(AMD64_R11_REGNUM,uc_r11); AMD64_WINNT_INIT_REG_OFFSET(AMD64_R12_REGNUM,uc_r12); AMD64_WINNT_INIT_REG_OFFSET(AMD64_R13_REGNUM,uc_r13); AMD64_WINNT_INIT_REG_OFFSET(AMD64_R14_REGNUM,uc_r14); AMD64_WINNT_INIT_REG_OFFSET(AMD64_R15_REGNUM,uc_r15); AMD64_WINNT_INIT_REG_OFFSET(AMD64_RIP_REGNUM,uc_rip); AMD64_WINNT_INIT_REG_OFFSET(AMD64_CS_REGNUM,uc_seg_cs); AMD64_WINNT_INIT_REG_OFFSET(AMD64_SS_REGNUM,uc_seg_ss); AMD64_WINNT_INIT_REG_OFFSET(AMD64_DS_REGNUM,uc_seg_ds); AMD64_WINNT_INIT_REG_OFFSET(AMD64_ES_REGNUM,uc_seg_es); AMD64_WINNT_INIT_REG_OFFSET(AMD64_FS_REGNUM,uc_seg_fs); AMD64_WINNT_INIT_REG_OFFSET(AMD64_GS_REGNUM,uc_seg_gs); AMD64_WINNT_INIT_REG_OFFSET(AMD64_EFLAGS_REGNUM,uc_eflags); AMD64_WINNT_INIT_MX_REG_OFFSET(AMD64_MXCSR_REGNUM,uc_mx_csr); AMD64_WINNT_INIT_XSAVE_REG_OFFSET(0,uc_control_word); AMD64_WINNT_INIT_XSAVE_REG_OFFSET(0,uc_status_word); AMD64_WINNT_INIT_XSAVE_REG_OFFSET(0,uc_tag_word); AMD64_WINNT_INIT_XSAVE_REG_OFFSET(0,uc_error_selector); AMD64_WINNT_INIT_XSAVE_REG_OFFSET(0,uc_error_offset); AMD64_WINNT_INIT_XSAVE_REG_OFFSET(0,uc_data_selector); AMD64_WINNT_INIT_XSAVE_REG_OFFSET(0,uc_data_offset); AMD64_WINNT_INIT_XSAVE_REG_OFFSET(0,uc_error_opcode); AMD64_WINNT_INIT_ST_REG_OFFSET(0,0); AMD64_WINNT_INIT_ST_REG_OFFSET(1,1); AMD64_WINNT_INIT_ST_REG_OFFSET(2,2); AMD64_WINNT_INIT_ST_REG_OFFSET(3,3); AMD64_WINNT_INIT_ST_REG_OFFSET(4,4); AMD64_WINNT_INIT_ST_REG_OFFSET(5,5); AMD64_WINNT_INIT_ST_REG_OFFSET(6,6); AMD64_WINNT_INIT_ST_REG_OFFSET(7,7); }