bfd_find_nearest_line on powerpc64

Alan Modra amodra@gmail.com
Tue Feb 7 07:05:00 GMT 2012


On Mon, Jan 23, 2012 at 04:24:19PM +1030, Alan Modra wrote:
> This fixes a problem we see on powerpc64 with bfd_find_nearest_line,
> used by tools like addr2line and in linker error messages.

So that didn't quite do the trick for oprofile (opreport really),
where synthetic symbols are included in the set of syms passed to
bfd_find_nearest_line.  The trouble is that a synthetic symbol is just
an asymbol;  They don't have the internal_elf_sym part of
elf_symbol_type.  Fortunately there wasn't any real need for
elf_find_function to look at that part of elf_symbol_type.

	* elf.c (elf_find_function): Don't use internal_elf_sym.
	(_bfd_elf_maybe_function_sym): Likewise.  Replace elf_symbol_type
	parameter with asymbol.
	* elf64-ppc.c (ppc64_elf_maybe_function_sym): Likewise.
	* elf-bfd.h (_bfd_elf_maybe_function_sym): Update prototype.
	(struct elf_backend_data <maybe_function_sym>): Likewise.

Index: bfd/elf-bfd.h
===================================================================
RCS file: /cvs/src/src/bfd/elf-bfd.h,v
retrieving revision 1.332
diff -u -p -r1.332 elf-bfd.h
--- bfd/elf-bfd.h	23 Jan 2012 06:16:37 -0000	1.332
+++ bfd/elf-bfd.h	7 Feb 2012 01:38:18 -0000
@@ -1223,7 +1223,7 @@ struct elf_backend_data
 
   /* Return TRUE if symbol may be a function.  Set *CODE_SEC and *CODE_VAL
      to the function's entry point.  */
-  bfd_boolean (*maybe_function_sym) (const elf_symbol_type *sym,
+  bfd_boolean (*maybe_function_sym) (const asymbol *sym,
 				     asection **code_sec, bfd_vma *code_off);
 
   /* Used to handle bad SHF_LINK_ORDER input.  */
@@ -2202,7 +2202,7 @@ extern bfd_boolean _bfd_elf_map_sections
 
 extern bfd_boolean _bfd_elf_is_function_type (unsigned int);
 
-extern bfd_boolean _bfd_elf_maybe_function_sym (const elf_symbol_type *,
+extern bfd_boolean _bfd_elf_maybe_function_sym (const asymbol *,
 						asection **, bfd_vma *);
 
 extern int bfd_elf_get_default_section_type (flagword);
Index: bfd/elf.c
===================================================================
RCS file: /cvs/src/src/bfd/elf.c,v
retrieving revision 1.548
diff -u -p -r1.548 elf.c
--- bfd/elf.c	23 Jan 2012 06:16:37 -0000	1.548
+++ bfd/elf.c	7 Feb 2012 01:38:22 -0000
@@ -7404,36 +7404,30 @@ elf_find_function (bfd *abfd,
 
   for (p = symbols; *p != NULL; p++)
     {
-      elf_symbol_type *q;
-      unsigned int type;
+      asymbol *sym = *p;
       asection *code_sec;
       bfd_vma code_off;
 
-      q = (elf_symbol_type *) *p;
-
-      type = ELF_ST_TYPE (q->internal_elf_sym.st_info);
-      switch (type)
+      if ((sym->flags & BSF_FILE) != 0)
 	{
-	case STT_FILE:
-	  file = &q->symbol;
+	  file = sym;
 	  if (state == symbol_seen)
 	    state = file_after_symbol_seen;
 	  continue;
-	default:
-	  if (bed->maybe_function_sym (q, &code_sec, &code_off)
-	      && code_sec == section
-	      && code_off >= low_func
-	      && code_off <= offset)
-	    {
-	      func = (asymbol *) q;
-	      low_func = code_off;
-	      filename = NULL;
-	      if (file != NULL
-		  && (ELF_ST_BIND (q->internal_elf_sym.st_info) == STB_LOCAL
-		      || state != file_after_symbol_seen))
-		filename = bfd_asymbol_name (file);
-	    }
-	  break;
+	}
+
+      if (bed->maybe_function_sym (sym, &code_sec, &code_off)
+	  && code_sec == section
+	  && code_off >= low_func
+	  && code_off <= offset)
+	{
+	  func = sym;
+	  low_func = code_off;
+	  filename = NULL;
+	  if (file != NULL
+	      && ((sym->flags & BSF_LOCAL) != 0
+		  || state != file_after_symbol_seen))
+	    filename = bfd_asymbol_name (file);
 	}
       if (state == nothing_seen)
 	state = symbol_seen;
@@ -9695,17 +9689,14 @@ _bfd_elf_is_function_type (unsigned int 
    and *CODE_OFF to the function's entry point.  */
 
 bfd_boolean
-_bfd_elf_maybe_function_sym (const elf_symbol_type *sym,
+_bfd_elf_maybe_function_sym (const asymbol *sym,
 			     asection **code_sec, bfd_vma *code_off)
 {
-  unsigned int type = ELF_ST_TYPE (sym->internal_elf_sym.st_info);
-  if (type == STT_NOTYPE
-      || type == STT_FUNC
-      || type == STT_GNU_IFUNC)
-    {
-      *code_sec = sym->symbol.section;
-      *code_off = sym->symbol.value;
-      return TRUE;
-    }
-  return FALSE;
+  if ((sym->flags & (BSF_SECTION_SYM | BSF_FILE | BSF_OBJECT
+		     | BSF_THREAD_LOCAL | BSF_RELC | BSF_SRELC)) != 0)
+    return FALSE;
+
+  *code_sec = sym->section;
+  *code_off = sym->value;
+  return TRUE;
 }
Index: bfd/elf64-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-ppc.c,v
retrieving revision 1.375
diff -u -p -r1.375 elf64-ppc.c
--- bfd/elf64-ppc.c	23 Jan 2012 06:16:38 -0000	1.375
+++ bfd/elf64-ppc.c	7 Feb 2012 01:38:34 -0000
@@ -5637,14 +5637,13 @@ opd_entry_value (asection *opd_sec,
    and *CODE_OFF to the function's entry point.  */
 
 static bfd_boolean
-ppc64_elf_maybe_function_sym (const elf_symbol_type *sym,
+ppc64_elf_maybe_function_sym (const asymbol *sym,
 			      asection **code_sec, bfd_vma *code_off)
 {
   if (_bfd_elf_maybe_function_sym (sym, code_sec, code_off))
     {
-      if (strcmp (sym->symbol.section->name, ".opd") == 0)
-	opd_entry_value (sym->symbol.section, sym->symbol.value,
-			 code_sec, code_off);
+      if (strcmp (sym->section->name, ".opd") == 0)
+	opd_entry_value (sym->section, sym->value, code_sec, code_off);
       return TRUE;
     }
   return FALSE;

-- 
Alan Modra
Australia Development Lab, IBM



More information about the Binutils mailing list