|
|
Microsoft Windows NT Build 511 (SDK Final Release) 07-24-1993
/*++
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"
PUCHAR UserRegs[10] = {0};
ULONG GetRegFlagValue (PDEBUGPACKET dp, ULONG regnum);
ULONG GetRegValue (PDEBUGPACKET dp, ULONG regnum);
ULONG GetRegName (void);
ULONG GetRegString (PUCHAR pszString);
void GetRegPCValue (PDEBUGPACKET dp, PULONG Address);
PULONG GetRegFPValue (PDEBUGPACKET dp);
void OutputAllRegs(PDEBUGPACKET dp);
void OutputOneReg (PDEBUGPACKET dp, ULONG regnum);
PUCHAR RegNameFromIndex (ULONG index);
static ULONG ProcessorType = 0;
ULONG cbBrkptLength = 4;
ULONG trapInstr = 0x0016000dL; // break 0x16 for brkpts
ULONG ContextType = CONTEXT_CONTROL | CONTEXT_INTEGER;
//
// Define MIPS nonvolatile register test macros.
//
#define IS_FLOATING_SAVED(Register) ((SAVED_FLOATING_MASK >> Register) & 1L)
#define IS_INTEGER_SAVED(Register) ((SAVED_INTEGER_MASK >> Register) & 1L)
//
// Define MIPS instruction opcode values.
//
#define ADDIU_OP 0x9 // add immediate unsigned integer register
#define ADDU_OP 0x21 // add unsigned integer register
#define JUMP_RA 0x3e00008 // jump indirect return address register
#define LUI_OP 0xf // load upper immediate integer register
#define SD_OP 0x2f // store double integer register
#define SW_OP 0x2b // store word integer register
#define SDC1_OP 0x3d // store double floating register
#define SWC1_OP 0x39 // store word floating register
#define SPEC_OP 0x0 // special opcode - use function field
#define SUBU_OP 0x23 // subtract unsigned integer register
//
// Define stack register and zero register numbers.
//
#define RA 0x1f // integer register 31
#define SP 0x1d // integer register 29
#define ZERO 0x0 // integer register 0
//
// Define saved register masks.
//
#define SAVED_FLOATING_MASK 0xfff00000 // saved floating registers
#define SAVED_INTEGER_MASK 0xf3ffff02 // saved integer registers
UCHAR szF0[] = "f0";
UCHAR szF1[] = "f1";
UCHAR szF2[] = "f2";
UCHAR szF3[] = "f3";
UCHAR szF4[] = "f4";
UCHAR szF5[] = "f5";
UCHAR szF6[] = "f6";
UCHAR szF7[] = "f7";
UCHAR szF8[] = "f8";
UCHAR szF9[] = "f9";
UCHAR szF10[] = "f10";
UCHAR szF11[] = "f11";
UCHAR szF12[] = "f12";
UCHAR szF13[] = "f13";
UCHAR szF14[] = "f14";
UCHAR szF15[] = "f15";
UCHAR szF16[] = "f16";
UCHAR szF17[] = "f17";
UCHAR szF18[] = "f18";
UCHAR szF19[] = "f19";
UCHAR szF20[] = "f20";
UCHAR szF21[] = "f21";
UCHAR szF22[] = "f22";
UCHAR szF23[] = "f23";
UCHAR szF24[] = "f24";
UCHAR szF25[] = "f25";
UCHAR szF26[] = "f26";
UCHAR szF27[] = "f27";
UCHAR szF28[] = "f28";
UCHAR szF29[] = "f29";
UCHAR szF30[] = "f30";
UCHAR szF31[] = "f31";
UCHAR szR0[] = "zero";
UCHAR szR1[] = "at";
UCHAR szR2[] = "v0";
UCHAR szR3[] = "v1";
UCHAR szR4[] = "a0";
UCHAR szR5[] = "a1";
UCHAR szR6[] = "a2";
UCHAR szR7[] = "a3";
UCHAR szR8[] = "t0";
UCHAR szR9[] = "t1";
UCHAR szR10[] = "t2";
UCHAR szR11[] = "t3";
UCHAR szR12[] = "t4";
UCHAR szR13[] = "t5";
UCHAR szR14[] = "t6";
UCHAR szR15[] = "t7";
UCHAR szR16[] = "s0";
UCHAR szR17[] = "s1";
UCHAR szR18[] = "s2";
UCHAR szR19[] = "s3";
UCHAR szR20[] = "s4";
UCHAR szR21[] = "s5";
UCHAR szR22[] = "s6";
UCHAR szR23[] = "s7";
UCHAR szR24[] = "t8";
UCHAR szR25[] = "t9";
UCHAR szR26[] = "k0";
UCHAR szR27[] = "k1";
UCHAR szR28[] = "gp";
UCHAR szR29[] = "sp";
UCHAR szR30[] = "s8";
UCHAR szR31[] = "ra";
UCHAR szLo[] = "lo";
UCHAR szHi[] = "hi";
UCHAR szFsr[] = "fsr";
UCHAR szFir[] = "fir";
UCHAR szPsr[] = "psr";
UCHAR szFlagCu[] = "cu";
UCHAR szFlagCu3[] = "cu3";
UCHAR szFlagCu2[] = "cu2";
UCHAR szFlagCu1[] = "cu1";
UCHAR szFlagCu0[] = "cu0";
UCHAR szFlagImsk[] = "imsk";
UCHAR szFlagInt5[] = "int5";
UCHAR szFlagInt4[] = "int4";
UCHAR szFlagInt3[] = "int3";
UCHAR szFlagInt2[] = "int2";
UCHAR szFlagInt1[] = "int1";
UCHAR szFlagInt0[] = "int0";
UCHAR szFlagSw1[] = "sw1";
UCHAR szFlagSw0[] = "sw0";
UCHAR szFlagKuo[] = "kuo";
UCHAR szFlagIeo[] = "ieo";
UCHAR szFlagKup[] = "kup";
UCHAR szFlagIep[] = "iep";
UCHAR szFlagKuc[] = "kuc";
UCHAR szFlagIec[] = "iec";
UCHAR szFlagKsu[] = "ksu";
UCHAR szFlagErl[] = "erl";
UCHAR szFlagExl[] = "exl";
UCHAR szFlagIe[] = "ie";
UCHAR szFlagFpc[] = "fpc";
char szEaPReg[] = "$ea";
char szExpPReg[] = "$exp";
char szRaPReg[] = "$ra";
char szPPReg[] = "$p";
char szU0Preg[] = "$u0";
char szU1Preg[] = "$u1";
char szU2Preg[] = "$u2";
char szU3Preg[] = "$u3";
char szU4Preg[] = "$u4";
char szU5Preg[] = "$u5";
char szU6Preg[] = "$u6";
char szU7Preg[] = "$u7";
char szU8Preg[] = "$u8";
char szU9Preg[] = "$u9";
PUCHAR pszReg[] = {
szF0, szF1, szF2, szF3, szF4, szF5, szF6, szF7,
szF8, szF9, szF10, szF11, szF12, szF13, szF14, szF15,
szF16, szF17, szF18, szF19, szF20, szF21, szF22, szF23,
szF24, szF25, szF26, szF27, szF28, szF29, szF30, szF31,
szR0, szR1, szR2, szR3, szR4, szR5, szR6, szR7,
szR8, szR9, szR10, szR11, szR12, szR13, szR14, szR15,
szR16, szR17, szR18, szR19, szR20, szR21, szR22, szR23,
szR24, szR25, szR26, szR27, szR28, szR29, szR30, szR31,
szLo, szHi, szFsr, szFir, szPsr,
szFlagCu, szFlagCu3, szFlagCu2, szFlagCu1, szFlagCu0,
szFlagImsk,
szFlagInt5, szFlagInt4, szFlagInt3, szFlagInt2, szFlagInt1, szFlagInt0,
szFlagSw1, szFlagSw0,
szFlagKuo, szFlagIeo, // R3000 flags
szFlagKup, szFlagIep, // ...
szFlagKuc, szFlagIec, // ...
szFlagKsu, szFlagErl, szFlagExl, szFlagIe, // R4000 flags
szFlagFpc, // fl pt condition
szEaPReg, szExpPReg, szRaPReg, szPPReg, // psuedo-registers
szU0Preg, szU1Preg, szU2Preg, szU3Preg, szU4Preg,
szU5Preg, szU6Preg, szU7Preg, szU8Preg, szU9Preg
};
#define REGNAMESIZE sizeof(pszReg) / sizeof(PUCHAR)
struct Reg {
char *psz;
ULONG value;
};
struct SubReg {
ULONG regindex;
ULONG shift;
ULONG mask;
};
struct SubReg subregname[] = {
{ REGPSR, 28, 0xf }, // CU mask
{ REGPSR, 31, 1 }, // CU3 flag
{ REGPSR, 30, 1 }, // CU2 flag
{ REGPSR, 29, 1 }, // CU1 flag
{ REGPSR, 28, 1 }, // CU0 flag
{ REGPSR, 8, 0xff }, // IMSK mask
{ REGPSR, 15, 1 }, // INT5 - int 5 enable
{ REGPSR, 14, 1 }, // INT4 - int 4 enable
{ REGPSR, 13, 1 }, // INT3 - int 3 enable
{ REGPSR, 12, 1 }, // INT2 - int 2 enable
{ REGPSR, 11, 1 }, // INT1 - int 1 enable
{ REGPSR, 10, 1 }, // INT0 - int 0 enable
{ REGPSR, 9, 1 }, // SW1 - software int 1 enable
{ REGPSR, 8, 1 }, // SW0 - software int 0 enable
// R3000-specific status bits
{ REGPSR, 5, 1 }, // KUO
{ REGPSR, 4, 1 }, // IEO
{ REGPSR, 3, 1 }, // KUP
{ REGPSR, 2, 1 }, // IEP
{ REGPSR, 1, 1 }, // KUC
{ REGPSR, 0, 1 }, // IEC
// R4000-specific status bits
{ REGPSR, 3, 2 }, // KSU
{ REGPSR, 2, 1 }, // ERL
{ REGPSR, 1, 1 }, // EXL
{ REGPSR, 0, 1 }, // IE
{ REGFSR, 23, 1 } // FPC - floating point condition
};
/*** UserRegTest - test if index is a user-defined register
*
* Purpose:
* Test if register is user-defined for upper routines.
*
* Input:
* index - index of register
*
* Returns:
* TRUE if user-defined register, else FALSE
*
*************************************************************************/
BOOLEAN
UserRegTest (ULONG index)
{
return (BOOLEAN)(index >= PREGU0 && index <= PREGU9);
}
/*** GetRegFlagValue - get register or flag value
*
* Purpose:
* Return the value of the specified register or flag.
* This routine calls GetRegValue to get the register
* value and shifts and masks appropriately to extract a
* flag value.
*
* Input:
* regnum - register or flag specification
*
* Returns:
* Value of register or flag.
*************************************************************************/
ULONG
GetRegFlagValue (PDEBUGPACKET dp, ULONG regnum)
{
ULONG value;
if (regnum < FLAGBASE || regnum >= PREGBASE)
value = GetRegValue(dp,regnum);
else {
regnum -= FLAGBASE;
value = GetRegValue(dp,subregname[regnum].regindex);
value = (value >> subregname[regnum].shift) & subregname[regnum].mask;
}
return value;
}
/*** GetRegValue - get register value
*
* Purpose:
* Returns the value of the register from the processor
* context structure.
*
* Input:
* regnum - register specification
*
* Returns:
* value of the register from the context structure
*
*************************************************************************/
ULONG
GetRegValue (PDEBUGPACKET dp, ULONG regnum)
{
return *(&dp->tctx->context.FltF0 + regnum);
}
ULONG
GetRegString (PUCHAR pszString)
{
ULONG count;
for (count = 0; count < REGNAMESIZE; count++)
if (!strcmp(pszString, pszReg[count]))
return count;
return (ULONG)-1;
}
void
GetRegPCValue (PDEBUGPACKET dp, PULONG Address)
{
*Address = GetRegValue(dp,REGFIR);
return;
}
PULONG
GetRegFPValue (PDEBUGPACKET dp)
{
static ULONG addrFP;
addrFP = GetRegValue(dp,REGGP);
return &addrFP;
}
/*** OutputAllRegs - output all registers and present instruction
*
* Purpose:
* Function of "r" command.
*
* To output the current register state of the processor.
* All integer registers are output as well as processor status
* registers. Important flag fields are also output separately.
* OutDisCurrent is called to output the current instruction(s).
*
* Input:
* None.
*
* Output:
* None.
*
*************************************************************************/
void
OutputAllRegs(PDEBUGPACKET dp)
{
int regindex;
for (regindex = 1; regindex < 37; regindex++) {
if (regindex == 34)
lprintfs(" ");
else {
lprintfs("%s=%08lx", pszReg[regindex + REGBASE],
GetRegValue(dp,regindex + REGBASE));
if (regindex % 6 == 0)
lprintfs("\r\n");
else
lprintfs(" ");
}
}
lprintfs("cu=%1lx%1lx%1lx%1lx intr(5:0)=%1lx%1lx%1lx%1lx%1lx%1lx ",
GetRegFlagValue(dp,FLAGCU3),
GetRegFlagValue(dp,FLAGCU2),
GetRegFlagValue(dp,FLAGCU1),
GetRegFlagValue(dp,FLAGCU0),
GetRegFlagValue(dp,FLAGINT5),
GetRegFlagValue(dp,FLAGINT4),
GetRegFlagValue(dp,FLAGINT3),
GetRegFlagValue(dp,FLAGINT2),
GetRegFlagValue(dp,FLAGINT1),
GetRegFlagValue(dp,FLAGINT0));
lprintfs("sw(1:0)=%1lx%1lx ",
GetRegFlagValue(dp,FLAGSW1),
GetRegFlagValue(dp,FLAGSW0));
if (ProcessorType == 0)
lprintfs("kuo=%01lx ieo=%01lx kup=%01lx "
"iep=%01lx kuc=%01lx iec=%01lx\r\n",
GetRegFlagValue(dp,FLAGKUO),
GetRegFlagValue(dp,FLAGIEO),
GetRegFlagValue(dp,FLAGKUP),
GetRegFlagValue(dp,FLAGIEP),
GetRegFlagValue(dp,FLAGKUC),
GetRegFlagValue(dp,FLAGIEC));
else
lprintfs("ksu=%01lx erl=%01lx exl=%01lx ie=%01lx\r\n",
GetRegFlagValue(dp,FLAGKSU),
GetRegFlagValue(dp,FLAGERL),
GetRegFlagValue(dp,FLAGEXL),
GetRegFlagValue(dp,FLAGIE));
lprintfs("\r\n\r\n");
}
/*** OutputOneReg - output one register value
*
* Purpose:
* Function for the "r <regname>" command.
*
* Output the value for the specified register or flag.
*
* Input:
* regnum - register or flag specification
*
* Output:
* None.
*
*************************************************************************/
void
OutputOneReg (PDEBUGPACKET dp, ULONG regnum)
{
ULONG value;
value = GetRegFlagValue(dp,regnum);
if (regnum < FLAGBASE)
lprintfs("%08lx\r\n", value);
else
lprintfs("%lx\r\n", value);
}
PUCHAR
RegNameFromIndex (ULONG index)
{
return pszReg[index];
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.