This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[RFC,v3] Yank out target_ops->to_sections


On Friday 29 May 2009 15:13:41, Pedro Alves wrote:
> On Wednesday 27 May 2009 19:24:06, Ulrich Weigand wrote:

> > In general, I like the idea of your patch, in particular the elimination of
> > sections from target_ops, and removal of xfer_memory.
> > 
> > I'm not quite sure what to think of the new current_target_sections variable,
> > in particular its interaction with target_get_section_table.  Why do you need
> > a generic fallback to current_target_sections, instead of e.g. having exec_ops
> > implement a to_get_section_table method? 
> 
> The issue I had in mind is that currently, it is possible to debug
> with process_stratum target pushed, without having the exec_ops
> target pushed.  In that case, nothing would reply to
> a to_get_section_table request, and so "trust-readonly-sections"
> would fail in those cases.
> 
> I've been thinking for a while that the exec_ops target
> should be pushed whenever we have any kind of file loaded (main
> executable or dynamic shared module) that we can read memory
> from.  It implements the file_stratum after all, and target.h says:
> 
> file_stratum,               /* Executable files, etc */
>                                                  ^^^

I think I'm convinced this it is the best to do, design-wise.
This way, we'll still be able to read memory from shared library
sections if no main executable is loaded into GDB (e.g., gdb -c foo,
without specifying an executable needs this).

I've given it a try, and, it does look like a cleaner solution
long term to me.  Even PIE executables blur the distintion of
what is specified as main executable vs what is reported by the
dynamic loader a bit more.  Another interesting fact, is that
the "vmap" bits spread about in exec.c for xcoffsolib are quite
similar in spirit to this "set of target sections we can read file
read memory from".  Find below an incremental patch that applies
on top of the v2 one I posted (the changes aren't that
many: push/unpush of exec_ops moved, plus that default of
target_get_section_table you pointed out goes away, replaced by
the exec_ops target returning the current set of target sections).
At the bottom there's the new v3 combined patch.

Please let me know what you think about this.  Re-tested on x86_64-linux.

-- 
Pedro Alves

---
 gdb/exec.c   |  120 ++++++++++++++++++++++++++++++++++++++++++++++-------------
 gdb/exec.h   |    7 +--
 gdb/solib.c  |    3 -
 gdb/target.c |   39 -------------------
 gdb/target.h |    6 --
 5 files changed, 100 insertions(+), 75 deletions(-)

Index: src/gdb/exec.c
===================================================================
--- src.orig/gdb/exec.c	2009-05-30 17:09:35.000000000 +0100
+++ src/gdb/exec.c	2009-05-30 17:15:28.000000000 +0100
@@ -71,6 +71,15 @@ struct target_ops exec_ops;
 bfd *exec_bfd = NULL;
 long exec_bfd_mtime = 0;
 
+/* 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 set of target sections matching the sections mapped into the
+   current inferior's address space.  */
+struct target_section_table *current_target_sections = &current_target_sections_1;
+
 /* Whether to open exec and core files read-only or read-write.  */
 
 int write_files = 0;
@@ -93,6 +102,28 @@ exec_open (char *args, int from_tty)
 }
 
 static void
