/*++
Copyright (c) 1993 Microsoft Corporation
Module Name:
regs.c
Abstract:
This file provides access to the machine's register set.
Author:
Wesley Witt (wesw) 1-May-1993 (ported from ntsd)
Environment:
User Mode
--*/
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "drwatson.h"
#include "proto.h"
#include "regs.h"
ULONG GetDregValue (PDEBUGPACKET dp, ULONG index);
char szGsReg[] = "gs";
char szFsReg[] = "fs";
char szEsReg[] = "es";
char szDsReg[] = "ds";
char szEdiReg[] = "edi";
char szEsiReg[] = "esi";
char szEbxReg[] = "ebx";
char szEdxReg[] = "edx";
char szEcxReg[] = "ecx";
char szEaxReg[] = "eax";
char szEbpReg[] = "ebp";
char szEipReg[] = "eip";
char szCsReg[] = "cs";
char szEflReg[] = "efl";
char szEspReg[] = "esp";
char szSsReg[] = "ss";
char szDiReg[] = "di";
char szSiReg[] = "si";
char szBxReg[] = "bx";
char szDxReg[] = "dx";
char szCxReg[] = "cx";
char szAxReg[] = "ax";
char szBpReg[] = "bp";
char szIpReg[] = "ip";
char szFlReg[] = "fl";
char szSpReg[] = "sp";
char szBlReg[] = "bl";
char szDlReg[] = "dl";
char szClReg[] = "cl";
char szAlReg[] = "al";
char szBhReg[] = "bh";
char szDhReg[] = "dh";
char szChReg[] = "ch";
char szAhReg[] = "ah";
char szIoplFlag[] = "iopl";
char szFlagOf[] = "of";
char szFlagDf[] = "df";
char szFlagIf[] = "if";
char szFlagTf[] = "tf";
char szFlagSf[] = "sf";
char szFlagZf[] = "zf";
char szFlagAf[] = "af";
char szFlagPf[] = "pf";
char szFlagCf[] = "cf";
char szFlagVip[] = "vip";
char szFlagVif[] = "vif";
struct Reg {
char *psz;
ULONG value;
};
struct SubReg {
ULONG regindex;
ULONG shift;
ULONG mask;
};
struct Reg regname[] = {
{ szGsReg, REGGS },
{ szFsReg, REGFS },
{ szEsReg, REGES },
{ szDsReg, REGDS },
{ szEdiReg, REGEDI },
{ szEsiReg, REGESI },
{ szEbxReg, REGEBX },
{ szEdxReg, REGEDX },
{ szEcxReg, REGECX },
{ szEaxReg, REGEAX },
{ szEbpReg, REGEBP },
{ szEipReg, REGEIP },
{ szCsReg, REGCS },
{ szEflReg, REGEFL },
{ szEspReg, REGESP },
{ szSsReg, REGSS },
{ szDiReg, REGDI },
{ szSiReg, REGSI },
{ szBxReg, REGBX },
{ szDxReg, REGDX },
{ szCxReg, REGCX },
{ szAxReg, REGAX },
{ szBpReg, REGBP },
{ szIpReg, REGIP },
{ szFlReg, REGFL },
{ szSpReg, REGSP },
{ szBlReg, REGBL },
{ szDlReg, REGDL },
{ szClReg, REGCL },
{ szAlReg, REGAL },
{ szBhReg, REGBH },
{ szDhReg, REGDH },
{ szChReg, REGCH },
{ szAhReg, REGAH },
{ szIoplFlag, FLAGIOPL },
{ szFlagOf, FLAGOF },
{ szFlagDf, FLAGDF },
{ szFlagIf, FLAGIF },
{ szFlagTf, FLAGTF },
{ szFlagSf, FLAGSF },
{ szFlagZf, FLAGZF },
{ szFlagAf, FLAGAF },
{ szFlagPf, FLAGPF },
{ szFlagCf, FLAGCF },
{ szFlagVip, FLAGVIP },
{ szFlagVif, FLAGVIF },
};
#define REGNAMESIZE (sizeof(regname) / sizeof(struct Reg))
struct SubReg subregname[] = {
{ REGEDI, 0, 0xffff }, // DI register
{ REGESI, 0, 0xffff }, // SI register
{ REGEBX, 0, 0xffff }, // BX register
{ REGEDX, 0, 0xffff }, // DX register
{ REGECX, 0, 0xffff }, // CX register
{ REGEAX, 0, 0xffff }, // AX register
{ REGEBP, 0, 0xffff }, // BP register
{ REGEIP, 0, 0xffff }, // IP register
{ REGEFL, 0, 0xffff }, // FL register
{ REGESP, 0, 0xffff }, // SP register
{ REGEBX, 0, 0xff }, // BL register
{ REGEDX, 0, 0xff }, // DL register
{ REGECX, 0, 0xff }, // CL register
{ REGEAX, 0, 0xff }, // AL register
{ REGEBX, 8, 0xff }, // BH register
{ REGEDX, 8, 0xff }, // DH register
{ REGECX, 8, 0xff }, // CH register
{ REGEAX, 8, 0xff }, // AH register
{ REGEFL, 12, 3 }, // IOPL level value
{ REGEFL, 11, 1 }, // OF (overflow flag)
{ REGEFL, 10, 1 }, // DF (direction flag)
{ REGEFL, 9, 1 }, // IF (interrupt enable flag)
{ REGEFL, 8, 1 }, // TF (trace flag)
{ REGEFL, 7, 1 }, // SF (sign flag)
{ REGEFL, 6, 1 }, // ZF (zero flag)
{ REGEFL, 4, 1 }, // AF (aux carry flag)
{ REGEFL, 2, 1 }, // PF (parity flag)
{ REGEFL, 0, 1 }, // CF (carry flag)
{ REGEFL, 20, 1 }, // VIP (virtual interrupt pending)
{ REGEFL, 19, 1 } // VIF (virtual interrupt flag)
};
DWORDLONG
GetRegFlagValue (PDEBUGPACKET dp, ULONG regnum)
{
DWORDLONG value;
if (regnum < FLAGBASE)
value = GetRegValue(dp, regnum);
else {
regnum -= FLAGBASE;
value = GetRegValue(dp, subregname[regnum].regindex);
value = (value >> subregname[regnum].shift) & subregname[regnum].mask;
}
return value;
}
DWORDLONG
GetRegValue (
PDEBUGPACKET dp,
ULONG regnum
)
{
switch (regnum) {
case REGGS:
return dp->tctx->context.SegGs;
case REGFS:
return dp->tctx->context.SegFs;
case REGES:
return dp->tctx->context.SegEs;
case REGDS:
return dp->tctx->context.SegDs;
case REGEDI:
return dp->tctx->context.Edi;
case REGESI:
return dp->tctx->context.Esi;
case REGSI:
return(dp->tctx->context.Esi & 0xffff);
case REGDI:
return(dp->tctx->context.Edi & 0xffff);
case REGEBX:
return dp->tctx->context.Ebx;
case REGEDX:
return dp->tctx->context.Edx;
case REGECX:
return dp->tctx->context.Ecx;
case REGEAX:
return dp->tctx->context.Eax;
case REGEBP:
return dp->tctx->context.Ebp;
case REGEIP:
return dp->tctx->context.Eip;
case REGCS:
return dp->tctx->context.SegCs;
case REGEFL:
return dp->tctx->context.EFlags;
case REGESP:
return dp->tctx->context.Esp;
case REGSS:
return dp->tctx->context.SegSs;
case PREGEA:
return 0;
case PREGEXP:
return 0;
case PREGRA: {
struct {
ULONG oldBP;
ULONG retAddr;
} stackRead;
DoMemoryRead( dp,
(LPVOID)dp->tctx->context.Ebp,
(LPVOID)&stackRead,
sizeof(stackRead),
NULL
);
return stackRead.retAddr;
}
case PREGP:
return 0;
case REGDR0:
return dp->tctx->context.Dr0;
case REGDR1:
return dp->tctx->context.Dr1;
case REGDR2:
return dp->tctx->context.Dr2;
case REGDR3:
return dp->tctx->context.Dr3;
case REGDR6:
return dp->tctx->context.Dr6;
case REGDR7:
return dp->tctx->context.Dr7;
default:
return 0;
}
}
ULONG
GetRegString (PUCHAR pszString)
{
ULONG count;
for (count = 0; count < REGNAMESIZE; count++) {
if (!strcmp(pszString, regname[count].psz)) {
return regname[count].value;
}
}
return (ULONG)-1;
}
void
OutputAllRegs( PDEBUGPACKET dp, BOOL Show64 )
{
lprintfs("eax=%08lx ebx=%08lx ecx=%08lx edx=%08lx esi=%08lx edi=%08lx\r\n",
(DWORD)GetRegValue(dp,REGEAX),
(DWORD)GetRegValue(dp,REGEBX),
(DWORD)GetRegValue(dp,REGECX),
(DWORD)GetRegValue(dp,REGEDX),
(DWORD)GetRegValue(dp,REGESI),
(DWORD)GetRegValue(dp,REGEDI));
lprintfs("eip=%08lx esp=%08lx ebp=%08lx iopl=%1lx "
"%s %s %s %s %s %s %s %s %s %s\r\n",
(DWORD)GetRegValue(dp,REGEIP),
(DWORD)GetRegValue(dp,REGESP),
(DWORD)GetRegValue(dp,REGEBP),
(DWORD)GetRegFlagValue(dp,FLAGIOPL),
(DWORD)GetRegFlagValue(dp,FLAGVIP) ? "vip" : " ",
(DWORD)GetRegFlagValue(dp,FLAGVIF) ? "vif" : " ",
(DWORD)GetRegFlagValue(dp,FLAGOF) ? "ov" : "nv",
(DWORD)GetRegFlagValue(dp,FLAGDF) ? "dn" : "up",
(DWORD)GetRegFlagValue(dp,FLAGIF) ? "ei" : "di",
(DWORD)GetRegFlagValue(dp,FLAGSF) ? "ng" : "pl",
(DWORD)GetRegFlagValue(dp,FLAGZF) ? "zr" : "nz",
(DWORD)GetRegFlagValue(dp,FLAGAF) ? "ac" : "na",
(DWORD)GetRegFlagValue(dp,FLAGPF) ? "po" : "pe",
(DWORD)GetRegFlagValue(dp,FLAGCF) ? "cy" : "nc");
lprintfs("cs=%04lx ss=%04lx ds=%04lx es=%04lx fs=%04lx gs=%04lx"
" efl=%08lx\r\n",
(DWORD)GetRegValue(dp,REGCS),
(DWORD)GetRegValue(dp,REGSS),
(DWORD)GetRegValue(dp,REGDS),
(DWORD)GetRegValue(dp,REGES),
(DWORD)GetRegValue(dp,REGFS),
(DWORD)GetRegValue(dp,REGGS),
(DWORD)GetRegFlagValue(dp,REGEFL));
lprintfs("\r\n\r\n");
}
void
OutputOneReg (PDEBUGPACKET dp, ULONG regnum, BOOL Show64)
{
DWORD value;
value = (DWORD)GetRegFlagValue(dp,regnum);
if (regnum < FLAGBASE) {
lprintfs("%08lx\r\n", value);
} else {
lprintfs("%lx\r\n", value);
}
}
ULONG
GetDregValue (PDEBUGPACKET dp, ULONG index)
{
if (index < 4) {
index += REGDR0;
} else {
index += REGDR6 - 6;
}
return (DWORD)GetRegValue(dp,index);
}
PUCHAR
RegNameFromIndex (ULONG index)
{
ULONG count;
for (count = 0; count < REGNAMESIZE; count++) {
if (regname[count].value == index) {
return regname[count].psz;
}
}
return NULL;
}