OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gdb-7.2/] [gdb/] [gdbserver/] [win32-i386-low.c] - Blame information for rev 861

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 330 jeremybenn
/* Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
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
7
   the Free Software Foundation; either version 3 of the License, or
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
16
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
17
 
18
#include "server.h"
19
#include "win32-low.h"
20
#include "i386-low.h"
21
 
22
#ifndef CONTEXT_EXTENDED_REGISTERS
23
#define CONTEXT_EXTENDED_REGISTERS 0
24
#endif
25
 
26
#define FCS_REGNUM 27
27
#define FOP_REGNUM 31
28
 
29
#define FLAG_TRACE_BIT 0x100
30
 
31
#ifdef __x86_64__
32
/* Defined in auto-generated file reg-amd64.c.  */
33
void init_registers_amd64 (void);
34
#else
35
/* Defined in auto-generated file reg-i386.c.  */
36
void init_registers_i386 (void);
37
#endif
38
 
39
static struct i386_debug_reg_state debug_reg_state;
40
 
41
static int debug_registers_changed = 0;
42
static int debug_registers_used = 0;
43
 
44
/* Update the inferior's debug register REGNUM from STATE.  */
45
 
46
void
47
i386_dr_low_set_addr (const struct i386_debug_reg_state *state, int regnum)
48
{
49
  if (! (regnum >= 0 && regnum <= DR_LASTADDR - DR_FIRSTADDR))
50
    fatal ("Invalid debug register %d", regnum);
51
 
52
  /* debug_reg_state.dr_mirror is already set.
53
     Just notify i386_set_thread_context, i386_thread_added
54
     that the registers need to be updated.  */
55
  debug_registers_changed = 1;
56
  debug_registers_used = 1;
57
}
58
 
59
/* Update the inferior's DR7 debug control register from STATE.  */
60
 
61
void
62
i386_dr_low_set_control (const struct i386_debug_reg_state *state)
63
{
64
  /* debug_reg_state.dr_control_mirror is already set.
65
     Just notify i386_set_thread_context, i386_thread_added
66
     that the registers need to be updated.  */
67
  debug_registers_changed = 1;
68
  debug_registers_used = 1;
69
}
70
 
71
/* Get the value of the DR6 debug status register from the inferior
72
   and record it in STATE.  */
73
 
74
void
75
i386_dr_low_get_status (struct i386_debug_reg_state *state)
76
{
77
  /* We don't need to do anything here, the last call to thread_rec for
78
     current_event.dwThreadId id has already set it.  */
79
}
80
 
81
/* Watchpoint support.  */
82
 
83
static int
84
i386_insert_point (char type, CORE_ADDR addr, int len)
85
{
86
  switch (type)
87
    {
88
    case '2':
89
    case '3':
90
    case '4':
91
      return i386_low_insert_watchpoint (&debug_reg_state,
92
                                         type, addr, len);
93
    default:
94
      /* Unsupported.  */
95
      return 1;
96
    }
97
}
98
 
99
static int
100
i386_remove_point (char type, CORE_ADDR addr, int len)
101
{
102
  switch (type)
103
    {
104
    case '2':
105
    case '3':
106
    case '4':
107
      return i386_low_remove_watchpoint (&debug_reg_state,
108
                                         type, addr, len);
109
    default:
110
      /* Unsupported.  */
111
      return 1;
112
    }
113
}
114
 
115
static int
116
i386_stopped_by_watchpoint (void)
117
{
118
  return i386_low_stopped_by_watchpoint (&debug_reg_state);
119
}
120
 
121
static CORE_ADDR
122
i386_stopped_data_address (void)
123
{
124
  CORE_ADDR addr;
125
  if (i386_low_stopped_data_address (&debug_reg_state, &addr))
126
    return addr;
127
  return 0;
128
}
129
 
130
static void
131
i386_initial_stuff (void)
132
{
133
  i386_low_init_dregs (&debug_reg_state);
134
  debug_registers_changed = 0;
135
  debug_registers_used = 0;
136
}
137
 
138
static void
139
i386_get_thread_context (win32_thread_info *th, DEBUG_EVENT* current_event)
140
{
141
  /* Requesting the CONTEXT_EXTENDED_REGISTERS register set fails if
142
     the system doesn't support extended registers.  */
143
  static DWORD extended_registers = CONTEXT_EXTENDED_REGISTERS;
144
 
145
 again:
146
  th->context.ContextFlags = (CONTEXT_FULL
147
                              | CONTEXT_FLOATING_POINT
148
                              | CONTEXT_DEBUG_REGISTERS
149
                              | extended_registers);
150
 
151
  if (!GetThreadContext (th->h, &th->context))
152
    {
153
      DWORD e = GetLastError ();
154
 
155
      if (extended_registers && e == ERROR_INVALID_PARAMETER)
156
        {
157
          extended_registers = 0;
158
          goto again;
159
        }
160
 
161
      error ("GetThreadContext failure %ld\n", (long) e);
162
    }
163
 
164
  debug_registers_changed = 0;
165
 
166
  if (th->tid == current_event->dwThreadId)
167
    {
168
      /* Copy dr values from the current thread.  */
169
      struct i386_debug_reg_state *dr = &debug_reg_state;
170
      dr->dr_mirror[0] = th->context.Dr0;
171
      dr->dr_mirror[1] = th->context.Dr1;
172
      dr->dr_mirror[2] = th->context.Dr2;
173
      dr->dr_mirror[3] = th->context.Dr3;
174
      dr->dr_status_mirror = th->context.Dr6;
175
      dr->dr_control_mirror = th->context.Dr7;
176
    }
177
}
178
 
