This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
ld fix for STB_GNU_UNIQUE PR10549
- From: Mark Wielaard <mjw at redhat dot com>
- To: binutils at sourceware dot org
- Cc: Nick Clifton <nickc at redhat dot com>, Ulrich Drepper <drepper at gmail dot com>
- Date: Thu, 07 Apr 2011 22:01:01 +0200
- Subject: ld fix for STB_GNU_UNIQUE PR10549
Hi [sorry for the repost, got the list-name wrong the first time]
This is the ld part of the fix for PR 10549. Nick Clifton already fixed
the assembler part. If STB_GNU_UNIQUE is used ELFOSABI_LINUX should be
set.
2011-04-07 Mark Wielaard <mjw@redhat.com>
PR 10549
* elf-bfd.h (has_ifunc_symbols): Renamed to has_gnu_symbols.
(has_gnu_symbols): Renamed from has_ifunc_symbols.
* bfd/elf.c (_bfd_elf_set_osabi): Use new has_gnu_symbols name.
* bfd/elf32-arm.c (elf32_arm_add_symbol_hook): Set has_gnu_symbols
also if STB_GNU_UNIQUE symbol binding was seen.
* bfd/elf32-i386.c (elf_i386_add_symbol_hook): Likewise.
* bfd/elf32-ppc.c (ppc_elf_add_symbol_hook): Likewise.
* bfd/elf32-sparc.c (elf32_sparc_add_symbol_hook): Likewise.
* bfd/elf64-ppc.c (ppc64_elf_add_symbol_hook): Likewise.
* bfd/elf64-sparc.c (elf64_sparc_add_symbol_hook): Likewise.
* bfd/elf64-x86-64.c (elf_x86_64_add_symbol_hook): Likewise.
Build and tested on x86_64 GNU/Linux with --enable-targets=all.
If this is good, could someone commit it for me?
Thanks,
Mark
diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
index 21ec38f..844610d 100644
--- a/bfd/elf-bfd.h
+++ b/bfd/elf-bfd.h
@@ -1634,9 +1634,9 @@ struct elf_obj_tdata
bfd_byte *build_id;
/* True if the bfd contains symbols that have the STT_GNU_IFUNC
- symbol type. Used to set the osabi field in the ELF header
- structure. */
- bfd_boolean has_ifunc_symbols;
+ symbol type or STB_GNU_UNIQUE binding. Used to set the osabi
+ field in the ELF header structure. */
+ bfd_boolean has_gnu_symbols;
/* An identifier used to distinguish different target
specific extensions to this structure. */
diff --git a/bfd/elf.c b/bfd/elf.c
index f69abf2..0bb0c5a 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -9506,9 +9506,9 @@ _bfd_elf_set_osabi (bfd * abfd,
/* To make things simpler for the loader on Linux systems we set the
osabi field to ELFOSABI_LINUX if the binary contains symbols of
- the STT_GNU_IFUNC type. */
+ the STT_GNU_IFUNC type or STB_GNU_UNIQUE binding. */
if (i_ehdrp->e_ident[EI_OSABI] == ELFOSABI_NONE
- && elf_tdata (abfd)->has_ifunc_symbols)
+ && elf_tdata (abfd)->has_gnu_symbols)
i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_LINUX;
}
diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c
index 6b69fd6..9fb3631 100644
--- a/bfd/elf32-arm.c
+++ b/bfd/elf32-arm.c
@@ -15229,9 +15229,10 @@ elf32_arm_add_symbol_hook (bfd *abfd, struct bfd_link_info *info,
Elf_Internal_Sym *sym, const char **namep,
flagword *flagsp, asection **secp, bfd_vma *valp)
{
- if ((abfd->flags & DYNAMIC) == 0
- && ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
- elf_tdata (info->output_bfd)->has_ifunc_symbols = TRUE;
+ if (((abfd->flags & DYNAMIC) == 0
+ && ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
+ || ELF_ST_BIND (sym->st_info) == STB_GNU_UNIQUE)
+ elf_tdata (info->output_bfd)->has_gnu_symbols = TRUE;
if (elf32_arm_hash_table (info)->vxworks_p
&& !elf_vxworks_add_symbol_hook (abfd, info, sym, namep,
diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
index 693c8e8..6e0733f 100644
--- a/bfd/elf32-i386.c
+++ b/bfd/elf32-i386.c
@@ -4698,9 +4698,10 @@ elf_i386_add_symbol_hook (bfd * abfd,
asection ** secp ATTRIBUTE_UNUSED,
bfd_vma * valp ATTRIBUTE_UNUSED)
{
- if ((abfd->flags & DYNAMIC) == 0
- && ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
- elf_tdata (info->output_bfd)->has_ifunc_symbols = TRUE;
+ if (((abfd->flags & DYNAMIC) == 0
+ && ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
+ || ELF_ST_BIND (sym->st_info) == STB_GNU_UNIQUE)
+ elf_tdata (info->output_bfd)->has_gnu_symbols = TRUE;
return TRUE;
}
diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c
index 9e097ad..1d2b2e7 100644
--- a/bfd/elf32-ppc.c
+++ b/bfd/elf32-ppc.c
@@ -3112,9 +3112,10 @@ ppc_elf_add_symbol_hook (bfd *abfd,
*valp = sym->st_size;
}
- if ((abfd->flags & DYNAMIC) == 0
- && ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
- elf_tdata (info->output_bfd)->has_ifunc_symbols = TRUE;
+ if (((abfd->flags & DYNAMIC) == 0
+ && ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
+ || ELF_ST_BIND (sym->st_info) == STB_GNU_UNIQUE)
+ elf_tdata (info->output_bfd)->has_gnu_symbols = TRUE;
return TRUE;
}
diff --git a/bfd/elf32-sparc.c b/bfd/elf32-sparc.c
index 187d466..5ec8c77 100644
--- a/bfd/elf32-sparc.c
+++ b/bfd/elf32-sparc.c
@@ -179,9 +179,10 @@ elf32_sparc_add_symbol_hook (bfd * abfd,
asection ** secp ATTRIBUTE_UNUSED,
bfd_vma * valp ATTRIBUTE_UNUSED)
{
- if ((abfd->flags & DYNAMIC) == 0
- && ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
- elf_tdata (info->output_bfd)->has_ifunc_symbols = TRUE;
+ if (((abfd->flags & DYNAMIC) == 0
+ && ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
+ || ELF_ST_BIND (sym->st_info) == STB_GNU_UNIQUE)
+ elf_tdata (info->output_bfd)->has_gnu_symbols = TRUE;
return TRUE;
}
diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
index 4cbd941..db53bba 100644
--- a/bfd/elf64-ppc.c
+++ b/bfd/elf64-ppc.c
@@ -4569,10 +4569,13 @@ ppc64_elf_add_symbol_hook (bfd *ibfd,
asection **sec,
bfd_vma *value ATTRIBUTE_UNUSED)
{
+ if (ELF_ST_BIND (isym->st_info) == STB_GNU_UNIQUE)
+ elf_tdata (info->output_bfd)->has_gnu_symbols = TRUE;
+
if (ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC)
{
if ((ibfd->flags & DYNAMIC) == 0)
- elf_tdata (info->output_bfd)->has_ifunc_symbols = TRUE;
+ elf_tdata (info->output_bfd)->has_gnu_symbols = TRUE;
}
else if (ELF_ST_TYPE (isym->st_info) == STT_FUNC)
;
diff --git a/bfd/elf64-sparc.c b/bfd/elf64-sparc.c
index 6bb2389..337b7da 100644
--- a/bfd/elf64-sparc.c
+++ b/bfd/elf64-sparc.c
@@ -425,9 +425,10 @@ elf64_sparc_add_symbol_hook (bfd *abfd, struct bfd_link_info *info,
{
static const char *const stt_types[] = { "NOTYPE", "OBJECT", "FUNCTION" };
- if ((abfd->flags & DYNAMIC) == 0
- && ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
- elf_tdata (info->output_bfd)->has_ifunc_symbols = TRUE;
+ if (((abfd->flags & DYNAMIC) == 0
+ && ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
+ || ELF_ST_BIND (sym->st_info) == STB_GNU_UNIQUE)
+ elf_tdata (info->output_bfd)->has_gnu_symbols = TRUE;
if (ELF_ST_TYPE (sym->st_info) == STT_REGISTER)
{
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
index 927b3ed..15d0baa 100644
--- a/bfd/elf64-x86-64.c
+++ b/bfd/elf64-x86-64.c
@@ -4450,9 +4450,10 @@ elf_x86_64_add_symbol_hook (bfd *abfd,
return TRUE;
}
- if ((abfd->flags & DYNAMIC) == 0
- && ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
- elf_tdata (info->output_bfd)->has_ifunc_symbols = TRUE;
+ if (((abfd->flags & DYNAMIC) == 0
+ && ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
+ || ELF_ST_BIND (sym->st_info) == STB_GNU_UNIQUE)
+ elf_tdata (info->output_bfd)->has_gnu_symbols = TRUE;
return TRUE;
}