Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* Windows DLL support update.
@ 2007-08-14  0:24 Pedro Alves
  2007-08-14  0:43 ` Pedro Alves
  2007-08-14 12:10 ` Christopher Faylor
  0 siblings, 2 replies; 7+ messages in thread
From: Pedro Alves @ 2007-08-14  0:24 UTC (permalink / raw)
  To: gdb-patches

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

Hi all,

Here is the new version of the patch that converts native win32
debugging to use the new solib-target.c.  The biggest difference
compared to the latest version Daniel posted is that this
version maintains the list of loaded dlls separately from
solib-target.c, similarly to what is done in current cvs.  The
previous versions always queried the target for the dll list
and maintained no private list.  At the time it sounded like a
good idea, since, well, if Windows already maintains the list, we
might as well just read it.  It turns out that this wasn't perfect
because it still required us to keep at least the last loaded dll
(last_loaded_dll_valid mechanism in the previous version),
because when a dll (un)load event occurs, the loader hasn't
completely finished the load, and the dll isn't reported on
the lists.  This version is now similar to what current
gdbserver is doing.

I've kept this version of the patch to a minimum, by removing the
fixes of formatting violations, typos and dead code removals
from the patch.

The patch could be easily be split further.  Probably the writebuf
fix in corelow.c and the infcmd.c hunks could go in on their own.
The xml and objstack changes could also go in separately, but
they don't have any other users yet.  Daniel, you've written
most of the changes outside of win32-nat.c, I'll leave that decision
to you.  If you want me to do that, just say so.

I've ran the testsuite on Windows XP several times against an
unpatched current cvs, against a gdb patched with the
previous patch, and with this patch.  I've carefully compared
the results (1), of all the runs and didn't see any regression.
I did see one consistent improvement in unload.exp

-FAIL: gdb.base/unload.exp: continuing to end of program
-FAIL: gdb.base/unload.exp: rerun to shared library breakpoint
-FAIL: gdb.base/unload.exp: continuing to end of program second time (the
program is no longer running)
+PASS: gdb.base/unload.exp: continuing to end of program
+PASS: gdb.base/unload.exp: rerun to shared library breakpoint
+PASS: gdb.base/unload.exp: continuing to end of program second time

I didn't really took the time to see why these tests
failed before.