179
static void
180
i386_set_thread_context (win32_thread_info *th, DEBUG_EVENT* current_event)
181
{
182
  if (debug_registers_changed)
183
    {
184
      struct i386_debug_reg_state *dr = &debug_reg_state;
185
      th->context.Dr0 = dr->dr_mirror[0];
186
      th->context.Dr1 = dr->dr_mirror[1];
187
      th->context.Dr2 = dr->dr_mirror[2];
188
      th->context.Dr3 = dr->dr_mirror[3];
189
      /* th->context.Dr6 = dr->dr_status_mirror;
190
         FIXME: should we set dr6 also ?? */
191
      th->context.Dr7 = dr->dr_control_mirror;
192
    }
193
 
194
  SetThreadContext (th->h, &th->context);
195
}
196
 
197
static void
198
i386_thread_added (win32_thread_info *th)
199
{
200
  /* Set the debug registers for the new thread if they are used.  */
201
  if (debug_registers_used)
202
    {
203
      struct i386_debug_reg_state *dr = &debug_reg_state;
204
      th->context.ContextFlags = CONTEXT_DEBUG_REGISTERS;
205
      GetThreadContext (th->h, &th->context);
206
 
207
      th->context.Dr0 = dr->dr_mirror[0];
208
      th->context.Dr1 = dr->dr_mirror[1];
209
      th->context.Dr2 = dr->dr_mirror[2];
210
      th->context.Dr3 = dr->dr_mirror[3];
211
      /* th->context.Dr6 = dr->dr_status_mirror;
212
         FIXME: should we set dr6 also ?? */
213
      th->context.Dr7 = dr->dr_control_mirror;
214
 
215
      SetThreadContext (th->h, &th->context);
216
      th->context.ContextFlags = 0;
217
    }
218
}
219
 
220
static void
221
i386_single_step (win32_thread_info *th)
222
{
223
  th->context.EFlags |= FLAG_TRACE_BIT;
224
}
225
 
226
#ifndef __x86_64__
227
 
228
/* An array of offset mappings into a Win32 Context structure.
229
   This is a one-to-one mapping which is indexed by gdb's register
230
   numbers.  It retrieves an offset into the context structure where
231
   the 4 byte register is located.
232
   An offset value of -1 indicates that Win32 does not provide this
233
   register in it's CONTEXT structure.  In this case regptr will return
234
   a pointer into a dummy register.  */
235
#define context_offset(x) ((int)&(((CONTEXT *)NULL)->x))
236
static const int mappings[] = {
237
  context_offset (Eax),
238
  context_offset (Ecx),
239
  context_offset (Edx),
240
  context_offset (Ebx),
241
  context_offset (Esp),
242
  context_offset (Ebp),
243
  context_offset (Esi),
244
  context_offset (Edi),
245
  context_offset (Eip),
246
  context_offset (EFlags),
247
  context_offset (SegCs),
248
  context_offset (SegSs),
249
  context_offset (SegDs),
250
  context_offset (SegEs),
251
  context_offset (SegFs),
252
  context_offset (SegGs),
253
  context_offset (FloatSave.RegisterArea[0 * 10]),
254
  context_offset (FloatSave.RegisterArea[1 * 10]),
255
  context_offset (FloatSave.RegisterArea[2 * 10]),
256
  context_offset (FloatSave.RegisterArea[3 * 10]),
257
  context_offset (FloatSave.RegisterArea[4 * 10]),
258
  context_offset (FloatSave.RegisterArea[5 * 10]),
259
  context_offset (FloatSave.RegisterArea[6 * 10]),
260
  context_offset (FloatSave.RegisterArea[7 * 10]),
261
  context_offset (FloatSave.ControlWord),
262
  context_offset (FloatSave.StatusWord),
263
  context_offset (FloatSave.TagWord),
264
  context_offset (FloatSave.ErrorSelector),
265
  context_offset (FloatSave.ErrorOffset),
266
  context_offset (FloatSave.DataSelector),
267
  context_offset (FloatSave.DataOffset),
268
  context_offset (FloatSave.ErrorSelector),
269
  /* XMM0-7 */
270
  context_offset (ExtendedRegisters[10 * 16]),
271
  context_offset (ExtendedRegisters[11 * 16]),
272
  context_offset (ExtendedRegisters[12 * 16]),
273
  context_offset (ExtendedRegisters[13 * 16]),
274
  context_offset (ExtendedRegisters[14 * 16]),
275
  context_offset (ExtendedRegisters[15 * 16]),
276
  context_offset (ExtendedRegisters[16 * 16]),
277
  context_offset (ExtendedRegisters[17 * 16]),
278
  /* MXCSR */
279
  context_offset (ExtendedRegisters[24])
280
};
281
#undef context_offset
282
 
