x86: Return -1 if bfd_canonicalize_dynamic_reloc returns 0
[deliverable/binutils-gdb.git] / gdb / gdbserver / win32-i386-low.c
CommitLineData
61baf725 1/* Copyright (C) 2007-2017 Free Software Foundation, Inc.
68070c10
PA
2
3 This file is part of GDB.
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
a9762ec7 7 the Free Software Foundation; either version 3 of the License, or
68070c10
PA
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
a9762ec7 16 along with this program. If not, see <http://www.gnu.org/licenses/>. */
68070c10
PA
17
18#include "server.h"
19#include "win32-low.h"
df7e5265 20#include "x86-low.h"
22916b07
YQ
21#include "x86-xstate.h"
22#ifdef __x86_64__
23#include "arch/amd64.h"
24#endif
25#include "arch/i386.h"
68070c10 26
54709339
PM
27#ifndef CONTEXT_EXTENDED_REGISTERS
28#define CONTEXT_EXTENDED_REGISTERS 0
29#endif
30
68070c10
PA
31#define FCS_REGNUM 27
32#define FOP_REGNUM 31
33
34#define FLAG_TRACE_BIT 0x100
35
df7e5265 36static struct x86_debug_reg_state debug_reg_state;
68070c10 37
a2abc7de
PA
38static int
39update_debug_registers_callback (struct inferior_list_entry *entry,
40 void *pid_p)
41{
42 struct thread_info *thr = (struct thread_info *) entry;
6afd337d 43 win32_thread_info *th = (win32_thread_info *) thread_target_data (thr);
a2abc7de
PA
44 int pid = *(int *) pid_p;
45
46 /* Only update the threads of this process. */
47 if (pid_of (thr) == pid)
48 {
49 /* The actual update is done later just before resuming the lwp,
50 we just mark that the registers need updating. */
51 th->debug_registers_changed = 1;
52 }
53
54 return 0;
55}
34b34921 56
aa5ca48f
DE
57/* Update the inferior's debug register REGNUM from STATE. */
58
42995dbd 59static void
df7e5265 60x86_dr_low_set_addr (int regnum, CORE_ADDR addr)
aa5ca48f 61{
a2abc7de
PA
62 /* Only update the threads of this process. */
63 int pid = pid_of (current_thread);
aa5ca48f 64
0a5b1e09 65 gdb_assert (DR_FIRSTADDR <= regnum && regnum <= DR_LASTADDR);
964e4306 66
a2abc7de 67 find_inferior (&all_threads, update_debug_registers_callback, &pid);
964e4306
PA
68}
69
aa5ca48f
DE
70/* Update the inferior's DR7 debug control register from STATE. */
71
42995dbd 72static void
df7e5265 73x86_dr_low_set_control (unsigned long control)
aa5ca48f 74{
a2abc7de
PA
75 /* Only update the threads of this process. */
76 int pid = pid_of (current_thread);
77
78 find_inferior (&all_threads, update_debug_registers_callback, &pid);
79}
80
81/* Return the current value of a DR register of the current thread's
82 context. */
83
84static DWORD64
85win32_get_current_dr (int dr)
86{
c3de4d92 87 win32_thread_info *th
6afd337d 88 = (win32_thread_info *) thread_target_data (current_thread);
a2abc7de
PA
89
90 win32_require_context (th);
91
92#define RET_DR(DR) \
93 case DR: \
94 return th->context.Dr ## DR
95
96 switch (dr)
97 {
98 RET_DR (0);
99 RET_DR (1);
100 RET_DR (2);
101 RET_DR (3);
102 RET_DR (6);
103 RET_DR (7);
104 }
105
106#undef RET_DR
107
108 gdb_assert_not_reached ("unhandled dr");
109}
110
111static CORE_ADDR
112x86_dr_low_get_addr (int regnum)
113{
114 gdb_assert (DR_FIRSTADDR <= regnum && regnum <= DR_LASTADDR);
115
116 return win32_get_current_dr (regnum - DR_FIRSTADDR);
aa5ca48f
DE
117}
118
42995dbd 119static unsigned long
df7e5265 120x86_dr_low_get_control (void)
964e4306 121{
a2abc7de 122 return win32_get_current_dr (7);
964e4306
PA
123}
124
aa5ca48f
DE
125/* Get the value of the DR6 debug status register from the inferior
126 and record it in STATE. */
127
42995dbd 128static unsigned long
df7e5265 129x86_dr_low_get_status (void)
aa5ca48f 130{
a2abc7de 131 return win32_get_current_dr (6);
aa5ca48f
DE
132}
133
42995dbd 134/* Low-level function vector. */
df7e5265 135struct x86_dr_low_type x86_dr_low =
42995dbd 136 {
df7e5265
GB
137 x86_dr_low_set_control,
138 x86_dr_low_set_addr,
139 x86_dr_low_get_addr,
140 x86_dr_low_get_status,
141 x86_dr_low_get_control,
42995dbd
GB
142 sizeof (void *),
143 };
144
802e8e6d 145/* Breakpoint/watchpoint support. */
aa5ca48f
DE
146
147static int
802e8e6d
PA
148i386_supports_z_point_type (char z_type)
149{
150 switch (z_type)
151 {
152 case Z_PACKET_WRITE_WP:
153 case Z_PACKET_ACCESS_WP:
154 return 1;
155 default:
156 return 0;
157 }
158}
159
160static int
161i386_insert_point (enum raw_bkpt_type type, CORE_ADDR addr,
162 int size, struct raw_breakpoint *bp)
aa5ca48f
DE
163{
164 switch (type)
165 {
802e8e6d
PA
166 case raw_bkpt_type_write_wp:
167 case raw_bkpt_type_access_wp:
a4165e94 168 {
802e8e6d
PA
169 enum target_hw_bp_type hw_type
170 = raw_bkpt_type_to_target_hw_bp_type (type);
a4165e94 171
df7e5265
GB
172 return x86_dr_insert_watchpoint (&debug_reg_state,
173 hw_type, addr, size);
a4165e94 174 }
aa5ca48f
DE
175 default:
176 /* Unsupported. */
177 return 1;
178 }
179}
180
181static int
802e8e6d
PA
182i386_remove_point (enum raw_bkpt_type type, CORE_ADDR addr,
183 int size, struct raw_breakpoint *bp)
aa5ca48f
DE
184{
185 switch (type)
186 {
802e8e6d
PA
187 case raw_bkpt_type_write_wp:
188 case raw_bkpt_type_access_wp:
a4165e94 189 {
802e8e6d
PA
190 enum target_hw_bp_type hw_type
191 = raw_bkpt_type_to_target_hw_bp_type (type);
a4165e94 192
df7e5265
GB
193 return x86_dr_remove_watchpoint (&debug_reg_state,
194 hw_type, addr, size);
a4165e94 195 }
aa5ca48f
DE
196 default:
197 /* Unsupported. */
198 return 1;
199 }
200}
201
202static int
df7e5265 203x86_stopped_by_watchpoint (void)
aa5ca48f 204{
df7e5265 205 return x86_dr_stopped_by_watchpoint (&debug_reg_state);
aa5ca48f
DE
206}
207
208static CORE_ADDR
df7e5265 209x86_stopped_data_address (void)
aa5ca48f
DE
210{
211 CORE_ADDR addr;
df7e5265 212 if (x86_dr_stopped_data_address (&debug_reg_state, &addr))
aa5ca48f
DE
213 return addr;
214 return 0;
215}
216
68070c10 217static void
34b34921 218i386_initial_stuff (void)
68070c10 219{
df7e5265 220 x86_low_init_dregs (&debug_reg_state);
68070c10
PA
221}
222
223static void
a2abc7de 224i386_get_thread_context (win32_thread_info *th)
68070c10 225{
912cf4ba
PA
226 /* Requesting the CONTEXT_EXTENDED_REGISTERS register set fails if
227 the system doesn't support extended registers. */
228 static DWORD extended_registers = CONTEXT_EXTENDED_REGISTERS;
34b34921 229
912cf4ba
PA
230 again:
231 th->context.ContextFlags = (CONTEXT_FULL
232 | CONTEXT_FLOATING_POINT
233 | CONTEXT_DEBUG_REGISTERS
234 | extended_registers);
235
236 if (!GetThreadContext (th->h, &th->context))
237 {
238 DWORD e = GetLastError ();
239
240 if (extended_registers && e == ERROR_INVALID_PARAMETER)
241 {
242 extended_registers = 0;
243 goto again;
244 }
245
246 error ("GetThreadContext failure %ld\n", (long) e);
247 }
68070c10
PA
248}
249
250static void
a2abc7de 251i386_prepare_to_resume (win32_thread_info *th)
68070c10 252{
a2abc7de 253 if (th->debug_registers_changed)
34b34921 254 {
df7e5265 255 struct x86_debug_reg_state *dr = &debug_reg_state;
a2abc7de
PA
256
257 win32_require_context (th);
258
aa5ca48f
DE
259 th->context.Dr0 = dr->dr_mirror[0];
260 th->context.Dr1 = dr->dr_mirror[1];
261 th->context.Dr2 = dr->dr_mirror[2];
262 th->context.Dr3 = dr->dr_mirror[3];
8d26e50c 263 /* th->context.Dr6 = dr->dr_status_mirror;
34b34921 264 FIXME: should we set dr6 also ?? */
8d26e50c 265 th->context.Dr7 = dr->dr_control_mirror;
34b34921 266
a2abc7de
PA
267 th->debug_registers_changed = 0;
268 }
68070c10
PA
269}
270
68070c10 271static void
34b34921 272i386_thread_added (win32_thread_info *th)
68070c10 273{
a2abc7de 274 th->debug_registers_changed = 1;
68070c10
PA
275}
276
277static void
34b34921 278i386_single_step (win32_thread_info *th)
68070c10
PA
279{
280 th->context.EFlags |= FLAG_TRACE_BIT;
281}
282
1c07cc19 283#ifndef __x86_64__
54709339 284
68070c10
PA
285/* An array of offset mappings into a Win32 Context structure.
286 This is a one-to-one mapping which is indexed by gdb's register
287 numbers. It retrieves an offset into the context structure where
288 the 4 byte register is located.
289 An offset value of -1 indicates that Win32 does not provide this
290 register in it's CONTEXT structure. In this case regptr will return
291 a pointer into a dummy register. */
292#define context_offset(x) ((int)&(((CONTEXT *)NULL)->x))
293static const int mappings[] = {
294 context_offset (Eax),
295 context_offset (Ecx),
296 context_offset (Edx),
297 context_offset (Ebx),
298 context_offset (Esp),
299 context_offset (Ebp),
300 context_offset (Esi),
301 context_offset (Edi),
302 context_offset (Eip),
303 context_offset (EFlags),
304 context_offset (SegCs),
305 context_offset (SegSs),
306 context_offset (SegDs),
307 context_offset (SegEs),
308 context_offset (SegFs),
309 context_offset (SegGs),
310 context_offset (FloatSave.RegisterArea[0 * 10]),
311 context_offset (FloatSave.RegisterArea[1 * 10]),
312 context_offset (FloatSave.RegisterArea[2 * 10]),
313 context_offset (FloatSave.RegisterArea[3 * 10]),
314 context_offset (FloatSave.RegisterArea[4 * 10]),
315 context_offset (FloatSave.RegisterArea[5 * 10]),
316 context_offset (FloatSave.RegisterArea[6 * 10]),
317 context_offset (FloatSave.RegisterArea[7 * 10]),
318 context_offset (FloatSave.ControlWord),
319 context_offset (FloatSave.StatusWord),
320 context_offset (FloatSave.TagWord),
321 context_offset (FloatSave.ErrorSelector),
322 context_offset (FloatSave.ErrorOffset),
323 context_offset (FloatSave.DataSelector),
324 context_offset (FloatSave.DataOffset),
325 context_offset (FloatSave.ErrorSelector),
326 /* XMM0-7 */
327 context_offset (ExtendedRegisters[10 * 16]),
328 context_offset (ExtendedRegisters[11 * 16]),
329 context_offset (ExtendedRegisters[12 * 16]),
330 context_offset (ExtendedRegisters[13 * 16]),
331 context_offset (ExtendedRegisters[14 * 16]),
332 context_offset (ExtendedRegisters[15 * 16]),
333 context_offset (ExtendedRegisters[16 * 16]),
334 context_offset (ExtendedRegisters[17 * 16]),
335 /* MXCSR */
336 context_offset (ExtendedRegisters[24])
337};
338#undef context_offset
339
1c07cc19 340#else /* __x86_64__ */
54709339
PM
341
342#define context_offset(x) (offsetof (CONTEXT, x))
343static const int mappings[] =
344{
345 context_offset (Rax),
346 context_offset (Rbx),
347 context_offset (Rcx),
348 context_offset (Rdx),
349 context_offset (Rsi),
350 context_offset (Rdi),
351 context_offset (Rbp),
352 context_offset (Rsp),
353 context_offset (R8),
354 context_offset (R9),
355 context_offset (R10),
356 context_offset (R11),
357 context_offset (R12),
358 context_offset (R13),
359 context_offset (R14),
360 context_offset (R15),
361 context_offset (Rip),
362 context_offset (EFlags),
363 context_offset (SegCs),
364 context_offset (SegSs),
365 context_offset (SegDs),
366 context_offset (SegEs),
367 context_offset (SegFs),
368 context_offset (SegGs),
369 context_offset (FloatSave.FloatRegisters[0]),
370 context_offset (FloatSave.FloatRegisters[1]),
371 context_offset (FloatSave.FloatRegisters[2]),
372 context_offset (FloatSave.FloatRegisters[3]),
373 context_offset (FloatSave.FloatRegisters[4]),
374 context_offset (FloatSave.FloatRegisters[5]),
375 context_offset (FloatSave.FloatRegisters[6]),
376 context_offset (FloatSave.FloatRegisters[7]),
377 context_offset (FloatSave.ControlWord),
378 context_offset (FloatSave.StatusWord),
379 context_offset (FloatSave.TagWord),
380 context_offset (FloatSave.ErrorSelector),
381 context_offset (FloatSave.ErrorOffset),
382 context_offset (FloatSave.DataSelector),
383 context_offset (FloatSave.DataOffset),
384 context_offset (FloatSave.ErrorSelector)
385 /* XMM0-7 */ ,
386 context_offset (Xmm0),
387 context_offset (Xmm1),
388 context_offset (Xmm2),
389 context_offset (Xmm3),
390 context_offset (Xmm4),
391 context_offset (Xmm5),
392 context_offset (Xmm6),
393 context_offset (Xmm7),
394 context_offset (Xmm8),
395 context_offset (Xmm9),
396 context_offset (Xmm10),
397 context_offset (Xmm11),
398 context_offset (Xmm12),
399 context_offset (Xmm13),
400 context_offset (Xmm14),
401 context_offset (Xmm15),
402 /* MXCSR */
403 context_offset (FloatSave.MxCsr)
404};
405#undef context_offset
406
1c07cc19 407#endif /* __x86_64__ */
54709339 408
34b34921
PA
409/* Fetch register from gdbserver regcache data. */
410static void
442ea881
PA
411i386_fetch_inferior_register (struct regcache *regcache,
412 win32_thread_info *th, int r)
34b34921
PA
413{
414 char *context_offset = (char *) &th->context + mappings[r];
415
416 long l;
417 if (r == FCS_REGNUM)
418 {
419 l = *((long *) context_offset) & 0xffff;
442ea881 420 supply_register (regcache, r, (char *) &l);
34b34921
PA
421 }
422 else if (r == FOP_REGNUM)
423 {
424 l = (*((long *) context_offset) >> 16) & ((1 << 11) - 1);
442ea881 425 supply_register (regcache, r, (char *) &l);
34b34921
PA
426 }
427 else
442ea881 428 supply_register (regcache, r, context_offset);
34b34921
PA
429}
430
431/* Store a new register value into the thread context of TH. */
432static void
442ea881
PA
433i386_store_inferior_register (struct regcache *regcache,
434 win32_thread_info *th, int r)
34b34921
PA
435{
436 char *context_offset = (char *) &th->context + mappings[r];
442ea881 437 collect_register (regcache, r, context_offset);
34b34921
PA
438}
439
912cf4ba
PA
440static const unsigned char i386_win32_breakpoint = 0xcc;
441#define i386_win32_breakpoint_len 1
442
54709339 443static void
3aee8918 444i386_arch_setup (void)
54709339 445{
1c07cc19 446#ifdef __x86_64__
22916b07
YQ
447 win32_tdesc = amd64_create_target_description (X86_XSTATE_SSE_MASK, false,
448 false);
54709339 449#else
22916b07 450 win32_tdesc = i386_create_target_description (X86_XSTATE_SSE_MASK, false);
54709339
PM
451#endif
452}
453
68070c10 454struct win32_target_ops the_low_target = {
3aee8918 455 i386_arch_setup,
68070c10 456 sizeof (mappings) / sizeof (mappings[0]),
34b34921
PA
457 i386_initial_stuff,
458 i386_get_thread_context,
a2abc7de 459 i386_prepare_to_resume,
34b34921
PA
460 i386_thread_added,
461 i386_fetch_inferior_register,
462 i386_store_inferior_register,
463 i386_single_step,
912cf4ba
PA
464 &i386_win32_breakpoint,
465 i386_win32_breakpoint_len,
802e8e6d 466 i386_supports_z_point_type,
aa5ca48f
DE
467 i386_insert_point,
468 i386_remove_point,
df7e5265
GB
469 x86_stopped_by_watchpoint,
470 x86_stopped_data_address
68070c10 471};
This page took 0.818843 seconds and 4 git commands to generate.