aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/ChangeLog13
-rw-r--r--bfd/elf64-ppc.c98
-rw-r--r--ld/testsuite/ChangeLog5
-rw-r--r--ld/testsuite/ld-powerpc/tlsso.r4
-rw-r--r--ld/testsuite/ld-powerpc/tlstocso.r4
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