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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-7.2/] [gdb/] [windows-tdep.c] - Blame information for rev 446

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

Line No. Rev Author Line
1 330 jeremybenn
/* Copyright (C) 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 "defs.h"
19
#include "windows-tdep.h"
20
#include "gdb_obstack.h"
21
#include "xml-support.h"
22
#include "gdbarch.h"
23
#include "target.h"
24
#include "value.h"
25
#include "inferior.h"
26
#include "command.h"
27
#include "gdbcmd.h"
28
#include "gdbthread.h"
29
 
30
struct cmd_list_element *info_w32_cmdlist;
31
 
32
typedef struct thread_information_block_32
33
  {
34
    uint32_t current_seh;                       /* %fs:0x0000 */
35
    uint32_t current_top_of_stack;              /* %fs:0x0004 */
36
    uint32_t current_bottom_of_stack;           /* %fs:0x0008 */
37
    uint32_t sub_system_tib;                    /* %fs:0x000c */
38
    uint32_t fiber_data;                        /* %fs:0x0010 */
39
    uint32_t arbitrary_data_slot;               /* %fs:0x0014 */
40
    uint32_t linear_address_tib;                /* %fs:0x0018 */
41
    uint32_t environment_pointer;               /* %fs:0x001c */
42
    uint32_t process_id;                        /* %fs:0x0020 */
43
    uint32_t current_thread_id;                 /* %fs:0x0024 */
44
    uint32_t active_rpc_handle;                 /* %fs:0x0028 */
45
    uint32_t thread_local_storage;              /* %fs:0x002c */
46
    uint32_t process_environment_block;         /* %fs:0x0030 */
47
    uint32_t last_error_number;                 /* %fs:0x0034 */
48
  }
49
thread_information_32;
50
 
51
typedef struct thread_information_block_64
52
  {
53
    uint64_t current_seh;                       /* %gs:0x0000 */
54
    uint64_t current_top_of_stack;              /* %gs:0x0008 */
55
    uint64_t current_bottom_of_stack;           /* %gs:0x0010 */
56
    uint64_t sub_system_tib;                    /* %gs:0x0018 */
57
    uint64_t fiber_data;                        /* %gs:0x0020 */
58
    uint64_t arbitrary_data_slot;               /* %gs:0x0028 */
59
    uint64_t linear_address_tib;                /* %gs:0x0030 */
60
    uint64_t environment_pointer;               /* %gs:0x0038 */
61
    uint64_t process_id;                        /* %gs:0x0040 */
62
    uint64_t current_thread_id;                 /* %gs:0x0048 */
63
    uint64_t active_rpc_handle;                 /* %gs:0x0050 */
64
    uint64_t thread_local_storage;              /* %gs:0x0058 */
65
    uint64_t process_environment_block;         /* %gs:0x0060 */
66
    uint64_t last_error_number;                 /* %gs:0x0068 */
67
  }
68
thread_information_64;
69
 
70
 
71
static const char* TIB_NAME[] =
72
  {
73
    " current_seh                 ",    /* %fs:0x0000 */
74
    " current_top_of_stack        ",    /* %fs:0x0004 */
75
    " current_bottom_of_stack     ",    /* %fs:0x0008 */
76
    " sub_system_tib              ",    /* %fs:0x000c */
77
    " fiber_data                  ",    /* %fs:0x0010 */
78
    " arbitrary_data_slot         ",    /* %fs:0x0014 */
79
    " linear_address_tib          ",    /* %fs:0x0018 */
80
    " environment_pointer         ",    /* %fs:0x001c */
81
    " process_id                  ",    /* %fs:0x0020 */
82
    " current_thread_id           ",    /* %fs:0x0024 */
83
    " active_rpc_handle           ",    /* %fs:0x0028 */
84
    " thread_local_storage        ",    /* %fs:0x002c */
85
    " process_environment_block   ",    /* %fs:0x0030 */
86
    " last_error_number           "     /* %fs:0x0034 */
87
  };
88
 
