[RFC,v2] Yank out target_ops->to_sections

Pedro Alves pedro@codesourcery.com
Tue May 26 23:30:00 GMT 2009


Hi Ulrich, all,

On Sunday 24 May 2009 02:35:20, Pedro Alves wrote:

> - Again, I've moved the whole handling of unmmaped overlay
>   sections to memory_xfer_partial.  There used to be a bit of it in xfer_memory.
>   It's now centralized, and, the memory reads are now always
>   really dispatched to read directly from files --- previously, they could
>   go to the core layer first (don't know if there's any target that
>   mixes core debugging with overlays, but if there is, I believe
>   this change is correct).

It seems I don't have access to any target using an overlay manager.  I
think Cell uses overlays?  Ulrich, perhaps I could ask you the favour of
confirming that I'm not breaking anything overlay related?  A genaral peek
over the patch would be much appreciated as well, of course.

> - The bfd-target.c is used by the frv target, by reading memory through
>   get_target_memory_unsigned, and that ends up going to memory_xfer_partial.
>   But, this is a bit broken --- if we're reading from an alternative, non-current
>   bfd target, neither the overlay support, neither the dcache should apply.
>   This is fixed by making get_target_memory request a
>   TARGET_OBJECT_RAW_MEMORY, instead of the cooked TARGET_OBJECT_MEMORY.

ppc64-linux may also use bfd-target.c (ppc64_linux_convert_from_func_ptr_addr,
which I think was the whole point of this bfd-target.c), so I found myself
such a machine, and gave it a spin there.  Surprisingly, I get this
consistently:

 -FAIL: gdb.base/gcore.exp: corefile restored backtrace
 +PASS: gdb.base/gcore.exp: corefile restored backtrace

@@ -24913,10 +24914,8 @@ backtrace
 #6  0x00000000100006c4 in factorial_func (value=5) at ../../../src/gdb/testsuite/gdb.base/gcore.c:60
 #7  0x00000000100006c4 in factorial_func (value=6) at ../../../src/gdb/testsuite/gdb.base/gcore.c:60
 #8  0x0000000010000720 in main () at ../../../src/gdb/testsuite/gdb.base/gcore.c:68
-#9  0x0000008091073cd8 in .generic_start_main () from /lib64/tls/libc.so.6
-Backtrace stopped: frame did not save the PC
-(gdb) FAIL: gdb.base/gcore.exp: corefile restored backtrace
-testcase ../../../src/gdb/testsuite/gdb.base/gcore.exp completed in 3 seconds
+(gdb) PASS: gdb.base/gcore.exp: corefile restored backtrace
+testcase ../../../src/gdb/testsuite/gdb.base/gcore.exp completed in 2 seconds

Always fails without the patch, always passes with.  No other changes in the
whole test run.  I haven't exactly pinpointed the exact reason why this is
now passing, though.

Here's the patch again.  Only change compared to the previous version is to
use an explicit xfree, instead of xrealloc (..., 0), because I found out
that libiberty's xrealloc still allocs when the 'size' argument is
0, instead of behaving like free (it is legal either way).

-- 
Pedro Alves

