[14/17] make minsyms progspace-independent

Tom Tromey tromey@redhat.com
Wed Dec 14 21:32:00 GMT 2011


This makes minimal symbols independent of the program space.

We change MSYMBOL_VALUE_ADDRESS to relocate on the fly.
This is not always what we want, though, so we also add
MSYMBOL_RAW_VALUE_ADDRESS to fetch the unrelocated value.
The latter is also cheaper to compute.

This has a hack in prim_record_minimal_symbol_full to subtract the
offset at minsym-creation time.  This let me avoid fixing all the symbol
readers; but eventually this has to be done.

There's still a FIXME where I neglected to update a big comment.

We have to bias the PC in lookup_minimal_symbol_by_pc_section_1 before
searching the minsym table, as the latter is now sorted by raw address,
not cooked address.

Tom

>From 5131df749c4a2bdaa42819ac48018c450a4dbffc Mon Sep 17 00:00:00 2001
From: Tom Tromey <tromey@redhat.com>
Date: Wed, 7 Dec 2011 14:12:10 -0700
Subject: [PATCH 14/18] make minsyms progspace-independent still has one FIXME
 - did not update the symbol readers yet

	* blockframe.c (find_pc_partial_function_gnu_ifunc): Use
	MSYMBOL_RAW_VALUE_ADDRESS.
	* minsyms.c (msymbol_objfile): Make argument const.
	(frob_address): New function.
	(lookup_minimal_symbol_by_pc_section_1): Use
	MSYMBOL_RAW_VALUE_ADDRESS and frob_address.
	(prim_record_minimal_symbol_full): Subtract offset from address.
	(compare_minimal_symbols): Use MSYMBOL_RAW_VALUE_ADDRESS.
	(compact_minimal_symbols): Likewise.
	(msymbols_sort): Remove.
	(msymbol_address): New function.
	* minsyms.h (msymbol_objfile): Update.
	(msymbols_sort): Remove.
	(msymbol_address): Declare.
	* objfiles.c (objfile_relocate1): Don't relocate minsyms.
	* sh64-tdep.c (sh64_elf_make_msymbol_special): Use
	MSYMBOL_RAW_VALUE_ADDRESS.
	* symtab.h (MSYMBOL_VALUE_ADDRESS): Redefine.
	(MSYMBOL_RAW_VALUE_ADDRESS): New macro.
---
 gdb/blockframe.c |    4 +-
 gdb/minsyms.c    |   95 +++++++++++++++++++++++++++++++++++++----------------
 gdb/minsyms.h    |   11 +++---
 gdb/objfiles.c   |   14 --------
 gdb/sh64-tdep.c  |    2 +-
 gdb/symtab.h     |    4 ++-
 6 files changed, 78 insertions(+), 52 deletions(-)

