From 4dc4a9a515d83cbef3d06d21b934df37e85d663c Mon Sep 17 00:00:00 2001 From: Daniel Jacobowitz Date: Fri, 20 May 2005 21:57:12 +0000 Subject: [PATCH] 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. --- bfd/ChangeLog | 11 +++++++++++ bfd/elf32-ppc.c | 30 ++++++++++++++++++++--------- ld/testsuite/ChangeLog | 6 ++++++ ld/testsuite/ld-powerpc/powerpc.exp | 4 ++++ ld/testsuite/ld-powerpc/sdadyn.d | 8 ++++++++ ld/testsuite/ld-powerpc/sdadyn.s | 3 +++ ld/testsuite/ld-powerpc/sdalib.s | 4 ++++ 7 files changed, 57 insertions(+), 9 deletions(-) create mode 100644 ld/testsuite/ld-powerpc/sdadyn.d create mode 100644 ld/testsuite/ld-powerpc/sdadyn.s create mode 100644 ld/testsuite/ld-powerpc/sdalib.s diff --git a/bfd/ChangeLog b/bfd/ChangeLog index d608100fded..a32d1fced2c 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,14 @@ +2005-05-20 Daniel Jacobowitz + + * 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 * elf32-xtensa.c (bfd_elf_xtensa_reloc): Make sure that diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c index a70255a3496..585bf7d5a04 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 2a07252570e..8cf395ad086 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2005-05-20 Daniel Jacobowitz + + * 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 * 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 9e452fbe78b..593d7e2f328 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 00000000000..42e389ff74c --- /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 00000000000..1b2d13f73d3 --- /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 00000000000..8a599386f17 --- /dev/null +++ b/ld/testsuite/ld-powerpc/sdalib.s @@ -0,0 +1,4 @@ + .globl lib_var + .type lib_var, @object +lib_var: + .word 1 -- 2.30.2