89
static const int MAX_TIB32 = sizeof (thread_information_32) / sizeof (uint32_t);
90
static const int MAX_TIB64 = sizeof (thread_information_64) / sizeof (uint64_t);
91
static const int FULL_TIB_SIZE = 0x1000;
92
 
93
static int maint_display_all_tib = 0;
94
 
95
/* Define Thread Local Base pointer type.  */
96
 
97
static struct type *
98
windows_get_tlb_type (struct gdbarch *gdbarch)
99
{
100
  static struct gdbarch *last_gdbarch = NULL;
101
  static struct type *last_tlb_type = NULL;
102
  struct type *dword_ptr_type, *dword32_type, *void_ptr_type;
103
  struct type *peb_ldr_type, *peb_ldr_ptr_type;
104
  struct type *peb_type, *peb_ptr_type, *list_type, *list_ptr_type;
105
  struct type *module_list_ptr_type;
106
  struct type *tib_type, *seh_type, *tib_ptr_type, *seh_ptr_type;
107
 
108
  /* Do not rebuild type if same gdbarch as last time.  */
109
  if (last_tlb_type && last_gdbarch == gdbarch)
110
    return last_tlb_type;
111
 
112
  dword_ptr_type = arch_integer_type (gdbarch, gdbarch_ptr_bit (gdbarch),
113
                                 1, "DWORD_PTR");
114
  dword32_type = arch_integer_type (gdbarch, 32,
115
                                 1, "DWORD32");
116
  void_ptr_type = lookup_pointer_type (builtin_type (gdbarch)->builtin_void);
117
 
118
  /* list entry */
119
 
120
  list_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT);
121
  TYPE_NAME (list_type) = xstrdup ("list");
122
 
123
  list_ptr_type = arch_type (gdbarch, TYPE_CODE_PTR,
124
                            TYPE_LENGTH (void_ptr_type), NULL);
125
 
126
  module_list_ptr_type = void_ptr_type;
127
 
128
  append_composite_type_field (list_type, "forward_list", module_list_ptr_type);
129
  append_composite_type_field (list_type, "backward_list",
130
                               module_list_ptr_type);
131
 
132
  /* Structured Exception Handler */
133
 
134
  seh_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT);
135
  TYPE_NAME (seh_type) = xstrdup ("seh");
136
 
137
  seh_ptr_type = arch_type (gdbarch, TYPE_CODE_PTR,
138
                            TYPE_LENGTH (void_ptr_type), NULL);
139
  TYPE_TARGET_TYPE (seh_ptr_type) = seh_type;
140
 
141
  append_composite_type_field (seh_type, "next_seh", seh_ptr_type);
142
  append_composite_type_field (seh_type, "handler",
143
                               builtin_type (gdbarch)->builtin_func_ptr);
144
 
145
  /* struct _PEB_LDR_DATA */
146
  peb_ldr_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT);
147
  TYPE_NAME (peb_ldr_type) = xstrdup ("peb_ldr_data");
148
 
149
  append_composite_type_field (peb_ldr_type, "length", dword32_type);
150
  append_composite_type_field (peb_ldr_type, "initialized", dword32_type);
151
  append_composite_type_field (peb_ldr_type, "ss_handle", void_ptr_type);
152
  append_composite_type_field (peb_ldr_type, "in_load_order", list_type);
153
  append_composite_type_field (peb_ldr_type, "in_memory_order", list_type);
154
  append_composite_type_field (peb_ldr_type, "in_init_order", list_type);
155
  append_composite_type_field (peb_ldr_type, "entry_in_progress",
156
                               void_ptr_type);
157
  peb_ldr_ptr_type = arch_type (gdbarch, TYPE_CODE_PTR,
158
                            TYPE_LENGTH (void_ptr_type), NULL);
159
  TYPE_TARGET_TYPE (peb_ldr_ptr_type) = peb_ldr_type;
160
 
161
 
162
  /* struct process environment block */
163
  peb_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT);
164
  TYPE_NAME (peb_type) = xstrdup ("peb");
165
 
166
  /* First bytes contain several flags.  */
167
  append_composite_type_field (peb_type, "flags", dword_ptr_type);