(1) Test results aren't stable.  I always have to repeat a few,
because they usually fail UNTESTED due to several reasons, like
the compile step failing because the output binfile is still
loaded by the previous test (Windows only), or, eg:
     (...)
     -PASS: gdb.cp/maint.exp: maint cp first_component foo<
     -PASS: gdb.cp/maint.exp: maint cp first_component foo(
     -PASS: gdb.cp/maint.exp: maint cp first_component bool operator<<char>
     -PASS: gdb.cp/maint.exp: maint cp namespace
     +ERROR: Process no longer exists
     +UNRESOLVED: gdb.cp/maint.exp: maint cp first_component operator  ->
     +ERROR: Couldn't send maint cp first_component foo() to GDB.
     +UNRESOLVED: gdb.cp/maint.exp: maint cp first_component foo()
     +ERROR: Couldn't send maint cp first_component foo(int) to GDB.
     +UNRESOLVED: gdb.cp/maint.exp: maint cp first_component foo(int)
     (...)

This should also fix the problem Joel reported at:
[win32] wrong solib from/to addresses
http://sourceware.org/ml/gdb-patches/2007-06/msg00210.html

... but I have no Vista to test on.

Cheers,
Pedro Alves

P.S.

The testresults (c, c++) look somewhat (1 above) like this with gcc+gdb patches
to overcome the '__main emitted in main breaks run_to_main' problem.

# of expected passes            9441
# of unexpected failures        177
# of unexpected successes       1
# of expected failures          47
# of known failures             30
# of unresolved testcases       21
# of untested testcases         16
# of unsupported tests          32





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

2007-07-02  Pedro Alves  <pedro_alves@portugalmail.pt>
	    Daniel Jacobowitz  <dan@codesourcery.com>

	* corelow.c (core_xfer_partial): Pass writebuf to
	deprecated_xfer_memory in TARGET_OBJECT_MEMORY case.  Add
	TARGET_OBJECT_LIBRARIES handling.
	* gdb_obstack.h (obstack_grow_str, obstack_grow_str0): New.
	* gdbcore.h: Include target.h.
	(struct core_fns): Add xfer_shared_libraries.
	* infcmd.c (post_create_inferior): Update comment.
	(run_command_1): Always call post_create_inferior with 0 as
	from_tty.
	* win32-nat.c: Include gdb_obstack.h and xml-support.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_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.
	(ignore_access_violation_p): New.
	(handle_exception): Use ignore_access_violation_p.
	(get_win32_debug_event): Remove unneeded calls.  Set state to
	TARGET_WAITKIND_LOADED on a dll unload.
	(map_code_section_args): Delete.
	(solib_to_xml): New.
	(dll_code_sections_add): Delete.
	(struct cspm_data): New.
	(core_section_load_dll_symbols): Delete.
	(core_section_process_module): New.
	(win32_current_sos): Delete.
	(win32_core_xfer_shared_libraries): New.
	(win32_xfer_shared_libraries): New.
	(win32_xfer_partial): New.
	(fetch_elf_core_registers): Rename to ...
	(win32_fetch_elf_core_registers): ... this.
	(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.
	(win32_elf_core_fn): The fetch_elf_core_registers function was
	renamed to win32_fetch_elf_core_registers - update.  Add
	win32_core_get_shared_libraries.

---
 gdb/corelow.c     |   10 -
 gdb/gdb_obstack.h |    5 
 gdb/gdbcore.h     |    9 
 gdb/infcmd.c      |    8 
 gdb/win32-nat.c   |  540 +++++++++++++++++++++---------------------------------
 gdb/xml-support.c |   67 ++++++
 gdb/xml-support.h |   42 ++--
 7 files changed, 328 insertions(+), 353 deletions(-)

Index: src/gdb/corelow.c
===================================================================
--- src.orig/gdb/corelow.c	2007-08-13 22:33:58.000000000 +0100
+++ src/gdb/corelow.c	2007-08-13 22:34:42.000000000 +0100
@@ -526,8 +526,8 @@ core_xfer_partial (struct target_ops *op
 	return (*ops->deprecated_xfer_memory) (offset, readbuf, len,
 					       0/*write*/, NULL, ops);
       if (writebuf)
-	return (*ops->deprecated_xfer_memory) (offset, readbuf, len,
-					       1/*write*/, NULL, ops);
+	return (*ops->deprecated_xfer_memory) (offset, (gdb_byte *) writebuf,
+					       len, 1/*write*/, NULL, ops);
       return -1;
 
     case TARGET_OBJECT_AUXV:
@@ -594,6 +594,12 @@ core_xfer_partial (struct target_ops *op
 	}
       return -1;
 
+    case TARGET_OBJECT_LIBRARIES:
+      if (core_vec->xfer_shared_libraries != NULL)
+	return core_vec->xfer_shared_libraries (ops, object, annex, readbuf,
+					       writebuf, offset, len);
+      /* FALL THROUGH */
+
     default:
       if (ops->beneath != NULL)
 	return ops->beneath->to_xfer_partial (ops->beneath, object, annex,
Index: src/gdb/gdb_obstack.h
===================================================================
--- src.orig/gdb/gdb_obstack.h	2007-08-13 22:33:52.000000000 +0100
+++ src/gdb/gdb_obstack.h	2007-08-13 22:34:10.000000000 +0100
@@ -42,4 +42,9 @@
 #define obstack_chunk_alloc xmalloc
 #define obstack_chunk_free xfree
 
+#define obstack_grow_str(OBSTACK,STRING) \
+  obstack_grow (OBSTACK, STRING, strlen (STRING))
+#define obstack_grow_str0(OBSTACK,STRING) \
+  obstack_grow0 (OBSTACK, STRING, strlen (STRING))
+
 #endif
Index: src/gdb/gdbcore.h
===================================================================
--- src.orig/gdb/gdbcore.h	2007-08-13 22:33:52.000000000 +0100
+++ src/gdb/gdbcore.h	2007-08-13 22:34:10.000000000 +0100
@@ -29,6 +29,7 @@ struct type;
 struct regcache;
 
 #include "bfd.h"
+#include "target.h"
 
 /* Return the name of the executable file as a string.
    ERR nonzero means get error if there is none specified;
@@ -193,6 +194,14 @@ struct core_fns
 				 unsigned core_reg_size,
 				 int which, CORE_ADDR reg_addr);
 
+    /* Refresh the list of shared libraries.  */
+    LONGEST (*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);
+
     /* Finds the next struct core_fns.  They are allocated and
        initialized in whatever module implements the functions pointed
        to; an initializer calls deprecated_add_core_fns to add them to
Index: src/gdb/infcmd.c
===================================================================
--- src.orig/gdb/infcmd.c	2007-08-13 22:33:52.000000000 +0100
+++ src/gdb/infcmd.c	2007-08-13 22:34:10.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-13 22:33:52.000000000 +0100
+++ src/gdb/win32-nat.c	2007-08-13 23:21:48.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,12 @@
 #include "exec.h"
 #include "solist.h"
 #include "solib.h"
+#include "xml-support.h"
 
 #include "i386-tdep.h"
 #include "i387-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 +601,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 +611,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 +638,9 @@ 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);
-
-  solib_end->next = so;
-  solib_end = so;
-  len = strlen (so->so_name);
-  if (readsyms)
-    solib_symbols_add (so, (CORE_ADDR) load_addr);
+  strcpy (so->so_original_name, name);
 
-  return so->so_name;
+  return so;
 }
 
 static char *
@@ -822,11 +701,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 +717,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 +733,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 +751,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)
@@ -1084,6 +945,58 @@ info_w32_command (char *args, int from_t
   help_list (info_w32_cmdlist, "info w32 ", class_info, gdb_stdout);
 }
 
+static int
+ignore_access_violation_p (PVOID exception_addr)
+{
+  bfd_vma addr = (bfd_vma) exception_addr;
+
+  if (!cygwin_exceptions)
+    {
+      /* See if the access violation happened within the cygwin DLL itself.
+	 Cygwin uses a kind of exception handling to deal with passed-in invalid
+	 addresses. gdb should not treat these as real SEGVs since they will be
+	 silently handled by cygwin.  A real SEGV will (theoretically) be caught
+	 by cygwin later in the process and will be sent as a
+	 cygwin-specific-signal.  So, ignore SEGVs if they show up within the
+	 text segment of the DLL itself. */
+
+      if (cygwin_load_start == 0 && cygwin_load_end == 0)
+	{
+	  struct so_list *so;
+
+	  for (so = master_so_list (); so; so = so->next)
+	    {
+	      char *p;
+	      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 (so->abfd, ".text");
+		  if (text)
+		    {
+		      cygwin_load_start = bfd_section_vma (so->abfd, text);
+		      cygwin_load_end = cygwin_load_start +
+			bfd_section_size (so->abfd, text);
+		    }
+		  break;
+		}
+	    }
+	}
+
+      if (cygwin_load_start <= addr && addr < cygwin_load_end)
+	return 1;
+    }
+
+  {
+    /* The IsBadXxxPtr family of Win32 functions triggers an access
+       violation by design.  */
+    char *fn;
+    if (find_pc_partial_function (addr, &fn, NULL, NULL)
+	&& strncmp (fn, "KERNEL32!IsBad", strlen ("KERNEL32!IsBad")) == 0)
+      return 1;
+  }
+
+  return 0;
+}
 
 #define DEBUG_EXCEPTION_SIMPLE(x)       if (debug_exceptions) \
   printf_unfiltered ("gdb: Target exception %s at 0x%08lx\n", x, \
@@ -1105,20 +1018,9 @@ handle_exception (struct target_waitstat
     case EXCEPTION_ACCESS_VIOLATION:
       DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ACCESS_VIOLATION");
       ourstatus->value.sig = TARGET_SIGNAL_SEGV;
-      {
-	/* See if the access violation happened within the cygwin DLL itself.  Cygwin uses
-	   a kind of exception handling to deal with passed-in invalid addresses. gdb
-	   should not treat these as real SEGVs since they will be silently handled by
-	   cygwin.  A real SEGV will (theoretically) be caught by cygwin later in the process
-	   and will be sent as a cygwin-specific-signal.  So, ignore SEGVs if they show up
-	   within the text segment of the DLL itself. */
-	char *fn;
-	bfd_vma addr = (bfd_vma) current_event.u.Exception.ExceptionRecord.ExceptionAddress;
-	if ((!cygwin_exceptions && (addr >= cygwin_load_start && addr < cygwin_load_end))
-	    || (find_pc_partial_function (addr, &fn, NULL, NULL)
-		&& strncmp (fn, "KERNEL32!IsBad", strlen ("KERNEL32!IsBad")) == 0))
-	  return 0;
-      }
+      if (ignore_access_violation_p
+	  (current_event.u.Exception.ExceptionRecord.ExceptionAddress))
+	return 0;
       break;
     case STATUS_STACK_OVERFLOW:
       DEBUG_EXCEPTION_SIMPLE ("STATUS_STACK_OVERFLOW");
@@ -1457,11 +1359,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 +1372,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:
@@ -2072,140 +1972,80 @@ 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)
+solib_to_xml (struct so_list *so, struct obstack *obstack)
 {
-  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;
-    }
+  char *p;
+  obstack_grow_str (obstack, "<library name=\"");
+  p = xml_escape_text (so->so_name);
+  obstack_grow_str (obstack, p);
+  xfree (p);
+  obstack_grow_str (obstack, "\"><segment address=\"0x");
+  /* 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. */
+  p = paddr_nz (so->lm_info->load_addr + 0x1000);
+  obstack_grow_str (obstack, p);
+  obstack_grow_str (obstack, "\"/></library>");
 }
 
-static int
-dll_code_sections_add (const char *dll_name, int base_addr, struct target_ops *target)
+struct cspm_data
 {
-  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;
-}
+  struct target_ops *target;
+  int module_count;
+  struct obstack *obstack;
+};
 
 static void
-core_section_load_dll_symbols (bfd *abfd, asection *sect, void *obj)
+core_section_process_module (bfd *abfd, asection *sect, void *obj)
 {
-  struct target_ops *target = (struct target_ops *) obj;
+  struct cspm_data *data = obj;
 
+  struct win32_pstatus *pstatus;
+  char *module_name;
+  int module_name_offset;
+  int module_name_size;
   DWORD base_addr;
 
-  int dll_name_size;
-  struct win32_pstatus *pstatus;
-  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);
+  buf = 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)))
+  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 (!(dll_basename = strrchr (dll_name, '/')))
-    dll_basename = dll_name;
-  else
-    dll_basename++;
-
-  ALL_OBJFILES (objfile)
-  {
-    char *objfile_basename = strrchr (objfile->name, '/');
+  memcpy (&base_addr, &pstatus->data.module_info.base_address,
+	  sizeof (base_addr));
 
-    if (objfile_basename &&
-	strcasecmp (dll_basename, objfile_basename + 1) == 0)
+  module_name_size = pstatus->data.module_info.module_name_size;
+  module_name = pstatus->data.module_info.module_name;
+  if (module_name - buf + module_name_size > bfd_get_section_size (sect))
       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);
+  data->module_count++;
+  /* ### TODO: What if the user supplied exec and/or symbol
+     files on the command line?  */
+  if (data->module_count == 1)
+    {
+      /* The first module is the .exe itself.  */
+      symbol_file_add_main (module_name, 0);
+    }
+  else
+    {
+      struct so_list *so = win32_make_so (module_name, base_addr);
+      solib_to_xml (so, data->obstack);
+      win32_free_so (so);
+    }
 
 out:
   if (buf)
@@ -2213,39 +2053,103 @@ out:
   return;
 }
 