2009-05-27  Pedro Alves  <pedro@codesourcery.com>

	* target.c: Include "exec.h".
	(update_current_target): Don't inherit to_sections or
	to_sections_end.
	(target_get_section_table): New.
	(target_section_by_addr): Fetch the section table from the passed
	in target.
	(memory_xfer_partial): Handle unmapped overlay sections before
	anything else.  Get the overlay mapped address here.  Adjust to
	use section_table_xfer_memory_partial.
	(get_target_memory): Reques a TARGET_OBJECT_RAW_MEMORY object
	instead of TARGET_OBJECT_MEMORY.
	(current_target_sections_1): New global.
	(current_target_sections): New global.
	(target_resize_to_sections): Delete.
	(remove_target_sections): Adjust to remove target sections from
	`current_target_sections', and use resize_section_table.
	* target.h (struct target_ops) <to_sections, to_sections_end>:
	Remove fields.
	<to_get_section_table>: New method.
	(xfer_memory, print_section_info): Delete declarations.
	(struct target_section_table): New type.
	(current_target_sections): Declare.
	(target_get_section_table): Declare.
	(target_resize_to_sections): Delete declaration.
	* bfd-target.c (target_bfd_xfer_partial): Get the section table
	from to_data.
	(target_bfd_get_section_table): New.
	(target_bfd_xclose): Adjust.
	(target_bfd_reopen): Store the section table in the to_data field.
	* corelow.c (core_data): New.
	(core_close): Adjust to release core_data and its sections.
	(core_open): Allocate core_data, and build its target sections
	table.
	(deprecated_core_resize_section_table): New.
	(core_files_info): Pass core_data to print_section_info.
	(core_xfer_partial): Adjust to use
	section_table_xfer_memory_partial for TARGET_OBJECT_MEMORY xfers.
	(init_core_ops): Do not install a deprecated_xfer_memory callback
	anymore.
	* solib.c (update_solib_list): Append the shared library sections
	in the current target sections table.
	* exec.c (exec_close): Remove the exec_bfd's sections from the
	current target sections table.  Adjust to not use to_sections.
	(exec_file_attach): Adjust to not use to_sections.  Append
	exec_bfd's sections in the current target sections table.
	(resize_section_table): New.
	(concat_section_table): New.
	(section_table_xfer_memory): Adjust to implement the xfer_partial
	interface, and rename to...
	(section_table_xfer_memory_partial): ... this, replacing the
	current function of that same name.
	(exec_xfer_partial): New.
	(xfer_memory): Delete.
	(print_section_info): Replace the target_ops parameter by a
	target_section_table parameter.
	(exec_files_info, set_section_command, exec_set_section_address):
	Adjust to use the current target sections table.
	(init_exec_ops): Do not register a deprecated_xfer_memory
	callback.  Register a to_xfer_partial callback.
	* infrun.c (handle_inferior_event): Update comments around
	solib_add.
	* rs6000-nat.c (xcoff_relocate_core): Adjust to use
	deprecated_core_resize_section_table.
	* exec.h (resize_section_table): Declare.
	(section_table_xfer_memory_partial): Add const char * argument.
	(concat_section_table): Declare.
	(print_section_info): Declare here.
	* gdbcore.h (deprecated_core_resize_section_table): Declare.

---
 gdb/bfd-target.c |   37 +++++++---
 gdb/corelow.c    |   56 +++++++++++-----
 gdb/exec.c       |  186 +++++++++++++++++++++++++++----------------------------
 gdb/exec.h       |   23 ++++++
 gdb/gdbcore.h    |    2 
 gdb/infrun.c     |   18 -----
 gdb/rs6000-nat.c |    3 
 gdb/solib.c      |   21 +-----
 gdb/target.c     |  183 ++++++++++++++++++++++++------------------------------
 gdb/target.h     |   39 ++++++-----
 10 files changed, 298 insertions(+), 270 deletions(-)

Index: src/gdb/target.c
===================================================================
--- src.orig/gdb/target.c	2009-05-24 22:46:23.000000000 +0100
+++ src/gdb/target.c	2009-05-25 16:04:38.000000000 +0100
@@ -41,6 +41,7 @@
 #include "target-descriptions.h"
 #include "gdbthread.h"
 #include "solib.h"
+#include "exec.h"
 
 static void target_info (char *, int);
 
@@ -491,8 +492,6 @@ update_current_target (void)
       INHERIT (to_has_registers, t);
       INHERIT (to_has_execution, t);
       INHERIT (to_has_thread_control, t);
-      INHERIT (to_sections, t);
-      INHERIT (to_sections_end, t);
       INHERIT (to_can_async_p, t);
       INHERIT (to_is_async_p, t);
       INHERIT (to_async, t);
@@ -1016,14 +1015,37 @@ done:
   return nbytes_read;
 }
 
+struct target_section_table *
+target_get_section_table (struct target_ops *target)
+{
+  struct target_ops *t;
+
+  if (targetdebug)
+    fprintf_unfiltered (gdb_stdlog, "target_get_section_table ()\n");
+
+  for (t = target; t != NULL; t = t->beneath)
+    if (t->to_get_section_table != NULL)
+      return (*t->to_get_section_table) (t);
+
+  /* Most targets will want to get at the target sections mapped into
+     the current address space of the current inferior.  Those that do
+     not want such fallback, will install a to_get_section_table
+     callback.  One example is bfd-target.c.  */
+  return current_target_sections;
+}
+
 /* Find a section containing ADDR.  */
+
 struct target_section *
-target_section_by_addr (struct target_ops *target, CORE_ADDR addr)
+target_section_by_addr (struct target_ops *ops, CORE_ADDR addr)
 {
+  struct target_section_table *table = target_get_section_table (ops);
   struct target_section *secp;
-  for (secp = target->to_sections;
-       secp < target->to_sections_end;
-       secp++)
+
+  if (table == NULL)
+    return NULL;
+
+  for (secp = table->sections; secp < table->sections_end; secp++)
     {
       if (addr >= secp->addr && addr < secp->endaddr)
 	return secp;
@@ -1046,24 +1068,40 @@ memory_xfer_partial (struct target_ops *
   if (len == 0)
     return 0;
 
-  /* Try the executable file, if "trust-readonly-sections" is set.  */
+  /* For accesses to unmapped overlay sections, read directly from
+     files.  Must do this first, as MEMADDR may need adjustment.  */
+  if (readbuf != NULL && overlay_debugging)
+    {
+      struct obj_section *section = find_pc_overlay (memaddr);
+      if (pc_in_unmapped_range (memaddr, section))
+	{
+	  struct target_section_table *table
+	    = target_get_section_table (ops);
+	  const char *section_name = section->the_bfd_section->name;
+	  memaddr = overlay_mapped_address (memaddr, section);
+	  return section_table_xfer_memory_partial (readbuf, writebuf,
+						    memaddr, len,
+						    table->sections,
+						    table->sections_end,
+						    section_name);
+	}
+    }
+
+  /* Try the executable files, if "trust-readonly-sections" is set.  */
   if (readbuf != NULL && trust_readonly)
     {
       struct target_section *secp;
-
+      struct target_section_table *table
+	= target_get_section_table (ops);
       secp = target_section_by_addr (ops, memaddr);
       if (secp != NULL
 	  && (bfd_get_section_flags (secp->bfd, secp->the_bfd_section)
 	      & SEC_READONLY))
-	return xfer_memory (memaddr, readbuf, len, 0, NULL, ops);
-    }
-
-  /* Likewise for accesses to unmapped overlay sections.  */
-  if (readbuf != NULL && overlay_debugging)
-    {
-      struct obj_section *section = find_pc_overlay (memaddr);
-      if (pc_in_unmapped_range (memaddr, section))
-	return xfer_memory (memaddr, readbuf, len, 0, NULL, ops);
+	return section_table_xfer_memory_partial (readbuf, writebuf,
+						  memaddr, len,
+						  table->sections,
+						  table->sections_end,
+						  NULL);
     }
 
   /* Try GDB's internal data cache.  */
@@ -1688,7 +1726,11 @@ void
 get_target_memory (struct target_ops *ops, CORE_ADDR addr, gdb_byte *buf,
 		   LONGEST len)
 {
-  if (target_read (ops, TARGET_OBJECT_MEMORY, NULL, buf, addr, len)
+  /* This method is used to read from an alternate, non-current
+     target.  This read must bypass the overlay support (as symbols
+     don't match this target), and GDB's internal cache (wrong cache
+     for this target).  */
+  if (target_read (ops, TARGET_OBJECT_RAW_MEMORY, NULL, buf, addr, len)
       != len)
     memory_error (EIO, addr);
 }
@@ -2338,95 +2380,38 @@ return_minus_one (void)
   return -1;
 }
 
-/*
- * Resize the to_sections pointer.  Also make sure that anyone that
- * was holding on to an old value of it gets updated.
- * Returns the old size.
- */
+/* GDB currently only supports a single symbol/address space for the
+   whole debug session.  When that limitation is lifted, this global
+   goes away.  */
+static struct target_section_table current_target_sections_1;
+
+/* The target sections (of the current address space) of the current
+   inferior.  */
+struct target_section_table *current_target_sections = &current_target_sections_1;
 
-int
-target_resize_to_sections (struct target_ops *target, int num_added)
-{
-  struct target_ops **t;
-  struct target_section *old_value;
-  int old_count;
-
-  old_value = target->to_sections;
-
-  if (target->to_sections)
-    {
-      old_count = target->to_sections_end - target->to_sections;
-      target->to_sections = (struct target_section *)
-	xrealloc ((char *) target->to_sections,
-		  (sizeof (struct target_section)) * (num_added + old_count));
-    }
-  else
-    {
-      old_count = 0;
-      target->to_sections = (struct target_section *)
-	xmalloc ((sizeof (struct target_section)) * num_added);
-    }
-  target->to_sections_end = target->to_sections + (num_added + old_count);
+/* Remove all target sections taken from ABFD.  */
 
-  /* Check to see if anyone else was pointing to this structure.
-     If old_value was null, then no one was. */
-
-  if (old_value)
-    {
-      for (t = target_structs; t < target_structs + target_struct_size;
-	   ++t)
-	{
-	  if ((*t)->to_sections == old_value)
-	    {
-	      (*t)->to_sections = target->to_sections;
-	      (*t)->to_sections_end = target->to_sections_end;
-	    }
-	}
-      /* There is a flattened view of the target stack in current_target,
-	 so its to_sections pointer might also need updating. */
-      if (current_target.to_sections == old_value)
-	{
-	  current_target.to_sections = target->to_sections;
-	  current_target.to_sections_end = target->to_sections_end;
-	}
-    }
-
-  return old_count;
-
-}
-
-/* Remove all target sections taken from ABFD.
-
-   Scan the current target stack for targets whose section tables
-   refer to sections from BFD, and remove those sections.  We use this
-   when we notice that the inferior has unloaded a shared object, for
-   example.  */
 void
 remove_target_sections (bfd *abfd)
 {
-  struct target_ops **t;
-
-  for (t = target_structs; t < target_structs + target_struct_size; t++)
-    {
-      struct target_section *src, *dest;
-
-      dest = (*t)->to_sections;
-      for (src = (*t)->to_sections; src < (*t)->to_sections_end; src++)
-	if (src->bfd != abfd)
-	  {
-	    /* Keep this section.  */
-	    if (dest < src) *dest = *src;
-	    dest++;
-	  }
-
-      /* If we've dropped any sections, resize the section table.  */
-      if (dest < src)
-	target_resize_to_sections (*t, dest - src);
-    }
-}
+  struct target_section *src, *dest;
 
+  struct target_section_table *table = current_target_sections;
 
+  dest = table->sections;
+  for (src = table->sections; src < table->sections_end; src++)
+    if (src->bfd != abfd)
+      {
+	/* Keep this section.  */
+	if (dest < src)
+	  *dest = *src;
+	dest++;
+      }
 
+  /* If we've dropped any sections, resize the section table.  */
+  if (dest < src)
+    resize_section_table (table, dest - src);
+}
 
 /* Find a single runnable target in the stack and return it.  If for
    some reason there is more than one, return NULL.  */
Index: src/gdb/target.h
===================================================================
--- src.orig/gdb/target.h	2009-05-24 22:46:23.000000000 +0100
+++ src/gdb/target.h	2009-05-25 16:04:38.000000000 +0100
@@ -30,6 +30,7 @@ struct mem_attrib;
 struct target_ops;
 struct bp_target_info;
 struct regcache;
+struct target_section_table;
 
 /* This include file defines the interface between the main part
    of the debugger, and the part which is target-specific, or
@@ -420,10 +421,8 @@ struct target_ops
     int to_has_execution;
     int to_has_thread_control;	/* control thread execution */
     int to_attach_no_wait;
-    struct target_section
-     *to_sections;
-    struct target_section
-     *to_sections_end;
+
+    struct target_section_table *(*to_get_section_table) (struct target_ops *);
     /* ASYNC target controls */
     int (*to_can_async_p) (void);
     int (*to_is_async_p) (void);
@@ -668,9 +667,6 @@ extern int target_read_memory (CORE_ADDR
 extern int target_write_memory (CORE_ADDR memaddr, const gdb_byte *myaddr,
 				int len);
 
-extern int xfer_memory (CORE_ADDR, gdb_byte *, int, int,
-			struct mem_attrib *, struct target_ops *);
-
 /* Fetches the target's memory map.  If one is found it is sorted
    and returned, after some consistency checking.  Otherwise, NULL
    is returned.  */
@@ -733,10 +729,6 @@ extern int inferior_has_vforked (ptid_t 
 
 extern int inferior_has_execd (ptid_t pid, char **execd_pathname);
 
-/* From exec.c */
-
-extern void print_section_info (struct target_ops *, bfd *);
-
 /* Print a line about the current target.  */
 
 #define	target_files_info()	\
@@ -1208,10 +1200,30 @@ struct target_section
     bfd *bfd;			/* BFD file pointer */
   };
 
+/* Holds an array of target sections.  Defined by [START..END[.  */
+
+struct target_section_table
+{
+  struct target_section *sections;
+  struct target_section *sections_end;
+};
+
+/* The current set of target sections matching the sections mapped
+   into the current inferior's address space.  */
+extern struct target_section_table *current_target_sections;
+
+extern void remove_target_sections (bfd *abfd);
+
 /* Return the "section" containing the specified address.  */
 struct target_section *target_section_by_addr (struct target_ops *target,
 					       CORE_ADDR addr);
 
+/* Return the target section table this target (or the targets
+   beneath) currently manipulate.  */
+
+extern struct target_section_table *target_get_section_table
+  (struct target_ops *target);
+
 /* From mem-break.c */
 
 extern int memory_remove_breakpoint (struct bp_target_info *);
@@ -1242,11 +1254,6 @@ extern struct target_ops *find_core_targ
 
 extern struct target_ops *find_target_beneath (struct target_ops *);
 
-extern int target_resize_to_sections (struct target_ops *target,
-				      int num_added);
-
-extern void remove_target_sections (bfd *abfd);
-
 /* Read OS data object of type TYPE from the target, and return it in
    XML format.  The result is NUL-terminated and returned as a string,
    allocated using xmalloc.  If an error occurs or the transfer is
Index: src/gdb/bfd-target.c
===================================================================
--- src.orig/gdb/bfd-target.c	2009-05-24 22:46:23.000000000 +0100
+++ src/gdb/bfd-target.c	2009-05-24 23:22:52.000000000 +0100
@@ -32,35 +32,52 @@ target_bfd_xfer_partial (struct target_o
   switch (object)
     {
     case TARGET_OBJECT_MEMORY:
-      return section_table_xfer_memory_partial (readbuf, writebuf, offset, len,
-						ops->to_sections,
-						ops->to_sections_end);
+      {
+	struct target_section_table *table = ops->to_data;
+	return section_table_xfer_memory_partial (readbuf, writebuf, offset, len,
+						  table->sections,
+						  table->sections_end,
+						  NULL);
+      }
     default:
       return -1;
     }
 }
 
+struct target_section_table *
+target_bfd_get_section_table (struct target_ops *ops)
+{
+  return ops->to_data;
+}
+
 static void
 target_bfd_xclose (struct target_ops *t, int quitting)
 {
-  bfd_close (t->to_data);
-  xfree (t->to_sections);
+  struct target_section_table *table = t->to_data;
+  if (table->sections)
+    bfd_close (table->sections->bfd);
+  xfree (table->sections);
+  xfree (table);
   xfree (t);
 }
 
 struct target_ops *
 target_bfd_reopen (struct bfd *bfd)
 {
-  struct target_ops *t = XZALLOC (struct target_ops);
+  struct target_ops *t;
+  struct target_section_table *table;
+
+  table = XZALLOC (struct target_section_table);
+  build_section_table (bfd, &table->sections, &table->sections_end);
+
+  t = XZALLOC (struct target_ops);
   t->to_shortname = "bfd";
   t->to_longname = _("BFD backed target");
   t->to_doc = _("You should never see this");
+  t->to_get_section_table = target_bfd_get_section_table;
   t->to_xfer_partial = target_bfd_xfer_partial;
   t->to_xclose = target_bfd_xclose;
-  t->to_data = bfd;
+  t->to_data = table;
 
-  build_section_table (bfd,
-		       &t->to_sections,
-		       &t->to_sections_end);
   return t;
 }
Index: src/gdb/corelow.c
===================================================================
--- src.orig/gdb/corelow.c	2009-05-24 22:46:23.000000000 +0100
+++ src/gdb/corelow.c	2009-05-25 16:04:38.000000000 +0100
@@ -67,6 +67,14 @@ static struct core_fns *core_vec = NULL;
 
 struct gdbarch *core_gdbarch = NULL;
 
+/* Per-core data.  Currently, only the section table.  Note that these
+   target sections are *not* mapped in the current address spaces' set
+   of target sections --- those should come only from pure executable
+   or shared library bfds.  The core bfd sections are an
+   implementation detail of the core target, just like ptrace is for
+   unix child targets.  */
+struct target_section_table *core_data;
+
 static void core_files_info (struct target_ops *);
 
 static struct core_fns *sniff_core_bfd (bfd *);
@@ -203,18 +211,16 @@ core_close (int quitting)
          comments in clear_solib in solib.c. */
       clear_solib ();
 
+      xfree (core_data->sections);
+      xfree (core_data);
+      core_data = NULL;
+
       name = bfd_get_filename (core_bfd);
       if (!bfd_close (core_bfd))
 	warning (_("cannot close \"%s\": %s"),
 		 name, bfd_errmsg (bfd_get_error ()));
       xfree (name);
       core_bfd = NULL;
-      if (core_ops.to_sections)
-	{
-	  xfree (core_ops.to_sections);
-	  core_ops.to_sections = NULL;
-	  core_ops.to_sections_end = NULL;
-	}
     }
   core_vec = NULL;
   core_gdbarch = NULL;
@@ -347,9 +353,11 @@ core_open (char *filename, int from_tty)
 
   validate_files ();
 
+  core_data = XZALLOC (struct target_section_table);
+
   /* Find the data section */
-  if (build_section_table (core_bfd, &core_ops.to_sections,
-			   &core_ops.to_sections_end))
+  if (build_section_table (core_bfd,
+			   &core_data->sections, &core_data->sections_end))
     error (_("\"%s\": Can't find sections: %s"),
 	   bfd_get_filename (core_bfd), bfd_errmsg (bfd_get_error ()));
 
@@ -434,6 +442,23 @@ core_detach (struct target_ops *ops, cha
     printf_filtered (_("No core file now.\n"));
 }
 
+#ifdef DEPRECATED_IBM6000_TARGET
+
+/* Resize the core memory's section table, by NUM_ADDED.  Returns a
+   pointer into the first new slot.  This will not be necessary when
+   the rs6000 target is converted to use the standard solib
+   framework.  */
+
+struct target_section *
+deprecated_core_resize_section_table (int num_added)
+{
+  int old_count;
+
+  old_count = resize_section_table (core_data, num_added);
+  return core_data->sections + old_count;
+}
+
+#endif
 
 /* Try to retrieve registers from a section in core_bfd, and supply
    them to core_vec->core_read_registers, as the register set numbered
@@ -562,7 +587,7 @@ get_core_registers (struct target_ops *o
 static void
 core_files_info (struct target_ops *t)
 {
-  print_section_info (t, core_bfd);
+  print_section_info (core_data, core_bfd);
 }
 
 static LONGEST
@@ -573,13 +598,11 @@ core_xfer_partial (struct target_ops *op
   switch (object)
     {
     case TARGET_OBJECT_MEMORY:
-      if (readbuf)
-	return (*ops->deprecated_xfer_memory) (offset, readbuf,
-					       len, 0/*read*/, NULL, ops);
-      if (writebuf)
-	return (*ops->deprecated_xfer_memory) (offset, (gdb_byte *) writebuf,
-					       len, 1/*write*/, NULL, ops);
-      return -1;
+      return section_table_xfer_memory_partial (readbuf, writebuf,
+						offset, len,
+						core_data->sections,
+						core_data->sections_end,
+						NULL);
 
     case TARGET_OBJECT_AUXV:
       if (readbuf)
@@ -738,7 +761,6 @@ init_core_ops (void)
   core_ops.to_detach = core_detach;
   core_ops.to_fetch_registers = get_core_registers;
   core_ops.to_xfer_partial = core_xfer_partial;
-  core_ops.deprecated_xfer_memory = xfer_memory;
   core_ops.to_files_info = core_files_info;
   core_ops.to_insert_breakpoint = ignore;
   core_ops.to_remove_breakpoint = ignore;
Index: src/gdb/solib.c
===================================================================
--- src.orig/gdb/solib.c	2009-05-24 22:46:23.000000000 +0100
+++ src/gdb/solib.c	2009-05-25 16:04:37.000000000 +0100
@@ -661,21 +661,12 @@ update_solib_list (int from_tty, struct 
 			"Error while mapping shared library sections:\n",
 			RETURN_MASK_ALL);
 
-	  /* If requested, add the shared object's sections to the TARGET's
-	     section table.  Do this immediately after mapping the object so
-	     that later nodes in the list can query this object, as is needed
-	     in solib-osf.c.  */
-	  if (target)
-	    {
-	      int count = (i->sections_end - i->sections);
-	      if (count > 0)
-		{
-		  int space = target_resize_to_sections (target, count);
-		  memcpy (target->to_sections + space,
-			  i->sections,
-			  count * sizeof (i->sections[0]));
-		}
-	    }
+	  /* Add the shared object's sections to the current set of
+	     file section tables.  Do this immediately after mapping
+	     the object so that later nodes in the list can query this
+	     object, as is needed in solib-osf.c.  */
+	  concat_section_table (current_target_sections,
+				i->sections, i->sections_end);
 
 	  /* Notify any observer that the shared object has been
              loaded now that we've added it to GDB's tables.  */
Index: src/gdb/exec.c
===================================================================
--- src.orig/gdb/exec.c	2009-05-24 22:46:23.000000000 +0100
+++ src/gdb/exec.c	2009-05-25 16:05:01.000000000 +0100
@@ -132,6 +132,8 @@ exec_close (int quitting)
     {
       char *name = bfd_get_filename (exec_bfd);
 
+      remove_target_sections (exec_bfd);
+
       if (!bfd_close (exec_bfd))
 	warning (_("cannot close \"%s\": %s"),
 		 name, bfd_errmsg (bfd_get_error ()));
@@ -139,13 +141,6 @@ exec_close (int quitting)
       exec_bfd = NULL;
       exec_bfd_mtime = 0;
     }
-
-  if (exec_ops.to_sections)
-    {
-      xfree (exec_ops.to_sections);
-      exec_ops.to_sections = NULL;
-      exec_ops.to_sections_end = NULL;
-    }
 }
 
 void
@@ -195,6 +190,7 @@ exec_file_attach (char *filename, int fr
       struct cleanup *cleanups;
       char *scratch_pathname;
       int scratch_chan;
+      struct target_section *sections = NULL, *sections_end = NULL;
 
       scratch_chan = openp (getenv ("PATH"), OPF_TRY_CWD_FIRST, filename,
 		   write_files ? O_RDWR | O_BINARY : O_RDONLY | O_BINARY,
@@ -254,8 +250,7 @@ exec_file_attach (char *filename, int fr
 	}
 #endif /* DEPRECATED_IBM6000_TARGET */
 
-      if (build_section_table (exec_bfd, &exec_ops.to_sections,
-			       &exec_ops.to_sections_end))
+      if (build_section_table (exec_bfd, &sections, &sections_end))
 	{
 	  /* Make sure to close exec_bfd, or else "run" might try to use
 	     it.  */
@@ -264,6 +259,11 @@ exec_file_attach (char *filename, int fr
 		 scratch_pathname, bfd_errmsg (bfd_get_error ()));
 	}
 
+      /* Add the executable's sections to the current address spaces'
+	 list of sections.  */
+      concat_section_table (current_target_sections, sections, sections_end);
+      xfree (sections);
+
       exec_bfd_mtime = bfd_get_mtime (exec_bfd);
 
       validate_files ();
@@ -370,6 +370,33 @@ add_to_section_table (bfd *abfd, struct 
   (*table_pp)++;
 }
 
+int
+resize_section_table (struct target_section_table *table, int num_added)
+{
+  struct target_section *old_value;
+  int old_count;
+  int new_count;
+
+  old_value = table->sections;
+  old_count = table->sections_end - table->sections;
+
+  new_count = num_added + old_count;
+
+  if (new_count)
+    {
+      table->sections
+	= xrealloc (table->sections, sizeof (struct target_section) * new_count);
+      table->sections_end = table->sections + new_count;
+    }
+  else
+    {
+      xfree (table->sections);
+      table->sections = table->sections_end = NULL;
+    }
+
+  return old_count;
+}
+
 /* Builds a section table, given args BFD, SECTABLE_PTR, SECEND_PTR.
    Returns 0 if OK, 1 on error.  */
 
@@ -390,6 +417,24 @@ build_section_table (struct bfd *some_bf
   /* We could realloc the table, but it probably loses for most files.  */
   return 0;
 }
+
+void
+concat_section_table (struct target_section_table *table,
+		      struct target_section *sections,
+		      struct target_section *sections_end)
+{
+  int count;
+
+  count = sections_end - sections;
+
+  if (count > 0)
+    {
+      int space = resize_section_table (table, count);
+      memcpy (table->sections + space,
+	      sections, count * sizeof (sections[0]));
+    }
+}
+
 
 static void
 bfdsec_to_vmap (struct bfd *abfd, struct bfd_section *sect, void *arg3)
@@ -467,22 +512,22 @@ map_vmap (bfd *abfd, bfd *arch)
    < 0:  We cannot handle this address, but if somebody
    else handles (-N) bytes, we can start from there.  */
 
-static int
-section_table_xfer_memory (CORE_ADDR memaddr, gdb_byte *myaddr,
-			   int len, int write,
-			   struct target_section *sections,
-			   struct target_section *sections_end,
-			   const char *section_name)
+int
+section_table_xfer_memory_partial (gdb_byte *readbuf, const gdb_byte *writebuf,
+				   ULONGEST offset, LONGEST len,
+				   struct target_section *sections,
+				   struct target_section *sections_end,
+				   const char *section_name)
 {
   int res;
   struct target_section *p;
-  CORE_ADDR nextsectaddr, memend;
+  ULONGEST memaddr = offset;
+  ULONGEST memend;
 
   if (len <= 0)
     internal_error (__FILE__, __LINE__, _("failed internal consistency check"));
 
   memend = memaddr + len;
-  nextsectaddr = memend;
 
   for (p = sections; p < sections_end; p++)
     {
@@ -493,13 +538,13 @@ section_table_xfer_memory (CORE_ADDR mem
 	  if (memend <= p->endaddr)
 	    {
 	      /* Entire transfer is within this section.  */
-	      if (write)
+	      if (writebuf)
 		res = bfd_set_section_contents (p->bfd, p->the_bfd_section,
-						myaddr, memaddr - p->addr,
+						writebuf, memaddr - p->addr,
 						len);
 	      else
 		res = bfd_get_section_contents (p->bfd, p->the_bfd_section,
-						myaddr, memaddr - p->addr,
+						readbuf, memaddr - p->addr,
 						len);
 	      return (res != 0) ? len : 0;
 	    }
@@ -512,90 +557,43 @@ section_table_xfer_memory (CORE_ADDR mem
 	    {
 	      /* This section overlaps the transfer.  Just do half.  */
 	      len = p->endaddr - memaddr;
-	      if (write)
+	      if (writebuf)
 		res = bfd_set_section_contents (p->bfd, p->the_bfd_section,
-						myaddr, memaddr - p->addr,
+						writebuf, memaddr - p->addr,
 						len);
 	      else
 		res = bfd_get_section_contents (p->bfd, p->the_bfd_section,
-						myaddr, memaddr - p->addr,
+						readbuf, memaddr - p->addr,
 						len);
 	      return (res != 0) ? len : 0;
 	    }
         }
-      else
-	nextsectaddr = min (nextsectaddr, p->addr);
     }
 
-  if (nextsectaddr >= memend)
-    return 0;			/* We can't help */
-  else
-    return -(nextsectaddr - memaddr);	/* Next boundary where we can help */
+  return 0;			/* We can't help */
 }
 
-int
-section_table_xfer_memory_partial (gdb_byte *readbuf, const gdb_byte *writebuf,
-				   ULONGEST offset, LONGEST len,
-				   struct target_section *sections,
-				   struct target_section *sections_end)
-{
-  if (readbuf != NULL)
-    return section_table_xfer_memory (offset, readbuf, len, 0,
-				      sections, sections_end, NULL);
+static LONGEST
+exec_xfer_partial (struct target_ops *ops, enum target_object object,
+		   const char *annex, gdb_byte *readbuf,
+		   const gdb_byte *writebuf,
+		   ULONGEST offset, LONGEST len)
+{
+  struct target_section_table *table = target_get_section_table (ops);
+
+  if (object == TARGET_OBJECT_MEMORY)
+    return section_table_xfer_memory_partial (readbuf, writebuf,
+					      offset, len,
+					      table->sections,
+					      table->sections_end,
+					      NULL);
   else
-    return section_table_xfer_memory (offset, (gdb_byte *) writebuf, len, 1,
-				      sections, sections_end, NULL);
-}
-
-/* Read or write the exec file.
-
-   Args are address within a BFD file, address within gdb address-space,
-   length, and a flag indicating whether to read or write.
-
-   Result is a length:
-
-   0:    We cannot handle this address and length.
-   > 0:  We have handled N bytes starting at this address.
-   (If N == length, we did it all.)  We might be able
-   to handle more bytes beyond this length, but no
-   promises.
-   < 0:  We cannot handle this address, but if somebody
-   else handles (-N) bytes, we can start from there.
-
-   The same routine is used to handle both core and exec files;
-   we just tail-call it with more arguments to select between them.  */
-
-int
-xfer_memory (CORE_ADDR memaddr, gdb_byte *myaddr, int len, int write,
-	     struct mem_attrib *attrib, struct target_ops *target)
-{
-  int res;
-  const char *section_name = NULL;
-
-  if (len <= 0)
-    internal_error (__FILE__, __LINE__, _("failed internal consistency check"));
-
-  if (overlay_debugging)
-    {
-      struct obj_section *section = find_pc_overlay (memaddr);
-
-      if (section != NULL)
-	{
-	  if (pc_in_unmapped_range (memaddr, section))
-	    memaddr = overlay_mapped_address (memaddr, section);
-	  section_name = section->the_bfd_section->name;
-	}
-    }
-
-  return section_table_xfer_memory (memaddr, myaddr, len, write,
-				    target->to_sections,
-				    target->to_sections_end,
-				    section_name);
+    return -1;
 }
 
 
 void
-print_section_info (struct target_ops *t, bfd *abfd)
+print_section_info (struct target_section_table *t, bfd *abfd)
 {
   struct target_section *p;
   /* FIXME: 16 is not wide enough when gdbarch_addr_bit > 64.  */
@@ -607,7 +605,7 @@ print_section_info (struct target_ops *t
   if (abfd == exec_bfd)
     printf_filtered (_("\tEntry point: %s\n"),
                      paddress (bfd_get_start_address (abfd)));
-  for (p = t->to_sections; p < t->to_sections_end; p++)
+  for (p = t->sections; p < t->sections_end; p++)
     {
       printf_filtered ("\t%s", hex_string_custom (p->addr, wid));
       printf_filtered (" - %s", hex_string_custom (p->endaddr, wid));
@@ -631,7 +629,7 @@ print_section_info (struct target_ops *t
 static void
 exec_files_info (struct target_ops *t)
 {
-  print_section_info (t, exec_bfd);
+  print_section_info (current_target_sections, exec_bfd);
 
   if (vmap)
     {
@@ -667,6 +665,7 @@ set_section_command (char *args, int fro
   unsigned long secaddr;
   char secprint[100];
   long offset;
+  struct target_section_table *table;
 
   if (args == 0)
     error (_("Must specify section name and its virtual address"));
@@ -678,7 +677,8 @@ set_section_command (char *args, int fro
   /* Parse out new virtual address */
   secaddr = parse_and_eval_address (args);
 
-  for (p = exec_ops.to_sections; p < exec_ops.to_sections_end; p++)
+  table = current_target_sections;
+  for (p = table->sections; p < table->sections_end; p++)
     {
       if (!strncmp (secname, bfd_section_name (exec_bfd, p->the_bfd_section), seclen)
 	  && bfd_section_name (exec_bfd, p->the_bfd_section)[seclen] == '\0')
@@ -705,8 +705,10 @@ void
 exec_set_section_address (const char *filename, int index, CORE_ADDR address)
 {
   struct target_section *p;
+  struct target_section_table *table;
 
-  for (p = exec_ops.to_sections; p < exec_ops.to_sections_end; p++)
+  table = current_target_sections;
+  for (p = table->sections; p < table->sections_end; p++)
     {
       if (strcmp (filename, p->bfd->filename) == 0
 	  && index == p->the_bfd_section->index)
@@ -754,7 +756,7 @@ Specify the filename of the executable f
   exec_ops.to_open = exec_open;
   exec_ops.to_close = exec_close;
   exec_ops.to_attach = find_default_attach;
-  exec_ops.deprecated_xfer_memory = xfer_memory;
+  exec_ops.to_xfer_partial = exec_xfer_partial;
   exec_ops.to_files_info = exec_files_info;
   exec_ops.to_insert_breakpoint = ignore;
   exec_ops.to_remove_breakpoint = ignore;
Index: src/gdb/infrun.c
===================================================================
--- src.orig/gdb/infrun.c	2009-05-24 22:46:23.000000000 +0100
+++ src/gdb/infrun.c	2009-05-25 16:04:45.000000000 +0100
@@ -2425,15 +2425,6 @@ handle_inferior_event (struct execution_
 	     operations such as address => section name and hence
 	     require the table to contain all sections (including
 	     those found in shared libraries).  */
-	  /* NOTE: cagney/2003-11-25: Pass current_target and not
-	     exec_ops to SOLIB_ADD.  This is because current GDB is
-	     only tooled to propagate section_table changes out from
-	     the "current_target" (see target_resize_to_sections), and
-	     not up from the exec stratum.  This, of course, isn't
-	     right.  "infrun.c" should only interact with the
-	     exec/process stratum, instead relying on the target stack
-	     to propagate relevant changes (stop, section table
-	     changed, ...) up to other layers.  */
 #ifdef SOLIB_ADD
 	  SOLIB_ADD (NULL, 0, &current_target, auto_solib_add);
 #else
@@ -3422,15 +3413,6 @@ infrun: BPSTAT_WHAT_SET_LONGJMP_RESUME (
 	     operations such as address => section name and hence
 	     require the table to contain all sections (including
 	     those found in shared libraries).  */
-	  /* NOTE: cagney/2003-11-25: Pass current_target and not
-	     exec_ops to SOLIB_ADD.  This is because current GDB is
-	     only tooled to propagate section_table changes out from
-	     the "current_target" (see target_resize_to_sections), and
-	     not up from the exec stratum.  This, of course, isn't
-	     right.  "infrun.c" should only interact with the
-	     exec/process stratum, instead relying on the target stack
-	     to propagate relevant changes (stop, section table
-	     changed, ...) up to other layers.  */
 #ifdef SOLIB_ADD
 	  SOLIB_ADD (NULL, 0, &current_target, auto_solib_add);
 #else
Index: src/gdb/rs6000-nat.c
===================================================================
--- src.orig/gdb/rs6000-nat.c	2009-05-24 22:46:23.000000000 +0100
+++ src/gdb/rs6000-nat.c	2009-05-24 23:22:52.000000000 +0100
@@ -1160,8 +1160,7 @@ xcoff_relocate_core (struct target_ops *
 	{
 	  struct target_section *stp;
 
-	  target_resize_to_sections (target, 2);
-	  stp = target->to_sections_end - 2;
+	  stp = deprecated_core_resize_section_table (2);
 
 	  stp->bfd = vp->bfd;
 	  stp->the_bfd_section = bfd_get_section_by_name (stp->bfd, ".text");
Index: src/gdb/exec.h
===================================================================
--- src.orig/gdb/exec.h	2009-05-24 22:46:23.000000000 +0100
+++ src/gdb/exec.h	2009-05-25 16:04:37.000000000 +0100
@@ -34,6 +34,11 @@ extern struct target_ops exec_ops;
 extern int build_section_table (struct bfd *, struct target_section **,
 				struct target_section **);
 
+/* Resize the section table held by TABLE, by NUM_ADDED.  Returns the
+   old size.  */
+
+extern int resize_section_table (struct target_section_table *, int);
+
 /* Request to transfer up to LEN 8-bit bytes of the target sections
    defined by SECTIONS and SECTIONS_END.  The OFFSET specifies the
    starting address.
@@ -50,9 +55,25 @@ extern int build_section_table (struct b
 extern int section_table_xfer_memory_partial (gdb_byte *, const gdb_byte *,
 					      ULONGEST, LONGEST,
 					      struct target_section *,
-					      struct target_section *);
+					      struct target_section *,
+					      const char *);
 
 /* Set the loaded address of a section.  */
 extern void exec_set_section_address (const char *, int, CORE_ADDR);
 
+/* Append the sections array defined by [SECTIONS..SECTIONS_END[ to
+   TABLE.  TABLE's memory is reallocated to fit in the new
+   sections.  */
+extern void concat_section_table (struct target_section_table *table,
+				  struct target_section *sections,
+				  struct target_section *sections_end);
+
+/* Prints info about all sections defined in the TABLE.  ABFD is
+   special cased --- it's filename is omitted; if it is the executable
+   file, its entry point is printed.  */
+
+extern void print_section_info (struct target_section_table *table,
+				bfd *abfd);
+
+
 #endif
Index: src/gdb/gdbcore.h
===================================================================
--- src.orig/gdb/gdbcore.h	2009-05-24 22:46:23.000000000 +0100
+++ src/gdb/gdbcore.h	2009-05-25 16:04:37.000000000 +0100
@@ -189,4 +189,6 @@ extern void deprecated_add_core_fns (str
 extern int default_core_sniffer (struct core_fns *cf, bfd * abfd);
 extern int default_check_format (bfd * abfd);
 
+struct target_section *deprecated_core_resize_section_table (int num_added);
+
 #endif /* !defined (GDBCORE_H) */



More information about the Gdb-patches mailing list