[binutils-gdb] Stop the BFD library from treating annobin symbols as potential function symbols.

Nick Clifton nickc@sourceware.org
Wed Apr 28 10:49:57 GMT 2021


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=24aebc79b16a82faef4736f4abdc7e4d95d4cc67

commit 24aebc79b16a82faef4736f4abdc7e4d95d4cc67
Author: Nick Clifton <nickc@redhat.com>
Date:   Wed Apr 28 11:49:09 2021 +0100

    Stop the BFD library from treating annobin symbols as potential function symbols.
    
    bfd     * elf.c (_bfd_elf_maybe_function_sym): Do not accept annobin
            symbols as potential function symbols.
            * elfnn-aarch64.c (elfNN_aarch64_maybe_function_sym): Likewise.
            * elf64-ppc.c (ppc64_elf_maybe_function_sym): Likewise.
            * elf32-arm.c (elf32_arm_maybe_function_sym): Likewise.
    
    ld      * testsuite/ld-elf/anno-sym.s: New test source file.
            * testsuite/ld-elf/anno-sym.d: New test driver.
            * testsuite/ld-elf/anno-sym.l: New test error output.

Diff:
---
 bfd/ChangeLog                  |  8 ++++++++
 bfd/elf.c                      | 23 +++++++++++++++++------
 bfd/elf32-arm.c                | 27 ++++++++++++++++++---------
 bfd/elf64-ppc.c                | 23 +++++++++++++++++------
 bfd/elfnn-aarch64.c            | 26 +++++++++++++++++---------
 ld/ChangeLog                   |  6 ++++++
 ld/testsuite/ld-elf/anno-sym.d |  5 +++++
 ld/testsuite/ld-elf/anno-sym.l |  4 ++++
 ld/testsuite/ld-elf/anno-sym.s | 13 +++++++++++++
 9 files changed, 105 insertions(+), 30 deletions(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 721fddc935d..47b9c913581 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,11 @@
+2021-04-28  Nick Clifton  <nickc@redhat.com>
+
+	* elf.c (_bfd_elf_maybe_function_sym): Do not accept annobin
+	symbols as potential function symbols.
+	* elfnn-aarch64.c (elfNN_aarch64_maybe_function_sym): Likewise.
+	* elf64-ppc.c (ppc64_elf_maybe_function_sym): Likewise.
+	* elf32-arm.c (elf32_arm_maybe_function_sym): Likewise.
+
 2021-04-26  Mike Frysinger  <vapier@gentoo.org>
 
 	* elf-bfd.h: Include stdlib.h.
diff --git a/bfd/elf.c b/bfd/elf.c
index 4846b7bd47f..851440b7652 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -12618,19 +12618,30 @@ _bfd_elf_maybe_function_sym (const asymbol *sym, asection *sec,
 			     bfd_vma *code_off)
 {
   bfd_size_type size;
+  elf_symbol_type * elf_sym = (elf_symbol_type *) sym;
 
   if ((sym->flags & (BSF_SECTION_SYM | BSF_FILE | BSF_OBJECT
 		     | BSF_THREAD_LOCAL | BSF_RELC | BSF_SRELC)) != 0
       || sym->section != sec)
     return 0;
 
+  size = (sym->flags & BSF_SYNTHETIC) ? 0 : elf_sym->internal_elf_sym.st_size;
+  
+  /* In theory we should check that the symbol's type satisfies
+     _bfd_elf_is_function_type(), but there are some function-like
+     symbols which would fail this test.  (eg _start).  Instead
+     we check for hidden, local, notype symbols with zero size.
+     This type of symbol is generated by the annobin plugin for gcc
+     and clang, and should not be considered to be a function symbol.  */
+  if (size == 0
+      && ((sym->flags & (BSF_SYNTHETIC | BSF_LOCAL)) == BSF_LOCAL)
+      && ELF_ST_TYPE (elf_sym->internal_elf_sym.st_info) == STT_NOTYPE
+      && ELF_ST_VISIBILITY (elf_sym->internal_elf_sym.st_other) == STV_HIDDEN)
+    return 0;
+  
   *code_off = sym->value;
-  size = 0;
-  if (!(sym->flags & BSF_SYNTHETIC))
-    size = ((elf_symbol_type *) sym)->internal_elf_sym.st_size;
-  if (size == 0)
-    size = 1;
-  return size;
+  /* Do not return 0 for the function's size.  */
+  return size ? size : 1;
 }
 
 /* Set to non-zero to enable some debug messages.  */
diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c
index 81667ea090d..79b94e836fc 100644
--- a/bfd/elf32-arm.c
+++ b/bfd/elf32-arm.c
@@ -15898,35 +15898,44 @@ elf32_arm_maybe_function_sym (const asymbol *sym, asection *sec,
 			      bfd_vma *code_off)
 {
   bfd_size_type size;
+  elf_symbol_type * elf_sym = (elf_symbol_type *) sym;
 
   if ((sym->flags & (BSF_SECTION_SYM | BSF_FILE | BSF_OBJECT
 		     | BSF_THREAD_LOCAL | BSF_RELC | BSF_SRELC)) != 0
       || sym->section != sec)
     return 0;
 
+  size = (sym->flags & BSF_SYNTHETIC) ? 0 : elf_sym->internal_elf_sym.st_size;
+
   if (!(sym->flags & BSF_SYNTHETIC))
-    switch (ELF_ST_TYPE (((elf_symbol_type *) sym)->internal_elf_sym.st_info))
+    switch (ELF_ST_TYPE (elf_sym->internal_elf_sym.st_info))
       {
+	case STT_NOTYPE:
+	  /* Ignore symbols created by the annobin plugin for gcc and clang.
+	     These symbols are hidden, local, notype and have a size of 0.  */
+	  if (size == 0
+	      && sym->flags & BSF_LOCAL
+	      && ELF_ST_VISIBILITY (elf_sym->internal_elf_sym.st_other) == STV_HIDDEN)
+	    return 0;
+	  /* Fall through.  */
 	case STT_FUNC:
 	case STT_ARM_TFUNC:
-	case STT_NOTYPE:
+	  /* FIXME: Allow STT_GNU_IFUNC as well ?  */
 	  break;
 	default:
 	  return 0;
       }
-
+											     
   if ((sym->flags & BSF_LOCAL)
       && bfd_is_arm_special_symbol_name (sym->name,
 					 BFD_ARM_SPECIAL_SYM_TYPE_ANY))
     return 0;
 
   *code_off = sym->value;
-  size = 0;
-  if (!(sym->flags & BSF_SYNTHETIC))
-    size = ((elf_symbol_type *) sym)->internal_elf_sym.st_size;
-  if (size == 0)
-    size = 1;
-  return size;
+
+  /* Do not return 0 for the function's size.  */
+  return size ? size : 1;
+
 }
 
 static bool
diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
index 08227f0e43a..ed72de27507 100644
--- a/bfd/elf64-ppc.c
+++ b/bfd/elf64-ppc.c
@@ -5534,14 +5534,25 @@ ppc64_elf_maybe_function_sym (const asymbol *sym, asection *sec,
 			      bfd_vma *code_off)
 {
   bfd_size_type size;
+  elf_symbol_type * elf_sym = (elf_symbol_type *) sym;
 
   if ((sym->flags & (BSF_SECTION_SYM | BSF_FILE | BSF_OBJECT
 		     | BSF_THREAD_LOCAL | BSF_RELC | BSF_SRELC)) != 0)
     return 0;
 
-  size = 0;
-  if (!(sym->flags & BSF_SYNTHETIC))
-    size = ((elf_symbol_type *) sym)->internal_elf_sym.st_size;
+  size = (sym->flags & BSF_SYNTHETIC) ? 0 : elf_sym->internal_elf_sym.st_size;
+
+  /* In theory we should check that the symbol's type satisfies
+     _bfd_elf_is_function_type(), but there are some function-like
+     symbols which would fail this test.  (eg _start).  Instead
+     we check for hidden, local, notype symbols with zero size.
+     This type of symbol is generated by the annobin plugin for gcc
+     and clang, and should not be considered to be a function symbol.  */
+  if (size == 0
+      && ((sym->flags & (BSF_SYNTHETIC | BSF_LOCAL)) == BSF_LOCAL)
+      && ELF_ST_TYPE (elf_sym->internal_elf_sym.st_info) == STT_NOTYPE
+      && ELF_ST_VISIBILITY (elf_sym->internal_elf_sym.st_other) == STV_HIDDEN)
+    return 0;
 
   if (strcmp (sym->section->name, ".opd") == 0)
     {
@@ -5585,9 +5596,9 @@ ppc64_elf_maybe_function_sym (const asymbol *sym, asection *sec,
 	return 0;
       *code_off = sym->value;
     }
-  if (size == 0)
-    size = 1;
-  return size;
+
+  /* Do not return 0 for the function's size.  */
+  return size ? size : 1;
 }
 
 /* Return true if symbol is a strong function defined in an ELFv2
diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c
index 0a1d7a617c8..b6f083e430b 100644
--- a/bfd/elfnn-aarch64.c
+++ b/bfd/elfnn-aarch64.c
@@ -8012,34 +8012,42 @@ elfNN_aarch64_maybe_function_sym (const asymbol *sym, asection *sec,
 				  bfd_vma *code_off)
 {
   bfd_size_type size;
+  elf_symbol_type * elf_sym = (elf_symbol_type *) sym;
 
   if ((sym->flags & (BSF_SECTION_SYM | BSF_FILE | BSF_OBJECT
 		     | BSF_THREAD_LOCAL | BSF_RELC | BSF_SRELC)) != 0
       || sym->section != sec)
     return 0;
 
+  size = (sym->flags & BSF_SYNTHETIC) ? 0 : elf_sym->internal_elf_sym.st_size;
+  
   if (!(sym->flags & BSF_SYNTHETIC))
-    switch (ELF_ST_TYPE (((elf_symbol_type *) sym)->internal_elf_sym.st_info))
+    switch (ELF_ST_TYPE (elf_sym->internal_elf_sym.st_info))
       {
-	case STT_FUNC:
 	case STT_NOTYPE:
+	  /* Ignore symbols created by the annobin plugin for gcc and clang.
+	     These symbols are hidden, local, notype and have a size of 0.  */
+	  if (size == 0
+	      && sym->flags & BSF_LOCAL
+	      && ELF_ST_VISIBILITY (elf_sym->internal_elf_sym.st_other) == STV_HIDDEN)
+	    return 0;
+	  /* Fall through.  */
+	case STT_FUNC:
+	  /* FIXME: Allow STT_GNU_IFUNC as well ?  */
 	  break;
 	default:
 	  return 0;
       }
-
+  
   if ((sym->flags & BSF_LOCAL)
       && bfd_is_aarch64_special_symbol_name (sym->name,
 					     BFD_AARCH64_SPECIAL_SYM_TYPE_ANY))
     return 0;
 
   *code_off = sym->value;
-  size = 0;
-  if (!(sym->flags & BSF_SYNTHETIC))
-    size = ((elf_symbol_type *) sym)->internal_elf_sym.st_size;
-  if (size == 0)
-    size = 1;
-  return size;
+
+  /* Do not return 0 for the function's size.  */
+  return size ? size : 1;
 }
 
 static bool