-static struct so_list *
-win32_current_sos (void)
-{
-  struct so_list *sop;
-  struct so_list *start = NULL;
-  struct so_list *last = NULL;
+static LONGEST
+win32_core_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 cspm_data data = { ops, 0, &obstack };
+
+  if (writebuf)
+    return -1;
+
+  obstack_init (&obstack);
+  obstack_grow_str (&obstack, "<library-list>\n");
+  bfd_map_over_sections (core_bfd,
+			 &core_section_process_module,
+			 &data);
+  obstack_grow_str0 (&obstack, "</library-list>\n");
+
+  buf = obstack_finish (&obstack);
+  len_avail = strlen (buf);
+  if (offset >= len_avail)
+    return 0;
 
-  if (!solib_start.next && core_bfd)
-    {
-      win32_clear_solib ();
-      bfd_map_over_sections (core_bfd, &core_section_load_dll_symbols,
-			     &win32_ops);
-    }
+  if (len > len_avail - offset)
+    len = len_avail - offset;
+  memcpy (readbuf, buf + offset, len);
+
+  obstack_free (&obstack, NULL);
+  return len;
+}
+
+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;
 
-  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;
-	}
-    }
+  if (writebuf)
+    return -1;
+
+  obstack_init (&obstack);
+  obstack_grow_str (&obstack, "<library-list>\n");
+  for (so = solib_start.next; so; so = so->next)
+    solib_to_xml (so, &obstack);
+  obstack_grow_str0 (&obstack, "</library-list>\n");
+
+  buf = obstack_finish (&obstack);
+  len_avail = strlen (buf);
+  if (offset >= len_avail)
+    return 0;
 
-  return start;
+  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);
+
+    default:
+      if (ops->beneath != NULL)
+	return ops->beneath->to_xfer_partial (ops->beneath, object, annex,
+					      readbuf, writebuf, offset, len);
+      return -1;
+    }
 }
 
 static void
