|
|
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: Wesley Witt (wesw) 1-May-1993 (ported from ntsd)
16:
17: Environment:
18:
19: User Mode
20:
21: --*/
22:
23: #include <windows.h>
24: #include <stdlib.h>
25: #include <stdio.h>
26: #include <string.h>
27:
28: #include "drwatson.h"
29: #include "proto.h"
30: #include "regs.h"
31:
32: PUCHAR UserRegs[10] = {0};
33:
34:
35: ULONG GetRegFlagValue (PDEBUGPACKET dp, ULONG regnum);
36: ULONG GetRegValue (PDEBUGPACKET dp, ULONG regnum);
37: ULONG GetRegName (void);
38: ULONG GetRegString (PUCHAR pszString);
39: void GetRegPCValue (PDEBUGPACKET dp, PULONG Address);
40: PULONG GetRegFPValue (PDEBUGPACKET dp);
41: void OutputAllRegs(PDEBUGPACKET dp);
42: void OutputOneReg (PDEBUGPACKET dp, ULONG regnum);
43: PUCHAR RegNameFromIndex (ULONG index);
44:
45:
46:
47:
48: static ULONG ProcessorType = 0;
49: ULONG cbBrkptLength = 4;
50: ULONG trapInstr = 0x0016000dL; // break 0x16 for brkpts
51: ULONG ContextType = CONTEXT_CONTROL | CONTEXT_INTEGER;
52:
53: //
54: // Define MIPS nonvolatile register test macros.
55: //
56:
57: #define IS_FLOATING_SAVED(Register) ((SAVED_FLOATING_MASK >> Register) & 1L)
58: #define IS_INTEGER_SAVED(Register) ((SAVED_INTEGER_MASK >> Register) & 1L)
59:
60: //
61: // Define MIPS instruction opcode values.
62: //
63:
64: #define ADDIU_OP 0x9 // add immediate unsigned integer register
65: #define ADDU_OP 0x21 // add unsigned integer register
66: #define JUMP_RA 0x3e00008 // jump indirect return address register
67: #define LUI_OP 0xf // load upper immediate integer register
68: #define SD_OP 0x2f // store double integer register
69: #define SW_OP 0x2b // store word integer register
70: #define SDC1_OP 0x3d // store double floating register
71: #define SWC1_OP 0x39 // store word floating register
72: #define SPEC_OP 0x0 // special opcode - use function field
73: #define SUBU_OP 0x23 // subtract unsigned integer register
74:
75: //
76: // Define stack register and zero register numbers.
77: //
78:
79: #define RA 0x1f // integer register 31
80: #define SP 0x1d // integer register 29
81: #define ZERO 0x0 // integer register 0
82:
83: //
84: // Define saved register masks.
85: //
86:
87: #define SAVED_FLOATING_MASK 0xfff00000 // saved floating registers
88: #define SAVED_INTEGER_MASK 0xf3ffff02 // saved integer registers
89:
90:
91: UCHAR szF0[] = "f0";
92: UCHAR szF1[] = "f1";
93: UCHAR szF2[] = "f2";
94: UCHAR szF3[] = "f3";
95: UCHAR szF4[] = "f4";
96: UCHAR szF5[] = "f5";
97: UCHAR szF6[] = "f6";
98: UCHAR szF7[] = "f7";
99: UCHAR szF8[] = "f8";
100: UCHAR szF9[] = "f9";
101: UCHAR szF10[] = "f10";
102: UCHAR szF11[] = "f11";
103: UCHAR szF12[] = "f12";
104: UCHAR szF13[] = "f13";
105: UCHAR szF14[] = "f14";
106: UCHAR szF15[] = "f15";
107: UCHAR szF16[] = "f16";
108: UCHAR szF17[] = "f17";
109: UCHAR szF18[] = "f18";
110: UCHAR szF19[] = "f19";
111: UCHAR szF20[] = "f20";
112: UCHAR szF21[] = "f21";
113: UCHAR szF22[] = "f22";
114: UCHAR szF23[] = "f23";
115: UCHAR szF24[] = "f24";
116: UCHAR szF25[] = "f25";
117: UCHAR szF26[] = "f26";
118: UCHAR szF27[] = "f27";
119: UCHAR szF28[] = "f28";
120: UCHAR szF29[] = "f29";
121: UCHAR szF30[] = "f30";
122: UCHAR szF31[] = "f31";
123:
124: UCHAR szR0[] = "zero";
125: UCHAR szR1[] = "at";
126: UCHAR szR2[] = "v0";
127: UCHAR szR3[] = "v1";
128: UCHAR szR4[] = "a0";
129: UCHAR szR5[] = "a1";
130: UCHAR szR6[] = "a2";
131: UCHAR szR7[] = "a3";
132: UCHAR szR8[] = "t0";
133: UCHAR szR9[] = "t1";
134: UCHAR szR10[] = "t2";
135: UCHAR szR11[] = "t3";
136: UCHAR szR12[] = "t4";
137: UCHAR szR13[] = "t5";
138: UCHAR szR14[] = "t6";
139: UCHAR szR15[] = "t7";
140: UCHAR szR16[] = "s0";
141: UCHAR szR17[] = "s1";
142: UCHAR szR18[] = "s2";
143: UCHAR szR19[] = "s3";
144: UCHAR szR20[] = "s4";
145: UCHAR szR21[] = "s5";
146: UCHAR szR22[] = "s6";
147: UCHAR szR23[] = "s7";
148: UCHAR szR24[] = "t8";
149: UCHAR szR25[] = "t9";
150: UCHAR szR26[] = "k0";
151: UCHAR szR27[] = "k1";
152: UCHAR szR28[] = "gp";
153: UCHAR szR29[] = "sp";
154: UCHAR szR30[] = "s8";
155: UCHAR szR31[] = "ra";
156:
157: UCHAR szLo[] = "lo";
158: UCHAR szHi[] = "hi";
159: UCHAR szFsr[] = "fsr";
160: UCHAR szFir[] = "fir";
161: UCHAR szPsr[] = "psr";
162:
163: UCHAR szFlagCu[] = "cu";
164: UCHAR szFlagCu3[] = "cu3";
165: UCHAR szFlagCu2[] = "cu2";
166: UCHAR szFlagCu1[] = "cu1";
167: UCHAR szFlagCu0[] = "cu0";
168: UCHAR szFlagImsk[] = "imsk";
169: UCHAR szFlagInt5[] = "int5";
170: UCHAR szFlagInt4[] = "int4";
171: UCHAR szFlagInt3[] = "int3";
172: UCHAR szFlagInt2[] = "int2";
173: UCHAR szFlagInt1[] = "int1";
174: UCHAR szFlagInt0[] = "int0";
175: UCHAR szFlagSw1[] = "sw1";
176: UCHAR szFlagSw0[] = "sw0";
177: UCHAR szFlagKuo[] = "kuo";
178: UCHAR szFlagIeo[] = "ieo";
179: UCHAR szFlagKup[] = "kup";
180: UCHAR szFlagIep[] = "iep";
181: UCHAR szFlagKuc[] = "kuc";
182: UCHAR szFlagIec[] = "iec";
183: UCHAR szFlagKsu[] = "ksu";
184: UCHAR szFlagErl[] = "erl";
185: UCHAR szFlagExl[] = "exl";
186: UCHAR szFlagIe[] = "ie";
187: UCHAR szFlagFpc[] = "fpc";
188:
189: char szEaPReg[] = "$ea";
190: char szExpPReg[] = "$exp";
191: char szRaPReg[] = "$ra";
192: char szPPReg[] = "$p";
193: char szU0Preg[] = "$u0";
194: char szU1Preg[] = "$u1";
195: char szU2Preg[] = "$u2";
196: char szU3Preg[] = "$u3";
197: char szU4Preg[] = "$u4";
198: char szU5Preg[] = "$u5";
199: char szU6Preg[] = "$u6";
200: char szU7Preg[] = "$u7";
201: char szU8Preg[] = "$u8";
202: char szU9Preg[] = "$u9";
203:
204: PUCHAR pszReg[] = {
205: szF0, szF1, szF2, szF3, szF4, szF5, szF6, szF7,
206: szF8, szF9, szF10, szF11, szF12, szF13, szF14, szF15,
207: szF16, szF17, szF18, szF19, szF20, szF21, szF22, szF23,
208: szF24, szF25, szF26, szF27, szF28, szF29, szF30, szF31,
209:
210: szR0, szR1, szR2, szR3, szR4, szR5, szR6, szR7,
211: szR8, szR9, szR10, szR11, szR12, szR13, szR14, szR15,
212: szR16, szR17, szR18, szR19, szR20, szR21, szR22, szR23,
213: szR24, szR25, szR26, szR27, szR28, szR29, szR30, szR31,
214:
215: szLo, szHi, szFsr, szFir, szPsr,
216:
217: szFlagCu, szFlagCu3, szFlagCu2, szFlagCu1, szFlagCu0,
218: szFlagImsk,
219: szFlagInt5, szFlagInt4, szFlagInt3, szFlagInt2, szFlagInt1, szFlagInt0,
220: szFlagSw1, szFlagSw0,
221: szFlagKuo, szFlagIeo, // R3000 flags
222: szFlagKup, szFlagIep, // ...
223: szFlagKuc, szFlagIec, // ...
224: szFlagKsu, szFlagErl, szFlagExl, szFlagIe, // R4000 flags
225:
226: szFlagFpc, // fl pt condition
227:
228: szEaPReg, szExpPReg, szRaPReg, szPPReg, // psuedo-registers
229: szU0Preg, szU1Preg, szU2Preg, szU3Preg, szU4Preg,
230: szU5Preg, szU6Preg, szU7Preg, szU8Preg, szU9Preg
231: };
232:
233: #define REGNAMESIZE sizeof(pszReg) / sizeof(PUCHAR)
234:
235: struct Reg {
236: char *psz;
237: ULONG value;
238: };
239:
240: struct SubReg {
241: ULONG regindex;
242: ULONG shift;
243: ULONG mask;
244: };
245:
246: struct SubReg subregname[] = {
247: { REGPSR, 28, 0xf }, // CU mask
248: { REGPSR, 31, 1 }, // CU3 flag
249: { REGPSR, 30, 1 }, // CU2 flag
250: { REGPSR, 29, 1 }, // CU1 flag
251: { REGPSR, 28, 1 }, // CU0 flag
252: { REGPSR, 8, 0xff }, // IMSK mask
253: { REGPSR, 15, 1 }, // INT5 - int 5 enable
254: { REGPSR, 14, 1 }, // INT4 - int 4 enable
255: { REGPSR, 13, 1 }, // INT3 - int 3 enable
256: { REGPSR, 12, 1 }, // INT2 - int 2 enable
257: { REGPSR, 11, 1 }, // INT1 - int 1 enable
258: { REGPSR, 10, 1 }, // INT0 - int 0 enable
259: { REGPSR, 9, 1 }, // SW1 - software int 1 enable
260: { REGPSR, 8, 1 }, // SW0 - software int 0 enable
261:
262: // R3000-specific status bits
263:
264: { REGPSR, 5, 1 }, // KUO
265: { REGPSR, 4, 1 }, // IEO
266: { REGPSR, 3, 1 }, // KUP
267: { REGPSR, 2, 1 }, // IEP
268: { REGPSR, 1, 1 }, // KUC
269: { REGPSR, 0, 1 }, // IEC
270:
271: // R4000-specific status bits
272:
273: { REGPSR, 3, 2 }, // KSU
274: { REGPSR, 2, 1 }, // ERL
275: { REGPSR, 1, 1 }, // EXL
276: { REGPSR, 0, 1 }, // IE
277:
278: { REGFSR, 23, 1 } // FPC - floating point condition
279: };
280:
281:
282: /*** UserRegTest - test if index is a user-defined register
283: *
284: * Purpose:
285: * Test if register is user-defined for upper routines.
286: *
287: * Input:
288: * index - index of register
289: *
290: * Returns:
291: * TRUE if user-defined register, else FALSE
292: *
293: *************************************************************************/
294:
295: BOOLEAN
296: UserRegTest (ULONG index)
297: {
298: return (BOOLEAN)(index >= PREGU0 && index <= PREGU9);
299: }
300:
301: /*** GetRegFlagValue - get register or flag value
302: *
303: * Purpose:
304: * Return the value of the specified register or flag.
305: * This routine calls GetRegValue to get the register
306: * value and shifts and masks appropriately to extract a
307: * flag value.
308: *
309: * Input:
310: * regnum - register or flag specification
311: *
312: * Returns:
313: * Value of register or flag.
314:
315: *************************************************************************/
316:
317: ULONG
318: GetRegFlagValue (PDEBUGPACKET dp, ULONG regnum)
319: {
320: ULONG value;
321:
322: if (regnum < FLAGBASE || regnum >= PREGBASE)
323: value = GetRegValue(dp,regnum);
324: else {
325: regnum -= FLAGBASE;
326: value = GetRegValue(dp,subregname[regnum].regindex);
327: value = (value >> subregname[regnum].shift) & subregname[regnum].mask;
328: }
329: return value;
330: }
331:
332: /*** GetRegValue - get register value
333: *
334: * Purpose:
335: * Returns the value of the register from the processor
336: * context structure.
337: *
338: * Input:
339: * regnum - register specification
340: *
341: * Returns:
342: * value of the register from the context structure
343: *
344: *************************************************************************/
345:
346: ULONG
347: GetRegValue (PDEBUGPACKET dp, ULONG regnum)
348: {
349: return *(&dp->tctx->context.FltF0 + regnum);
350: }
351:
352:
353: ULONG
354: GetRegString (PUCHAR pszString)
355: {
356: ULONG count;
357:
358: for (count = 0; count < REGNAMESIZE; count++)
359: if (!strcmp(pszString, pszReg[count]))
360: return count;
361: return (ULONG)-1;
362: }
363:
364: void
365: GetRegPCValue (PDEBUGPACKET dp, PULONG Address)
366: {
367: *Address = GetRegValue(dp,REGFIR);
368: return;
369: }
370:
371: PULONG
372: GetRegFPValue (PDEBUGPACKET dp)
373: {
374: static ULONG addrFP;
375:
376: addrFP = GetRegValue(dp,REGGP);
377: return &addrFP;
378: }
379:
380: /*** OutputAllRegs - output all registers and present instruction
381: *
382: * Purpose:
383: * Function of "r" command.
384: *
385: * To output the current register state of the processor.
386: * All integer registers are output as well as processor status
387: * registers. Important flag fields are also output separately.
388: * OutDisCurrent is called to output the current instruction(s).
389: *
390: * Input:
391: * None.
392: *
393: * Output:
394: * None.
395: *
396: *************************************************************************/
397:
398: void
399: OutputAllRegs(PDEBUGPACKET dp)
400: {
401: int regindex;
402:
403: for (regindex = 1; regindex < 37; regindex++) {
404: if (regindex == 34)
405: lprintfs(" ");
406: else {
407: lprintfs("%s=%08lx", pszReg[regindex + REGBASE],
408: GetRegValue(dp,regindex + REGBASE));
409: if (regindex % 6 == 0)
410: lprintfs("\r\n");
411: else
412: lprintfs(" ");
413: }
414: }
415: lprintfs("cu=%1lx%1lx%1lx%1lx intr(5:0)=%1lx%1lx%1lx%1lx%1lx%1lx ",
416: GetRegFlagValue(dp,FLAGCU3),
417: GetRegFlagValue(dp,FLAGCU2),
418: GetRegFlagValue(dp,FLAGCU1),
419: GetRegFlagValue(dp,FLAGCU0),
420: GetRegFlagValue(dp,FLAGINT5),
421: GetRegFlagValue(dp,FLAGINT4),
422: GetRegFlagValue(dp,FLAGINT3),
423: GetRegFlagValue(dp,FLAGINT2),
424: GetRegFlagValue(dp,FLAGINT1),
425: GetRegFlagValue(dp,FLAGINT0));
426: lprintfs("sw(1:0)=%1lx%1lx ",
427: GetRegFlagValue(dp,FLAGSW1),
428: GetRegFlagValue(dp,FLAGSW0));
429: if (ProcessorType == 0)
430: lprintfs("kuo=%01lx ieo=%01lx kup=%01lx "
431: "iep=%01lx kuc=%01lx iec=%01lx\r\n",
432: GetRegFlagValue(dp,FLAGKUO),
433: GetRegFlagValue(dp,FLAGIEO),
434: GetRegFlagValue(dp,FLAGKUP),
435: GetRegFlagValue(dp,FLAGIEP),
436: GetRegFlagValue(dp,FLAGKUC),
437: GetRegFlagValue(dp,FLAGIEC));
438: else
439: lprintfs("ksu=%01lx erl=%01lx exl=%01lx ie=%01lx\r\n",
440: GetRegFlagValue(dp,FLAGKSU),
441: GetRegFlagValue(dp,FLAGERL),
442: GetRegFlagValue(dp,FLAGEXL),
443: GetRegFlagValue(dp,FLAGIE));
444: lprintfs("\r\n\r\n");
445: }
446:
447: /*** OutputOneReg - output one register value
448: *
449: * Purpose:
450: * Function for the "r <regname>" command.
451: *
452: * Output the value for the specified register or flag.
453: *
454: * Input:
455: * regnum - register or flag specification
456: *
457: * Output:
458: * None.
459: *
460: *************************************************************************/
461:
462: void
463: OutputOneReg (PDEBUGPACKET dp, ULONG regnum)
464: {
465: ULONG value;
466:
467: value = GetRegFlagValue(dp,regnum);
468: if (regnum < FLAGBASE)
469: lprintfs("%08lx\r\n", value);
470: else
471: lprintfs("%lx\r\n", value);
472: }
473:
474: PUCHAR
475: RegNameFromIndex (ULONG index)
476: {
477: return pszReg[index];
478: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.