GDBserver
|
00001 /* Copyright (C) 2007-2013 Free Software Foundation, Inc. 00002 00003 This file is part of GDB. 00004 00005 This program is free software; you can redistribute it and/or modify 00006 it under the terms of the GNU General Public License as published by 00007 the Free Software Foundation; either version 3 of the License, or 00008 (at your option) any later version. 00009 00010 This program is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 GNU General Public License for more details. 00014 00015 You should have received a copy of the GNU General Public License 00016 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 00017 00018 #include "server.h" 00019 #include "win32-low.h" 00020 #include "i386-low.h" 00021 00022 #ifndef CONTEXT_EXTENDED_REGISTERS 00023 #define CONTEXT_EXTENDED_REGISTERS 0 00024 #endif 00025 00026 #define FCS_REGNUM 27 00027 #define FOP_REGNUM 31 00028 00029 #define FLAG_TRACE_BIT 0x100 00030 00031 #ifdef __x86_64__ 00032 /* Defined in auto-generated file reg-amd64.c. */ 00033 void init_registers_amd64 (void); 00034 extern const struct target_desc *tdesc_amd64; 00035 #else 00036 /* Defined in auto-generated file reg-i386.c. */ 00037 void init_registers_i386 (void); 00038 extern const struct target_desc *tdesc_i386; 00039 #endif 00040 00041 static struct i386_debug_reg_state debug_reg_state; 00042 00043 static int debug_registers_changed = 0; 00044 static int debug_registers_used = 0; 00045 00046 /* Update the inferior's debug register REGNUM from STATE. */ 00047 00048 void 00049 i386_dr_low_set_addr (const struct i386_debug_reg_state *state, int regnum) 00050 { 00051 if (! (regnum >= 0 && regnum <= DR_LASTADDR - DR_FIRSTADDR)) 00052 fatal ("Invalid debug register %d", regnum); 00053 00054 /* debug_reg_state.dr_mirror is already set. 00055 Just notify i386_set_thread_context, i386_thread_added 00056 that the registers need to be updated. */ 00057 debug_registers_changed = 1; 00058 debug_registers_used = 1; 00059 } 00060 00061 CORE_ADDR 00062 i386_dr_low_get_addr (int regnum) 00063 { 00064 gdb_assert (DR_FIRSTADDR <= regnum && regnum <= DR_LASTADDR); 00065 00066 return debug_reg_state.dr_mirror[regnum]; 00067 } 00068 00069 /* Update the inferior's DR7 debug control register from STATE. */ 00070 00071 void 00072 i386_dr_low_set_control (const struct i386_debug_reg_state *state) 00073 { 00074 /* debug_reg_state.dr_control_mirror is already set. 00075 Just notify i386_set_thread_context, i386_thread_added 00076 that the registers need to be updated. */ 00077 debug_registers_changed = 1; 00078 debug_registers_used = 1; 00079 } 00080 00081 unsigned 00082 i386_dr_low_get_control (void) 00083 { 00084 return debug_reg_state.dr_control_mirror; 00085 } 00086 00087 /* Get the value of the DR6 debug status register from the inferior 00088 and record it in STATE. */ 00089 00090 unsigned 00091 i386_dr_low_get_status (void) 00092 { 00093 /* We don't need to do anything here, the last call to thread_rec for 00094 current_event.dwThreadId id has already set it. */ 00095 return debug_reg_state.dr_status_mirror; 00096 } 00097 00098 /* Watchpoint support. */ 00099 00100 static int 00101 i386_insert_point (char type, CORE_ADDR addr, int len) 00102 { 00103 switch (type) 00104 { 00105 case '2': 00106 case '3': 00107 case '4': 00108 return i386_low_insert_watchpoint (&debug_reg_state, 00109 type, addr, len); 00110 default: 00111 /* Unsupported. */ 00112 return 1; 00113 } 00114 } 00115 00116 static int 00117 i386_remove_point (char type, CORE_ADDR addr, int len) 00118 { 00119 switch (type) 00120 { 00121 case '2': 00122 case '3': 00123 case '4': 00124 return i386_low_remove_watchpoint (&debug_reg_state, 00125 type, addr, len); 00126 default: 00127 /* Unsupported. */ 00128 return 1; 00129 } 00130 } 00131 00132 static int 00133 i386_stopped_by_watchpoint (void) 00134 { 00135 return i386_low_stopped_by_watchpoint (&debug_reg_state); 00136 } 00137 00138 static CORE_ADDR 00139 i386_stopped_data_address (void) 00140 { 00141 CORE_ADDR addr; 00142 if (i386_low_stopped_data_address (&debug_reg_state, &addr)) 00143 return addr; 00144 return 0; 00145 } 00146 00147 static void 00148 i386_initial_stuff (void) 00149 { 00150 i386_low_init_dregs (&debug_reg_state); 00151 debug_registers_changed = 0; 00152 debug_registers_used = 0; 00153 } 00154 00155 static void 00156 i386_get_thread_context (win32_thread_info *th, DEBUG_EVENT* current_event) 00157 { 00158 /* Requesting the CONTEXT_EXTENDED_REGISTERS register set fails if 00159 the system doesn't support extended registers. */ 00160 static DWORD extended_registers = CONTEXT_EXTENDED_REGISTERS; 00161 00162 again: 00163 th->context.ContextFlags = (CONTEXT_FULL 00164 | CONTEXT_FLOATING_POINT 00165 | CONTEXT_DEBUG_REGISTERS 00166 | extended_registers); 00167 00168 if (!GetThreadContext (th->h, &th->context)) 00169 { 00170 DWORD e = GetLastError (); 00171 00172 if (extended_registers && e == ERROR_INVALID_PARAMETER) 00173 { 00174 extended_registers = 0; 00175 goto again; 00176 } 00177 00178 error ("GetThreadContext failure %ld\n", (long) e); 00179 } 00180 00181 debug_registers_changed = 0; 00182 00183 if (th->tid == current_event->dwThreadId) 00184 { 00185 /* Copy dr values from the current thread. */ 00186 struct i386_debug_reg_state *dr = &debug_reg_state; 00187 dr->dr_mirror[0] = th->context.Dr0; 00188 dr->dr_mirror[1] = th->context.Dr1; 00189 dr->dr_mirror[2] = th->context.Dr2; 00190 dr->dr_mirror[3] = th->context.Dr3; 00191 dr->dr_status_mirror = th->context.Dr6; 00192 dr->dr_control_mirror = th->context.Dr7; 00193 } 00194 } 00195 00196 static void 00197 i386_set_thread_context (win32_thread_info *th, DEBUG_EVENT* current_event) 00198 { 00199 if (debug_registers_changed) 00200 { 00201 struct i386_debug_reg_state *dr = &debug_reg_state; 00202 th->context.Dr0 = dr->dr_mirror[0]; 00203 th->context.Dr1 = dr->dr_mirror[1]; 00204 th->context.Dr2 = dr->dr_mirror[2]; 00205 th->context.Dr3 = dr->dr_mirror[3]; 00206 /* th->context.Dr6 = dr->dr_status_mirror; 00207 FIXME: should we set dr6 also ?? */ 00208 th->context.Dr7 = dr->dr_control_mirror; 00209 } 00210 00211 SetThreadContext (th->h, &th->context); 00212 } 00213 00214 static void 00215 i386_thread_added (win32_thread_info *th) 00216 { 00217 /* Set the debug registers for the new thread if they are used. */ 00218 if (debug_registers_used) 00219 { 00220 struct i386_debug_reg_state *dr = &debug_reg_state; 00221 th->context.ContextFlags = CONTEXT_DEBUG_REGISTERS; 00222 GetThreadContext (th->h, &th->context); 00223 00224 th->context.Dr0 = dr->dr_mirror[0]; 00225 th->context.Dr1 = dr->dr_mirror[1]; 00226 th->context.Dr2 = dr->dr_mirror[2]; 00227 th->context.Dr3 = dr->dr_mirror[3]; 00228 /* th->context.Dr6 = dr->dr_status_mirror; 00229 FIXME: should we set dr6 also ?? */ 00230 th->context.Dr7 = dr->dr_control_mirror; 00231 00232 SetThreadContext (th->h, &th->context); 00233 th->context.ContextFlags = 0; 00234 } 00235 } 00236 00237 static void 00238 i386_single_step (win32_thread_info *th) 00239 { 00240 th->context.EFlags |= FLAG_TRACE_BIT; 00241 } 00242 00243 #ifndef __x86_64__ 00244 00245 /* An array of offset mappings into a Win32 Context structure. 00246 This is a one-to-one mapping which is indexed by gdb's register 00247 numbers. It retrieves an offset into the context structure where 00248 the 4 byte register is located. 00249 An offset value of -1 indicates that Win32 does not provide this 00250 register in it's CONTEXT structure. In this case regptr will return 00251 a pointer into a dummy register. */ 00252 #define context_offset(x) ((int)&(((CONTEXT *)NULL)->x)) 00253 static const int mappings[] = { 00254 context_offset (Eax), 00255 context_offset (Ecx), 00256 context_offset (Edx), 00257 context_offset (Ebx), 00258 context_offset (Esp), 00259 context_offset (Ebp), 00260 context_offset (Esi), 00261 context_offset (Edi), 00262 context_offset (Eip), 00263 context_offset (EFlags), 00264 context_offset (SegCs), 00265 context_offset (SegSs), 00266 context_offset (SegDs), 00267 context_offset (SegEs), 00268 context_offset (SegFs), 00269 context_offset (SegGs), 00270 context_offset (FloatSave.RegisterArea[0 * 10]), 00271 context_offset (FloatSave.RegisterArea[1 * 10]), 00272 context_offset (FloatSave.RegisterArea[2 * 10]), 00273 context_offset (FloatSave.RegisterArea[3 * 10]), 00274 context_offset (FloatSave.RegisterArea[4 * 10]), 00275 context_offset (FloatSave.RegisterArea[5 * 10]), 00276 context_offset (FloatSave.RegisterArea[6 * 10]), 00277 context_offset (FloatSave.RegisterArea[7 * 10]), 00278 context_offset (FloatSave.ControlWord), 00279 context_offset (FloatSave.StatusWord), 00280 context_offset (FloatSave.TagWord), 00281 context_offset (FloatSave.ErrorSelector), 00282 context_offset (FloatSave.ErrorOffset), 00283 context_offset (FloatSave.DataSelector), 00284 context_offset (FloatSave.DataOffset), 00285 context_offset (FloatSave.ErrorSelector), 00286 /* XMM0-7 */ 00287 context_offset (ExtendedRegisters[10 * 16]), 00288 context_offset (ExtendedRegisters[11 * 16]), 00289 context_offset (ExtendedRegisters[12 * 16]), 00290 context_offset (ExtendedRegisters[13 * 16]), 00291 context_offset (ExtendedRegisters[14 * 16]), 00292 context_offset (ExtendedRegisters[15 * 16]), 00293 context_offset (ExtendedRegisters[16 * 16]), 00294 context_offset (ExtendedRegisters[17 * 16]), 00295 /* MXCSR */ 00296 context_offset (ExtendedRegisters[24]) 00297 }; 00298 #undef context_offset 00299 00300 #else /* __x86_64__ */ 00301 00302 #define context_offset(x) (offsetof (CONTEXT, x)) 00303 static const int mappings[] = 00304 { 00305 context_offset (Rax), 00306 context_offset (Rbx), 00307 context_offset (Rcx), 00308 context_offset (Rdx), 00309 context_offset (Rsi), 00310 context_offset (Rdi), 00311 context_offset (Rbp), 00312 context_offset (Rsp), 00313 context_offset (R8), 00314 context_offset (R9), 00315 context_offset (R10), 00316 context_offset (R11), 00317 context_offset (R12), 00318 context_offset (R13), 00319 context_offset (R14), 00320 context_offset (R15), 00321 context_offset (Rip), 00322 context_offset (EFlags), 00323 context_offset (SegCs), 00324 context_offset (SegSs), 00325 context_offset (SegDs), 00326 context_offset (SegEs), 00327 context_offset (SegFs), 00328 context_offset (SegGs), 00329 context_offset (FloatSave.FloatRegisters[0]), 00330 context_offset (FloatSave.FloatRegisters[1]), 00331 context_offset (FloatSave.FloatRegisters[2]), 00332 context_offset (FloatSave.FloatRegisters[3]), 00333 context_offset (FloatSave.FloatRegisters[4]), 00334 context_offset (FloatSave.FloatRegisters[5]), 00335 context_offset (FloatSave.FloatRegisters[6]), 00336 context_offset (FloatSave.FloatRegisters[7]), 00337 context_offset (FloatSave.ControlWord), 00338 context_offset (FloatSave.StatusWord), 00339 context_offset (FloatSave.TagWord), 00340 context_offset (FloatSave.ErrorSelector), 00341 context_offset (FloatSave.ErrorOffset), 00342 context_offset (FloatSave.DataSelector), 00343 context_offset (FloatSave.DataOffset), 00344 context_offset (FloatSave.ErrorSelector) 00345 /* XMM0-7 */ , 00346 context_offset (Xmm0), 00347 context_offset (Xmm1), 00348 context_offset (Xmm2), 00349 context_offset (Xmm3), 00350 context_offset (Xmm4), 00351 context_offset (Xmm5), 00352 context_offset (Xmm6), 00353 context_offset (Xmm7), 00354 context_offset (Xmm8), 00355 context_offset (Xmm9), 00356 context_offset (Xmm10), 00357 context_offset (Xmm11), 00358 context_offset (Xmm12), 00359 context_offset (Xmm13), 00360 context_offset (Xmm14), 00361 context_offset (Xmm15), 00362 /* MXCSR */ 00363 context_offset (FloatSave.MxCsr) 00364 }; 00365 #undef context_offset 00366 00367 #endif /* __x86_64__ */ 00368 00369 /* Fetch register from gdbserver regcache data. */ 00370 static void 00371 i386_fetch_inferior_register (struct regcache *regcache, 00372 win32_thread_info *th, int r) 00373 { 00374 char *context_offset = (char *) &th->context + mappings[r]; 00375 00376 long l; 00377 if (r == FCS_REGNUM) 00378 { 00379 l = *((long *) context_offset) & 0xffff; 00380 supply_register (regcache, r, (char *) &l); 00381 } 00382 else if (r == FOP_REGNUM) 00383 { 00384 l = (*((long *) context_offset) >> 16) & ((1 << 11) - 1); 00385 supply_register (regcache, r, (char *) &l); 00386 } 00387 else 00388 supply_register (regcache, r, context_offset); 00389 } 00390 00391 /* Store a new register value into the thread context of TH. */ 00392 static void 00393 i386_store_inferior_register (struct regcache *regcache, 00394 win32_thread_info *th, int r) 00395 { 00396 char *context_offset = (char *) &th->context + mappings[r]; 00397 collect_register (regcache, r, context_offset); 00398 } 00399 00400 static const unsigned char i386_win32_breakpoint = 0xcc; 00401 #define i386_win32_breakpoint_len 1 00402 00403 static void 00404 i386_arch_setup (void) 00405 { 00406 #ifdef __x86_64__ 00407 init_registers_amd64 (); 00408 win32_tdesc = tdesc_amd64; 00409 #else 00410 init_registers_i386 (); 00411 win32_tdesc = tdesc_i386; 00412 #endif 00413 } 00414 00415 struct win32_target_ops the_low_target = { 00416 i386_arch_setup, 00417 sizeof (mappings) / sizeof (mappings[0]), 00418 i386_initial_stuff, 00419 i386_get_thread_context, 00420 i386_set_thread_context, 00421 i386_thread_added, 00422 i386_fetch_inferior_register, 00423 i386_store_inferior_register, 00424 i386_single_step, 00425 &i386_win32_breakpoint, 00426 i386_win32_breakpoint_len, 00427 i386_insert_point, 00428 i386_remove_point, 00429 i386_stopped_by_watchpoint, 00430 i386_stopped_data_address 00431 };