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]

Re: [RFC,v3] Yank out target_ops->to_sections


On Tuesday 02 June 2009 12:10:24, Ulrich Weigand wrote:

> I think this makes sense.  Your new combined patch looks good to me.

Thank you very much for the review.  Deeply appreciated.

> > 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;
> 
> This can be "static" now, right?

Indeed.  I had a couple of other cases that could be made static.  Fixed now,
and checked in, as below.

Thanks again!

-- 
Pedro Alves
2009-06-03  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.

---
 gdb/bfd-target.c |   37 +++++--
 gdb/corelow.c    |   56 +++++++---
 gdb/exec.c       |  286 ++++++++++++++++++++++++++++++++++---------------------
 gdb/exec.h       |   26 ++++-
 gdb/gdbcore.h    |    2 
 gdb/infrun.c     |   18 ---
 gdb/rs6000-nat.c |    3 
 gdb/solib.c      |   20 ---
 gdb/target.c     |  163 ++++++++++---------------------
 gdb/target.h     |   32 +++---
 10 files changed, 353 insertions(+), 290 deletions(-)

Index: src/gdb/target.c
===================================================================
--- src.orig/gdb/target.c	2009-06-03 19:34:02.000000000 +0100
+++ src/gdb/target.c	2009-06-03 19:42:33.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)
 {
+  struct target_section_table *table = target_get_section_table (target);
   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,43 @@ 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;
 
       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);
+	{
+	  table = target_get_section_table (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 +1725,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 +2379,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-06-03 19:34:03.000000000 +0100
+++ src/gdb/target.h	2009-06-03 19:42:33.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
@@ -412,6 +413,7 @@ struct target_ops
     void (*to_rcmd) (char *command, struct ui_file *output);
     char *(*to_pid_to_exec_file) (int pid);
     void (*to_log_command) (const char *);
+    struct target_section_table *(*to_get_section_table) (struct target_ops *);
     enum strata to_stratum;
     int to_has_all_memory;
     int to_has_memory;
@@ -420,10 +422,6 @@ 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;
     /* ASYNC target controls */
     int (*to_can_async_p) (void);
     int (*to_is_async_p) (void);
@@ -668,9 +666,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 +728,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 +1199,24 @@ struct target_section
     bfd *bfd;			/* BFD file pointer */
   };
 
+/* Holds an array of target sections.  Defined by [SECTIONS..SECTIONS_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 +1247,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-06-03 19:34:02.000000000 +0100
+++ src/gdb/bfd-target.c	2009-06-03 19:42:33.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;
     }
 }
 
+static 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-06-03 19:34:03.000000000 +0100
+++ src/gdb/corelow.c	2009-06-03 19:42:33.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.  */
+static 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-06-03 19:34:03.000000000 +0100
+++ src/gdb/solib.c	2009-06-03 19:42:33.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-06-03 19:34:02.000000000 +0100
+++ src/gdb/exec.c	2009-06-03 19:42:33.000000000 +0100
@@ -71,6 +71,16 @@ 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.  */
+static 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;
@@ -92,6 +102,31 @@ exec_open (char *args, int from_tty)
   exec_file_attach (args, from_tty);
 }
 
+/* Close and clear exec_bfd.  If we end up with no target sections to
+   read memory from, this unpushes the exec_ops target.  */
+
+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)
 {
@@ -128,31 +163,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 +203,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 +219,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 +258,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 +273,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 +294,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 +397,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 +444,65 @@ build_section_table (struct bfd *some_bf
   /* We could realloc the table, but it probably loses for most files.  */
   return 0;
 }
+
+/* Add the sections array defined by [SECTIONS..SECTIONS_END[ to the
+   current set of target sections.  */
+
+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 +580,21 @@ 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 = memaddr + len;
 
   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 +605,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 +624,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 +678,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 +702,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 +738,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 +750,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 +778,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 +829,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-06-03 19:34:47.000000000 +0100
+++ src/gdb/infrun.c	2009-06-03 19:42:33.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
@@ -3446,15 +3437,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-06-03 19:34:03.000000000 +0100
+++ src/gdb/rs6000-nat.c	2009-06-03 19:42:33.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-06-03 19:34:03.000000000 +0100
+++ src/gdb/exec.h	2009-06-03 19:42:33.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,28 @@ 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);
 
+/* Remove all target sections taken from ABFD.  */
+
+extern void remove_target_sections (bfd *abfd);
+
+/* Add the sections array defined by [SECTIONS..SECTIONS_END[ to the
+   current set of target 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-06-03 19:34:03.000000000 +0100
+++ src/gdb/gdbcore.h	2009-06-03 19:42:33.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]