Tweak powerpc64 support for old (dot-sym) object vs. as-needed libs
Alan Modra
amodra@bigpond.net.au
Tue Feb 1 03:40:00 GMT 2005
Found when running glibc testsuite with latest binutils. glibc
references .__tls_get_addr, which didn't trigger DT_NEEDED for ld64.so.1.
bfd/
* elf64-ppc.c (func_desc_adjust): Move code creating func desc sym to..
(make_fdh): ..here. New function. Don't set BSF_OBJECT for
undefined syms.
(struct add_symbol_adjust_data): New.
(add_symbol_adjust): Make an undefweak func desc for old ABI
objects to link with --as-needed shared libs. Return fail status.
Don't adjust old ABI func entry sym to weak if func desc syms
isn't defined.
(ppc64_elf_check_directives): Adjust call to add_symbol_adjust,
and return status.
ld/testsuite/
* ld-powerpc/tlsso.r: Update.
* ld-powerpc/tlstocso.r: Update.
Index: bfd/elf64-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-ppc.c,v
retrieving revision 1.186
diff -u -p -r1.186 elf64-ppc.c
--- bfd/elf64-ppc.c 1 Feb 2005 01:11:13 -0000 1.186
+++ bfd/elf64-ppc.c 1 Feb 2005 02:19:50 -0000
@@ -3937,6 +3937,37 @@ get_fdh (struct ppc_link_hash_entry *fh,
return fdh;
}
+/* Make a fake function descriptor sym for the code sym FH. */
+
+static struct ppc_link_hash_entry *
+make_fdh (struct bfd_link_info *info,
+ struct ppc_link_hash_entry *fh,
+ flagword flags)
+{
+ bfd *abfd;
+ asymbol *newsym;
+ struct bfd_link_hash_entry *bh;
+ struct ppc_link_hash_entry *fdh;
+
+ abfd = fh->elf.root.u.undef.abfd;
+ newsym = bfd_make_empty_symbol (abfd);
+ newsym->name = fh->elf.root.root.string + 1;
+ newsym->section = bfd_und_section_ptr;
+ newsym->value = 0;
+ newsym->flags = flags;
+
+ bh = NULL;
+ if (!_bfd_generic_link_add_one_symbol (info, abfd, newsym->name,
+ newsym->flags, newsym->section,
+ newsym->value, NULL, FALSE, FALSE,
+ &bh))
+ return NULL;
+
+ fdh = (struct ppc_link_hash_entry *) bh;
+ fdh->elf.non_elf = 0;
+ return fdh;
+}
+
/* Hacks to support old ABI code.
When making function calls, old ABI code references function entry
points (dot symbols), while new ABI code references the function
@@ -4009,10 +4040,16 @@ ppc64_elf_archive_symbol_lookup (bfd *ab
most restrictive visibility of the function descriptor and the
function entry symbol is used. */
+struct add_symbol_adjust_data
+{
+ struct bfd_link_info *info;
+ bfd_boolean ok;
+};
+
static bfd_boolean
add_symbol_adjust (struct elf_link_hash_entry *h, void *inf)
{
- struct bfd_link_info *info;
+ struct add_symbol_adjust_data *data;
struct ppc_link_hash_table *htab;
struct ppc_link_hash_entry *eh;
struct ppc_link_hash_entry *fdh;
@@ -4026,11 +4063,25 @@ add_symbol_adjust (struct elf_link_hash_
if (h->root.root.string[0] != '.')
return TRUE;
- info = inf;
- htab = ppc_hash_table (info);
+ data = inf;
+ htab = ppc_hash_table (data->info);
eh = (struct ppc_link_hash_entry *) h;
fdh = get_fdh (eh, htab);
- if (fdh != NULL)
+ if (fdh == NULL
+ && (eh->elf.root.type == bfd_link_hash_undefined
+ || eh->elf.root.type == bfd_link_hash_undefweak)
+ && eh->elf.ref_regular)
+ {
+ /* Make an undefweak function descriptor sym, which is enough to
+ pull in an --as-needed shared lib, but won't cause link
+ errors. Archives are handled elsewhere. */
+ fdh = make_fdh (data->info, eh, BSF_WEAK);
+ if (fdh == NULL)
+ data->ok = FALSE;
+ else
+ fdh->elf.ref_regular = 1;
+ }
+ else if (fdh != NULL)
{
unsigned entry_vis = ELF_ST_VISIBILITY (eh->elf.other) - 1;
unsigned descr_vis = ELF_ST_VISIBILITY (fdh->elf.other) - 1;
@@ -4039,7 +4090,9 @@ add_symbol_adjust (struct elf_link_hash_
else if (entry_vis > descr_vis)
eh->elf.other += descr_vis - entry_vis;
- if (eh->elf.root.type == bfd_link_hash_undefined)
+ if (eh->elf.root.type == bfd_link_hash_undefined
+ && (fdh->elf.root.type == bfd_link_hash_defined
+ || fdh->elf.root.type == bfd_link_hash_defweak))
{
eh->elf.root.type = bfd_link_hash_undefweak;
eh->was_undefined = 1;
@@ -4055,12 +4108,15 @@ ppc64_elf_check_directives (bfd *abfd AT
struct bfd_link_info *info)
{
struct ppc_link_hash_table *htab;
+ struct add_symbol_adjust_data data;
htab = ppc_hash_table (info);
if (!is_ppc64_elf_target (htab->elf.root.creator))
return TRUE;
- elf_link_hash_traverse (&htab->elf, add_symbol_adjust, info);
+ data.info = info;
+ data.ok = TRUE;
+ elf_link_hash_traverse (&htab->elf, add_symbol_adjust, &data);
/* We need to fix the undefs list for any syms we have twiddled to
undef_weak. */
@@ -4069,7 +4125,7 @@ ppc64_elf_check_directives (bfd *abfd AT
bfd_link_repair_undef_list (&htab->elf.root);
htab->twiddled_syms = 0;
}
- return TRUE;
+ return data.ok;
}
static bfd_boolean
@@ -5358,30 +5414,12 @@ func_desc_adjust (struct elf_link_hash_e
&& (fh->elf.root.type == bfd_link_hash_undefined
|| fh->elf.root.type == bfd_link_hash_undefweak))
{
- bfd *abfd;
- asymbol *newsym;
- struct bfd_link_hash_entry *bh;
-
- abfd = fh->elf.root.u.undef.abfd;
- newsym = bfd_make_empty_symbol (abfd);
- newsym->name = fh->elf.root.root.string + 1;
- newsym->section = bfd_und_section_ptr;
- newsym->value = 0;
- newsym->flags = BSF_OBJECT;
+ flagword flags = 0;
if (fh->elf.root.type == bfd_link_hash_undefweak)
- newsym->flags |= BSF_WEAK;
-
- bh = &fdh->elf.root;
- if ( !(_bfd_generic_link_add_one_symbol
- (info, abfd, newsym->name, newsym->flags,
- newsym->section, newsym->value, NULL, FALSE, FALSE, &bh)))
- {
- return FALSE;
- }
- fdh = (struct ppc_link_hash_entry *) bh;
- fdh->elf.non_elf = 0;
- fdh->elf.size = 24;
- fdh->elf.type = STT_OBJECT;
+ flags = BSF_WEAK;
+ fdh = make_fdh (info, fh, flags);
+ if (fdh == NULL)
+ return FALSE;
}
if (fdh != NULL
Index: ld/testsuite/ld-powerpc/tlsso.r
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-powerpc/tlsso.r,v
retrieving revision 1.9
diff -u -p -r1.9 tlsso.r
--- ld/testsuite/ld-powerpc/tlsso.r 1 Oct 2004 02:19:04 -0000 1.9
+++ ld/testsuite/ld-powerpc/tlsso.r 1 Feb 2005 02:05:06 -0000
@@ -82,7 +82,7 @@ Symbol table '\.dynsym' contains 22 entr
+[0-9]+: 0+10700 +0 OBJECT +GLOBAL DEFAULT +ABS _DYNAMIC
+[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT +UND gd
+[0-9]+: 0+60 +0 TLS +GLOBAL DEFAULT +8 le0
- +[0-9]+: 0+ +24 OBJECT +GLOBAL DEFAULT +UND __tls_get_addr
+ +[0-9]+: 0+ +0 NOTYPE +GLOBAL DEFAULT +UND __tls_get_addr
+[0-9]+: 0+40 +0 TLS +GLOBAL DEFAULT +8 ld0
+[0-9]+: 0+68 +0 TLS +GLOBAL DEFAULT +8 le1
+[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT +UND ld
@@ -127,7 +127,7 @@ Symbol table '\.symtab' contains 42 entr
+[0-9]+: 0+10700 +0 OBJECT +GLOBAL DEFAULT +ABS _DYNAMIC
+[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT +UND gd
+[0-9]+: 0+60 +0 TLS +GLOBAL DEFAULT +8 le0
- +[0-9]+: 0+ +24 OBJECT +GLOBAL DEFAULT +UND __tls_get_addr
+ +[0-9]+: 0+ +0 NOTYPE +GLOBAL DEFAULT +UND __tls_get_addr
+[0-9]+: 0+40 +0 TLS +GLOBAL DEFAULT +8 ld0
+[0-9]+: 0+68 +0 TLS +GLOBAL DEFAULT +8 le1
+[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT +UND ld
Index: ld/testsuite/ld-powerpc/tlstocso.r
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-powerpc/tlstocso.r,v
retrieving revision 1.10
diff -u -p -r1.10 tlstocso.r
--- ld/testsuite/ld-powerpc/tlstocso.r 1 Oct 2004 02:19:04 -0000 1.10
+++ ld/testsuite/ld-powerpc/tlstocso.r 1 Feb 2005 02:05:06 -0000
@@ -77,7 +77,7 @@ Symbol table '\.dynsym' contains 22 entr
+[0-9]+: 0+10648 +0 OBJECT +GLOBAL DEFAULT +ABS _DYNAMIC
+[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT +UND gd
+[0-9]+: 0+60 +0 TLS +GLOBAL DEFAULT +8 le0
- +[0-9]+: 0+ +24 OBJECT +GLOBAL DEFAULT +UND __tls_get_addr
+ +[0-9]+: 0+ +0 NOTYPE +GLOBAL DEFAULT +UND __tls_get_addr
+[0-9]+: 0+40 +0 TLS +GLOBAL DEFAULT +8 ld0
+[0-9]+: 0+68 +0 TLS +GLOBAL DEFAULT +8 le1
+[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT +UND ld
@@ -123,7 +123,7 @@ Symbol table '\.symtab' contains 43 entr
+[0-9]+: 0+10648 +0 OBJECT +GLOBAL DEFAULT +ABS _DYNAMIC
+[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT +UND gd
+[0-9]+: 0+60 +0 TLS +GLOBAL DEFAULT +8 le0
- +[0-9]+: 0+ +24 OBJECT +GLOBAL DEFAULT +UND __tls_get_addr
+ +[0-9]+: 0+ +0 NOTYPE +GLOBAL DEFAULT +UND __tls_get_addr
+[0-9]+: 0+40 +0 TLS +GLOBAL DEFAULT +8 ld0
+[0-9]+: 0+68 +0 TLS +GLOBAL DEFAULT +8 le1
+[0-9]+: 0+ +0 TLS +GLOBAL DEFAULT +UND ld
--
Alan Modra
IBM OzLabs - Linux Technology Centre
More information about the Binutils
mailing list