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.
This commit is contained in:
Nick Clifton
2021-04-28 11:49:09 +01:00
parent edeaceda7b
commit 24aebc79b1
9 changed files with 105 additions and 30 deletions
+8
View File
@@ -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.
+17 -6
View File
@@ -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. */
+18 -9
View File
@@ -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
+17 -6
View File
@@ -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
+17 -9
View File
@@ -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
+6
View File
@@ -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,
+5
View File
@@ -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*
+4
View File
@@ -0,0 +1,4 @@
#...
.*: in function `(|_)start':
.*: undefined reference to `foo'
#pass
+13
View File
@@ -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