📄 regs-x86.c
字号:
/* * libDebug * * Copyright (C) 2000 Patrick Alken * This library comes with absolutely NO WARRANTY * * Should you choose to use and/or modify this source code, please * do so under the terms of the GNU General Public License under which * this library is distributed. * * $Id: regs-x86.c,v 1.2 2004/10/09 17:34:15 pa33 Exp $ * * This module contains routines dealing with x86 registers which are common to * all operating systems. */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <assert.h>/* * Top-level includes */#include "libDebug.h"#include "Strn.h"/* * List of x86 registers - the elements in this array are ordered to * correspond to the REG_xxx indices defined in regs-x86.h */struct x86RegInfo x86Registers[] = { { "eax", 4, R_BITS32|R_GENERAL, (void *) 0 }, { "ebx", 4, R_BITS32|R_GENERAL, (void *) 0 }, { "ecx", 4, R_BITS32|R_GENERAL, (void *) 0 }, { "edx", 4, R_BITS32|R_GENERAL, (void *) 0 }, { "esp", 4, R_BITS32|R_GENERAL, (void *) 0 }, { "ebp", 4, R_BITS32|R_GENERAL, (void *) 0 }, { "esi", 4, R_BITS32|R_GENERAL, (void *) 0 }, { "edi", 4, R_BITS32|R_GENERAL, (void *) 0 }, { "ds", 2, R_BITS16|R_GENERAL, (void *) 0 }, { "es", 2, R_BITS16|R_GENERAL, (void *) 0 }, { "fs", 2, R_BITS16|R_GENERAL, (void *) 0 }, { "gs", 2, R_BITS16|R_GENERAL, (void *) 0 }, { "ss", 2, R_BITS16|R_GENERAL, (void *) 0 }, { "cs", 2, R_BITS16|R_GENERAL, (void *) 0 }, { "eip", 4, R_BITS32|R_GENERAL, (void *) 0 }, { "eflags", 4, R_BITS32|R_GENERAL, (void *) 0 }, { "null", 0, 0, (void *) 0 }, /* REG_ENDGENERAL */ /* * These can be modified, but do not display them when * the user wishes to display all registers */ { "ah", 2, R_BITS8|R_NODISPLAY|R_GENERAL, (void *) 0 }, { "al", 1, R_BITS8|R_NODISPLAY|R_GENERAL, (void *) 0 }, { "ax", 2, R_BITS16|R_NODISPLAY|R_GENERAL, (void *) 0 }, { "bh", 2, R_BITS8|R_NODISPLAY|R_GENERAL, (void *) 0 }, { "bl", 1, R_BITS8|R_NODISPLAY|R_GENERAL, (void *) 0 }, { "bx", 2, R_BITS16|R_NODISPLAY|R_GENERAL, (void *) 0 }, { "ch", 2, R_BITS8|R_NODISPLAY|R_GENERAL, (void *) 0 }, { "cl", 1, R_BITS8|R_NODISPLAY|R_GENERAL, (void *) 0 }, { "cx", 2, R_BITS16|R_NODISPLAY|R_GENERAL, (void *) 0 }, { "dh", 2, R_BITS8|R_NODISPLAY|R_GENERAL, (void *) 0 }, { "dl", 1, R_BITS8|R_NODISPLAY|R_GENERAL, (void *) 0 }, { "dx", 2, R_BITS16|R_NODISPLAY|R_GENERAL, (void *) 0 }, { "sp", 2, R_BITS16|R_NODISPLAY|R_GENERAL, (void *) 0 }, { "bp", 2, R_BITS16|R_NODISPLAY|R_GENERAL, (void *) 0 }, { "si", 2, R_BITS16|R_NODISPLAY|R_GENERAL, (void *) 0 }, { "di", 2, R_BITS16|R_NODISPLAY|R_GENERAL, (void *) 0 }, { "ip", 2, R_BITS16|R_NODISPLAY|R_GENERAL, (void *) 0 }, { "flags", 2, R_BITS16|R_NODISPLAY|R_GENERAL, (void *) 0 }, /* * FPU (Floating Point Unit) registers */ { "st0", 0, R_BITS80|R_FPU|R_FPU_DATA, (void *) 0 }, { "st1", 0, R_BITS80|R_FPU|R_FPU_DATA, (void *) 0 }, { "st2", 0, R_BITS80|R_FPU|R_FPU_DATA, (void *) 0 }, { "st3", 0, R_BITS80|R_FPU|R_FPU_DATA, (void *) 0 }, { "st4", 0, R_BITS80|R_FPU|R_FPU_DATA, (void *) 0 }, { "st5", 0, R_BITS80|R_FPU|R_FPU_DATA, (void *) 0 }, { "st6", 0, R_BITS80|R_FPU|R_FPU_DATA, (void *) 0 }, { "st7", 0, R_BITS80|R_FPU|R_FPU_DATA, (void *) 0 }, { "fctrl", 2, R_BITS16|R_FPU, (void *) 0 }, { "fstat", 2, R_BITS16|R_FPU, (void *) 0 }, { "ftag", 2, R_BITS16|R_FPU, (void *) 0 }, { "fipoff", 4, R_BITS32|R_FPU, (void *) 0 }, { "fipseg", 2, R_BITS16|R_FPU, (void *) 0 }, { "fopcode", 2, R_BITS16|R_FPU, (void *) 0 }, { "fooff", 4, R_BITS32|R_FPU, (void *) 0 }, { "foseg", 4, R_BITS32|R_FPU, (void *) 0 }, /* * MMX registers */ { "mm0", 0, R_BITS64|R_MMX, (void *) 0 }, { "mm1", 0, R_BITS64|R_MMX, (void *) 0 }, { "mm2", 0, R_BITS64|R_MMX, (void *) 0 }, { "mm3", 0, R_BITS64|R_MMX, (void *) 0 }, { "mm4", 0, R_BITS64|R_MMX, (void *) 0 }, { "mm5", 0, R_BITS64|R_MMX, (void *) 0 }, { "mm6", 0, R_BITS64|R_MMX, (void *) 0 }, { "mm7", 0, R_BITS64|R_MMX, (void *) 0 }, { 0, 0, 0, (void *) 0 }};/*x86findRegisterDebug() Attempt to locate the given register name in x86Registers[]Return: index in x86Registers[] if found -1 if not*/intx86findRegisterDebug(struct debugWorkspace *ws, char *name){ struct x86RegInfo *rptr; for (rptr = x86Registers; rptr->name; ++rptr) { if (!Strcasecmp(name, rptr->name)) return ((int) (rptr - x86Registers)); } /* * Not found */ return (-1);} /* x86findRegisterDebug() *//*x86readRegisterDebug() Read the contents of a specified register. Before calling thisfunction, x86getRegistersDebug() should be called to obtain thelatest register contents via ptraceInputs: ws - debug workspace rptr - pointer to a register in x86Registers[] regVal - store register value in hereReturn: size of register in bytesSide effects: regVal.lvalue is set to the register's value if it is a 16 or 32 bit register If it is a fpu data register, regVal.stptr is set to the position on the fpu data stack of the register*/size_tx86readRegisterDebug(struct debugWorkspace *ws, struct x86RegInfo *rptr, struct x86RegValue *regVal){ int size; if (rptr->valptr == (void *) 0) { fprintf(stderr, "x86readRegisterDebug: valptr field of register %s is null\n", rptr->name); return (0); } if ((rptr->flags & R_FPU_DATA) || (rptr->flags & R_MMX)) { /* * We want to read one of the fpu data registers. The appropriate * location in i387.st_space was computed for each data register in * x86initRegistersDebug, so we just need to assign stptr to valptr. */ regVal->stptr = (unsigned char *) rptr->valptr; size = 8; } else { if (rptr->flags & R_BITS8) { /* * We only get here from x86setRegisterDebug(), and we do not * want to "and" this value to strip off the last byte, since * we may be trying to set the ah/bh/ch/dh registers which don't * occur in the last byte. So let x86setRegisterDebug() worry * about that stuff. */ size = 1; regVal->lvalue = *((unsigned long *) rptr->valptr); } else if (rptr->flags & R_BITS16) { size = 2; regVal->lvalue = *((unsigned long *) rptr->valptr) & 0xFFFF; } else if (rptr->flags & R_BITS32) { size = 4; regVal->lvalue = *((unsigned long *) rptr->valptr); } else return (0); } return (size);} /* x86readRegisterDebug() *//*x86printRegistersDebug() Traverse the list of registers and call a given callback functionwith each register's name and value.Inputs: ws - debug workspace regindex - optional index of x86Registers to display (-1 to display all registers) flags - flags (see REGFL_xxx in libDebug.h) callback - callback function: void *callback(struct debugRegisterInfo *regInfo, void *args); callbackArgs - arguments to callback functionReturn: 1 if successful 0 upon ptrace error*/intx86printRegistersDebug(struct debugWorkspace *ws, int regindex, unsigned int flags, void (*callback)(), void *callbackArgs){ struct x86fpuInfo *fpuState; struct x86RegInfo *rptr; unsigned char *stptr; char *bufptr; int ii, jj; int shr; unsigned long regvalue; size_t size; struct x86RegValue regVal; unsigned int regFlags; int needbreak; /* * Grab the process' registers */ if (!x86getRegistersDebug(ws)) return (0); needbreak = 0; if (regindex < 0) { /* * They want to display all registers - traverse register list */ if (flags & DB_REGFL_DISPLAY_GENERAL) { /* * Print out the general registers first */ ws->regInfo.flags |= DB_RI_GENERAL; for (ii = 0; ii < REG_ENDGENERAL; ++ii) { rptr = x86Registers + ii; if (rptr->flags & R_NODISPLAY) continue; size = x86readRegisterDebug(ws, rptr, ®Val); ws->regInfo.size = size; ws->regInfo.value = regVal.lvalue; strcpy(ws->regInfo.name, rptr->name); /* * Call our callback function with the register information */ (*callback)(&(ws->regInfo), callbackArgs); } /* for (ii = 0; ii < REG_ENDGENERAL; ++ii) */ ws->regInfo.flags &= ~DB_RI_GENERAL; needbreak = 1; } /* if (flags & DB_REGFL_DISPLAY_GENERAL) */ if (flags & DB_REGFL_DISPLAY_FPREGS) { if (needbreak) { ws->regInfo.flags |= DB_RI_BREAK; (*callback)(&(ws->regInfo), callbackArgs); ws->regInfo.flags &= ~DB_RI_BREAK; needbreak = 0; } /* * Get and print out fpu registers */ fpuState = (struct x86fpuInfo *) ws->fpuState; if (!x86readFPUDebug(ws, fpuState)) return (0);#if 0 /* big endian */ stptr = fpuState->stptr;#endif /* * Traverse the list of floating point data registers */ ws->regInfo.flags |= DB_RI_FPU_DATA; ws->regInfo.size = 2; for (ii = 0; ii < FPU_NUM_DATA_REGS; ++ii) { sprintf(ws->regInfo.name, "st%d", ii); bufptr = ws->regInfo.hexvalue; bufptr += sprintf(bufptr, "%s", "0x");#if 0 /* big endian */ for (jj = 0; jj < FPU_DATA_REG_SIZE; ++jj) bufptr += sprintf(bufptr, "%02x", *stptr++);#endif stptr = fpuState->stptr + ((ii + 1) * FPU_DATA_REG_SIZE - 1); for (jj = 0; jj < FPU_DATA_REG_SIZE; ++jj) bufptr += sprintf(bufptr, "%02x", *stptr--); ws->regInfo.rawbuf = fpuState->stptr + ii*FPU_DATA_REG_SIZE; (*callback)(&(ws->regInfo), callbackArgs); } /* for (ii = 0; ii < FPU_NUM_DATA_REGS; ++ii) */ ws->regInfo.flags &= ~DB_RI_FPU_DATA; ws->regInfo.size = 2; strcpy(ws->regInfo.name, x86Registers[REG_FCTRL].name); ws->regInfo.value = (unsigned long) fpuState->fctrl; (*callback)(&(ws->regInfo), callbackArgs); strcpy(ws->regInfo.name, x86Registers[REG_FSTAT].name); ws->regInfo.value = (unsigned long) fpuState->fstat; (*callback)(&(ws->regInfo), callbackArgs); strcpy(ws->regInfo.name, x86Registers[REG_FTAG].name); ws->regInfo.value = (unsigned long) fpuState->ftag; (*callback)(&(ws->regInfo), callbackArgs); ws->regInfo.size = 2; strcpy(ws->regInfo.name, x86Registers[REG_FCS].name); ws->regInfo.value = fpuState->fcs; (*callback)(&(ws->regInfo), callbackArgs); ws->regInfo.size = 4; strcpy(ws->regInfo.name, x86Registers[REG_FIP].name);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -