bfd/
authorDaniel Jacobowitz <drow@false.org>
Fri, 20 May 2005 21:57:12 +0000 (21:57 +0000)
committerDaniel Jacobowitz <drow@false.org>
Fri, 20 May 2005 21:57:12 +0000 (21:57 +0000)
* 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
bfd/elf32-ppc.c
ld/testsuite/ChangeLog
ld/testsuite/ld-powerpc/powerpc.exp
ld/testsuite/ld-powerpc/sdadyn.d [new file with mode: 0644]
ld/testsuite/ld-powerpc/sdadyn.s [new file with mode: 0644]
ld/testsuite/ld-powerpc/sdalib.s [new file with mode: 0644]

index d608100..a32d1fc 100644 (file)
@@ -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
index a70255a..585bf7d 100644 (file)
@@ -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;
index 2a07252..8cf395a 100644 (file)
@@ -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-*-*.
index 9e452fb..593d7e2 100644 (file)
@@ -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 (file)
index 0000000..42e389f
--- /dev/null
@@ -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 (file)
index 0000000..1b2d13f
--- /dev/null
@@ -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 (file)
index 0000000..8a59938
--- /dev/null
@@ -0,0 +1,4 @@
+       .globl lib_var
+       .type lib_var, @object
+lib_var:
+       .word   1