|
|
1.1 ! root 1: /*++ ! 2: ! 3: Copyright (c) 1993 Microsoft Corporation ! 4: ! 5: Module Name: ! 6: ! 7: regs.c ! 8: ! 9: Abstract: ! 10: ! 11: This file provides access to the machine's register set. ! 12: ! 13: Author: ! 14: ! 15: Miche Baker-Harvey (v-michbh) 1-May-1993 (ported from ntsd) ! 16: ! 17: Environment: ! 18: ! 19: User Mode ! 20: ! 21: --*/ ! 22: ! 23: ! 24: /* ! 25: // ! 26: // This line keeps alpha pseudo ops from being defined in kxalpha.h ! 27: #ifdef ALPHA ! 28: #define HEADER_FILE ! 29: #endif ! 30: */ ! 31: ! 32: ! 33: #include <windows.h> ! 34: #include <stdlib.h> ! 35: #include <stdio.h> ! 36: #include <string.h> ! 37: ! 38: #include "drwatson.h" ! 39: #include "proto.h" ! 40: #include "regs.h" ! 41: ! 42: #include <alphaops.h> ! 43: #include "strings.h" ! 44: ! 45: // we want the definitions of PSR_MODE, etc, which ! 46: // are derived in genalpha.c by Joe for ksalpha.h. ! 47: // They don't exist as separate defines anywhere else. ! 48: // However, if we include ksalpha.h, we get bunches ! 49: // of duplicate definitions. So for now (hack,hack), ! 50: // just make a local copy of the definitions. ! 51: // MBH TODO bugbug - ksalpha.h hack ! 52: // #include <ksalpha.h> ! 53: ! 54: #define PSR_USER_MODE 0x1 ! 55: ! 56: #define PSR_MODE 0x0 // Mode bit in PSR (bit 0) ! 57: #define PSR_MODE_MASK 0x1 // Mask (1 bit) for mode in PSR ! 58: #define PSR_IE 0x1 // Interrupt Enable bit in PSR (bit 1) ! 59: #define PSR_IE_MASK 0x1 // Mask (1 bit) for IE in PSR ! 60: #define PSR_IRQL 0x2 // IRQL in PSR (bit 2) ! 61: #define PSR_IRQL_MASK 0x7 // Mask (2 bits) for IRQL in PSR ! 62: ! 63: ! 64: CONTEXT SavedRegisterContext; ! 65: ! 66: extern ULONG EXPRLastExpression; // from module ntexpr.c ! 67: extern ULONG EXPRLastDump; // from module ntcmd.c ! 68: extern int fControlC; ! 69: ! 70: PUCHAR UserRegs[10] = {0}; ! 71: ! 72: ! 73: ULONG GetIntRegNumber(ULONG); ! 74: BOOLEAN UserRegTest(ULONG); ! 75: BOOLEAN NeedUpper(PDEBUGPACKET, ULONG); ! 76: ! 77: void GetQuadRegValue(PDEBUGPACKET, ULONG , PLARGE_INTEGER ); ! 78: void GetFloatingPointRegValue(PDEBUGPACKET, ULONG , PCONVERTED_DOUBLE); ! 79: void OutputAllRegs(PDEBUGPACKET); ! 80: void OutputOneReg(PDEBUGPACKET, ULONG); ! 81: void GetRegPCValue(PDEBUGPACKET, PULONG); ! 82: PULONG GetRegFPValue(PDEBUGPACKET); ! 83: PUCHAR RegNameFromIndex(ULONG); ! 84: ULONG GetRegString(PUCHAR); ! 85: ! 86: ! 87: ! 88: // ! 89: // This is the length of an instruction, and the instruction ! 90: // to be used in setting a breakpoint (common code writes the ! 91: // breakpoint instruction into the memory stream. ! 92: // ! 93: ULONG cbBrkptLength = 4; ! 94: // these are defined in alphaops.h ! 95: ULONG trapInstr = CALLPAL_OP | BPT_FUNC ; ! 96: ULONG breakInstrs[] = {CALLPAL_OP | BPT_FUNC, ! 97: CALLPAL_OP | KBPT_FUNC, ! 98: CALLPAL_OP | CALLKD_FUNC}; ! 99: ! 100: ULONG ContextType = CONTEXT_FULL; ! 101: ! 102: #define IS_FLOATING_SAVED(Register) ((SAVED_FLOATING_MASK >> Register) & 1L) ! 103: #define IS_INTEGER_SAVED(Register) ((SAVED_INTEGER_MASK >> Register) & 1L) ! 104: ! 105: ! 106: // ! 107: // Define saved register masks. ! 108: ! 109: #define SAVED_FLOATING_MASK 0xfff00000 // saved floating registers ! 110: #define SAVED_INTEGER_MASK 0xf3ffff02 // saved integer registers ! 111: ! 112: ! 113: // ! 114: // Instruction opcode values are defined in alphaops.h ! 115: // ! 116: ! 117: // ! 118: // Define stack register and zero register numbers. ! 119: // ! 120: ! 121: #define RA 0x1a // integer register 26 ! 122: #define SP 0x1e // integer register 30 ! 123: #define ZERO 0x1f // integer register 31 ! 124: ! 125: // ! 126: // Some Alpha specific register names ! 127: // ! 128: ! 129: #define FP 0x0f // integer register 15 ! 130: #define GP 0x1d // integer register 29 ! 131: ! 132: ! 133: // ! 134: // This parallels ntreg.h ! 135: // ! 136: ! 137: PUCHAR pszReg[] = { ! 138: szF0, szF1, szF2, szF3, szF4, szF5, szF6, szF7, ! 139: szF8, szF9, szF10, szF11, szF12, szF13, szF14, szF15, ! 140: szF16, szF17, szF18, szF19, szF20, szF21, szF22, szF23, ! 141: szF24, szF25, szF26, szF27, szF28, szF29, szF30, szF31, ! 142: ! 143: szR0, szR1, szR2, szR3, szR4, szR5, szR6, szR7, ! 144: szR8, szR9, szR10, szR11, szR12, szR13, szR14, szR15, ! 145: szR16, szR17, szR18, szR19, szR20, szR21, szR22, szR23, ! 146: szR24, szR25, szR26, szR27, szR28, szR29, szR30, szR31, ! 147: ! 148: szFpcr, szSoftFpcr, szFir, szPsr, //szIE, ! 149: ! 150: szFlagMode, szFlagIe, szFlagIrql, ! 151: // ! 152: // Currently assuming this is right since shadows alpha.h; ! 153: // but know that alpha.h flag's are wrong. ! 154: // ! 155: szEaPReg, szExpPReg, szRaPReg, szGPReg, // psuedo-registers ! 156: szU0Preg, szU1Preg, szU2Preg, szU3Preg, szU4Preg, ! 157: szU5Preg, szU6Preg, szU7Preg, szU8Preg, szU9Preg ! 158: }; ! 159: ! 160: #define REGNAMESIZE sizeof(pszReg) / sizeof(PUCHAR) ! 161: ! 162: // ! 163: // from ntsdp.h: ULONG RegIndex, Shift, Mask; ! 164: // PSR & IE definitions are from ksalpha.h ! 165: // which is generated automatically. ! 166: // Steal from \\bbox2\alphado\nt\public\sdk\inc\ksalpha.h ! 167: // NB: our masks are already shifted: ! 168: // ! 169: struct Reg { ! 170: char *psz; ! 171: ULONG value; ! 172: }; ! 173: ! 174: struct SubReg { ! 175: ULONG regindex; ! 176: ULONG shift; ! 177: ULONG mask; ! 178: }; ! 179: ! 180: struct SubReg subregname[] = { ! 181: { REGPSR, PSR_MODE, PSR_MODE_MASK }, ! 182: { REGPSR, PSR_IE, PSR_IE_MASK }, ! 183: { REGPSR, PSR_IRQL, PSR_IRQL_MASK }, ! 184: }; ! 185: ! 186: ! 187: /*** UserRegTest - test if index is a user-defined register ! 188: * ! 189: * Purpose: ! 190: * Test if register is user-defined for upper routines. ! 191: * ! 192: * Input: ! 193: * index - index of register ! 194: * ! 195: * Returns: ! 196: * TRUE if user-defined register, else FALSE ! 197: * ! 198: *************************************************************************/ ! 199: ! 200: BOOLEAN UserRegTest (ULONG index) ! 201: { ! 202: return (BOOLEAN)(index >= PREGU0 && index <= PREGU12); ! 203: } ! 204: ! 205: ! 206: ! 207: /*** GetRegFlagValue - get register or flag value ! 208: * ! 209: * Purpose: ! 210: * Return the value of the specified register or flag. ! 211: * This routine calls GetRegValue to get the register ! 212: * value and shifts and masks appropriately to extract a ! 213: * flag value. ! 214: * ! 215: * Input: ! 216: * regnum - register or flag specification ! 217: * ! 218: * Returns: ! 219: * Value of register or flag. ! 220: ! 221: *************************************************************************/ ! 222: ! 223: ULONG GetRegFlagValue (PDEBUGPACKET dp, ULONG regnum) ! 224: { ! 225: ULONG value; ! 226: ! 227: if (regnum < FLAGBASE || regnum >= PREGBASE) ! 228: value = GetRegValue(dp, regnum); ! 229: else { ! 230: regnum -= FLAGBASE; ! 231: value = GetRegValue(dp, subregname[regnum].regindex); ! 232: value = (value >> subregname[regnum].shift) & subregname[regnum].mask; ! 233: } ! 234: return value; ! 235: } ! 236: ! 237: BOOLEAN NeedUpper(PDEBUGPACKET dp, ULONG index) ! 238: { ! 239: ULONG LowPart, HighPart; ! 240: ! 241: LowPart = *(&dp->tctx->context.FltF0 + index); ! 242: HighPart = *(&dp->tctx->context.HighFltF0 + index); ! 243: ! 244: // ! 245: // if the high bit of the low part is set, then the ! 246: // high part must be all ones, else it must be zero. ! 247: // ! 248: if (LowPart & (1<<31) ) { ! 249: ! 250: if (HighPart != 0xffffffff) ! 251: return TRUE; ! 252: else ! 253: return FALSE; ! 254: } else { ! 255: ! 256: if (HighPart != 0) ! 257: return TRUE; ! 258: else ! 259: return FALSE; ! 260: } ! 261: } ! 262: ! 263: /*** GetRegValue - get register value ! 264: * ! 265: * Purpose: ! 266: * Returns the value of the register from the processor ! 267: * context structure. ! 268: * ! 269: * Input: ! 270: * regnum - register specification ! 271: * ! 272: * Returns: ! 273: * value of the register from the context structure ! 274: * ! 275: *************************************************************************/ ! 276: ! 277: ULONG GetRegValue (PDEBUGPACKET dp, ULONG regnum) ! 278: { ! 279: return *(&dp->tctx->context.FltF0 + regnum); ! 280: } ! 281: ! 282: void GetQuadRegValue(PDEBUGPACKET dp, ULONG regnum, PLARGE_INTEGER pli) ! 283: { ! 284: pli->LowPart = *(&dp->tctx->context.FltF0 + regnum); ! 285: pli->HighPart = *(&dp->tctx->context.HighFltF0 + regnum); ! 286: } ! 287: ! 288: void ! 289: GetFloatingPointRegValue(PDEBUGPACKET dp, ULONG regnum, PCONVERTED_DOUBLE dv) ! 290: { ! 291: dv->li.LowPart = *(&dp->tctx->context.FltF0 + regnum); ! 292: dv->li.HighPart = *(&dp->tctx->context.HighFltF0 + regnum); ! 293: ! 294: } ! 295: ! 296: /*** GetIntRegNumber - Get a register number ! 297: * ! 298: * ! 299: * Purpose: ! 300: * Get a register number, from an index value. ! 301: * There are places where we want integers to be ! 302: * numbered from 0-31, and this converts into ! 303: * a CONTEXT structure. ! 304: * ! 305: * Input: ! 306: * index: integer register number, between 0 and 31 ! 307: * ! 308: * Output: ! 309: * regnum: offset into the CONTEXT structure ! 310: * ! 311: * Exceptions: ! 312: * None ! 313: * ! 314: * Notes: ! 315: * This is dependent on the CONTEXT structure ! 316: * ! 317: ******************************************************************/ ! 318: ! 319: ULONG GetIntRegNumber (ULONG index) ! 320: { ! 321: /* ! 322: if (index == 26) { ! 323: return(REGRA); ! 324: } ! 325: ! 326: if (index < 26) { ! 327: return(REGBASE + index); ! 328: } ! 329: if (index > 26) { ! 330: return(REGBASE + index - 1); ! 331: } ! 332: */ ! 333: return(REGBASE + index); ! 334: } ! 335: ! 336: ! 337: ULONG GetRegString (PUCHAR pszString) ! 338: { ! 339: ULONG count; ! 340: ! 341: for (count = 0; count < REGNAMESIZE; count++) ! 342: if (!strcmp(pszString, pszReg[count])) ! 343: return count; ! 344: return 0xffffffff; ! 345: } ! 346: ! 347: void GetRegPCValue (PDEBUGPACKET dp, PULONG Address) ! 348: { ! 349: ! 350: *Address = GetRegValue(dp, REGFIR); ! 351: return; ! 352: } ! 353: ! 354: PULONG GetRegFPValue (PDEBUGPACKET dp) ! 355: { ! 356: static ULONG addrFP; ! 357: ! 358: addrFP = GetRegValue(dp, FP_REG); ! 359: return &addrFP; ! 360: } ! 361: ! 362: /*** OutputAllRegs - output all registers and present instruction ! 363: * ! 364: * Purpose: ! 365: * Function of "r" command. ! 366: * ! 367: * To output the current register state of the processor. ! 368: * All integer registers are output as well as processor status ! 369: * registers. Important flag fields are also output separately. ! 370: * OutDisCurrent is called to output the current instruction(s). ! 371: * ! 372: * Input: ! 373: * None. ! 374: * ! 375: * Output: ! 376: * None. ! 377: * ! 378: *************************************************************************/ ! 379: ! 380: void OutputAllRegs(PDEBUGPACKET dp) ! 381: { ! 382: int regindex; ! 383: int regnumber; ! 384: LARGE_INTEGER qv; ! 385: ! 386: ! 387: for (regindex = 0; regindex < 32; regindex++) { ! 388: ! 389: regnumber = GetIntRegNumber(regindex); ! 390: lprintfs("%4s=%08lx", pszReg[regnumber], ! 391: GetRegValue(dp, regnumber)); ! 392: ! 393: if (NeedUpper(dp, regnumber)) ! 394: lprintfs("*"); ! 395: else lprintfs(" "); ! 396: ! 397: if (regindex % 4 == 3) ! 398: lprintfs("\r\n"); ! 399: else lprintfs(" "); ! 400: } ! 401: // ! 402: // print out the fpcr as 64 bits regardless, ! 403: // and the FIR and Fpcr's - assuming we know they follow ! 404: // the floating and integer registers. ! 405: // ! 406: ! 407: regnumber = GetIntRegNumber(32); // Fpcr ! 408: GetQuadRegValue(dp, regnumber, &qv); ! 409: lprintfs("%4s=%08lx%08lx\t", pszReg[regnumber], ! 410: qv.HighPart, qv.LowPart); ! 411: ! 412: regnumber = GetIntRegNumber(33); // Soft Fpcr ! 413: GetQuadRegValue(dp, regnumber, &qv); ! 414: lprintfs("%4s=%08lx%08lx\t", pszReg[regnumber], ! 415: qv.HighPart, qv.LowPart); ! 416: ! 417: regnumber = GetIntRegNumber(34); // Fir ! 418: lprintfs("%4s=%08lx\r\n", pszReg[regnumber], ! 419: GetRegValue(dp, regnumber)); ! 420: ! 421: regnumber = GetIntRegNumber(35); // Psr ! 422: lprintfs("%4s=%08lx\r\n", pszReg[regnumber], ! 423: GetRegValue(dp, regnumber)); ! 424: ! 425: lprintfs("mode=%1lx ie=%1lx irql=%1lx \r\n", ! 426: GetRegFlagValue(dp, FLAGMODE), ! 427: GetRegFlagValue(dp, FLAGIE), ! 428: GetRegFlagValue(dp, FLAGIRQL)); ! 429: } ! 430: ! 431: /*** OutputOneReg - output one register value ! 432: * ! 433: * Purpose: ! 434: * Function for the "r <regname>" command. ! 435: * ! 436: * Output the value for the specified register or flag. ! 437: * ! 438: * Input: ! 439: * regnum - register or flag specification ! 440: * ! 441: * Output: ! 442: * None. ! 443: * ! 444: *************************************************************************/ ! 445: ! 446: void OutputOneReg (PDEBUGPACKET dp, ULONG regnum) ! 447: { ! 448: ULONG value; ! 449: ! 450: value = GetRegFlagValue(dp, regnum); ! 451: if (regnum < FLAGBASE) { ! 452: lprintfs("%08lx\r\n", value); ! 453: if (NeedUpper(dp, regnum)) ! 454: lprintf("*"); ! 455: } ! 456: else ! 457: lprintfs("%lx\r\n", value); ! 458: } ! 459: ! 460: PUCHAR RegNameFromIndex (ULONG index) ! 461: { ! 462: return pszReg[index]; ! 463: } ! 464: ! 465:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.