2 * Debugger register handling
4 * Copyright 1995 Alexandre Julliard
12 /***********************************************************************
15 * Set a register value.
17 void DEBUG_SetRegister( enum debug_regs reg
, int val
)
22 case REG_EAX
: DEBUG_context
.Eax
= val
; break;
23 case REG_EBX
: DEBUG_context
.Ebx
= val
; break;
24 case REG_ECX
: DEBUG_context
.Ecx
= val
; break;
25 case REG_EDX
: DEBUG_context
.Edx
= val
; break;
26 case REG_ESI
: DEBUG_context
.Esi
= val
; break;
27 case REG_EDI
: DEBUG_context
.Edi
= val
; break;
28 case REG_EBP
: DEBUG_context
.Ebp
= val
; break;
29 case REG_EFL
: DEBUG_context
.EFlags
= val
; break;
30 case REG_EIP
: DEBUG_context
.Eip
= val
; break;
31 case REG_ESP
: DEBUG_context
.Esp
= val
; break;
32 case REG_CS
: DEBUG_context
.SegCs
= val
; break;
33 case REG_DS
: DEBUG_context
.SegDs
= val
; break;
34 case REG_ES
: DEBUG_context
.SegEs
= val
; break;
35 case REG_SS
: DEBUG_context
.SegSs
= val
; break;
36 case REG_FS
: DEBUG_context
.SegFs
= val
; break;
37 case REG_GS
: DEBUG_context
.SegGs
= val
; break;
38 #define SET_LOW_WORD(dw,lw) ((dw) = ((dw) & 0xFFFF0000) | LOWORD(lw))
39 case REG_AX
: SET_LOW_WORD(DEBUG_context
.Eax
,val
); break;
40 case REG_BX
: SET_LOW_WORD(DEBUG_context
.Ebx
,val
); break;
41 case REG_CX
: SET_LOW_WORD(DEBUG_context
.Ecx
,val
); break;
42 case REG_DX
: SET_LOW_WORD(DEBUG_context
.Edx
,val
); break;
43 case REG_SI
: SET_LOW_WORD(DEBUG_context
.Esi
,val
); break;
44 case REG_DI
: SET_LOW_WORD(DEBUG_context
.Edi
,val
); break;
45 case REG_BP
: SET_LOW_WORD(DEBUG_context
.Ebp
,val
); break;
46 case REG_FL
: SET_LOW_WORD(DEBUG_context
.EFlags
,val
); break;
47 case REG_IP
: SET_LOW_WORD(DEBUG_context
.Eip
,val
); break;
48 case REG_SP
: SET_LOW_WORD(DEBUG_context
.Esp
,val
); break;
55 int DEBUG_PrintRegister(enum debug_regs reg
)
61 case REG_EAX
: val
= "%%eax"; break;
62 case REG_EBX
: val
= "%%ebx"; break;
63 case REG_ECX
: val
= "%%ecx"; break;
64 case REG_EDX
: val
= "%%edx"; break;
65 case REG_ESI
: val
= "%%esi"; break;
66 case REG_EDI
: val
= "%%edi"; break;
67 case REG_EBP
: val
= "%%ebp"; break;
68 case REG_EFL
: val
= "%%efl"; break;
69 case REG_EIP
: val
= "%%eip"; break;
70 case REG_ESP
: val
= "%%esp"; break;
71 case REG_AX
: val
= "%%ax"; break;
72 case REG_BX
: val
= "%%bx"; break;
73 case REG_CX
: val
= "%%cx"; break;
74 case REG_DX
: val
= "%%dx"; break;
75 case REG_SI
: val
= "%%si"; break;
76 case REG_DI
: val
= "%%di"; break;
77 case REG_BP
: val
= "%%bp"; break;
78 case REG_FL
: val
= "%%fl"; break;
79 case REG_IP
: val
= "%%ip"; break;
80 case REG_SP
: val
= "%%sp"; break;
81 case REG_CS
: val
= "%%cs"; break;
82 case REG_DS
: val
= "%%ds"; break;
83 case REG_ES
: val
= "%%es"; break;
84 case REG_SS
: val
= "%%ss"; break;
85 case REG_FS
: val
= "%%fs"; break;
86 case REG_GS
: val
= "%%gs"; break;
88 if (val
) DEBUG_Printf(DBG_CHN_MESG
, val
);
95 /***********************************************************************
98 * Get a register value.
100 int DEBUG_GetRegister( enum debug_regs reg
)
105 case REG_EAX
: return DEBUG_context
.Eax
;
106 case REG_EBX
: return DEBUG_context
.Ebx
;
107 case REG_ECX
: return DEBUG_context
.Ecx
;
108 case REG_EDX
: return DEBUG_context
.Edx
;
109 case REG_ESI
: return DEBUG_context
.Esi
;
110 case REG_EDI
: return DEBUG_context
.Edi
;
111 case REG_EBP
: return DEBUG_context
.Ebp
;
112 case REG_EFL
: return DEBUG_context
.EFlags
;
113 case REG_EIP
: return DEBUG_context
.Eip
;
114 case REG_ESP
: return DEBUG_context
.Esp
;
115 case REG_CS
: return DEBUG_context
.SegCs
;
116 case REG_DS
: return DEBUG_context
.SegDs
;
117 case REG_ES
: return DEBUG_context
.SegEs
;
118 case REG_SS
: return DEBUG_context
.SegSs
;
119 case REG_FS
: return DEBUG_context
.SegFs
;
120 case REG_GS
: return DEBUG_context
.SegGs
;
121 case REG_AX
: return LOWORD(DEBUG_context
.Eax
);
122 case REG_BX
: return LOWORD(DEBUG_context
.Ebx
);
123 case REG_CX
: return LOWORD(DEBUG_context
.Ecx
);
124 case REG_DX
: return LOWORD(DEBUG_context
.Edx
);
125 case REG_SI
: return LOWORD(DEBUG_context
.Esi
);
126 case REG_DI
: return LOWORD(DEBUG_context
.Edi
);
127 case REG_BP
: return LOWORD(DEBUG_context
.Ebp
);
128 case REG_FL
: return LOWORD(DEBUG_context
.EFlags
);
129 case REG_IP
: return LOWORD(DEBUG_context
.Eip
);
130 case REG_SP
: return LOWORD(DEBUG_context
.Esp
);
133 return 0; /* should not happen */
137 /***********************************************************************
140 * Return Flag String.
142 char *DEBUG_Flags( DWORD flag
, char *buf
)
146 strcpy( buf
, " - 00 - - - " );
147 pt
= buf
+ strlen( buf
);
148 if ( buf
>= pt
-- ) return( buf
);
149 if ( flag
& 0x00000001 ) *pt
= 'C'; /* Carry Falg */
150 if ( buf
>= pt
-- ) return( buf
);
151 if ( flag
& 0x00000002 ) *pt
= '1';
152 if ( buf
>= pt
-- ) return( buf
);
153 if ( flag
& 0x00000004 ) *pt
= 'P'; /* Parity Flag */
154 if ( buf
>= pt
-- ) return( buf
);
155 if ( flag
& 0x00000008 ) *pt
= '-';
156 if ( buf
>= pt
-- ) return( buf
);
157 if ( flag
& 0x00000010 ) *pt
= 'A'; /* Auxiliary Carry Flag */
158 if ( buf
>= pt
-- ) return( buf
);
159 if ( flag
& 0x00000020 ) *pt
= '-';
160 if ( buf
>= pt
-- ) return( buf
);
161 if ( flag
& 0x00000040 ) *pt
= 'Z'; /* Zero Flag */
162 if ( buf
>= pt
-- ) return( buf
);
163 if ( flag
& 0x00000080 ) *pt
= 'S'; /* Sign Flag */
164 if ( buf
>= pt
-- ) return( buf
);
165 if ( flag
& 0x00000100 ) *pt
= 'T'; /* Trap/Trace Flag */
166 if ( buf
>= pt
-- ) return( buf
);
167 if ( flag
& 0x00000200 ) *pt
= 'I'; /* Interupt Enable Flag */
168 if ( buf
>= pt
-- ) return( buf
);
169 if ( flag
& 0x00000400 ) *pt
= 'D'; /* Direction Indicator */
170 if ( buf
>= pt
-- ) return( buf
);
171 if ( flag
& 0x00000800 ) *pt
= 'O'; /* Overflow Flag */
172 if ( buf
>= pt
-- ) return( buf
);
173 if ( flag
& 0x00001000 ) *pt
= '1'; /* I/O Privilage Level */
174 if ( buf
>= pt
-- ) return( buf
);
175 if ( flag
& 0x00002000 ) *pt
= '1'; /* I/O Privilage Level */
176 if ( buf
>= pt
-- ) return( buf
);
177 if ( flag
& 0x00004000 ) *pt
= 'N'; /* Nested Task Flag */
178 if ( buf
>= pt
-- ) return( buf
);
179 if ( flag
& 0x00008000 ) *pt
= '-';
180 if ( buf
>= pt
-- ) return( buf
);
181 if ( flag
& 0x00010000 ) *pt
= 'R'; /* Resume Flag */
182 if ( buf
>= pt
-- ) return( buf
);
183 if ( flag
& 0x00020000 ) *pt
= 'V'; /* Vritual Mode Flag */
184 if ( buf
>= pt
-- ) return( buf
);
185 if ( flag
& 0x00040000 ) *pt
= 'a'; /* Alignment Check Flag */
186 if ( buf
>= pt
-- ) return( buf
);
191 /***********************************************************************
192 * DEBUG_InfoRegisters
194 * Display registers information.
196 void DEBUG_InfoRegisters(void)
198 DEBUG_Printf(DBG_CHN_MESG
,"Register dump:\n");
201 /* First get the segment registers out of the way */
202 DEBUG_Printf( DBG_CHN_MESG
," CS:%04x SS:%04x DS:%04x ES:%04x FS:%04x GS:%04x",
203 (WORD
)DEBUG_context
.SegCs
, (WORD
)DEBUG_context
.SegSs
,
204 (WORD
)DEBUG_context
.SegDs
, (WORD
)DEBUG_context
.SegEs
,
205 (WORD
)DEBUG_context
.SegFs
, (WORD
)DEBUG_context
.SegGs
);
206 if (DEBUG_CurrThread
->dbg_mode
== 16)
210 DEBUG_Printf( DBG_CHN_MESG
,"\n IP:%04x SP:%04x BP:%04x FLAGS:%04x(%s)\n",
211 LOWORD(DEBUG_context
.Eip
), LOWORD(DEBUG_context
.Esp
),
212 LOWORD(DEBUG_context
.Ebp
), LOWORD(DEBUG_context
.EFlags
),
213 DEBUG_Flags(LOWORD(DEBUG_context
.EFlags
), flag
));
214 DEBUG_Printf( DBG_CHN_MESG
," AX:%04x BX:%04x CX:%04x DX:%04x SI:%04x DI:%04x\n",
215 LOWORD(DEBUG_context
.Eax
), LOWORD(DEBUG_context
.Ebx
),
216 LOWORD(DEBUG_context
.Ecx
), LOWORD(DEBUG_context
.Edx
),
217 LOWORD(DEBUG_context
.Esi
), LOWORD(DEBUG_context
.Edi
) );
219 else /* 32-bit mode */
223 DEBUG_Printf( DBG_CHN_MESG
, "\n EIP:%08lx ESP:%08lx EBP:%08lx EFLAGS:%08lx(%s)\n",
224 DEBUG_context
.Eip
, DEBUG_context
.Esp
,
225 DEBUG_context
.Ebp
, DEBUG_context
.EFlags
,
226 DEBUG_Flags(DEBUG_context
.EFlags
, flag
));
227 DEBUG_Printf( DBG_CHN_MESG
, " EAX:%08lx EBX:%08lx ECX:%08lx EDX:%08lx\n",
228 DEBUG_context
.Eax
, DEBUG_context
.Ebx
,
229 DEBUG_context
.Ecx
, DEBUG_context
.Edx
);
230 DEBUG_Printf( DBG_CHN_MESG
, " ESI:%08lx EDI:%08lx\n",
231 DEBUG_context
.Esi
, DEBUG_context
.Edi
);
237 /***********************************************************************
238 * DEBUG_ValidateRegisters
240 * Make sure all registers have a correct value for returning from
241 * the signal handler.
243 BOOL
DEBUG_ValidateRegisters(void)
246 if (DEBUG_context
.EFlags
& V86_FLAG
) return TRUE
;
249 /* Check that a selector is a valid ring-3 LDT selector, or a NULL selector */
250 #define CHECK_SEG(seg,name) \
251 if (((seg) & ~3) && ((((seg) & 7) != 7) || !DEBUG_IsSelector(seg))) { \
252 DEBUG_Printf( DBG_CHN_MESG, "*** Invalid value for %s register: %04x\n", \
253 (name), (WORD)(seg) ); \
259 if (CS_reg(DEBUG_context
) != cs
) CHECK_SEG(CS_reg(DEBUG_context
), "CS");
260 if (SS_reg(DEBUG_context
) != ds
) CHECK_SEG(SS_reg(DEBUG_context
), "SS");
261 if (DS_reg(DEBUG_context
) != ds
) CHECK_SEG(DS_reg(DEBUG_context
), "DS");
262 if (ES_reg(DEBUG_context
) != ds
) CHECK_SEG(ES_reg(DEBUG_context
), "ES");
263 if (FS_reg(DEBUG_context
) != ds
) CHECK_SEG(FS_reg(DEBUG_context
), "FS");
264 if (GS_reg(DEBUG_context
) != ds
) CHECK_SEG(GS_reg(DEBUG_context
), "GS");
267 /* Check that CS and SS are not NULL */
269 if (!(DEBUG_context
.SegCs
& ~3))
271 DEBUG_Printf( DBG_CHN_MESG
, "*** Invalid value for CS register: %04x\n",
272 (WORD
)DEBUG_context
.SegCs
);
275 if (!(DEBUG_context
.SegSs
& ~3))
277 DEBUG_Printf( DBG_CHN_MESG
, "*** Invalid value for SS register: %04x\n",
278 (WORD
)DEBUG_context
.SegSs
);