From: Pedro Alves Date: Tue, 4 Sep 2007 01:12:18 +0000 (+0000) Subject: * infcmd.c (post_create_inferior): Update comment. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=de1b3c3d02b5d4c969a36d3bddcedbbce2551d19;p=binutils-gdb.git * infcmd.c (post_create_inferior): Update comment. (run_command_1): Always call post_create_inferior with 0 as from_tty. * i386-cygwin-tdep.h: New. * i386-cygwin-tdep.c: Include "i386-cygwin-tdep.h". (win32_xfer_shared_library): Make it extern. * win32-nat.c: Include gdb_obstack.h and xml-support.h and i386-cygwin-tdep.h. (win32_so_ops): Delete. (get_relocated_section_addrs): Delete. (solib_symbols_add): Delete. (register_loaded_dll): Delete. (win32_make_so): New. (handle_load_dll): Use win32_make_so. (win32_free_so): Free the passed in so. (win32_relocate_section_addresses): Delete. (win32_solib_create_inferior_hook): Delete. (handle_unload_dll): Don't add PE offset here. Free so with win32_free_so instead of free_so. (win32_special_symbol_handling): Delete. (get_win32_debug_event): Remove unneeded calls. Set state to TARGET_WAITKIND_LOADED on a dll unload. (do_initial_win32_stuff): Clear cygwin_load_start and cygwin_load_end. (map_code_section_args): Delete. (dll_code_sections_add): Delete. (core_section_load_dll_symbols): Delete. (win32_xfer_shared_libraries): New. (win32_current_sos): Delete. (win32_xfer_partial): New. (open_symbol_file_object): Delete. (in_dynsym_resolve_code): Delete. (init_win32_ops): Set win32_xfer_partial as to_xfer_partial member of win32_ops. Remove win32_so_ops settings. Don't set current_target_so_ops here. * Makefile.in (i386_cygwin_tdep_h): New variable. (i386-cygwin-tdep.o): Update dependencies. (win32-nat.o): Update dependencies. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 7dce17cb42a..d8eca3ad187 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,48 @@ +2007-09-04 Pedro Alves + Daniel Jacobowitz + + * infcmd.c (post_create_inferior): Update comment. + (run_command_1): Always call post_create_inferior with 0 as + from_tty. + + * i386-cygwin-tdep.h: New. + * i386-cygwin-tdep.c: Include "i386-cygwin-tdep.h". + (win32_xfer_shared_library): Make it extern. + + * win32-nat.c: Include gdb_obstack.h and xml-support.h and + i386-cygwin-tdep.h. + (win32_so_ops): Delete. + (get_relocated_section_addrs): Delete. + (solib_symbols_add): Delete. + (register_loaded_dll): Delete. + (win32_make_so): New. + (handle_load_dll): Use win32_make_so. + (win32_free_so): Free the passed in so. + (win32_relocate_section_addresses): Delete. + (win32_solib_create_inferior_hook): Delete. + (handle_unload_dll): Don't add PE offset here. Free so with + win32_free_so instead of free_so. + (win32_special_symbol_handling): Delete. + (get_win32_debug_event): Remove unneeded calls. Set state to + TARGET_WAITKIND_LOADED on a dll unload. + (do_initial_win32_stuff): Clear cygwin_load_start and + cygwin_load_end. + (map_code_section_args): Delete. + (dll_code_sections_add): Delete. + (core_section_load_dll_symbols): Delete. + (win32_xfer_shared_libraries): New. + (win32_current_sos): Delete. + (win32_xfer_partial): New. + (open_symbol_file_object): Delete. + (in_dynsym_resolve_code): Delete. + (init_win32_ops): Set win32_xfer_partial as to_xfer_partial member + of win32_ops. Remove win32_so_ops settings. Don't set + current_target_so_ops here. + + * Makefile.in (i386_cygwin_tdep_h): New variable. + (i386-cygwin-tdep.o): Update dependencies. + (win32-nat.o): Update dependencies. + 2007-09-04 Pedro Alves Daniel Jacobowitz diff --git a/gdb/Makefile.in b/gdb/Makefile.in index 4deb4f5d60a..a3a350b1789 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -734,6 +734,7 @@ gnu_v2_abi_h = gnu-v2-abi.h gregset_h = gregset.h hppa_tdep_h = hppa-tdep.h i386bsd_nat_h = i386bsd-nat.h +i386_cygwin_tdep_h = i386-cygwin-tdep.h i386_linux_tdep_h = i386-linux-tdep.h i386_tdep_h = i386-tdep.h i387_tdep_h = i387-tdep.h @@ -2103,7 +2104,7 @@ i386bsd-tdep.o: i386bsd-tdep.c $(defs_h) $(arch_utils_h) $(frame_h) \ $(gdbcore_h) $(regcache_h) $(osabi_h) $(gdb_string_h) $(i386_tdep_h) i386-cygwin-tdep.o: i386-cygwin-tdep.c $(defs_h) $(osabi_h) $(gdb_string_h) \ $(i386_tdep_h) $(regset_h) $(gdb_obstack_h) $(xml_support_h) \ - $(gdbcore_h) + $(gdbcore_h) $(i386_cygwin_tdep_h) i386fbsd-nat.o: i386fbsd-nat.c $(defs_h) $(inferior_h) $(regcache_h) \ $(target_h) $(fbsd_nat_h) $(i386_tdep_h) $(i386bsd_nat_h) \ $(bsd_kvm_h) @@ -2838,7 +2839,8 @@ win32-nat.o: win32-nat.c $(defs_h) $(frame_h) $(inferior_h) $(target_h) \ $(exceptions_h) $(gdbcore_h) $(command_h) $(completer_h) \ $(regcache_h) $(top_h) $(buildsym_h) $(symfile_h) $(objfiles_h) \ $(gdb_string_h) $(gdbthread_h) $(gdbcmd_h) $(exec_h) $(solist_h) \ - $(solib_h) $(i386_tdep_h) $(i387_tdep_h) + $(solib_h) $(i386_tdep_h) $(i387_tdep_h) $(gdb_obstack_h) \ + $(xml_support_h) $(i386_cygwin_tdep_h) win32-termcap.o: win32-termcap.c wrapper.o: wrapper.c $(defs_h) $(value_h) $(exceptions_h) $(wrapper_h) \ $(ui_out_h) diff --git a/gdb/i386-cygwin-tdep.c b/gdb/i386-cygwin-tdep.c index 0185a0a36b3..9aa2773743a 100644 --- a/gdb/i386-cygwin-tdep.c +++ b/gdb/i386-cygwin-tdep.c @@ -21,6 +21,7 @@ #include "osabi.h" #include "gdb_string.h" #include "i386-tdep.h" +#include "i386-cygwin-tdep.h" #include "regset.h" #include "gdb_obstack.h" #include "xml-support.h" @@ -108,7 +109,7 @@ i386_win32_regset_from_core_section (struct gdbarch *gdbarch, return NULL; } -static void +void win32_xfer_shared_library (const char* so_name, CORE_ADDR load_addr, struct obstack *obstack) { diff --git a/gdb/i386-cygwin-tdep.h b/gdb/i386-cygwin-tdep.h new file mode 100644 index 00000000000..dfca8496a52 --- /dev/null +++ b/gdb/i386-cygwin-tdep.h @@ -0,0 +1,30 @@ +/* Target-dependent code for Cygwin running on i386's, for GDB. + + Copyright (C) 2007 + Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#ifndef I386_CYGWIN_TDEP_H +#define I386_CYGWIN_TDEP_H + +struct obstack; + +extern void win32_xfer_shared_library (const char* so_name, + CORE_ADDR load_addr, + struct obstack *obstack); + +#endif /* I386_CYGWIN_TDEP_H */ diff --git a/gdb/infcmd.c b/gdb/infcmd.c index f1838068ebb..1690b5cde11 100644 --- a/gdb/infcmd.c +++ b/gdb/infcmd.c @@ -417,7 +417,9 @@ post_create_inferior (struct target_ops *target, int from_tty) { /* Sometimes the platform-specific hook loads initial shared libraries, and sometimes it doesn't. Try to do so first, so - that we can add them with the correct value for FROM_TTY. */ + that we can add them with the correct value for FROM_TTY. + If we made all the inferior hook methods consistent, + this call could be removed. */ #ifdef SOLIB_ADD SOLIB_ADD (NULL, from_tty, target, auto_solib_add); #else @@ -558,7 +560,9 @@ run_command_1 (char *args, int from_tty, int tbreak_at_main) target_create_inferior (exec_file, get_inferior_args (), environ_vector (inferior_environ), from_tty); - post_create_inferior (¤t_target, from_tty); + /* Pass zero for FROM_TTY, because at this point the "run" command + has done its thing; now we are setting up the running program. */ + post_create_inferior (¤t_target, 0); /* Start the target running. */ proceed ((CORE_ADDR) -1, TARGET_SIGNAL_0, 0); @@ -1193,11 +1197,11 @@ print_return_value (int struct_return, struct type *value_type) internal_error (__FILE__, __LINE__, _("bad switch")); } + stb = ui_out_stream_new (uiout); + old_chain = make_cleanup_ui_out_stream_delete (stb); if (value) { /* Print it. */ - stb = ui_out_stream_new (uiout); - old_chain = make_cleanup_ui_out_stream_delete (stb); ui_out_text (uiout, "Value returned is "); ui_out_field_fmt (uiout, "gdb-result-var", "$%d", record_latest_value (value)); @@ -1205,15 +1209,16 @@ print_return_value (int struct_return, struct type *value_type) value_print (value, stb->stream, 0, Val_no_prettyprint); ui_out_field_stream (uiout, "return-value", stb); ui_out_text (uiout, "\n"); - do_cleanups (old_chain); } else { + /* Just print the type. */ ui_out_text (uiout, "Value returned has type: "); - ui_out_field_string (uiout, "return-type", TYPE_NAME (value_type)); - ui_out_text (uiout, "."); - ui_out_text (uiout, " Cannot determine contents\n"); + type_print (value_type, NULL, stb->stream, 0); + ui_out_field_stream (uiout, "return-type", stb); + ui_out_text (uiout, ". Cannot determine contents.\n"); } + do_cleanups (old_chain); } /* Stuff that needs to be done by the finish command after the target diff --git a/gdb/win32-nat.c b/gdb/win32-nat.c index 7100e359122..c960ac3c5bb 100644 --- a/gdb/win32-nat.c +++ b/gdb/win32-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, "\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, "\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 diff --git a/gdb/windows-nat.c b/gdb/windows-nat.c index 7100e359122..c960ac3c5bb 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, "\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, "\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