summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Jacobowitz <dan@debian.org>2005-05-20 21:57:12 +0000
committerDaniel Jacobowitz <dan@debian.org>2005-05-20 21:57:12 +0000
commit1142a712a0fea9b2d5403e5cca5b978d283be73f (patch)
tree629151c8fbe02a8b48aff4938989019bb7c9c2d9
parent3146e89399e146d9e389cb268e30752c9cc4aa4f (diff)
downloadbinutils-redhat-1142a712a0fea9b2d5403e5cca5b978d283be73f.tar.gz
bfd/
* bfd/elf32-ppc.c (struct ppc_elf_link_hash_entry): Add new field has_sda_refs. (ppc_elf_copy_indirect_symbol): Copy has_sda_refs. (ppc_elf_check_relocs): Set has_sda_refs. (ppc_elf_adjust_dynamic_symbol): Check has_sda_refs before eliminating copy relocations. Use has_sda_refs to place variables in .sbss. (ppc_elf_finish_dynamic_symbol): Use has_sda_refs to place variables in .sbss. ld/testsuite/ * ld-powerpc/sdalib.s, ld-powerpc/sdadyn.s, ld-powerpc/sdadyn.d: New files. * ld-powerpc/powerpc.exp: Run the new test.
-rw-r--r--bfd/ChangeLog11
-rw-r--r--bfd/elf32-ppc.c30
-rw-r--r--ld/testsuite/ChangeLog6
-rw-r--r--ld/testsuite/ld-powerpc/powerpc.exp4
-rw-r--r--ld/testsuite/ld-powerpc/sdadyn.d8
-rw-r--r--ld/testsuite/ld-powerpc/sdadyn.s3
-rw-r--r--ld/testsuite/ld-powerpc/sdalib.s4
7 files changed, 57 insertions, 9 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index d608100fde..a32d1fced2 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,14 @@
+2005-05-20 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * bfd/elf32-ppc.c (struct ppc_elf_link_hash_entry): Add new field
+ has_sda_refs.
+ (ppc_elf_copy_indirect_symbol): Copy has_sda_refs.
+ (ppc_elf_check_relocs): Set has_sda_refs.
+ (ppc_elf_adjust_dynamic_symbol): Check has_sda_refs before eliminating
+ copy relocations. Use has_sda_refs to place variables in .sbss.
+ (ppc_elf_finish_dynamic_symbol): Use has_sda_refs to place variables in
+ .sbss.
+
2005-05-20 Bob Wilson <bob.wilson@acm.org>
* elf32-xtensa.c (bfd_elf_xtensa_reloc): Make sure that
diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c
index a70255a349..585bf7d5a0 100644
--- a/bfd/elf32-ppc.c
+++ b/bfd/elf32-ppc.c
@@ -2269,6 +2269,10 @@ struct ppc_elf_link_hash_entry
#define TLS_TLS 16 /* Any TLS reloc. */
#define TLS_TPRELGD 32 /* TPREL reloc resulting from GD->IE. */
char tls_mask;
+
+ /* Nonzero if we have seen a small data relocation referring to this
+ symbol. */
+ unsigned char has_sda_refs;
};
#define ppc_elf_hash_entry(ent) ((struct ppc_elf_link_hash_entry *) (ent))
@@ -2520,6 +2524,7 @@ ppc_elf_copy_indirect_symbol (const struct elf_backend_data *bed ATTRIBUTE_UNUSE
}
edir->tls_mask |= eind->tls_mask;
+ edir->has_sda_refs |= eind->has_sda_refs;
/* If called to transfer flags for a weakdef during processing
of elf_adjust_dynamic_symbol, don't copy non_got_ref.
@@ -3026,6 +3031,12 @@ ppc_elf_check_relocs (bfd *abfd,
bad_shared_reloc (abfd, r_type);
return FALSE;
}
+ if (h != NULL)
+ {
+ ppc_elf_hash_entry (h)->has_sda_refs = TRUE;
+ /* We may need a copy reloc. */
+ h->non_got_ref = TRUE;
+ }
break;
case R_PPC_PLT32:
@@ -3923,7 +3934,11 @@ ppc_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
if (!h->non_got_ref)
return TRUE;
- if (ELIMINATE_COPY_RELOCS)
+ /* If we didn't find any dynamic relocs in read-only sections, then we'll
+ be keeping the dynamic relocs and avoiding the copy reloc. We can't
+ do this if there are any small data relocations. */
+ if (ELIMINATE_COPY_RELOCS
+ && !ppc_elf_hash_entry (h)->has_sda_refs)
{
struct ppc_elf_dyn_relocs *p;
for (p = ppc_elf_hash_entry (h)->dyn_relocs; p != NULL; p = p->next)
@@ -3933,8 +3948,6 @@ ppc_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
break;
}
- /* If we didn't find any dynamic relocs in read-only sections, then
- we'll be keeping the dynamic relocs and avoiding the copy reloc. */
if (p == NULL)
{
h->non_got_ref = 0;
@@ -3952,11 +3965,10 @@ ppc_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
both the dynamic object and the regular object will refer to the
same memory location for the variable.
- Of course, if the symbol is sufficiently small, we must instead
- allocate it in .sbss. FIXME: It would be better to do this if and
- only if there were actually SDAREL relocs for that symbol. */
+ Of course, if the symbol is referenced using SDAREL relocs, we
+ must instead allocate it in .sbss. */
- if (h->size <= elf_gp_size (htab->elf.dynobj))
+ if (ppc_elf_hash_entry (h)->has_sda_refs)
s = htab->dynsbss;
else
s = htab->dynbss;
@@ -3970,7 +3982,7 @@ ppc_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
{
asection *srel;
- if (h->size <= elf_gp_size (htab->elf.dynobj))
+ if (ppc_elf_hash_entry (h)->has_sda_refs)
srel = htab->relsbss;
else
srel = htab->relbss;
@@ -6544,7 +6556,7 @@ ppc_elf_finish_dynamic_symbol (bfd *output_bfd,
BFD_ASSERT (h->dynindx != -1);
- if (h->size <= elf_gp_size (htab->elf.dynobj))
+ if (ppc_elf_hash_entry (h)->has_sda_refs)
s = htab->relsbss;
else
s = htab->relbss;
diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog
index 2a07252570..8cf395ad08 100644
--- a/ld/testsuite/ChangeLog
+++ b/ld/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2005-05-20 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * ld-powerpc/sdalib.s, ld-powerpc/sdadyn.s, ld-powerpc/sdadyn.d: New
+ files.
+ * ld-powerpc/powerpc.exp: Run the new test.
+
2005-05-20 Bob Wilson <bob.wilson@acm.org>
* ld-undefined/undefined.exp: Revert xfail for xtensa-*-*.
diff --git a/ld/testsuite/ld-powerpc/powerpc.exp b/ld/testsuite/ld-powerpc/powerpc.exp
index 9e452fbe78..593d7e2f32 100644
--- a/ld/testsuite/ld-powerpc/powerpc.exp
+++ b/ld/testsuite/ld-powerpc/powerpc.exp
@@ -69,6 +69,10 @@ set ppcelftests {
{{readelf -WSsrl tlsso32.r} {objdump -dr tlsso32.d}
{objdump -sj.got tlsso32.g} {objdump -sj.tdata tlsso32.t}}
"tls32.so"}
+ {"Shared library with global symbol" "-shared -melf32ppc" "" {sdalib.s}
+ {} "sdalib.so"}
+ {"Dynamic application with SDA" "-melf32ppc tmpdir/sdalib.so" "" {sdadyn.s}
+ {{objdump -R sdadyn.d}} "sdadyn"}
}
set ppc64elftests {
diff --git a/ld/testsuite/ld-powerpc/sdadyn.d b/ld/testsuite/ld-powerpc/sdadyn.d
new file mode 100644
index 0000000000..42e389ff74
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/sdadyn.d
@@ -0,0 +1,8 @@
+
+.*: +file format elf32-powerpc
+
+DYNAMIC RELOCATION RECORDS
+OFFSET TYPE VALUE
+#...
+.* R_PPC_COPY lib_var
+#pass
diff --git a/ld/testsuite/ld-powerpc/sdadyn.s b/ld/testsuite/ld-powerpc/sdadyn.s
new file mode 100644
index 0000000000..1b2d13f73d
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/sdadyn.s
@@ -0,0 +1,3 @@
+ .globl _start
+_start:
+ lwz 3,lib_var@sda21(0)
diff --git a/ld/testsuite/ld-powerpc/sdalib.s b/ld/testsuite/ld-powerpc/sdalib.s
new file mode 100644
index 0000000000..8a599386f1
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/sdalib.s
@@ -0,0 +1,4 @@
+ .globl lib_var
+ .type lib_var, @object
+lib_var:
+ .word 1