168
  append_composite_type_field (peb_type, "mutant", void_ptr_type);
169
  append_composite_type_field (peb_type, "image_base_address", void_ptr_type);
170
  append_composite_type_field (peb_type, "ldr", peb_ldr_ptr_type);
171
  append_composite_type_field (peb_type, "process_parameters", void_ptr_type);
172
  append_composite_type_field (peb_type, "sub_system_data", void_ptr_type);
173
  append_composite_type_field (peb_type, "process_heap", void_ptr_type);
174
  append_composite_type_field (peb_type, "fast_peb_lock", void_ptr_type);
175
  peb_ptr_type = arch_type (gdbarch, TYPE_CODE_PTR,
176
                            TYPE_LENGTH (void_ptr_type), NULL);
177
  TYPE_TARGET_TYPE (peb_ptr_type) = peb_type;
178
 
179
 
180
  /* struct thread information block */
181
  tib_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT);
182
  TYPE_NAME (tib_type) = xstrdup ("tib");
183
 
184
  /* uint32_t current_seh;                      %fs:0x0000 */
185
  append_composite_type_field (tib_type, "current_seh", seh_ptr_type);
186
  /* uint32_t current_top_of_stack;             %fs:0x0004 */
187
  append_composite_type_field (tib_type, "current_top_of_stack", void_ptr_type);
188
  /* uint32_t current_bottom_of_stack;          %fs:0x0008 */
189
  append_composite_type_field (tib_type, "current_bottom_of_stack",
190
                               void_ptr_type);
191
  /* uint32_t sub_system_tib;                   %fs:0x000c */
192
  append_composite_type_field (tib_type, "sub_system_tib", void_ptr_type);
193
 
194
  /* uint32_t fiber_data;                       %fs:0x0010 */
195
  append_composite_type_field (tib_type, "fiber_data", void_ptr_type);
196
  /* uint32_t arbitrary_data_slot;              %fs:0x0014 */
197
  append_composite_type_field (tib_type, "arbitrary_data_slot", void_ptr_type);
198
  /* uint32_t linear_address_tib;               %fs:0x0018 */
199
  append_composite_type_field (tib_type, "linear_address_tib", void_ptr_type);
200
  /* uint32_t environment_pointer;              %fs:0x001c */
201
  append_composite_type_field (tib_type, "environment_pointer", void_ptr_type);
202
  /* uint32_t process_id;                       %fs:0x0020 */
203
  append_composite_type_field (tib_type, "process_id", dword_ptr_type);
204
  /* uint32_t current_thread_id;                %fs:0x0024 */
205
  append_composite_type_field (tib_type, "thread_id", dword_ptr_type);
206
  /* uint32_t active_rpc_handle;                %fs:0x0028 */
207
  append_composite_type_field (tib_type, "active_rpc_handle", dword_ptr_type);
208
  /* uint32_t thread_local_storage;             %fs:0x002c */
209
  append_composite_type_field (tib_type, "thread_local_storage", void_ptr_type);
210
  /* uint32_t process_environment_block;        %fs:0x0030 */
211
  append_composite_type_field (tib_type, "process_environment_block",
212
                               peb_ptr_type);
213
  /* uint32_t last_error_number;                %fs:0x0034 */
214
  append_composite_type_field (tib_type, "last_error_number", dword_ptr_type);
215
 
216
  tib_ptr_type = arch_type (gdbarch, TYPE_CODE_PTR,
217
                            TYPE_LENGTH (void_ptr_type), NULL);
218
  TYPE_TARGET_TYPE (tib_ptr_type) = tib_type;
219
 
220
  last_tlb_type = tib_ptr_type;
221
  last_gdbarch = gdbarch;
222
 
223
  return tib_ptr_type;
224
}
225
 
226
/* The $_tlb convenience variable is a bit special.  We don't know
227
   for sure the type of the value until we actually have a chance to
228
   fetch the data.  The type can change depending on gdbarch, so it is
229
   also dependent on which thread you have selected.  */
230
 
231
/* This function implements the lval_computed support for reading a
232
   $_tlb value.  */