-fetch_elf_core_registers (struct regcache *regcache,
+win32_fetch_elf_core_registers (struct regcache *regcache,
 			  char *core_reg_sect,
 			  unsigned core_reg_size,
 			  int which,
@@ -2261,18 +2165,6 @@ fetch_elf_core_registers (struct regcach
     regcache_raw_supply (regcache, r, core_reg_sect + mappings[r]);
 }
 
-static int
-open_symbol_file_object (void *from_ttyp)
-{
-  return 0;
-}
-
-static int
-in_dynsym_resolve_code (CORE_ADDR pc)
-{
-  return 0;
-}
-
 static void
 init_win32_ops (void)
 {
@@ -2289,6 +2181,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;
@@ -2313,18 +2206,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
@@ -2467,7 +2348,8 @@ static struct core_fns win32_elf_core_fn
   bfd_target_elf_flavour,
   default_check_format,
   default_core_sniffer,
-  fetch_elf_core_registers,
+  win32_fetch_elf_core_registers,
+  win32_core_xfer_shared_libraries,
   NULL
 };
 
Index: src/gdb/xml-support.c
===================================================================
--- src.orig/gdb/xml-support.c	2007-08-13 22:33:52.000000000 +0100
+++ src/gdb/xml-support.c	2007-08-13 22:34:10.000000000 +0100
@@ -546,6 +546,8 @@ gdb_xml_parse (struct gdb_xml_parser *pa
   enum XML_Status status;
   const char *error_string;
 
+  gdb_xml_debug (parser, _("Starting:\n%s"), buffer);
+
   status = XML_Parse (parser->expat_parser, buffer, strlen (buffer), 1);
 
   if (status == XML_STATUS_OK && parser->error.reason == 0)
@@ -871,8 +873,7 @@ xml_process_xincludes (const char *name,
       result = xstrdup (obstack_finish (&data->obstack));
 
       if (depth == 0)
-	gdb_xml_debug (parser, _("XInclude processing succeeded:\n%s"),
-		       result);
+	gdb_xml_debug (parser, _("XInclude processing succeeded."));
     }
   else
     result = NULL;
@@ -936,6 +937,68 @@ show_debug_xml (struct ui_file *file, in
   fprintf_filtered (file, _("XML debugging is %s.\n"), value);
 }
 
+/* Return a malloc allocated string with special characters from TEXT
+   replaced by entity references.  */
+
+char *
+xml_escape_text (const char *text)
+{
+  char *result;
+  int i, special;
+
+  /* Compute the length of the result.  */
+  for (i = 0, special = 0; text[i] != '\0'; i++)
+    switch (text[i])
+      {
+      case '\'':
+      case '\"':
+	special += 5;
+	break;
+      case '&':
+	special += 4;
+	break;
+      case '<':
+      case '>':
+	special += 3;
+	break;
+      default:
+	break;
+      }
+
+  /* Expand the result.  */
+  result = xmalloc (i + special + 1);
+  for (i = 0, special = 0; text[i] != '\0'; i++)
+    switch (text[i])
+      {
+      case '\'':
+	strcpy (result + i + special, "&apos;");
+	special += 5;
+	break;
+      case '\"':
+	strcpy (result + i + special, "&quot;");
+	special += 5;
+	break;
+      case '&':
+	strcpy (result + i + special, "&amp;");
+	special += 4;
+	break;
+      case '<':
+	strcpy (result + i + special, "&lt;");
+	special += 3;
+	break;
+      case '>':
+	strcpy (result + i + special, "&gt;");
+	special += 3;
+	break;
+      default:
+	result[i + special] = text[i];
+	break;
+      }
+  result[i + special] = '\0';
+
+  return result;
+}
+
 void _initialize_xml_support (void);
 
 void
Index: src/gdb/xml-support.h
===================================================================
--- src.orig/gdb/xml-support.h	2007-08-13 22:33:52.000000000 +0100
+++ src/gdb/xml-support.h	2007-08-13 22:34:10.000000000 +0100
@@ -30,24 +30,6 @@ struct gdb_xml_parser;
 struct gdb_xml_element;
 struct gdb_xml_attribute;
 
-/* Support for XInclude.  */
-
-/* Callback to fetch a new XML file, based on the provided HREF.  */
-
-typedef char *(*xml_fetch_another) (const char *href, void *baton);
-
-/* Return a new string which is the expansion of TEXT after processing
-   <xi:include> tags.  FETCHER will be called (with FETCHER_BATON) to
-   retrieve any new files.  DEPTH should be zero on the initial call.
-
-   On failure, this function uses NAME in a warning and returns NULL.
-   It may throw an exception, but does not for XML parsing
-   problems.  */
-
-char *xml_process_xincludes (const char *name, const char *text,
-			     xml_fetch_another fetcher, void *fetcher_baton,
-			     int depth);
-
 /* Return an XML document which was compiled into GDB, from
    the given FILENAME, or NULL if the file was not compiled in.  */
 
@@ -64,8 +46,32 @@ LONGEST xml_builtin_xfer_partial (const 
 
 /* The text of compiled-in XML documents, from xml-builtin.c
    (generated).  */
+
 extern const char *xml_builtin[][2];
 
+/* Return a malloc allocated string with special characters from TEXT
+   replaced by entity references.  */
+
+char *xml_escape_text (const char *text);
+
+/* Support for XInclude.  */
+
+/* Callback to fetch a new XML file, based on the provided HREF.  */
+
+typedef char *(*xml_fetch_another) (const char *href, void *baton);
+
+/* Return a new string which is the expansion of TEXT after processing
+   <xi:include> tags.  FETCHER will be called (with FETCHER_BATON) to
+   retrieve any new files.  DEPTH should be zero on the initial call.
+
+   On failure, this function uses NAME in a warning and returns NULL.
+   It may throw an exception, but does not for XML parsing
+   problems.  */
+
+char *xml_process_xincludes (const char *name, const char *text,
+			     xml_fetch_another fetcher, void *fetcher_baton,
+			     int depth);
+
 /* Simplified XML parser infrastructure.  */
 
 /* A name and value pair, used to record parsed attributes.  */




^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Windows DLL support update.
  2007-08-14  0:24 Windows DLL support update Pedro Alves
@ 2007-08-14  0:43 ` Pedro Alves
  2007-08-14 12:10 ` Christopher Faylor
  1 sibling, 0 replies; 7+ messages in thread
From: Pedro Alves @ 2007-08-14  0:43 UTC (permalink / raw)
  To: gdb-patches

Pedro Alves wrote:
> Hi all,
> 
> Here is the new version of the patch that converts native win32
> debugging to use the new solib-target.c.  The biggest difference
> compared to the latest version Daniel posted is that this
> version maintains the list of loaded dlls separately from
> solib-target.c, similarly to what is done in current cvs.  The
> previous versions always queried the target for the dll list
> and maintained no private list.  At the time it sounded like a
> good idea, since, well, if Windows already maintains the list, we
> might as well just read it.  It turns out that this wasn't perfect
> because it still required us to keep at least the last loaded dll
> (last_loaded_dll_valid mechanism in the previous version),
> because when a dll (un)load event occurs, the loader hasn't
> completely finished the load, and the dll isn't reported on
> the lists.  This version is now similar to what current
> gdbserver is doing.
> 
> I've kept this version of the patch to a minimum, by removing the
> fixes of formatting violations, typos and dead code removals
> from the patch.
> 
> The patch could be easily be split further.  Probably the writebuf
> fix in corelow.c and the infcmd.c hunks could go in on their own.
> The xml and objstack changes could also go in separately, but
> they don't have any other users yet.  Daniel, you've written
> most of the changes outside of win32-nat.c, I'll leave that decision
> to you.  If you want me to do that, just say so.
> 
> I've ran the testsuite on Windows XP several times against an
> unpatched current cvs, against a gdb patched with the
> previous patch, and with this patch.  I've carefully compared
> the results (1), of all the runs and didn't see any regression.
> I did see one consistent improvement in unload.exp
> 
> -FAIL: gdb.base/unload.exp: continuing to end of program
> -FAIL: gdb.base/unload.exp: rerun to shared library breakpoint
> -FAIL: gdb.base/unload.exp: continuing to end of program second time (the
> program is no longer running)
> +PASS: gdb.base/unload.exp: continuing to end of program
> +PASS: gdb.base/unload.exp: rerun to shared library breakpoint
> +PASS: gdb.base/unload.exp: continuing to end of program second time
> 
> I didn't really took the time to see why these tests
> failed before.
> 
> (1) Test results aren't stable.  I always have to repeat a few,
> because they usually fail UNTESTED due to several reasons, like
> the compile step failing because the output binfile is still
> loaded by the previous test (Windows only), or, eg:
>     (...)
>     -PASS: gdb.cp/maint.exp: maint cp first_component foo<
>     -PASS: gdb.cp/maint.exp: maint cp first_component foo(
>     -PASS: gdb.cp/maint.exp: maint cp first_component bool operator<<char>
>     -PASS: gdb.cp/maint.exp: maint cp namespace
>     +ERROR: Process no longer exists
>     +UNRESOLVED: gdb.cp/maint.exp: maint cp first_component operator  ->
>     +ERROR: Couldn't send maint cp first_component foo() to GDB.
>     +UNRESOLVED: gdb.cp/maint.exp: maint cp first_component foo()
>     +ERROR: Couldn't send maint cp first_component foo(int) to GDB.
>     +UNRESOLVED: gdb.cp/maint.exp: maint cp first_component foo(int)
>     (...)
> 
> This should also fix the problem Joel reported at:
> [win32] wrong solib from/to addresses
> http://sourceware.org/ml/gdb-patches/2007-06/msg00210.html
> 
> ... but I have no Vista to test on.
> 


And I forgot to say the reason I did this now.  This is one
way to enable a Cygwin hosted gdb to take advantage of the
new gdbserver dll support.  Currently win32-nat.c has one of
those beauties:

   /* FIXME: Don't do this here.  *_gdbarch_init() should set so_ops. */
   current_target_so_ops = &win32_so_ops;

... target remote then always uses win32_so_ops, which, of course,
is broken ...

If this patch is too late for 6.7, I'd like to at least have that
fixed.

Cheers,
Pedro Alves


> 
> P.S.
> 
> The testresults (c, c++) look somewhat (1 above) like this with gcc+gdb 
> patches
> to overcome the '__main emitted in main breaks run_to_main' problem.
> 
> # of expected passes            9441
> # of unexpected failures        177
> # of unexpected successes       1
> # of expected failures          47
> # of known failures             30
> # of unresolved testcases       21
> # of untested testcases         16
> # of unsupported tests          32
> 
> 







^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Windows DLL support update.
  2007-08-14  0:24 Windows DLL support update Pedro Alves
  2007-08-14  0:43 ` Pedro Alves
@ 2007-08-14 12:10 ` Christopher Faylor
  2007-08-16  0:44   ` Pedro Alves
  1 sibling, 1 reply; 7+ messages in thread
From: Christopher Faylor @ 2007-08-14 12:10 UTC (permalink / raw)
  To: gdb-patches

On Tue, Aug 14, 2007 at 01:23:28AM +0100, Pedro Alves wrote:
> Here is the new version of the patch that converts native win32
> debugging to use the new solib-target.c.

I have a few of questions/observations wrt the win32-nat.c changes.

1) Does it still properly handle the "exceptions" that are thrown by
cygwin which must be ignored?  I believe that the most populr source
of complaints about those came from people who were using pthreads
functions.

2) Is there some reason you didn't record the cygwin load/start address
in win32_make_so?  Isn't all of the information you need available when
that function is called?

3) If the answer to the above question is no, then it seems like
cygwin_load_start and cygwin_load_end should be static variables local
to ignore_access_violation_p.  I wonder if that logic should even be
further broken out into its own inside_cygwin(addr) function.

4) I'd prefer it if you dropped the _p from "ignore_access_violation".

Thanks for the patch.

cgf


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Windows DLL support update.
  2007-08-14 12:10 ` Christopher Faylor
@ 2007-08-16  0:44   ` Pedro Alves
  2007-08-16  0:57     ` Daniel Jacobowitz
  2007-08-16  1:59     ` Christopher Faylor
  0 siblings, 2 replies; 7+ messages in thread
From: Pedro Alves @ 2007-08-16  0:44 UTC (permalink / raw)
  To: gdb-patches

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

Christopher Faylor wrote:
> On Tue, Aug 14, 2007 at 01:23:28AM +0100, Pedro Alves wrote:
>> Here is the new version of the patch that converts native win32
>> debugging to use the new solib-target.c.
> 
> I have a few of questions/observations wrt the win32-nat.c changes.
> 

Thanks for such a quick review.

> 1) Does it still properly handle the "exceptions" that are thrown by
> cygwin which must be ignored?  I believe that the most populr source
> of complaints about those came from people who were using pthreads
> functions.
> 

Yes.  I tried with this:
http://www.cygwin.com/ml/cygwin/2006-05/msg00650.html

'set cygwin-exceptions 1' shows the SEGV, 'set cygwin-exceptions 0'
doesn't.

> 2) Is there some reason you didn't record the cygwin load/start address
> in win32_make_so?  Isn't all of the information you need available when
> that function is called?
> 

I could open a bfd and look for .text like old solib_symbols_add
does, but the so_list of the main list will have one open, so we can
use that instead.  I'll want to move these bits of cygwin detection and
exception ignoring into a win32-tdep.c file that can be reused
when remote debugging.  This is step in that direction, but I'll
understand if you still prefer the old way.

> 3) If the answer to the above question is no, then it seems like
> cygwin_load_start and cygwin_load_end should be static variables local
> to ignore_access_violation_p.  

Storing the cygwin1.dll addresses and reusing
it across runs should be ok if we assume that we are always
debugging cygwin apps, but it could mask an access exception in
a non-cygwin app that happened to occur in a dll loaded in that
range by coincidence.  I was going to leave it for later, but
since you've asked, I'm now clearing the start/end addresses
in do_initial_win32_stuff.  This shows why they can't be local
static.

 > I wonder if that logic should even be
 > further broken out into its own inside_cygwin(addr) function.

Wonder no more.  Done.

> 4) I'd prefer it if you dropped the _p from "ignore_access_violation".
> 

Done.


I gave it another testsuite spin, and it looks good.

-- 
Cheers,
Pedro Alves





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

2007-07-02  Pedro Alves  <pedro_alves@portugalmail.pt>
	    Daniel Jacobowitz  <dan@codesourcery.com>

	* corelow.c (core_xfer_partial): Pass writebuf to
	deprecated_xfer_memory in TARGET_OBJECT_MEMORY case.  Add
	TARGET_OBJECT_LIBRARIES handling.

	* gdb_obstack.h (obstack_grow_str, obstack_grow_str0): New.

	* gdbcore.h: Include target.h.
	(struct core_fns): Add xfer_shared_libraries.

	* infcmd.c (post_create_inferior): Update comment.
	(run_command_1): Always call post_create_inferior with 0 as
	from_tty.

	* win32-nat.c: Include gdb_obstack.h and xml-support.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.
	(inside_cygwin): New.
	(ignore_access_violation_p): New.
	(handle_exception): Use ignore_access_violation_p.
	(get_win32_debug_event): Remove unneeded calls.  Set state to
	TARGET_WAITKIND_LOADED on a dll unload.
	(map_code_section_args): Delete.
	(solib_to_xml): New.
	(dll_code_sections_add): Delete.
	(struct cspm_data): New.
	(core_section_load_dll_symbols): Delete.
	(core_section_process_module): New.
	(win32_current_sos): Delete.
	(win32_core_xfer_shared_libraries): New.
	(win32_xfer_shared_libraries): New.
	(win32_xfer_partial): New.
	(fetch_elf_core_registers): Rename to ...
	(win32_fetch_elf_core_registers): ... this.
	(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.
	(win32_elf_core_fn): The fetch_elf_core_registers function was
	renamed to win32_fetch_elf_core_registers - update.  Add
	win32_core_get_shared_libraries.

	* xml-support.c (gdb_xml_parse): Debug tweaks.
	(xml_escape_text): New.
	* xml-support.h (xml_escape_text): Declare.

---
 gdb/corelow.c     |   10 
 gdb/gdb_obstack.h |    5 
 gdb/gdbcore.h     |    9 
 gdb/infcmd.c      |    8 
 gdb/win32-nat.c   |  553 +++++++++++++++++++++---------------------------------
 gdb/xml-support.c |   67 ++++++
 gdb/xml-support.h |   42 ++--
 7 files changed, 341 insertions(+), 353 deletions(-)

Index: src/gdb/corelow.c
===================================================================
--- src.orig/gdb/corelow.c	2007-08-13 22:33:58.000000000 +0100
+++ src/gdb/corelow.c	2007-08-13 22:34:42.000000000 +0100
@@ -526,8 +526,8 @@ core_xfer_partial (struct target_ops *op
 	return (*ops->deprecated_xfer_memory) (offset, readbuf, len,
 					       0/*write*/, NULL, ops);
       if (writebuf)
-	return (*ops->deprecated_xfer_memory) (offset, readbuf, len,
-					       1/*write*/, NULL, ops);
+	return (*ops->deprecated_xfer_memory) (offset, (gdb_byte *) writebuf,
+					       len, 1/*write*/, NULL, ops);
       return -1;
 
     case TARGET_OBJECT_AUXV:
@@ -594,6 +594,12 @@ core_xfer_partial (struct target_ops *op
 	}
       return -1;
 
+    case TARGET_OBJECT_LIBRARIES:
+      if (core_vec->xfer_shared_libraries != NULL)
+	return core_vec->xfer_shared_libraries (ops, object, annex, readbuf,
+					       writebuf, offset, len);
+      /* FALL THROUGH */
+
     default:
       if (ops->beneath != NULL)
 	return ops->beneath->to_xfer_partial (ops->beneath, object, annex,
Index: src/gdb/gdb_obstack.h
===================================================================
--- src.orig/gdb/gdb_obstack.h	2007-08-13 22:33:52.000000000 +0100
+++ src/gdb/gdb_obstack.h	2007-08-13 22:34:10.000000000 +0100
@@ -42,4 +42,9 @@
 #define obstack_chunk_alloc xmalloc
 #define obstack_chunk_free xfree
 
+#define obstack_grow_str(OBSTACK,STRING) \
+  obstack_grow (OBSTACK, STRING, strlen (STRING))
+#define obstack_grow_str0(OBSTACK,STRING) \
+  obstack_grow0 (OBSTACK, STRING, strlen (STRING))
+
 #endif
Index: src/gdb/gdbcore.h
===================================================================
--- src.orig/gdb/gdbcore.h	2007-08-13 22:33:52.000000000 +0100
+++ src/gdb/gdbcore.h	2007-08-13 22:34:10.000000000 +0100
@@ -29,6 +29,7 @@ struct type;
 struct regcache;
 
 #include "bfd.h"
+#include "target.h"
 
 /* Return the name of the executable file as a string.
    ERR nonzero means get error if there is none specified;
@@ -193,6 +194,14 @@ struct core_fns
 				 unsigned core_reg_size,
 				 int which, CORE_ADDR reg_addr);
 
+    /* Refresh the list of shared libraries.  */
+    LONGEST (*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);
+
     /* Finds the next struct core_fns.  They are allocated and
        initialized in whatever module implements the functions pointed
        to; an initializer calls deprecated_add_core_fns to add them to
Index: src/gdb/infcmd.c
===================================================================
--- src.orig/gdb/infcmd.c	2007-08-13 22:33:52.000000000 +0100
+++ src/gdb/infcmd.c	2007-08-13 22:34:10.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-13 22:33:52.000000000 +0100
+++ src/gdb/win32-nat.c	2007-08-16 01:08:48.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,12 @@
 #include "exec.h"
 #include "solist.h"
 #include "solib.h"
+#include "xml-support.h"
 
 #include "i386-tdep.h"
 #include "i387-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 +601,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 +611,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 +638,9 @@ 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);
-
-  solib_end->next = so;
-  solib_end = so;
-  len = strlen (so->so_name);
-  if (readsyms)
-    solib_symbols_add (so, (CORE_ADDR) load_addr);
+  strcpy (so->so_original_name, name);
 
-  return so->so_name;
+  return so;
 }
 
 static char *
@@ -822,11 +701,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 +717,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 +733,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 +751,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)
@@ -1084,6 +945,67 @@ info_w32_command (char *args, int from_t
   help_list (info_w32_cmdlist, "info w32 ", class_info, gdb_stdout);
 }
 
+/* Returns 1 if ADDR is within the cygwin1.dll text segment, returns 0
+   otherwise.  */
+static int
+inside_cygwin (CORE_ADDR addr)
+{
+  if (cygwin_load_start == 0)
+    {
+      struct so_list *so;
+
+      for (so = master_so_list (); so; so = so->next)
+	{
+	  char *p;
+	  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 (so->abfd, ".text");
+	      if (text)
+		{
+		  cygwin_load_start = bfd_section_vma (so->abfd, text);
+		  cygwin_load_end = cygwin_load_start
+		    + bfd_section_size (so->abfd, text);
+		}
+	      break;
+	    }
+	}
+    }
+
+  if (cygwin_load_start == 0)
+    return 0;
+
+  return (cygwin_load_start <= addr && addr < cygwin_load_end);
+}
+
+static int
+ignore_access_violation (CORE_ADDR addr)
+{
+  if (!cygwin_exceptions)
+    {
+      /* See if the access violation happened within the cygwin DLL
+	 itself.  Cygwin uses a kind of exception handling to deal
+	 with passed-in invalid addresses. gdb should not treat these
+	 as real SEGVs since they will be silently handled by cygwin.
+	 A real SEGV will (theoretically) be caught by cygwin later in
+	 the process and will be sent as a cygwin-specific-signal.
+	 So, ignore SEGVs if they show up within the text segment of
+	 the DLL itself. */
+      if (inside_cygwin (addr))
+	return 1;
+    }
+
+  {
+    /* The IsBadXxxPtr family of Win32 functions triggers an access
+       violation by design.  */
+    char *fn;
+    if (find_pc_partial_function (addr, &fn, NULL, NULL)
+	&& strncmp (fn, "KERNEL32!IsBad", strlen ("KERNEL32!IsBad")) == 0)
+      return 1;
+  }
+
+  return 0;
+}
 
 #define DEBUG_EXCEPTION_SIMPLE(x)       if (debug_exceptions) \
   printf_unfiltered ("gdb: Target exception %s at 0x%08lx\n", x, \
@@ -1105,20 +1027,10 @@ handle_exception (struct target_waitstat
     case EXCEPTION_ACCESS_VIOLATION:
       DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ACCESS_VIOLATION");
       ourstatus->value.sig = TARGET_SIGNAL_SEGV;
-      {
-	/* See if the access violation happened within the cygwin DLL itself.  Cygwin uses
-	   a kind of exception handling to deal with passed-in invalid addresses. gdb
-	   should not treat these as real SEGVs since they will be silently handled by
-	   cygwin.  A real SEGV will (theoretically) be caught by cygwin later in the process
-	   and will be sent as a cygwin-specific-signal.  So, ignore SEGVs if they show up
-	   within the text segment of the DLL itself. */
-	char *fn;
-	bfd_vma addr = (bfd_vma) current_event.u.Exception.ExceptionRecord.ExceptionAddress;
-	if ((!cygwin_exceptions && (addr >= cygwin_load_start && addr < cygwin_load_end))
-	    || (find_pc_partial_function (addr, &fn, NULL, NULL)
-		&& strncmp (fn, "KERNEL32!IsBad", strlen ("KERNEL32!IsBad")) == 0))
-	  return 0;
-      }
+      if (ignore_access_violation
+	  ((CORE_ADDR) current_event.u.
+	   Exception.ExceptionRecord.ExceptionAddress))
+	return 0;
       break;
     case STATUS_STACK_OVERFLOW:
       DEBUG_EXCEPTION_SIMPLE ("STATUS_STACK_OVERFLOW");
@@ -1457,11 +1369,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 +1382,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 +1492,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,140 +1983,82 @@ 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)
+solib_to_xml (struct so_list *so, struct obstack *obstack)
 {
-  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;
-    }
+  char *p;
+  obstack_grow_str (obstack, "<library name=\"");
+  p = xml_escape_text (so->so_name);
+  obstack_grow_str (obstack, p);
+  xfree (p);
+  obstack_grow_str (obstack, "\"><segment address=\"0x");
+  /* 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. */
+  p = paddr_nz (so->lm_info->load_addr + 0x1000);
+  obstack_grow_str (obstack, p);
+  obstack_grow_str (obstack, "\"/></library>");
 }
 
-static int
-dll_code_sections_add (const char *dll_name, int base_addr, struct target_ops *target)
+struct cspm_data
 {
-  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;
-}
+  struct target_ops *target;
+  int module_count;
+  struct obstack *obstack;
+};
 
 static void
-core_section_load_dll_symbols (bfd *abfd, asection *sect, void *obj)
+core_section_process_module (bfd *abfd, asection *sect, void *obj)
 {
-  struct target_ops *target = (struct target_ops *) obj;
+  struct cspm_data *data = obj;
 
+  struct win32_pstatus *pstatus;
+  char *module_name;
+  int module_name_offset;
+  int module_name_size;
   DWORD base_addr;
 
-  int dll_name_size;
-  struct win32_pstatus *pstatus;
-  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);
+  buf = 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)))
+  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 (!(dll_basename = strrchr (dll_name, '/')))
-    dll_basename = dll_name;
-  else
-    dll_basename++;
-
-  ALL_OBJFILES (objfile)
-  {
-    char *objfile_basename = strrchr (objfile->name, '/');
+  memcpy (&base_addr, &pstatus->data.module_info.base_address,
+	  sizeof (base_addr));
 
-    if (objfile_basename &&
-	strcasecmp (dll_basename, objfile_basename + 1) == 0)
+  module_name_size = pstatus->data.module_info.module_name_size;
+  module_name = pstatus->data.module_info.module_name;
+  if (module_name - buf + module_name_size > bfd_get_section_size (sect))
       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);
+  if (data->module_count == 0)
+    {
+#if 0
+      /* TODO: What if the user supplied exec and/or
+	 symbol files on the command line?  */
+      /* The first module is the .exe itself.  */
+      symbol_file_add_main (module_name, 0);
+#endif
+    }
+  else
+    {
+      struct so_list *so = win32_make_so (module_name, base_addr);
+      solib_to_xml (so, data->obstack);
+      win32_free_so (so);
+    }
+  data->module_count++;
 
 out:
   if (buf)
@@ -2213,39 +2066,103 @@ out:
   return;
 }
 
-static struct so_list *
-win32_current_sos (void)
-{
-  struct so_list *sop;
-  struct so_list *start = NULL;
-  struct so_list *last = NULL;
+static LONGEST
+win32_core_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 cspm_data data = { ops, 0, &obstack };
+
+  if (writebuf)
+    return -1;
+
+  obstack_init (&obstack);
+  obstack_grow_str (&obstack, "<library-list>\n");
+  bfd_map_over_sections (core_bfd,
+			 &core_section_process_module,
+			 &data);
+  obstack_grow_str0 (&obstack, "</library-list>\n");
+
+  buf = obstack_finish (&obstack);
+  len_avail = strlen (buf);
+  if (offset >= len_avail)
+    return 0;
 
-  if (!solib_start.next && core_bfd)
-    {
-      win32_clear_solib ();
-      bfd_map_over_sections (core_bfd, &core_section_load_dll_symbols,
-			     &win32_ops);
-    }
+  if (len > len_avail - offset)
+    len = len_avail - offset;
+  memcpy (readbuf, buf + offset, len);
+
+  obstack_free (&obstack, NULL);
+  return len;
+}
+
+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;
 
-  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;
-	}
-    }
+  if (writebuf)
+    return -1;
+
+  obstack_init (&obstack);
+  obstack_grow_str (&obstack, "<library-list>\n");
+  for (so = solib_start.next; so; so = so->next)
+    solib_to_xml (so, &obstack);
+  obstack_grow_str0 (&obstack, "</library-list>\n");
+
+  buf = obstack_finish (&obstack);
+  len_avail = strlen (buf);
+  if (offset >= len_avail)
+    return 0;
 
-  return start;
+  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);
+
+    default:
+      if (ops->beneath != NULL)
+	return ops->beneath->to_xfer_partial (ops->beneath, object, annex,
+					      readbuf, writebuf, offset, len);
+      return -1;
+    }
 }
 
 static void
-fetch_elf_core_registers (struct regcache *regcache,
+win32_fetch_elf_core_registers (struct regcache *regcache,
 			  char *core_reg_sect,
 			  unsigned core_reg_size,
 			  int which,
@@ -2261,18 +2178,6 @@ fetch_elf_core_registers (struct regcach
     regcache_raw_supply (regcache, r, core_reg_sect + mappings[r]);
 }
 
-static int
-open_symbol_file_object (void *from_ttyp)
-{
-  return 0;
-}
-
-static int
-in_dynsym_resolve_code (CORE_ADDR pc)
-{
-  return 0;
-}
-
 static void
 init_win32_ops (void)
 {
@@ -2289,6 +2194,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;
@@ -2313,18 +2219,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
@@ -2467,7 +2361,8 @@ static struct core_fns win32_elf_core_fn
   bfd_target_elf_flavour,
   default_check_format,
   default_core_sniffer,
-  fetch_elf_core_registers,
+  win32_fetch_elf_core_registers,
+  win32_core_xfer_shared_libraries,
   NULL
 };
 
Index: src/gdb/xml-support.c
===================================================================
--- src.orig/gdb/xml-support.c	2007-08-13 22:33:52.000000000 +0100
+++ src/gdb/xml-support.c	2007-08-13 22:34:10.000000000 +0100
@@ -546,6 +546,8 @@ gdb_xml_parse (struct gdb_xml_parser *pa
   enum XML_Status status;
   const char *error_string;
 
+  gdb_xml_debug (parser, _("Starting:\n%s"), buffer);
+
   status = XML_Parse (parser->expat_parser, buffer, strlen (buffer), 1);
 
   if (status == XML_STATUS_OK && parser->error.reason == 0)
@@ -871,8 +873,7 @@ xml_process_xincludes (const char *name,
       result = xstrdup (obstack_finish (&data->obstack));
 
       if (depth == 0)
-	gdb_xml_debug (parser, _("XInclude processing succeeded:\n%s"),
-		       result);
+	gdb_xml_debug (parser, _("XInclude processing succeeded."));
     }
   else
     result = NULL;
@@ -936,6 +937,68 @@ show_debug_xml (struct ui_file *file, in
   fprintf_filtered (file, _("XML debugging is %s.\n"), value);
 }
 
+/* Return a malloc allocated string with special characters from TEXT
+   replaced by entity references.  */
+
+char *
+xml_escape_text (const char *text)
+{
+  char *result;
+  int i, special;
+
+  /* Compute the length of the result.  */
+  for (i = 0, special = 0; text[i] != '\0'; i++)
+    switch (text[i])
+      {
+      case '\'':
+      case '\"':
+	special += 5;
+	break;
+      case '&':
+	special += 4;
+	break;
+      case '<':
+      case '>':
+	special += 3;
+	break;
+      default:
+	break;
+      }
+
+  /* Expand the result.  */
+  result = xmalloc (i + special + 1);
+  for (i = 0, special = 0; text[i] != '\0'; i++)
+    switch (text[i])
+      {
+      case '\'':
+	strcpy (result + i + special, "&apos;");
+	special += 5;
+	break;
+      case '\"':
+	strcpy (result + i + special, "&quot;");
+	special += 5;
+	break;
+      case '&':
+	strcpy (result + i + special, "&amp;");
+	special += 4;
+	break;
+      case '<':
+	strcpy (result + i + special, "&lt;");
+	special += 3;
+	break;
+      case '>':
+	strcpy (result + i + special, "&gt;");
+	special += 3;
+	break;
+      default:
+	result[i + special] = text[i];
+	break;
+      }
+  result[i + special] = '\0';
+
+  return result;
+}
+
 void _initialize_xml_support (void);
 
 void
Index: src/gdb/xml-support.h
===================================================================
--- src.orig/gdb/xml-support.h	2007-08-13 22:33:52.000000000 +0100
+++ src/gdb/xml-support.h	2007-08-13 22:34:10.000000000 +0100
@@ -30,24 +30,6 @@ struct gdb_xml_parser;
 struct gdb_xml_element;
 struct gdb_xml_attribute;
 
-/* Support for XInclude.  */
-
-/* Callback to fetch a new XML file, based on the provided HREF.  */
-
-typedef char *(*xml_fetch_another) (const char *href, void *baton);
-
-/* Return a new string which is the expansion of TEXT after processing
-   <xi:include> tags.  FETCHER will be called (with FETCHER_BATON) to
-   retrieve any new files.  DEPTH should be zero on the initial call.
-
-   On failure, this function uses NAME in a warning and returns NULL.
-   It may throw an exception, but does not for XML parsing
-   problems.  */
-
-char *xml_process_xincludes (const char *name, const char *text,
-			     xml_fetch_another fetcher, void *fetcher_baton,
-			     int depth);
-
 /* Return an XML document which was compiled into GDB, from
    the given FILENAME, or NULL if the file was not compiled in.  */
 
@@ -64,8 +46,32 @@ LONGEST xml_builtin_xfer_partial (const 
 
 /* The text of compiled-in XML documents, from xml-builtin.c
    (generated).  */
+
 extern const char *xml_builtin[][2];
 
+/* Return a malloc allocated string with special characters from TEXT
+   replaced by entity references.  */
+
+char *xml_escape_text (const char *text);
+
+/* Support for XInclude.  */
+
+/* Callback to fetch a new XML file, based on the provided HREF.  */
+
+typedef char *(*xml_fetch_another) (const char *href, void *baton);
+
+/* Return a new string which is the expansion of TEXT after processing
+   <xi:include> tags.  FETCHER will be called (with FETCHER_BATON) to
+   retrieve any new files.  DEPTH should be zero on the initial call.
+
+   On failure, this function uses NAME in a warning and returns NULL.
+   It may throw an exception, but does not for XML parsing
+   problems.  */
+
+char *xml_process_xincludes (const char *name, const char *text,
+			     xml_fetch_another fetcher, void *fetcher_baton,
+			     int depth);
+
 /* Simplified XML parser infrastructure.  */
 
 /* A name and value pair, used to record parsed attributes.  */




^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Windows DLL support update.
  2007-08-16  0:44   ` Pedro Alves
@ 2007-08-16  0:57     ` Daniel Jacobowitz
  2007-08-17 23:26       ` Pedro Alves
  2007-08-16  1:59     ` Christopher Faylor
  1 sibling, 1 reply; 7+ messages in thread
From: Daniel Jacobowitz @ 2007-08-16  0:57 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb-patches

On Thu, Aug 16, 2007 at 01:40:48AM +0100, Pedro Alves wrote:
> I gave it another testsuite spin, and it looks good.

I have one concern; one of us should fix the problem Ulrich pointed
out with my core changes:

> On Tue, Jun 19, 2007 at 09:05:51PM +0200, Ulrich Weigand wrote:
> > One thing I don't quite like is this:
> >
> > > +    case TARGET_OBJECT_LIBRARIES:
> > > +      if (core_vec->xfer_shared_libraries != NULL)
> > > +   return core_vec->xfer_shared_libraries (ops, object, annex,
> > > readbuf,
> > > +                                          writebuf, offset, len);
> >
> > I had understood the core_fns method of providing a core file target
> > to
> > be deprecated, and in fact I just recently got rid of it for AIX in
> > favour
> > of the gdbarch_regset_from_core_section callback ...   I'd prefer
> > this to
> > be a gdbarch callback (which would also support core file
> > cross-debugging).
>
> I hadn't even thought about it.  Yes, you're right.

Also, we added #include's so the Makefile needs an update.

> +/* Returns 1 if ADDR is within the cygwin1.dll text segment, returns 0
> +   otherwise.  */
> +static int
> +inside_cygwin (CORE_ADDR addr)
> +{
> +  if (cygwin_load_start == 0)
> +    {
> +      struct so_list *so;
> +
> +      for (so = master_so_list (); so; so = so->next)

Nothing outside of the solib implementations calls master_so_list.  I
think that's best; can you use ALL_OBJFILES here instead?

> +  if (data->module_count == 0)
> +    {
> +#if 0
> +      /* TODO: What if the user supplied exec and/or
> +	 symbol files on the command line?  */
> +      /* The first module is the .exe itself.  */
> +      symbol_file_add_main (module_name, 0);
> +#endif
> +    }
> +  else
> +    {
> +      struct so_list *so = win32_make_so (module_name, base_addr);
> +      solib_to_xml (so, data->obstack);
> +      win32_free_so (so);
> +    }
> +  data->module_count++;

Let's not add #if 0 / TODO.  I think we can drop this code, how about
you?

Other than that it looks good to me if it looks good to Chris.

-- 
Daniel Jacobowitz
CodeSourcery


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Windows DLL support update.
  2007-08-16  0:44   ` Pedro Alves
  2007-08-16  0:57     ` Daniel Jacobowitz
@ 2007-08-16  1:59     ` Christopher Faylor
  1 sibling, 0 replies; 7+ messages in thread
From: Christopher Faylor @ 2007-08-16  1:59 UTC (permalink / raw)
  To: Pedro Alves, gdb-patches

On Thu, Aug 16, 2007 at 01:40:48AM +0100, Pedro Alves wrote:
> Christopher Faylor wrote:
>> On Tue, Aug 14, 2007 at 01:23:28AM +0100, Pedro Alves wrote:
>>> Here is the new version of the patch that converts native win32
>>> debugging to use the new solib-target.c.
>> I have a few of questions/observations wrt the win32-nat.c changes.
>
> Thanks for such a quick review.
>
>> 1) Does it still properly handle the "exceptions" that are thrown by
>> cygwin which must be ignored?  I believe that the most populr source
>> of complaints about those came from people who were using pthreads
>> functions.
>
> Yes.  I tried with this:
> http://www.cygwin.com/ml/cygwin/2006-05/msg00650.html
>
> 'set cygwin-exceptions 1' shows the SEGV, 'set cygwin-exceptions 0'
> doesn't.
>
>> 2) Is there some reason you didn't record the cygwin load/start address
>> in win32_make_so?  Isn't all of the information you need available when
>> that function is called?
>
> I could open a bfd and look for .text like old solib_symbols_add
> does, but the so_list of the main list will have one open, so we can
> use that instead.  I'll want to move these bits of cygwin detection and
> exception ignoring into a win32-tdep.c file that can be reused
> when remote debugging.  This is step in that direction, but I'll
> understand if you still prefer the old way.
>
>> 3) If the answer to the above question is no, then it seems like
>> cygwin_load_start and cygwin_load_end should be static variables local
>> to ignore_access_violation_p.  
>
> Storing the cygwin1.dll addresses and reusing
> it across runs should be ok if we assume that we are always
> debugging cygwin apps, but it could mask an access exception in
> a non-cygwin app that happened to occur in a dll loaded in that
> range by coincidence.  I was going to leave it for later, but
> since you've asked, I'm now clearing the start/end addresses
> in do_initial_win32_stuff.  This shows why they can't be local
> static.
>
> > I wonder if that logic should even be
> > further broken out into its own inside_cygwin(addr) function.
>
> Wonder no more.  Done.
>
>> 4) I'd prefer it if you dropped the _p from "ignore_access_violation".
>
> Done.
>
>
> I gave it another testsuite spin, and it looks good.

Ok.  I approve the win32 specific parts.  Thanks for the explanations.

cgf


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Windows DLL support update.
  2007-08-16  0:57     ` Daniel Jacobowitz
@ 2007-08-17 23:26       ` Pedro Alves
  0 siblings, 0 replies; 7+ messages in thread
From: Pedro Alves @ 2007-08-17 23:26 UTC (permalink / raw)
  To: gdb-patches

Daniel Jacobowitz wrote:
> 
> I have one concern; one of us should fix the problem Ulrich pointed
> out with my core changes:
> 

Ooouups, I totally forgot seeing it.

>> On Tue, Jun 19, 2007 at 09:05:51PM +0200, Ulrich Weigand wrote:
>>> One thing I don't quite like is this:
>>>
>>>> +    case TARGET_OBJECT_LIBRARIES:
>>>> +      if (core_vec->xfer_shared_libraries != NULL)
>>>> +   return core_vec->xfer_shared_libraries (ops, object, annex,
>>>> readbuf,
>>>> +                                          writebuf, offset, len);
>>> I had understood the core_fns method of providing a core file target
>>> to
>>> be deprecated, and in fact I just recently got rid of it for AIX in
>>> favour
>>> of the gdbarch_regset_from_core_section callback ...   I'd prefer
>>> this to
>>> be a gdbarch callback (which would also support core file
>>> cross-debugging).
>> I hadn't even thought about it.  Yes, you're right.
> 

OK, I'll take a stab at it, although an interface suggestion
would be nice.

Should it be a callback with a similar interface
to xfer_shared_libraries and to be called in core_xfer_partial
(the callback is expected to fill a TARGET_OBJECT_LIBRARIES,
  similar to what you had, but implemented as a gdbarch callback),
or do you think it should be somethink different?

I'm giving the first option a try, and while looking at it, I've
implemented gdbarch_regset_from_core_section for
i386/win32/Cygwin, meaning core file cross debugging is on
the way for Cygwin.

> Also, we added #include's so the Makefile needs an update.
> 

Ooouups 2.  Will do.

>> +/* Returns 1 if ADDR is within the cygwin1.dll text segment, returns 0
>> +   otherwise.  */
>> +static int
>> +inside_cygwin (CORE_ADDR addr)
>> +{
>> +  if (cygwin_load_start == 0)
>> +    {
>> +      struct so_list *so;
>> +
>> +      for (so = master_so_list (); so; so = so->next)
> 
> Nothing outside of the solib implementations calls master_so_list.  I
> think that's best; can you use ALL_OBJFILES here instead?
> 

It would not work with 'set auto-solib-add 0'.  In that case,
the so_list from the master list has an open associated bfd
to look at, but ALL_OBJFILES doesn't report cygwin1.dll,
because the symbols haven't been read yet.  This means that
in that case, the user would see the internal Cygwin
exceptions as SIGSEGVs.  That would be a functionality
regression.

Perhaps the cygwin1.dll .text range recording could also be
implemented with a callback (observer?) that gets called
on every solib loaded instead of iterating through all
loaded libs.

Let me explain why I was doing it differently from how it was
done before, because we may come to the conclusion this is
the wrong way to do it.

The current win32-nat.c records the cygwin1.dll
.text load start/end addresses when imediatelly when the
dll event is reported.  This range is then
used to filter any Windows exception that occurs inside Cygwin,
since they will be handled internally by Cygwin - the user should
never see them.  Same thing happens with the IsBadXxxPtr family
of win32 functions.  They trigger an access violation by design,
so the debugger although has a chance to see it, shouldn't
normally pass it to the user when they are used.  It is
desirable to also have this filtering funcionality on the
gdbserver side.  The function in the patch implements the base
for the filtering pretty much decoupled from the rest of the
win32-nat.c code.

Instead of teaching gdbserver about these things, we could move
these bits into win32-tdep.c, or i386-cygwin-tdep.c, and install
a gdbarch callback to be called from/near handle_inferior_event.
The callback could then decide to ignore the SIGTRAP, for
instance.

Alternativelly, we could extend the qSymbol mechanism, and have
gdbserver know how to ignore the exceptions itself.  qSymbol
allows gdbserver to know the address of a symbol, but the
IsBadxxPtr case needs a start-end function range, because the
exception happens *inside* that function.  The cygwin1.dll .text
start/end could be solved if we add __cygwin_text_start__ and
__cygwin_text_end__ symbols to cygwin1.dll.  The
advantage of this approach is that an app triggering
lots of internal cygwin exceptions, or calling IsBadXxxPtr in a
tight loop would perform much faster under gdbserver, as the
ignore addresses could be cached, instead of passing a SIGTRAP
to gdb every time, just to have it ignored.  I'm not sure it
justifies the extra complexity, though.

The gdb-only method side has the advantage that doesn't
need any protocol change, is simpler, and possibly more
extensible/flexible, and can share the same user
commands (set cygwin-exceptions x).

Of course for all this to work gdb needs to see
a copy of the same version of the dlls installed in
the target.  Not sure about licensing problems with
OS components...  Perhaps the best way would be to
require dbghelp.dll (MSFTs symbol reader API) on
gdbserver, and use it to get at the symbols.  Then all
this becomes moot.

Anyways, a lot to avoid the master_so_list call.  :)

If desired, I'll revert to the old method of getting
at the cygwin1.dll ranges on dll load, and come back to
it after this patch is in.

>> +  if (data->module_count == 0)
>> +    {
>> +#if 0
>> +      /* TODO: What if the user supplied exec and/or
>> +	 symbol files on the command line?  */
>> +      /* The first module is the .exe itself.  */
>> +      symbol_file_add_main (module_name, 0);
>> +#endif
>> +    }
>> +  else
>> +    {
>> +      struct so_list *so = win32_make_so (module_name, base_addr);
>> +      solib_to_xml (so, data->obstack);
>> +      win32_free_so (so);
>> +    }
>> +  data->module_count++;
> 
> Let's not add #if 0 / TODO.  I think we can drop this code, how about
> you?
> 

Ahh, it worked - I was hoping somebody would comment
on that.  I'll remove it.  :)

Cheers,
Pedro Alves







^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2007-08-17 23:26 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-08-14  0:24 Windows DLL support update Pedro Alves
2007-08-14  0:43 ` Pedro Alves
2007-08-14 12:10 ` Christopher Faylor
2007-08-16  0:44   ` Pedro Alves
2007-08-16  0:57     ` Daniel Jacobowitz
2007-08-17 23:26       ` Pedro Alves
2007-08-16  1:59     ` Christopher Faylor

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox