|
|
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.