* 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.
This commit is contained in:
parent
892bacea17
commit
de1b3c3d02
7 changed files with 288 additions and 687 deletions
|
@ -1,3 +1,48 @@
|
|||
2007-09-04 Pedro Alves <pedro_alves@portugalmail.pt>
|
||||
Daniel Jacobowitz <dan@codesourcery.com>
|
||||
|
||||
* 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 <pedro_alves@portugalmail.pt>
|
||||
Daniel Jacobowitz <dan@codesourcery.com>
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
30
gdb/i386-cygwin-tdep.h
Normal file
30
gdb/i386-cygwin-tdep.h
Normal file
|
@ -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 <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#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 */
|
21
gdb/infcmd.c
21
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
|
||||
|
|
435
gdb/win32-nat.c
435
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);
|
||||
|
||||
solib_end->next = so;
|
||||
solib_end = so;
|
||||
len = strlen (so->so_name);
|
||||
if (readsyms)
|
||||
solib_symbols_add (so, (CORE_ADDR) load_addr);
|
||||
/* 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;
|
||||
|
||||
return so->so_name;
|
||||
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);
|
||||
|
||||
bfd_close (abfd);
|
||||
}
|
||||
|
||||
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
|
||||
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;
|
||||
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)
|
||||
{
|
||||
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;
|
||||
if (writebuf)
|
||||
return -1;
|
||||
|
||||
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;
|
||||
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");
|
||||
|
||||
pstatus = (struct win32_pstatus *) buf;
|
||||
buf = obstack_finish (&obstack);
|
||||
len_avail = strlen (buf);
|
||||
if (offset >= len_avail)
|
||||
return 0;
|
||||
|
||||
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;
|
||||
if (len > len_avail - offset)
|
||||
len = len_avail - offset;
|
||||
memcpy (readbuf, buf + offset, len);
|
||||
|
||||
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);
|
||||
|
||||
if (!dll_code_sections_add (dll_name, (DWORD) base_addr, target))
|
||||
printf_unfiltered ("%s: Failed to map dll code sections.\n", dll_name);
|
||||
|
||||
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);
|
||||
|
||||
default:
|
||||
if (ops->beneath != NULL)
|
||||
return ops->beneath->to_xfer_partial (ops->beneath, object, annex,
|
||||
readbuf, writebuf, offset, len);
|
||||
return -1;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
|
|
@ -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);
|
||||
|
||||
solib_end->next = so;
|
||||
solib_end = so;
|
||||
len = strlen (so->so_name);
|
||||
if (readsyms)
|
||||
solib_symbols_add (so, (CORE_ADDR) load_addr);
|
||||
/* 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;
|
||||
|
||||
return so->so_name;
|
||||
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);
|
||||
|
||||
bfd_close (abfd);
|
||||
}
|
||||
|
||||
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
|
||||
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;
|
||||
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)
|
||||
{
|
||||
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;
|
||||
if (writebuf)
|
||||
return -1;
|
||||
|
||||
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;
|
||||
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");
|
||||
|
||||
pstatus = (struct win32_pstatus *) buf;
|
||||
buf = obstack_finish (&obstack);
|
||||
len_avail = strlen (buf);
|
||||
if (offset >= len_avail)
|
||||
return 0;
|
||||
|
||||
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;
|
||||
if (len > len_avail - offset)
|
||||
len = len_avail - offset;
|
||||
memcpy (readbuf, buf + offset, len);
|
||||
|
||||
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);
|
||||
|
||||
if (!dll_code_sections_add (dll_name, (DWORD) base_addr, target))
|
||||
printf_unfiltered ("%s: Failed to map dll code sections.\n", dll_name);
|
||||
|
||||
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);
|
||||
|
||||
default:
|
||||
if (ops->beneath != NULL)
|
||||
return ops->beneath->to_xfer_partial (ops->beneath, object, annex,
|
||||
readbuf, writebuf, offset, len);
|
||||
return -1;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
|
Loading…
Reference in a new issue