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