diff options
-rw-r--r-- | bfd/ChangeLog | 13 | ||||
-rw-r--r-- | bfd/elf64-ppc.c | 98 | ||||
-rw-r--r-- | ld/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | ld/testsuite/ld-powerpc/tlsso.r | 4 | ||||
-rw-r--r-- | ld/testsuite/ld-powerpc/tlstocso.r | 4 |
5 files changed, 90 insertions, 34 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index e4ecd4a..5607b97 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,16 @@ +2005-02-01 Alan Modra <amodra@bigpond.net.au> + + * 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. + 2005-02-01 Hans-Peter Nilsson <hp@axis.com> * cpu-cris.c (get_compatible): Rearrange disabled code and comment diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c index c75c34a..5439671 100644 --- a/bfd/elf64-ppc.c +++ b/bfd/elf64-ppc.c @@ -3937,6 +3937,37 @@ get_fdh (struct ppc_link_hash_entry *fh, struct ppc_link_hash_table *htab) 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 *abfd, 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_entry *h, void *inf) 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_entry *h, void *inf) 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 ATTRIBUTE_UNUSED, 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 ATTRIBUTE_UNUSED, 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_entry *h, void *inf) && (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 diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog index 6850a0b..e98ec43 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2005-02-01 Alan Modra <amodra@bigpond.net.au> + + * ld-powerpc/tlsso.r: Update. + * ld-powerpc/tlstocso.r: Update. + 2005-01-31 Daniel Jacobowitz <dan@codesourcery.com> * ld-mips-elf/elf-rel-got-n32.d, ld-mips-elf/elf-rel-got-n64-linux.d, diff --git a/ld/testsuite/ld-powerpc/tlsso.r b/ld/testsuite/ld-powerpc/tlsso.r index 9cb00ff..17faa1e 100644 --- a/ld/testsuite/ld-powerpc/tlsso.r +++ b/ld/testsuite/ld-powerpc/tlsso.r @@ -82,7 +82,7 @@ Symbol table '\.dynsym' contains 22 entries: +[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 entries: +[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 diff --git a/ld/testsuite/ld-powerpc/tlstocso.r b/ld/testsuite/ld-powerpc/tlstocso.r index 8369b5a..1dc285a 100644 --- a/ld/testsuite/ld-powerpc/tlstocso.r +++ b/ld/testsuite/ld-powerpc/tlstocso.r @@ -77,7 +77,7 @@ Symbol table '\.dynsym' contains 22 entries: +[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 entries: +[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 |