233
 
234
static void
235
tlb_value_read (struct value *val)
236
{
237
  CORE_ADDR tlb;
238
  struct type *type = check_typedef (value_type (val));
239
 
240
  if (!target_get_tib_address (inferior_ptid, &tlb))
241
    error (_("Unable to read tlb"));
242
  store_typed_address (value_contents_raw (val), type, tlb);
243
}
244
 
245
/* This function implements the lval_computed support for writing a
246
   $_tlb value.  */
247
 
248
static void
249
tlb_value_write (struct value *v, struct value *fromval)
250
{
251
  error (_("Impossible to change the Thread Local Base"));
252
}
253
 
254
static struct lval_funcs tlb_value_funcs =
255
  {
256
    tlb_value_read,
257
    tlb_value_write
258
  };
259
 
260
 
261
/* Return a new value with the correct type for the tlb object of
262
   the current thread using architecture GDBARCH.  Return a void value
263
   if there's no object available.  */
264
 
265
static struct value *
266
tlb_make_value (struct gdbarch *gdbarch, struct internalvar *var)
267
{
268
  if (target_has_stack && !ptid_equal (inferior_ptid, null_ptid))
269
    {
270
      struct type *type = windows_get_tlb_type (gdbarch);
271
      return allocate_computed_value (type, &tlb_value_funcs, NULL);
272
    }
273
 
274
  return allocate_value (builtin_type (gdbarch)->builtin_void);
275
}
276
 
277
 
278
/* Display thread information block of a given thread.  */
279
 
280
static int
281
display_one_tib (ptid_t ptid)
282
{
283
  gdb_byte *tib = NULL;
284
  gdb_byte *index;
285
  CORE_ADDR thread_local_base;
286
  ULONGEST i, val, max, max_name, size, tib_size;
287
  ULONGEST sizeof_ptr = gdbarch_ptr_bit (target_gdbarch);
288
  enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch);
289
 
290
  if (sizeof_ptr == 64)
291
    {
292
      size = sizeof (uint64_t);
293
      tib_size = sizeof (thread_information_64);
294
      max = MAX_TIB64;
295
    }
296
  else
297
    {
298
      size = sizeof (uint32_t);
299
      tib_size = sizeof (thread_information_32);
300
      max = MAX_TIB32;
301
    }
302
 
303
  max_name = max;
304
 
305
  if (maint_display_all_tib)
306
    {
307
      tib_size = FULL_TIB_SIZE;
308
      max = tib_size / size;
309
    }
310
 
311
  tib = alloca (tib_size);
312
 
313
  if (target_get_tib_address (ptid, &thread_local_base) == 0)
314
    {
315
      printf_filtered (_("Unable to get thread local base for %s\n"),
316
        target_pid_to_str (ptid));
317
      return -1;
318
    }
319
 
320
  if (target_read (&current_target, TARGET_OBJECT_MEMORY,
321
                   NULL, tib, thread_local_base, tib_size) != tib_size)
322
    {
323
      printf_filtered (_("Unable to read thread information block for %s at \
324
address %s\n"),
325
        target_pid_to_str (ptid),
326
        paddress (target_gdbarch, thread_local_base));
327
      return -1;
328
    }
329
 
330
  printf_filtered (_("Thread Information Block %s at %s\n"),
331
                   target_pid_to_str (ptid),
332
                   paddress (target_gdbarch, thread_local_base));
333
 
334
  index = (gdb_byte *) tib;
335
 
336
  /* All fields have the size of a pointer, this allows to iterate
337
     using the same for loop for both layouts.  */
338
  for (i = 0; i < max; i++)
339
    {
340
      val = extract_unsigned_integer (index, size, byte_order);
341
      if (i < max_name)
342
        printf_filtered (_("%s is 0x%s\n"), TIB_NAME[i], phex (val, size));
343
      else if (val != 0)
344
        printf_filtered (_("TIB[0x%s] is 0x%s\n"), phex (i * size, 2),
345
                         phex (val, size));
346
      index += size;
347
    }
348
  return 1;
349
}
350
 