283
#else /* __x86_64__ */
284
 
285
#define context_offset(x) (offsetof (CONTEXT, x))
286
static const int mappings[] =
287
{
288
  context_offset (Rax),
289
  context_offset (Rbx),
290
  context_offset (Rcx),
291
  context_offset (Rdx),
292
  context_offset (Rsi),
293
  context_offset (Rdi),
294
  context_offset (Rbp),
295
  context_offset (Rsp),
296
  context_offset (R8),
297
  context_offset (R9),
298
  context_offset (R10),
299
  context_offset (R11),
300
  context_offset (R12),
301
  context_offset (R13),
302
  context_offset (R14),
303
  context_offset (R15),
304
  context_offset (Rip),
305
  context_offset (EFlags),
306
  context_offset (SegCs),
307
  context_offset (SegSs),
308
  context_offset (SegDs),
309
  context_offset (SegEs),
310
  context_offset (SegFs),
311
  context_offset (SegGs),
312
  context_offset (FloatSave.FloatRegisters[0]),
313
  context_offset (FloatSave.FloatRegisters[1]),
314
  context_offset (FloatSave.FloatRegisters[2]),
315
  context_offset (FloatSave.FloatRegisters[3]),
316
  context_offset (FloatSave.FloatRegisters[4]),
317
  context_offset (FloatSave.FloatRegisters[5]),
318
  context_offset (FloatSave.FloatRegisters[6]),
319
  context_offset (FloatSave.FloatRegisters[7]),
320
  context_offset (FloatSave.ControlWord),
321
  context_offset (FloatSave.StatusWord),
322
  context_offset (FloatSave.TagWord),
323
  context_offset (FloatSave.ErrorSelector),
324
  context_offset (FloatSave.ErrorOffset),
325
  context_offset (FloatSave.DataSelector),
326
  context_offset (FloatSave.DataOffset),
327
  context_offset (FloatSave.ErrorSelector)
328
  /* XMM0-7 */ ,
329
  context_offset (Xmm0),
330
  context_offset (Xmm1),
331
  context_offset (Xmm2),
332
  context_offset (Xmm3),
333
  context_offset (Xmm4),
334
  context_offset (Xmm5),
335
  context_offset (Xmm6),
336
  context_offset (Xmm7),
337
  context_offset (Xmm8),
338
  context_offset (Xmm9),
339
  context_offset (Xmm10),
340
  context_offset (Xmm11),
341
  context_offset (Xmm12),
342
  context_offset (Xmm13),
343
  context_offset (Xmm14),
344
  context_offset (Xmm15),
345
  /* MXCSR */
346
  context_offset (FloatSave.MxCsr)
347
};
348
#undef context_offset
349
 
350
#endif /* __x86_64__ */
351
 
352
/* Fetch register from gdbserver regcache data.  */
353
static void
354
i386_fetch_inferior_register (struct regcache *regcache,
355
                              win32_thread_info *th, int r)
356
{
357
  char *context_offset = (char *) &th->context + mappings[r];
358
 
359
  long l;
360
  if (r == FCS_REGNUM)
361
    {
362
      l = *((long *) context_offset) & 0xffff;
363
      supply_register (regcache, r, (char *) &l);
364
    }
365
  else if (r == FOP_REGNUM)
366
    {
367
      l = (*((long *) context_offset) >> 16) & ((1 << 11) - 1);
368
      supply_register (regcache, r, (char *) &l);
369
    }
370
  else
371
    supply_register (regcache, r, context_offset);
372
}
373
 
374
/* Store a new register value into the thread context of TH.  */
375
static void
376
i386_store_inferior_register (struct regcache *regcache,
377
                              win32_thread_info *th, int r)
378
{
379
  char *context_offset = (char *) &th->context + mappings[r];
380
  collect_register (regcache, r, context_offset);
381
}
382
 
383
static const unsigned char i386_win32_breakpoint = 0xcc;
384
#define i386_win32_breakpoint_len 1
385
 
386
static void
387
init_windows_x86 (void)
388
{
389
#ifdef __x86_64__
390
  init_registers_amd64 ();
391
#else
392
  init_registers_i386 ();
393
#endif
394
}
395
 
396
struct win32_target_ops the_low_target = {
397
  init_windows_x86,
398
  sizeof (mappings) / sizeof (mappings[0]),
399
  i386_initial_stuff,
400
  i386_get_thread_context,
401
  i386_set_thread_context,
402
  i386_thread_added,
403
  i386_fetch_inferior_register,
404
  i386_store_inferior_register,
405
  i386_single_step,
406
  &i386_win32_breakpoint,
407
  i386_win32_breakpoint_len,
408
  i386_insert_point,
409
  i386_remove_point,
410
  i386_stopped_by_watchpoint,
411
  i386_stopped_data_address
412
};

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.