Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Pedro Alves <pedro_alves@portugalmail.pt>
To: gdb-patches@sourceware.org
Subject: Windows DLL support update.
Date: Tue, 14 Aug 2007 00:24:00 -0000	[thread overview]
Message-ID: <46C0F600.5010607@portugalmail.pt> (raw)

[-- 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.  */




             reply	other threads:[~2007-08-14  0:24 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-08-14  0:24 Pedro Alves [this message]
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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=46C0F600.5010607@portugalmail.pt \
    --to=pedro_alves@portugalmail.pt \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox