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: Re: Windows DLL support update.
Date: Thu, 16 Aug 2007 00:44:00 -0000	[thread overview]
Message-ID: <46C39D10.3020001@portugalmail.pt> (raw)
In-Reply-To: <20070814121008.GA18838@ednor.casa.cgf.cx>

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




  reply	other threads:[~2007-08-16  0:44 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-08-14  0:24 Pedro Alves
2007-08-14  0:43 ` Pedro Alves
2007-08-14 12:10 ` Christopher Faylor
2007-08-16  0:44   ` Pedro Alves [this message]
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=46C39D10.3020001@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