aboutsummaryrefslogtreecommitdiff
path: root/bfd/elf32-ppc.c
diff options
context:
space:
mode:
authorDaniel Jacobowitz <drow@false.org>2005-05-20 21:57:12 +0000
committerDaniel Jacobowitz <drow@false.org>2005-05-20 21:57:12 +0000
commit4dc4a9a515d83cbef3d06d21b934df37e85d663c (patch)
treec0a226ebcb87e21cb73f3bc2060fe26585e20a0f /bfd/elf32-ppc.c
parentdd1a320be63abd442e85607f8052ff597901efe5 (diff)
downloadgdb-4dc4a9a515d83cbef3d06d21b934df37e85d663c.zip
gdb-4dc4a9a515d83cbef3d06d21b934df37e85d663c.tar.gz
gdb-4dc4a9a515d83cbef3d06d21b934df37e85d663c.tar.bz2
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.
Diffstat (limited to 'bfd/elf32-ppc.c')
-rw-r--r--bfd/elf32-ppc.c30
1 files changed, 21 insertions, 9 deletions
diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c
index a70255a..585bf7d 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;