Windows DLL support update (a bit slimmer version)

Pedro Alves
2007-08-19T22:06:20Z

[-- Attachment #1: Type: text/plain, Size: 913 bytes --]

Hi,

Here is the new patch that migrates win32-nat.c to the new
solib-target.c solib support, finally enabling a native cygwin
gdb to take advantage of the new gdbserver dll support.

The core dump support migrated into its own patch, which
moves it into i386-cygwin-tdep.c, so this consists mostly
of win32-nat.c changes. It should only be applied after
my previous patch is in.

This patch removes references to master_so_list, by reverting
to the same method the current cvs version uses, except that
the current version was broken when cygwin1.dll wasn't
loaded at its prefered load address (was relocated).
I've ensured that this version still correctly ignores
the internal cygwin exceptions. I'm sorry to have shoving
in more funcionality than was needed in the previous rounds
and for triggering extra review work ... If we ever meet,
you can splap me in my forehead (once). :)

Cheers,
Pedro Alves

[-- Attachment #2: solib_target_cygwin.diff --]
[-- Type: text/x-diff, Size: 23285 bytes --]

2007-08-19 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.

---
gdb/Makefile.in | 6
gdb/i386-cygwin-tdep.c | 3
gdb/i386-cygwin-tdep.h | 30 +++
gdb/infcmd.c | 8
gdb/win32-nat.c | 447 +++++++++++--------------------------------------
5 files changed, 145 insertions(+), 349 deletions(-)

Index: src/gdb/infcmd.c
===================================================================
--- src.orig/gdb/infcmd.c 2007-08-19 20:14:42.000000000 +0100
+++ src/gdb/infcmd.c 2007-08-19 22:02:58.000000000 +0100
@@ -419,7 +419,9 @@ post_create_inferior (struct target_ops
{
/* 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
@@ -560,7 +562,9 @@ run_command_1 (char *args, int from_tty,
target_create_inferior (exec_file, get_inferior_args (),
environ_vector (inferior_environ), from_tty);

- post_create_inferior (&current_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 (&current_target, 0);

/* Start the target running. */
proceed ((CORE_ADDR) -1, TARGET_SIGNAL_0, 0);
Index: src/gdb/win32-nat.c
===================================================================
--- src.orig/gdb/win32-nat.c 2007-08-19 20:23:24.000000000 +0100
+++ src/gdb/win32-nat.c 2007-08-19 22:26:40.000000000 +0100
@@ -48,6 +48,7 @@
#include "buildsym.h"
#include "symfile.h"
#include "objfiles.h"
+#include "gdb_obstack.h"
#include "gdb_string.h"
#include "gdbthread.h"
#include "gdbcmd.h"
@@ -56,12 +57,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;
@@ -600,123 +603,8 @@ safe_symbol_file_add (char *name, int fr
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];
@@ -725,7 +613,6 @@ register_loaded_dll (const char *name, D
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);
@@ -753,15 +640,40 @@ register_loaded_dll (const char *name, D
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");

- solib_end->next = so;
- solib_end = so;
- len = strlen (so->so_name);
- if (readsyms)
- solib_symbols_add (so, (CORE_ADDR) load_addr);
+ if (!abfd)
+ return so;

- return so->so_name;
+ 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 *
@@ -822,11 +734,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;
}
@@ -836,27 +750,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)
@@ -866,7 +766,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;
}
@@ -884,12 +784,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)
@@ -1457,11 +1351,9 @@ get_win32_debug_event (int pid, struct t
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:
@@ -1472,9 +1364,9 @@ get_win32_debug_event (int pid, struct t
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:
@@ -1582,6 +1474,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 (&current_event, 0, sizeof (current_event));
push_target (&win32_ops);
@@ -2072,188 +1965,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)
-{
- struct target_ops *target = (struct target_ops *) obj;
-
- DWORD base_addr;
-
- int dll_name_size;
- struct win32_pstatus *pstatus;
+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 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;
-
- 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;
-
- dll_name = pstatus->data.module_info.module_name;
+ if (writebuf)
+ return -1;

- 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_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");
+
+ buf = obstack_finish (&obstack);
+ len_avail = strlen (buf);
+ if (offset >= len_avail)
+ return 0;

-static struct so_list *
-win32_current_sos (void)
-{
- struct so_list *sop;
- struct so_list *start = NULL;
- struct so_list *last = NULL;
+ if (len > len_avail - offset)
+ len = len_avail - offset;
+ memcpy (readbuf, buf + offset, len);
+
+ obstack_free (&obstack, NULL);
+ return len;
+}
+
+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)
+{
+ switch (object)
+ {
+ 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);

- if (!solib_start.next && core_bfd)
- {
- win32_clear_solib ();
- bfd_map_over_sections (core_bfd, &core_section_load_dll_symbols,
- &win32_ops);
- }
-
- 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
@@ -2272,6 +2042,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;
@@ -2296,18 +2067,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
Index: src/gdb/Makefile.in
===================================================================
--- src.orig/gdb/Makefile.in 2007-08-19 21:46:14.000000000 +0100
+++ src/gdb/Makefile.in 2007-08-19 22:11:56.000000000 +0100
@@ -733,6 +733,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
@@ -2102,7 +2103,7 @@ i386bsd-tdep.o: i386bsd-tdep.c $(defs_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)
@@ -2837,7 +2838,8 @@ win32-nat.o: win32-nat.c $(defs_h) $(fra
$(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)
Index: src/gdb/i386-cygwin-tdep.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ src/gdb/i386-cygwin-tdep.h 2007-08-19 22:02:58.000000000 +0100
@@ -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 2 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, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA. */
+
+#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 */
Index: src/gdb/i386-cygwin-tdep.c
===================================================================
--- src.orig/gdb/i386-cygwin-tdep.c 2007-08-19 21:43:46.000000000 +0100
+++ src/gdb/i386-cygwin-tdep.c 2007-08-19 22:08:12.000000000 +0100
@@ -23,6 +23,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"
@@ -110,7 +111,7 @@ i386_win32_regset_from_core_section (str
return NULL;
}

-static void
+void
win32_xfer_shared_library (const char* so_name, CORE_ADDR load_addr,
struct obstack *obstack)
{