+exec_close_1 (void)
+{
+  if (exec_bfd)
+    {
+      bfd *abfd = exec_bfd;
+      char *name = bfd_get_filename (abfd);
+
+      if (!bfd_close (abfd))
+	warning (_("cannot close \"%s\": %s"),
+		 name, bfd_errmsg (bfd_get_error ()));
+      xfree (name);
+
+      /* Removing target sections may close the exec_ops target.
+	 Clear exec_bfd before doing so to prevent recursion.  */
+      exec_bfd = NULL;
+      exec_bfd_mtime = 0;
+
+      remove_target_sections (abfd);
+    }
+}
+
+static void
 exec_close (int quitting)
 {
   int need_symtab_cleanup = 0;
@@ -128,26 +159,20 @@ exec_close (int quitting)
 
   vmap = NULL;
 
-  if (exec_bfd)
-    {
-      char *name = bfd_get_filename (exec_bfd);
-
-      remove_target_sections (exec_bfd);
+  /* Delete all target sections.  */
+  resize_section_table
+    (current_target_sections,
+     -resize_section_table (current_target_sections, 0));
 
-      if (!bfd_close (exec_bfd))
-	warning (_("cannot close \"%s\": %s"),
-		 name, bfd_errmsg (bfd_get_error ()));
-      xfree (name);
-      exec_bfd = NULL;
-      exec_bfd_mtime = 0;
-    }
+  /* Remove exec file.  */
+  exec_close_1 ();
 }
 
 void
 exec_file_clear (int from_tty)
 {
   /* Remove exec file.  */
-  unpush_target (&exec_ops);
+  exec_close_1 ();
 
   if (from_tty)
     printf_unfiltered (_("No executable file now.\n"));
@@ -174,7 +199,7 @@ void
 exec_file_attach (char *filename, int from_tty)
 {
   /* Remove any previous exec file.  */
-  unpush_target (&exec_ops);
+  exec_close_1 ();
 
   /* Now open and digest the file the user requested, if any.  */
 
@@ -229,7 +254,7 @@ exec_file_attach (char *filename, int fr
 	{
 	  /* Make sure to close exec_bfd, or else "run" might try to use
 	     it.  */
-	  exec_close (0);
+	  exec_close_1 ();
 	  error (_("\"%s\": not in executable format: %s"),
 		 scratch_pathname, bfd_errmsg (bfd_get_error ()));
 	}
@@ -244,7 +269,7 @@ exec_file_attach (char *filename, int fr
 	{
 	  /* Make sure to close exec_bfd, or else "run" might try to use
 	     it.  */
-	  exec_close (0);
+	  exec_close_1 ();
 	  error (_("\"%s\": can't find the file sections: %s"),
 		 scratch_pathname, bfd_errmsg (bfd_get_error ()));
 	}
@@ -254,23 +279,21 @@ exec_file_attach (char *filename, int fr
 	{
 	  /* Make sure to close exec_bfd, or else "run" might try to use
 	     it.  */
-	  exec_close (0);
+	  exec_close_1 ();
 	  error (_("\"%s\": can't find the file sections: %s"),
 		 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 ();
 
       set_gdbarch_from_file (exec_bfd);
 
-      push_target (&exec_ops);
+      /* Add the executable's sections to the current address spaces'
+	 list of sections.  */
+      add_target_sections (sections, sections_end);
+      xfree (sections);
 
       /* Tell display code (if any) about the changed file name.  */
       if (deprecated_exec_file_display_hook)
@@ -419,11 +442,11 @@ build_section_table (struct bfd *some_bf
 }
 
 void
-concat_section_table (struct target_section_table *table,
-		      struct target_section *sections,
-		      struct target_section *sections_end)
+add_target_sections (struct target_section *sections,
+		     struct target_section *sections_end)
 {
   int count;
+  struct target_section_table *table = current_target_sections;
 
   count = sections_end - sections;
 
@@ -432,6 +455,44 @@ concat_section_table (struct target_sect
       int space = resize_section_table (table, count);
       memcpy (table->sections + space,
 	      sections, count * sizeof (sections[0]));
+
+      /* If these are the first file sections we can provide memory
+	 from, push the file_stratum target.  */
+      if (space == 0)
+	push_target (&exec_ops);
+    }
+}
+
+/* Remove all target sections taken from ABFD.  */
+
+void
+remove_target_sections (bfd *abfd)
+{
+  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)
+    {
+      int old_count;
+
+      old_count = resize_section_table (table, dest - src);
+
+      /* If we don't have any more sections to read memory from,
+	 remove the file_stratum target from the stack.  */
+      if (old_count + (dest - src) == 0)
+	unpush_target (&exec_ops);
     }
 }
 
@@ -573,6 +634,12 @@ section_table_xfer_memory_partial (gdb_b
   return 0;			/* We can't help */
 }
 
+struct target_section_table *
+exec_get_section_table (struct target_ops *ops)
+{
+  return current_target_sections;
+}
+
 static LONGEST
 exec_xfer_partial (struct target_ops *ops, enum target_object object,
 		   const char *annex, gdb_byte *readbuf,
@@ -757,6 +824,7 @@ Specify the filename of the executable f
   exec_ops.to_close = exec_close;
   exec_ops.to_attach = find_default_attach;
   exec_ops.to_xfer_partial = exec_xfer_partial;
+  exec_ops.to_get_section_table = exec_get_section_table;
   exec_ops.to_files_info = exec_files_info;
   exec_ops.to_insert_breakpoint = ignore;
   exec_ops.to_remove_breakpoint = ignore;
Index: src/gdb/exec.h
===================================================================
--- src.orig/gdb/exec.h	2009-05-30 17:09:35.000000000 +0100
+++ src/gdb/exec.h	2009-05-30 17:09:37.000000000 +0100
@@ -61,12 +61,13 @@ extern int section_table_xfer_memory_par
 /* Set the loaded address of a section.  */
 extern void exec_set_section_address (const char *, int, CORE_ADDR);
 
+extern void remove_target_sections (bfd *abfd);
+
 /* 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);
+extern void add_target_sections (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
Index: src/gdb/solib.c
===================================================================
--- src.orig/gdb/solib.c	2009-05-30 17:09:35.000000000 +0100
+++ src/gdb/solib.c	2009-05-30 17:09:37.000000000 +0100
@@ -665,8 +665,7 @@ update_solib_list (int from_tty, struct 
 	     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);
+	  add_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/target.c
===================================================================
--- src.orig/gdb/target.c	2009-05-30 17:09:35.000000000 +0100
+++ src/gdb/target.c	2009-05-30 17:12:52.000000000 +0100
@@ -1027,11 +1027,7 @@ target_get_section_table (struct target_
     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;
+  return NULL;
 }
 
 /* Find a section containing ADDR.  */
@@ -2380,39 +2376,6 @@ return_minus_one (void)
   return -1;
 }
 
-/* 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;
-
-/* Remove all target sections taken from ABFD.  */
-
-void
-remove_target_sections (bfd *abfd)
-{
-  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-30 17:09:35.000000000 +0100
+++ src/gdb/target.h	2009-05-30 17:12:05.000000000 +0100
@@ -1208,12 +1208,6 @@ struct target_section_table
   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);

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

New combined patch below:

2009-05-30  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): Request a TARGET_OBJECT_RAW_MEMORY object
	instead of TARGET_OBJECT_MEMORY.
	(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.
	(target_get_section_table): Declare.
	(target_resize_to_sections): Delete declaration.
	(remove_target_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): Add the shared library sections
	to the current target sections table.
	* exec.c (current_target_sections_1): New global.
	(current_target_sections): New global.
	
	(exec_close_1): New function, refactored from exec_close.  Remove
	the exec_bfd's sections from the current target sections table.
	Adjust to not use to_sections.
	(exec_close): Remove all target sections.  Call exec_close_1.
	(exec_file_clear): Use exec_close_1 instead of unpushing the
	target.
	(exec_file_attach): Likewise.  Adjust to not use to_sections.  Add
	exec_bfd's sections to the current target sections table.  Don't
	push the exec_ops target here.
	(resize_section_table): New.
	(add_target_sections): New.
	(remove_target_sections): Moved here.
	(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_get_section_table): New.
	(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 sections table.
	(init_exec_ops): Do not register a deprecated_xfer_memory
	callback.  Register to_xfer_partial and to_get_section_table
	callbacks.
	
	* 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.
	(remove_target_sections): Declare here.
	(add_target_sections): Declare.
	(print_section_info): Declare here.
	* gdbcore.h (deprecated_core_resize_section_table): Declare.

Index: src/gdb/target.c
===================================================================
--- src.orig/gdb/target.c	2009-05-30 17:24:30.000000000 +0100
+++ src/gdb/target.c	2009-05-30 17:24:47.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,33 @@ 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);
+
+  return NULL;
+}
+
 /* 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 +1064,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 +1722,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,96 +2376,6 @@ 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.
- */
-
-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);
-
-  /* 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);
-    }
-}
-
-
-
-
 /* 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-30 17:24:30.000000000 +0100
+++ src/gdb/target.h	2009-05-30 17:24:47.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,24 @@ 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;
+};
+
 /* 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 +1248,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-30 17:24:30.000000000 +0100
+++ src/gdb/bfd-target.c	2009-05-30 17:24:45.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-30 17:24:30.000000000 +0100
+++ src/gdb/corelow.c	2009-05-30 17:24:45.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-30 17:24:30.000000000 +0100
+++ src/gdb/solib.c	2009-05-30 17:24:47.000000000 +0100
@@ -661,21 +661,11 @@ 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.  */
+	  add_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-30 17:24:30.000000000 +0100
+++ src/gdb/exec.c	2009-05-30 17:24:47.000000000 +0100
@@ -71,6 +71,15 @@ struct target_ops exec_ops;
 bfd *exec_bfd = NULL;
 long exec_bfd_mtime = 0;
 
+/* 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 set of target sections matching the sections mapped into the
+   current inferior's address space.  */
+struct target_section_table *current_target_sections = &current_target_sections_1;
+
 /* Whether to open exec and core files read-only or read-write.  */
 
 int write_files = 0;
@@ -93,6 +102,28 @@ exec_open (char *args, int from_tty)
 }
 
 static void
+exec_close_1 (void)
+{
+  if (exec_bfd)
+    {
+      bfd *abfd = exec_bfd;
+      char *name = bfd_get_filename (abfd);
+
+      if (!bfd_close (abfd))
+	warning (_("cannot close \"%s\": %s"),
+		 name, bfd_errmsg (bfd_get_error ()));
+      xfree (name);
+
+      /* Removing target sections may close the exec_ops target.
+	 Clear exec_bfd before doing so to prevent recursion.  */
+      exec_bfd = NULL;
+      exec_bfd_mtime = 0;
+
+      remove_target_sections (abfd);
+    }
+}
+
+static void
 exec_close (int quitting)
 {
   int need_symtab_cleanup = 0;
@@ -128,31 +159,20 @@ exec_close (int quitting)
 
   vmap = NULL;
 
-  if (exec_bfd)
-    {
-      char *name = bfd_get_filename (exec_bfd);
-
-      if (!bfd_close (exec_bfd))
-	warning (_("cannot close \"%s\": %s"),
-		 name, bfd_errmsg (bfd_get_error ()));
-      xfree (name);
-      exec_bfd = NULL;
-      exec_bfd_mtime = 0;
-    }
+  /* Delete all target sections.  */
+  resize_section_table
+    (current_target_sections,
+     -resize_section_table (current_target_sections, 0));
 
-  if (exec_ops.to_sections)
-    {
-      xfree (exec_ops.to_sections);
-      exec_ops.to_sections = NULL;
-      exec_ops.to_sections_end = NULL;
-    }
+  /* Remove exec file.  */
+  exec_close_1 ();
 }
 
 void
 exec_file_clear (int from_tty)
 {
   /* Remove exec file.  */
-  unpush_target (&exec_ops);
+  exec_close_1 ();
 
   if (from_tty)
     printf_unfiltered (_("No executable file now.\n"));
@@ -179,7 +199,7 @@ void
 exec_file_attach (char *filename, int from_tty)
 {
   /* Remove any previous exec file.  */
-  unpush_target (&exec_ops);
+  exec_close_1 ();
 
   /* Now open and digest the file the user requested, if any.  */
 
@@ -195,6 +215,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,
@@ -233,7 +254,7 @@ exec_file_attach (char *filename, int fr
 	{
 	  /* Make sure to close exec_bfd, or else "run" might try to use
 	     it.  */
-	  exec_close (0);
+	  exec_close_1 ();
 	  error (_("\"%s\": not in executable format: %s"),
 		 scratch_pathname, bfd_errmsg (bfd_get_error ()));
 	}
@@ -248,18 +269,17 @@ exec_file_attach (char *filename, int fr
 	{
 	  /* Make sure to close exec_bfd, or else "run" might try to use
 	     it.  */
-	  exec_close (0);
+	  exec_close_1 ();
 	  error (_("\"%s\": can't find the file sections: %s"),
 		 scratch_pathname, bfd_errmsg (bfd_get_error ()));
 	}
 #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.  */
-	  exec_close (0);
+	  exec_close_1 ();
 	  error (_("\"%s\": can't find the file sections: %s"),
 		 scratch_pathname, bfd_errmsg (bfd_get_error ()));
 	}
@@ -270,7 +290,10 @@ exec_file_attach (char *filename, int fr
 
       set_gdbarch_from_file (exec_bfd);
 
-      push_target (&exec_ops);
+      /* Add the executable's sections to the current address spaces'
+	 list of sections.  */
+      add_target_sections (sections, sections_end);
+      xfree (sections);
 
       /* Tell display code (if any) about the changed file name.  */
       if (deprecated_exec_file_display_hook)
@@ -370,6 +393,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 +440,62 @@ build_section_table (struct bfd *some_bf
   /* We could realloc the table, but it probably loses for most files.  */
   return 0;
 }
+
+void
+add_target_sections (struct target_section *sections,
+		     struct target_section *sections_end)
+{
+  int count;
+  struct target_section_table *table = current_target_sections;
+
+  count = sections_end - sections;
+
+  if (count > 0)
+    {
+      int space = resize_section_table (table, count);
+      memcpy (table->sections + space,
+	      sections, count * sizeof (sections[0]));
+
+      /* If these are the first file sections we can provide memory
+	 from, push the file_stratum target.  */
+      if (space == 0)
+	push_target (&exec_ops);
+    }
+}
+
+/* Remove all target sections taken from ABFD.  */
+
+void
+remove_target_sections (bfd *abfd)
+{
+  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)
+    {
+      int old_count;
+
+      old_count = resize_section_table (table, dest - src);
+
+      /* If we don't have any more sections to read memory from,
+	 remove the file_stratum target from the stack.  */
+      if (old_count + (dest - src) == 0)
+	unpush_target (&exec_ops);
+    }
+}
+
 
 static void
 bfdsec_to_vmap (struct bfd *abfd, struct bfd_section *sect, void *arg3)
@@ -467,22 +573,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 +599,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 +618,49 @@ 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)
+struct target_section_table *
+exec_get_section_table (struct target_ops *ops)
 {
-  if (readbuf != NULL)
-    return section_table_xfer_memory (offset, readbuf, len, 0,
-				      sections, sections_end, NULL);
-  else
-    return section_table_xfer_memory (offset, (gdb_byte *) writebuf, len, 1,
-				      sections, sections_end, NULL);
+  return current_target_sections;
 }
 
-/* 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)
+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)
 {
-  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;
-	}
-    }
+  struct target_section_table *table = target_get_section_table (ops);
 
-  return section_table_xfer_memory (memaddr, myaddr, len, write,
-				    target->to_sections,
-				    target->to_sections_end,
-				    section_name);
+  if (object == TARGET_OBJECT_MEMORY)
+    return section_table_xfer_memory_partial (readbuf, writebuf,
+					      offset, len,
+					      table->sections,
+					      table->sections_end,
+					      NULL);
+  else
+    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 +672,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 +696,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 +732,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 +744,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 +772,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 +823,8 @@ 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_get_section_table = exec_get_section_table;
   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-30 17:24:31.000000000 +0100
+++ src/gdb/infrun.c	2009-05-30 17:24:45.000000000 +0100
@@ -2448,15 +2448,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
@@ -3447,15 +3438,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-30 17:24:30.000000000 +0100
+++ src/gdb/rs6000-nat.c	2009-05-30 17:24:45.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-30 17:24:30.000000000 +0100
+++ src/gdb/exec.h	2009-05-30 17:24:47.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,26 @@ 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);
 
+extern void remove_target_sections (bfd *abfd);
+
+/* Append the sections array defined by [SECTIONS..SECTIONS_END[ to
+   TABLE.  TABLE's memory is reallocated to fit in the new
+   sections.  */
+extern void add_target_sections (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-30 17:24:30.000000000 +0100
+++ src/gdb/gdbcore.h	2009-05-30 17:24:45.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) */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]