REGS.C
/*++ 
 
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; 
}