diff --git a/gdb/blockframe.c b/gdb/blockframe.c
index 704c871..9d9205b 100644
--- a/gdb/blockframe.c
+++ b/gdb/blockframe.c
@@ -292,8 +292,8 @@ find_pc_partial_function_gnu_ifunc (CORE_ADDR pc, char **name,
 
       for (i = 1; MSYMBOL_LINKAGE_NAME (msymbol + i) != NULL; i++)
 	{
-	  if (MSYMBOL_VALUE_ADDRESS (msymbol + i)
-	      != MSYMBOL_VALUE_ADDRESS (msymbol)
+	  if (MSYMBOL_RAW_VALUE_ADDRESS (msymbol + i)
+	      != MSYMBOL_RAW_VALUE_ADDRESS (msymbol)
 	      && MSYMBOL_SECTION_INDEX (msymbol + i)
 	      == MSYMBOL_SECTION_INDEX (msymbol))
 	    break;
diff --git a/gdb/minsyms.c b/gdb/minsyms.c
index ff5113a..4352cd2 100644
--- a/gdb/minsyms.c
+++ b/gdb/minsyms.c
@@ -144,7 +144,7 @@ add_minsym_to_demangled_hash_table (struct minimal_symbol *sym,
 
 /* Return OBJFILE where minimal symbol SYM is defined.  */
 struct objfile *
-msymbol_objfile (struct minimal_symbol *sym)
+msymbol_objfile (const struct minimal_symbol *sym)
 {
   struct objfile *objf;
   struct minimal_symbol *tsym;
@@ -511,6 +511,28 @@ lookup_minimal_symbol_solib_trampoline (const char *name,
   return NULL;
 }
 
+/* A helper function that makes *PC section-relative.  This searches
+   the sections of OBJFILE and if *PC is in a section, it subtracts
+   the section offset and returns true.  Otherwise it returns
+   false.  */
+
+static int
+frob_address (struct objfile *objfile, CORE_ADDR *pc)
+{
+  struct obj_section *iter;
+
+  ALL_OBJFILE_OSECTIONS (objfile, iter)
+    {
+      if (*pc >= obj_section_addr (iter) && *pc < obj_section_endaddr (iter))
+	{
+	  *pc -= obj_section_offset (iter);
+	  return 1;
+	}
+    }
+
+  return 0;
+}
+
 /* Search through the minimal symbol table for each objfile and find
    the symbol whose address is the largest address that is still less
    than or equal to PC, and matches SECTION (which is not NULL).
@@ -527,7 +549,7 @@ lookup_minimal_symbol_solib_trampoline (const char *name,
    Otherwise prefer mst_text symbols.  */
 
 static struct minimal_symbol *
-lookup_minimal_symbol_by_pc_section_1 (CORE_ADDR pc,
+lookup_minimal_symbol_by_pc_section_1 (CORE_ADDR pc_in,
 				       struct obj_section *section,
 				       int want_trampoline)
 {
@@ -557,6 +579,8 @@ lookup_minimal_symbol_by_pc_section_1 (CORE_ADDR pc,
        objfile != NULL;
        objfile = objfile_separate_debug_iterate (section->objfile, objfile))
     {
+      CORE_ADDR pc = pc_in;
+
       /* If this objfile has a minimal symbol table, go search it using
          a binary search.  Note that a minimal symbol table always consists
          of at least two symbols, a "real" symbol and the terminating
@@ -571,6 +595,10 @@ lookup_minimal_symbol_by_pc_section_1 (CORE_ADDR pc,
 	  lo = 0;
 	  hi = objfile->minimal_symbol_count - 1;
 
+	  /* FIXME
+	     fix up the comment here
+	  */
+
 	  /* This code assumes that the minimal symbols are sorted by
 	     ascending address values.  If the pc value is greater than or
 	     equal to the first symbol's address, then some symbol in this
@@ -589,15 +617,15 @@ lookup_minimal_symbol_by_pc_section_1 (CORE_ADDR pc,
 
 	     Warning: this code is trickier than it would appear at first.  */
 
-	  /* Should also require that pc is <= end of objfile.  FIXME!  */
-	  if (pc >= MSYMBOL_VALUE_ADDRESS (&msymbol[lo]))
+	  if (frob_address (objfile, &pc)
+	      && pc >= MSYMBOL_RAW_VALUE_ADDRESS (&msymbol[lo]))
 	    {
-	      while (MSYMBOL_VALUE_ADDRESS (&msymbol[hi]) > pc)
+	      while (MSYMBOL_RAW_VALUE_ADDRESS (&msymbol[hi]) > pc)
 		{
 		  /* pc is still strictly less than highest address.  */
 		  /* Note "new" will always be >= lo.  */
 		  new = (lo + hi) / 2;
-		  if ((MSYMBOL_VALUE_ADDRESS (&msymbol[new]) >= pc) ||
+		  if ((MSYMBOL_RAW_VALUE_ADDRESS (&msymbol[new]) >= pc) ||
 		      (lo == new))
 		    {
 		      hi = new;
@@ -612,8 +640,8 @@ lookup_minimal_symbol_by_pc_section_1 (CORE_ADDR pc,
 	         hi to point to the last one.  That way we can find the
 	         right symbol if it has an index greater than hi.  */
 	      while (hi < objfile->minimal_symbol_count - 1
-		     && (MSYMBOL_VALUE_ADDRESS (&msymbol[hi])
-			 == MSYMBOL_VALUE_ADDRESS (&msymbol[hi + 1])))
+		     && (MSYMBOL_RAW_VALUE_ADDRESS (&msymbol[hi])
+			 == MSYMBOL_RAW_VALUE_ADDRESS (&msymbol[hi + 1])))
 		hi++;
 
 	      /* Skip various undesirable symbols.  */
@@ -660,8 +688,8 @@ lookup_minimal_symbol_by_pc_section_1 (CORE_ADDR pc,
 		      && MSYMBOL_TYPE (&msymbol[hi - 1]) == want_type
 		      && (MSYMBOL_SIZE (&msymbol[hi])
 			  == MSYMBOL_SIZE (&msymbol[hi - 1]))
-		      && (MSYMBOL_VALUE_ADDRESS (&msymbol[hi])
-			  == MSYMBOL_VALUE_ADDRESS (&msymbol[hi - 1]))
+		      && (MSYMBOL_RAW_VALUE_ADDRESS (&msymbol[hi])
+			  == MSYMBOL_RAW_VALUE_ADDRESS (&msymbol[hi - 1]))
 		      && (MSYMBOL_SECTION_INDEX (&msymbol[hi])
 			  == MSYMBOL_SECTION_INDEX (&msymbol[hi - 1])))
 		    {
@@ -690,9 +718,9 @@ lookup_minimal_symbol_by_pc_section_1 (CORE_ADDR pc,
 		     the cancellable variants, but both have sizes.  */
 		  if (hi > 0
 		      && MSYMBOL_SIZE (&msymbol[hi]) != 0
-		      && pc >= (MSYMBOL_VALUE_ADDRESS (&msymbol[hi])
+		      && pc >= (MSYMBOL_RAW_VALUE_ADDRESS (&msymbol[hi])
 				+ MSYMBOL_SIZE (&msymbol[hi]))
-		      && pc < (MSYMBOL_VALUE_ADDRESS (&msymbol[hi - 1])
+		      && pc < (MSYMBOL_RAW_VALUE_ADDRESS (&msymbol[hi - 1])
 			       + MSYMBOL_SIZE (&msymbol[hi - 1])))
 		    {
 		      hi--;
@@ -722,7 +750,7 @@ lookup_minimal_symbol_by_pc_section_1 (CORE_ADDR pc,
 
 	      if (hi >= 0
 		  && MSYMBOL_SIZE (&msymbol[hi]) != 0
-		  && pc >= (MSYMBOL_VALUE_ADDRESS (&msymbol[hi])
+		  && pc >= (MSYMBOL_RAW_VALUE_ADDRESS (&msymbol[hi])
 			    + MSYMBOL_SIZE (&msymbol[hi])))
 		{
 		  if (best_zero_sized != -1)
@@ -738,8 +766,8 @@ lookup_minimal_symbol_by_pc_section_1 (CORE_ADDR pc,
 
 	      if (hi >= 0
 		  && ((best_symbol == NULL) ||
-		      (MSYMBOL_VALUE_ADDRESS (best_symbol) <
-		       MSYMBOL_VALUE_ADDRESS (&msymbol[hi]))))
+		      (MSYMBOL_RAW_VALUE_ADDRESS (best_symbol) <
+		       MSYMBOL_RAW_VALUE_ADDRESS (&msymbol[hi]))))
 		{
 		  best_symbol = &msymbol[hi];
 		}
@@ -986,6 +1014,11 @@ prim_record_minimal_symbol_full (const char *name, int name_len, int copy_name,
   MSYMBOL_SET_LANGUAGE (msymbol, language_auto);
   MSYMBOL_SET_NAMES (msymbol, name, name_len, copy_name, objfile);
 
+  /* FIXME: this is horrible.  The symbol readers should present
+     unrelocated symbols instead.  */
+  if (section >= 0)
+    address -= ANOFFSET (objfile->section_offsets, section);
+
   SET_MSYMBOL_VALUE_ADDRESS (msymbol, address);
   MSYMBOL_SECTION (msymbol) = section;
   MSYMBOL_SECTION_INDEX (msymbol) = 0;
@@ -1045,11 +1078,11 @@ compare_minimal_symbols (const void *fn1p, const void *fn2p)
   fn1 = (const struct minimal_symbol *) fn1p;
   fn2 = (const struct minimal_symbol *) fn2p;
 
-  if (MSYMBOL_VALUE_ADDRESS (fn1) < MSYMBOL_VALUE_ADDRESS (fn2))
+  if (MSYMBOL_RAW_VALUE_ADDRESS (fn1) < MSYMBOL_RAW_VALUE_ADDRESS (fn2))
     {
       return (-1);		/* addr 1 is less than addr 2.  */
     }
-  else if (MSYMBOL_VALUE_ADDRESS (fn1) > MSYMBOL_VALUE_ADDRESS (fn2))
+  else if (MSYMBOL_RAW_VALUE_ADDRESS (fn1) > MSYMBOL_RAW_VALUE_ADDRESS (fn2))
     {
       return (1);		/* addr 1 is greater than addr 2.  */
     }
@@ -1147,8 +1180,8 @@ compact_minimal_symbols (struct minimal_symbol *msymbol, int mcount,
       copyfrom = copyto = msymbol;
       while (copyfrom < msymbol + mcount - 1)
 	{
-	  if (MSYMBOL_VALUE_ADDRESS (copyfrom)
-	      == MSYMBOL_VALUE_ADDRESS ((copyfrom + 1))
+	  if (MSYMBOL_RAW_VALUE_ADDRESS (copyfrom)
+	      == MSYMBOL_RAW_VALUE_ADDRESS ((copyfrom + 1))
 	      && strcmp (MSYMBOL_LINKAGE_NAME (copyfrom),
 			 MSYMBOL_LINKAGE_NAME ((copyfrom + 1))) == 0)
 	    {
@@ -1351,16 +1384,6 @@ terminate_minimal_symbol_table (struct objfile *objfile)
   }
 }
 
-/* Sort all the minimal symbols in OBJFILE.  */
-
-void
-msymbols_sort (struct objfile *objfile)
-{
-  qsort (objfile->msymbols, objfile->minimal_symbol_count,
-	 sizeof (struct minimal_symbol), compare_minimal_symbols);
-  build_minimal_symbol_hash_tables (objfile);
-}
-
 /* Check if PC is in a shared library trampoline code stub.
    Return minimal symbol for the trampoline entry or NULL if PC is not
    in a trampoline code stub.  */
@@ -1427,3 +1450,17 @@ find_solib_trampoline_target (struct frame_info *frame, CORE_ADDR pc)
     }
   return 0;
 }
+
+/* See minsyms.h.  */
+
+CORE_ADDR
+msymbol_address (const struct minimal_symbol *msym)
+{
+  struct objfile *objf = msymbol_objfile (msym);
+  CORE_ADDR addr = MSYMBOL_RAW_VALUE_ADDRESS (msym);
+
+  if (MSYMBOL_SECTION (msym) >= 0)
+    addr += ANOFFSET (objf->section_offsets, MSYMBOL_SECTION (msym));
+
+  return addr;
+}
diff --git a/gdb/minsyms.h b/gdb/minsyms.h
index f66b1e0..0b58c53 100644
--- a/gdb/minsyms.h
+++ b/gdb/minsyms.h
@@ -54,7 +54,7 @@ unsigned int msymbol_hash (const char *);
 #define SYMBOL_HASH_NEXT(hash, c)			\
   ((hash) * 67 + tolower ((unsigned char) (c)) - 113)
 
-struct objfile *msymbol_objfile (struct minimal_symbol *sym);
+struct objfile *msymbol_objfile (const struct minimal_symbol *sym);
 
 void add_minsym_to_hash_table (struct minimal_symbol *sym,
 			       struct minimal_symbol **table);
@@ -98,10 +98,6 @@ struct cleanup *make_cleanup_discard_minimal_symbols (void);
 
 void install_minimal_symbols (struct objfile *);
 
-/* Sort all the minimal symbols in OBJFILE.  */
-
-void msymbols_sort (struct objfile *objfile);
-
 /* Create the terminating entry of OBJFILE's minimal symbol table.
    If OBJFILE->msymbols is zero, allocate a single entry from
    OBJFILE->objfile_obstack; otherwise, just initialize
@@ -115,4 +111,9 @@ void iterate_over_minimal_symbols (struct objfile *objf,
 						     void *),
 				   void *user_data);
 
+/* Return the "cooked" address of MSYM.  This is the raw address with
+   any needed section offset added in.  */
+
+CORE_ADDR msymbol_address (const struct minimal_symbol *msym);
+
 #endif /* MINSYMS_H */
diff --git a/gdb/objfiles.c b/gdb/objfiles.c
index 3d0d5ed..e879873 100644
--- a/gdb/objfiles.c
+++ b/gdb/objfiles.c
@@ -778,20 +778,6 @@ objfile_relocate1 (struct objfile *objfile,
   if (objfile->sf)
     objfile->sf->qf->relocate (objfile, new_offsets, delta);
 
-  {
-    struct minimal_symbol *msym;
-
-    ALL_OBJFILE_MSYMBOLS (objfile, msym)
-      if (MSYMBOL_SECTION (msym) >= 0)
-	SET_MSYMBOL_VALUE_ADDRESS (msym,
-				   MSYMBOL_VALUE_ADDRESS (msym)
-				   + ANOFFSET (delta,
-					       MSYMBOL_SECTION (msym)));
-  }
-  /* Relocating different sections by different amounts may cause the symbols
-     to be out of order.  */
-  msymbols_sort (objfile);
-
   if (objfile->ei.entry_point_p)
     {
       /* Relocate ei.entry_point with its section offset, use SECT_OFF_TEXT
diff --git a/gdb/sh64-tdep.c b/gdb/sh64-tdep.c
index 28d0a78..3ee940a 100644
--- a/gdb/sh64-tdep.c
+++ b/gdb/sh64-tdep.c
@@ -225,7 +225,7 @@ sh64_elf_make_msymbol_special (asymbol *sym, struct minimal_symbol *msym)
   if (((elf_symbol_type *)(sym))->internal_elf_sym.st_other == STO_SH5_ISA32)
     {
       MSYMBOL_TARGET_FLAG_1 (msym) = 1;
-      SET_MSYMBOL_VALUE_ADDRESS (msym, 1 | MSYMBOL_VALUE_ADDRESS (msym));
+      SET_MSYMBOL_VALUE_ADDRESS (msym, 1 | MSYMBOL_RAW_VALUE_ADDRESS (msym));
     }
 }
 
diff --git a/gdb/symtab.h b/gdb/symtab.h
index c5d9917..75a926c 100644
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -381,7 +381,9 @@ struct minimal_symbol
 #define MSYMBOL_TYPE(msymbol)		(msymbol)->type
 
 #define MSYMBOL_VALUE(symbol)		(symbol)->mginfo.value.ivalue
-#define MSYMBOL_VALUE_ADDRESS(symbol)	((symbol)->mginfo.value.address + 0)
+#define MSYMBOL_VALUE_ADDRESS(symbol)	msymbol_address (symbol)
+#define MSYMBOL_RAW_VALUE_ADDRESS(symbol) \
+  ((symbol)->mginfo.value.address + 0)
 #define SET_MSYMBOL_VALUE_ADDRESS(symbol, addr)	\
   ((symbol)->mginfo.value.address) = (addr)
 
-- 
1.7.6.4



More information about the Gdb-patches mailing list