351
/* Display thread information block of a thread specified by ARGS.
352
   If ARGS is empty, display thread information block of current_thread
353
   if current_thread is non NULL.
354
   Otherwise ARGS is parsed and converted to a integer that should
355
   be the windows ThreadID (not the internal GDB thread ID).  */
356
 
357
static void
358
display_tib (char * args, int from_tty)
359
{
360
  if (args)
361
    {
362
      struct thread_info *tp;
363
      int gdb_id = value_as_long (parse_and_eval (args));
364
 
365
      tp = find_thread_id (gdb_id);
366
 
367
      if (!tp)
368
        error (_("Thread ID %d not known."), gdb_id);
369
 
370
      if (!target_thread_alive (tp->ptid))
371
        error (_("Thread ID %d has terminated."), gdb_id);
372
 
373
      display_one_tib (tp->ptid);
374
    }
375
  else if (!ptid_equal (inferior_ptid, null_ptid))
376
    display_one_tib (inferior_ptid);
377
}
378
 
379
void
380
windows_xfer_shared_library (const char* so_name, CORE_ADDR load_addr,
381
                             struct gdbarch *gdbarch, struct obstack *obstack)
382
{
383
  char *p;
384
  obstack_grow_str (obstack, "<library name=\"");
385
  p = xml_escape_text (so_name);
386
  obstack_grow_str (obstack, p);
387
  xfree (p);
388
  obstack_grow_str (obstack, "\"><segment address=\"");
389
  /* The symbols in a dll are offset by 0x1000, which is the the
390
     offset from 0 of the first byte in an image - because of the file
391
     header and the section alignment. */
392
  obstack_grow_str (obstack, paddress (gdbarch, load_addr + 0x1000));
393
  obstack_grow_str (obstack, "\"/></library>");
394
}
395
 
396
static void
397
show_maint_show_all_tib (struct ui_file *file, int from_tty,
398
                struct cmd_list_element *c, const char *value)
399
{
400
  fprintf_filtered (file, _("Show all non-zero elements of Thread Information \
401
Block is %s.\n"), value);
402
}
403
 
404
static void
405
info_w32_command (char *args, int from_tty)
406
{
407
  help_list (info_w32_cmdlist, "info w32 ", class_info, gdb_stdout);
408
}
409
 
410
static int w32_prefix_command_valid = 0;
411
void
412
init_w32_command_list (void)
413
{
414
  if (!w32_prefix_command_valid)
415
    {
416
      add_prefix_cmd ("w32", class_info, info_w32_command,
417
                      _("Print information specific to Win32 debugging."),
418
                      &info_w32_cmdlist, "info w32 ", 0, &infolist);
419
      w32_prefix_command_valid = 1;
420
    }
421
}
422
 
423
void
424
_initialize_windows_tdep (void)
425
{
426
  init_w32_command_list ();
427
  add_cmd ("thread-information-block", class_info, display_tib,
428
           _("Display thread information block."),
429
           &info_w32_cmdlist);
430
  add_alias_cmd ("tib", "thread-information-block", class_info, 1,
431
                 &info_w32_cmdlist);
432
 
433
  add_setshow_boolean_cmd ("show-all-tib", class_maintenance,
434
                           &maint_display_all_tib, _("\
435
Set whether to display all non-zero fields of thread information block."), _("\
436
Show whether to display all non-zero fields of thread information block."), _("\
437
Use \"on\" to enable, \"off\" to disable.\n\
438
If enabled, all non-zero fields of thread information block are displayed,\n\
439
even if their meaning is unknown."),
440
                           NULL,
441
                           show_maint_show_all_tib,
442
                           &maintenance_set_cmdlist,
443
                           &maintenance_show_cmdlist);
444
 
445
  /* Explicitly create without lookup, since that tries to create a
446
     value with a void typed value, and when we get here, gdbarch
447
     isn't initialized yet.  At this point, we're quite sure there
448
     isn't another convenience variable of the same name.  */
449
  create_internalvar_type_lazy ("_tlb", tlb_make_value);
450
}

powered by: WebSVN 2.1.0

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