diff --git a/ld/ChangeLog b/ld/ChangeLog
index 9bb178e4248..3c4bec58949 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,3 +1,9 @@
+2021-04-28  Nick Clifton  <nickc@redhat.com>
+
+	* testsuite/ld-elf/anno-sym.s: New test source file.
+	* testsuite/ld-elf/anno-sym.d: New test driver.
+	* testsuite/ld-elf/anno-sym.l: New test error output.
+
 2021-04-26  Jan Beulich  <jbeulich@suse.com>
 
 	* testsuite/ld-i386/pcrel16-2.s, testsuite/ld-i386/pcrel16-2.d,
diff --git a/ld/testsuite/ld-elf/anno-sym.d b/ld/testsuite/ld-elf/anno-sym.d
new file mode 100644
index 00000000000..9e53c4a9c16
--- /dev/null
+++ b/ld/testsuite/ld-elf/anno-sym.d
@@ -0,0 +1,5 @@
+# Check that linking anno-sym.o produces an undefined reference message referring to '_start' and not 'annobin_hello.c'
+#ld:  -e _start
+#error_output: anno-sym.l
+# The mips-irix6 target fails this test because it does not find any function symbols.  Not sure why.
+#skip: *-*-irix*
diff --git a/ld/testsuite/ld-elf/anno-sym.l b/ld/testsuite/ld-elf/anno-sym.l
new file mode 100644
index 00000000000..ee9611aef4e
--- /dev/null
+++ b/ld/testsuite/ld-elf/anno-sym.l
@@ -0,0 +1,4 @@
+#...
+.*: in function `(|_)start':
+.*: undefined reference to `foo'
+#pass
diff --git a/ld/testsuite/ld-elf/anno-sym.s b/ld/testsuite/ld-elf/anno-sym.s
new file mode 100644
index 00000000000..0e4b5aa79c3
--- /dev/null
+++ b/ld/testsuite/ld-elf/anno-sym.s
@@ -0,0 +1,13 @@
+	.text
+
+	.hidden .annobin_hello.c
+	.type .annobin_hello.c, STT_NOTYPE
+	.equiv .annobin_hello.c, .
+	.size .annobin_hello.c, 0
+	
+	.global _start
+_start:
+	.nop
+	.align 4
+	.dc.a foo
+


More information about the Binutils-cvs mailing list