diff options
Diffstat (limited to 'gdb/windows-nat.c')
-rw-r--r-- | gdb/windows-nat.c | 433 |
1 files changed, 96 insertions, 337 deletions
diff --git a/gdb/windows-nat.c b/gdb/windows-nat.c index 7100e35..c960ac3 100644 --- a/gdb/windows-nat.c +++ b/gdb/windows-nat.c @@ -46,6 +46,7 @@ #include "buildsym.h" #include "symfile.h" #include "objfiles.h" +#include "gdb_obstack.h" #include "gdb_string.h" #include "gdbthread.h" #include "gdbcmd.h" @@ -54,12 +55,14 @@ #include "exec.h" #include "solist.h" #include "solib.h" +#include "xml-support.h" #include "i386-tdep.h" #include "i387-tdep.h" +#include "i386-cygwin-tdep.h" + static struct target_ops win32_ops; -static struct target_so_ops win32_so_ops; /* The starting and ending address of the cygwin1.dll text segment. */ static bfd_vma cygwin_load_start; @@ -598,123 +601,8 @@ safe_symbol_file_add (char *name, int from_tty, return p.ret; } -/* Get the loaded address of all sections, given that .text was loaded - at text_load. Assumes that all sections are subject to the same - relocation offset. Returns NULL if problems occur or if the - sections were not relocated. */ - -static struct section_addr_info * -get_relocated_section_addrs (bfd *abfd, CORE_ADDR text_load) -{ - struct section_addr_info *result = NULL; - int section_count = bfd_count_sections (abfd); - asection *text_section = bfd_get_section_by_name (abfd, ".text"); - CORE_ADDR text_vma; - - if (!text_section) - { - /* Couldn't get the .text section. Weird. */ - } - else if (text_load == (text_vma = bfd_get_section_vma (abfd, text_section))) - { - /* DLL wasn't relocated. */ - } - else - { - /* Figure out all sections' loaded addresses. The offset here is - such that taking a bfd_get_section_vma() result and adding - offset will give the real load address of the section. */ - - CORE_ADDR offset = text_load - text_vma; - - struct section_table *table_start = NULL; - struct section_table *table_end = NULL; - struct section_table *iter = NULL; - - build_section_table (abfd, &table_start, &table_end); - - for (iter = table_start; iter < table_end; ++iter) - { - /* Relocated addresses. */ - iter->addr += offset; - iter->endaddr += offset; - } - - result = build_section_addr_info_from_section_table (table_start, - table_end); - - xfree (table_start); - } - - return result; -} - -/* Add DLL symbol information. */ -static void -solib_symbols_add (struct so_list *so, CORE_ADDR load_addr) -{ - struct section_addr_info *addrs = NULL; - static struct objfile *result = NULL; - char *name = so->so_name; - bfd *abfd = NULL; - char *p; - - /* The symbols in a dll are offset by 0x1000, which is the - the offset from 0 of the first byte in an image - because - of the file header and the section alignment. */ - - if (!name || !name[0]) - return; - - abfd = bfd_openr (name, "pei-i386"); - - if (!abfd) - { - /* pei failed - try pe */ - abfd = bfd_openr (name, "pe-i386"); - } - - if (abfd) - { - if (bfd_check_format (abfd, bfd_object)) - addrs = get_relocated_section_addrs (abfd, load_addr); - } - - if (addrs) - { - result = safe_symbol_file_add (name, 0, addrs, 0, OBJF_SHARED); - free_section_addr_info (addrs); - } - else - { - /* Fallback on handling just the .text section. */ - struct cleanup *my_cleanups; - - addrs = alloc_section_addr_info (1); - my_cleanups = make_cleanup (xfree, addrs); - addrs->other[0].name = ".text"; - addrs->other[0].addr = load_addr; - - result = safe_symbol_file_add (name, 0, addrs, 0, OBJF_SHARED); - do_cleanups (my_cleanups); - } - - p = strchr (so->so_name, '\0') - (sizeof ("/cygwin1.dll") - 1); - if (p >= so->so_name && strcasecmp (p, "/cygwin1.dll") == 0) - { - asection *text = bfd_get_section_by_name (abfd, ".text"); - cygwin_load_start = bfd_section_vma (abfd, text); - cygwin_load_end = cygwin_load_start + bfd_section_size (abfd, text); - } - - bfd_close (abfd); - - so->symbols_loaded = !!result; - return; -} - -static char * -register_loaded_dll (const char *name, DWORD load_addr, int readsyms) +static struct so_list * +win32_make_so (const char *name, DWORD load_addr) { struct so_list *so; char buf[MAX_PATH + 1]; @@ -723,7 +611,6 @@ register_loaded_dll (const char *name, DWORD load_addr, int readsyms) WIN32_FIND_DATA w32_fd; HANDLE h = FindFirstFile(name, &w32_fd); MEMORY_BASIC_INFORMATION m; - size_t len; if (h == INVALID_HANDLE_VALUE) strcpy (buf, name); @@ -751,15 +638,40 @@ register_loaded_dll (const char *name, DWORD load_addr, int readsyms) so->lm_info = (struct lm_info *) xmalloc (sizeof (struct lm_info)); so->lm_info->load_addr = load_addr; cygwin_conv_to_posix_path (buf, so->so_name); - strcpy (so->so_original_name, so->so_name); + strcpy (so->so_original_name, name); + + /* Record cygwin1.dll .text start/end. */ + p = strchr (so->so_name, '\0') - (sizeof ("/cygwin1.dll") - 1); + if (p >= so->so_name && strcasecmp (p, "/cygwin1.dll") == 0) + { + bfd *abfd; + asection *text = NULL; + CORE_ADDR text_vma; + + abfd = bfd_openr (name, "pei-i386"); + + if (!abfd) + return so; + + if (bfd_check_format (abfd, bfd_object)) + text = bfd_get_section_by_name (abfd, ".text"); + + if (!text) + { + bfd_close (abfd); + return so; + } + + /* The symbols in a dll are offset by 0x1000, which is the the + offset from 0 of the first byte in an image - because of the + file header and the section alignment. */ + cygwin_load_start = load_addr + 0x1000; + cygwin_load_end = cygwin_load_start + bfd_section_size (abfd, text); - solib_end->next = so; - solib_end = so; - len = strlen (so->so_name); - if (readsyms) - solib_symbols_add (so, (CORE_ADDR) load_addr); + bfd_close (abfd); + } - return so->so_name; + return so; } static char * @@ -820,11 +732,13 @@ handle_load_dll (void *dummy) dll_name = dll_buf; if (*dll_name == '\0') - dll_name = get_image_name (current_process_handle, event->lpImageName, event->fUnicode); + dll_name = get_image_name (current_process_handle, + event->lpImageName, event->fUnicode); if (!dll_name) return 1; - register_loaded_dll (dll_name, (DWORD) event->lpBaseOfDll + 0x1000, auto_solib_add); + solib_end->next = win32_make_so (dll_name, (DWORD) event->lpBaseOfDll); + solib_end = solib_end->next; return 1; } @@ -834,27 +748,13 @@ win32_free_so (struct so_list *so) { if (so->lm_info) xfree (so->lm_info); -} - -static void -win32_relocate_section_addresses (struct so_list *so, - struct section_table *sec) -{ - /* FIXME */ - return; -} - -static void -win32_solib_create_inferior_hook (void) -{ - solib_add (NULL, 0, NULL, auto_solib_add); - return; + xfree (so); } static int handle_unload_dll (void *dummy) { - DWORD lpBaseOfDll = (DWORD) current_event.u.UnloadDll.lpBaseOfDll + 0x1000; + DWORD lpBaseOfDll = (DWORD) current_event.u.UnloadDll.lpBaseOfDll; struct so_list *so; for (so = &solib_start; so->next != NULL; so = so->next) @@ -864,7 +764,7 @@ handle_unload_dll (void *dummy) so->next = sodel->next; if (!so->next) solib_end = so; - free_so (sodel); + win32_free_so (sodel); solib_add (NULL, 0, NULL, auto_solib_add); return 1; } @@ -882,12 +782,6 @@ win32_clear_solib (void) solib_end = &solib_start; } -static void -win32_special_symbol_handling (void) -{ - return; -} - /* Load DLL symbol info. */ void dll_symbol_command (char *args, int from_tty) @@ -1455,11 +1349,9 @@ get_win32_debug_event (int pid, struct target_waitstatus *ourstatus) if (saw_create != 1) break; catch_errors (handle_load_dll, NULL, (char *) "", RETURN_MASK_ALL); - registers_changed (); /* mark all regs invalid */ ourstatus->kind = TARGET_WAITKIND_LOADED; ourstatus->value.integer = 0; retval = main_thread_id; - re_enable_breakpoints_in_shlibs (); break; case UNLOAD_DLL_DEBUG_EVENT: @@ -1470,9 +1362,9 @@ get_win32_debug_event (int pid, struct target_waitstatus *ourstatus) if (saw_create != 1) break; catch_errors (handle_unload_dll, NULL, (char *) "", RETURN_MASK_ALL); - registers_changed (); /* mark all regs invalid */ - /* ourstatus->kind = TARGET_WAITKIND_UNLOADED; - does not exist yet. */ + ourstatus->kind = TARGET_WAITKIND_LOADED; + ourstatus->value.integer = 0; + retval = main_thread_id; break; case EXCEPTION_DEBUG_EVENT: @@ -1580,6 +1472,7 @@ do_initial_win32_stuff (DWORD pid) debug_registers_used = 0; for (i = 0; i < sizeof (dr) / sizeof (dr[0]); i++) dr[i] = 0; + cygwin_load_start = cygwin_load_end = 0; current_event.dwProcessId = pid; memset (¤t_event, 0, sizeof (current_event)); push_target (&win32_ops); @@ -2070,188 +1963,65 @@ cygwin_pid_to_str (ptid_t ptid) return buf; } -typedef struct -{ - struct target_ops *target; - bfd_vma addr; -} map_code_section_args; - -static void -map_single_dll_code_section (bfd *abfd, asection *sect, void *obj) -{ - int old; - int update_coreops; - struct section_table *new_target_sect_ptr; - - map_code_section_args *args = (map_code_section_args *) obj; - struct target_ops *target = args->target; - if (sect->flags & SEC_CODE) - { - update_coreops = core_ops.to_sections == target->to_sections; - - if (target->to_sections) - { - old = target->to_sections_end - target->to_sections; - target->to_sections = (struct section_table *) - xrealloc ((char *) target->to_sections, - (sizeof (struct section_table)) * (1 + old)); - } - else - { - old = 0; - target->to_sections = (struct section_table *) - xmalloc ((sizeof (struct section_table))); - } - target->to_sections_end = target->to_sections + (1 + old); - - /* Update the to_sections field in the core_ops structure - if needed. */ - if (update_coreops) - { - core_ops.to_sections = target->to_sections; - core_ops.to_sections_end = target->to_sections_end; - } - new_target_sect_ptr = target->to_sections + old; - new_target_sect_ptr->addr = args->addr + bfd_section_vma (abfd, sect); - new_target_sect_ptr->endaddr = args->addr + bfd_section_vma (abfd, sect) + - bfd_section_size (abfd, sect);; - new_target_sect_ptr->the_bfd_section = sect; - new_target_sect_ptr->bfd = abfd; - } -} - -static int -dll_code_sections_add (const char *dll_name, int base_addr, struct target_ops *target) -{ - bfd *dll_bfd; - map_code_section_args map_args; - asection *lowest_sect; - char *name; - if (dll_name == NULL || target == NULL) - return 0; - name = xstrdup (dll_name); - dll_bfd = bfd_openr (name, "pei-i386"); - if (dll_bfd == NULL) - return 0; - - if (bfd_check_format (dll_bfd, bfd_object)) - { - lowest_sect = bfd_get_section_by_name (dll_bfd, ".text"); - if (lowest_sect == NULL) - return 0; - map_args.target = target; - map_args.addr = base_addr - bfd_section_vma (dll_bfd, lowest_sect); - - bfd_map_over_sections (dll_bfd, &map_single_dll_code_section, (void *) (&map_args)); - } - - return 1; -} - -static void -core_section_load_dll_symbols (bfd *abfd, asection *sect, void *obj) +static LONGEST +win32_xfer_shared_libraries (struct target_ops *ops, + enum target_object object, const char *annex, + gdb_byte *readbuf, const gdb_byte *writebuf, + ULONGEST offset, LONGEST len) { - struct target_ops *target = (struct target_ops *) obj; - - DWORD base_addr; - - int dll_name_size; - struct win32_pstatus *pstatus; + struct obstack obstack; + const char *buf; + LONGEST len_avail; struct so_list *so; - char *dll_name; - char *buf = NULL; - char *p; - struct objfile *objfile; - const char *dll_basename; - - if (strncmp (sect->name, ".module", 7) != 0) - return; - - buf = (char *) xmalloc (bfd_get_section_size (sect) + 1); - if (!buf) - { - printf_unfiltered ("memory allocation failed for %s\n", sect->name); - goto out; - } - if (!bfd_get_section_contents (abfd, sect, buf, 0, bfd_get_section_size (sect))) - goto out; - pstatus = (struct win32_pstatus *) buf; + if (writebuf) + return -1; - memmove (&base_addr, &(pstatus->data.module_info.base_address), sizeof (base_addr)); - dll_name_size = pstatus->data.module_info.module_name_size; - if (offsetof (struct win32_pstatus, data.module_info.module_name) + dll_name_size > bfd_get_section_size (sect)) - goto out; + obstack_init (&obstack); + obstack_grow_str (&obstack, "<library-list>\n"); + for (so = solib_start.next; so; so = so->next) + win32_xfer_shared_library (so->so_name, so->lm_info->load_addr, &obstack); + obstack_grow_str0 (&obstack, "</library-list>\n"); - dll_name = pstatus->data.module_info.module_name; - - if (!(dll_basename = strrchr (dll_name, '/'))) - dll_basename = dll_name; - else - dll_basename++; - - ALL_OBJFILES (objfile) - { - char *objfile_basename = strrchr (objfile->name, '/'); - - if (objfile_basename && - strcasecmp (dll_basename, objfile_basename + 1) == 0) - goto out; - } - - base_addr += 0x1000; - dll_name = register_loaded_dll (dll_name, base_addr, 1); + buf = obstack_finish (&obstack); + len_avail = strlen (buf); + if (offset >= len_avail) + return 0; - if (!dll_code_sections_add (dll_name, (DWORD) base_addr, target)) - printf_unfiltered ("%s: Failed to map dll code sections.\n", dll_name); + if (len > len_avail - offset) + len = len_avail - offset; + memcpy (readbuf, buf + offset, len); -out: - if (buf) - xfree (buf); - return; + obstack_free (&obstack, NULL); + return len; } -static struct so_list * -win32_current_sos (void) +static LONGEST +win32_xfer_partial (struct target_ops *ops, enum target_object object, + const char *annex, gdb_byte *readbuf, + const gdb_byte *writebuf, ULONGEST offset, LONGEST len) { - struct so_list *sop; - struct so_list *start = NULL; - struct so_list *last = NULL; - - if (!solib_start.next && core_bfd) + switch (object) { - win32_clear_solib (); - bfd_map_over_sections (core_bfd, &core_section_load_dll_symbols, - &win32_ops); - } + case TARGET_OBJECT_MEMORY: + if (readbuf) + return (*ops->deprecated_xfer_memory) (offset, readbuf, + len, 0/*write*/, NULL, ops); + if (writebuf) + return (*ops->deprecated_xfer_memory) (offset, (gdb_byte *) writebuf, + len, 1/*write*/, NULL, ops); + return -1; + + case TARGET_OBJECT_LIBRARIES: + return win32_xfer_shared_libraries (ops, object, annex, readbuf, + writebuf, offset, len); - for (sop = solib_start.next; sop; sop = sop->next) - { - struct so_list *new = XZALLOC (struct so_list); - strcpy (new->so_name, sop->so_name); - strcpy (new->so_original_name, sop->so_original_name); - if (!start) - last = start = new; - else - { - last->next = new; - last = new; - } + default: + if (ops->beneath != NULL) + return ops->beneath->to_xfer_partial (ops->beneath, object, annex, + readbuf, writebuf, offset, len); + return -1; } - - return start; -} - -static int -open_symbol_file_object (void *from_ttyp) -{ - return 0; -} - -static int -in_dynsym_resolve_code (CORE_ADDR pc) -{ - return 0; } static void @@ -2270,6 +2040,7 @@ init_win32_ops (void) win32_ops.to_store_registers = win32_store_inferior_registers; win32_ops.to_prepare_to_store = win32_prepare_to_store; win32_ops.deprecated_xfer_memory = win32_xfer_memory; + win32_ops.to_xfer_partial = win32_xfer_partial; win32_ops.to_files_info = win32_files_info; win32_ops.to_insert_breakpoint = memory_insert_breakpoint; win32_ops.to_remove_breakpoint = memory_remove_breakpoint; @@ -2294,18 +2065,6 @@ init_win32_ops (void) win32_ops.to_has_execution = 1; win32_ops.to_magic = OPS_MAGIC; win32_ops.to_pid_to_exec_file = win32_pid_to_exec_file; - - win32_so_ops.relocate_section_addresses = win32_relocate_section_addresses; - win32_so_ops.free_so = win32_free_so; - win32_so_ops.clear_solib = win32_clear_solib; - win32_so_ops.solib_create_inferior_hook = win32_solib_create_inferior_hook; - win32_so_ops.special_symbol_handling = win32_special_symbol_handling; - win32_so_ops.current_sos = win32_current_sos; - win32_so_ops.open_symbol_file_object = open_symbol_file_object; - win32_so_ops.in_dynsym_resolve_code = in_dynsym_resolve_code; - - /* FIXME: Don't do this here. *_gdbarch_init() should set so_ops. */ - current_target_so_ops = &win32_so_ops; } static void |