public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* Fix a linker segfault for PPC sdata
@ 2005-05-17 21:29 Daniel Jacobowitz
  2005-05-19 10:24 ` Alan Modra
  0 siblings, 1 reply; 2+ messages in thread
From: Daniel Jacobowitz @ 2005-05-17 21:29 UTC (permalink / raw)
  To: binutils

This is a slightly weird patch...

One of our customers has an environment which supports both small data
access and shared libraries on PowerPC.  Non-PIC code generates sdata
relocations, PIC code doesn't.  If it so happens that a variable is defined
in a shared library, referenced in a non-PIC object, and of the appropriate
size, then there will be SDA21 relocations against it.  This crashes ld; we
check the output section for the variable unconditionally.

This is the obvious solution: generate a copy relocation into .sbss.  There
was already some code to do this, but it hasn't worked lately (I didn't do
the archeology).

OK?  Tested on cross binutils to powerpc-linux; without the bfd patch, the
ld test causes a linker segfault.

-- 
Daniel Jacobowitz
CodeSourcery, LLC

2005-05-17  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-17  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.

Index: bfd/elf32-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-ppc.c,v
retrieving revision 1.159
diff -u -p -r1.159 elf32-ppc.c
--- bfd/elf32-ppc.c	17 May 2005 13:55:02 -0000	1.159
+++ bfd/elf32-ppc.c	17 May 2005 21:17:30 -0000
@@ -2241,6 +2241,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))
@@ -2486,6 +2490,7 @@ ppc_elf_copy_indirect_symbol (const stru
     }
 
   edir->tls_mask |= eind->tls_mask;
+  edir->has_sda_refs |= eind->has_sda_refs;
 
   if (ELIMINATE_COPY_RELOCS
       && ind->root.type != bfd_link_hash_indirect
@@ -2899,6 +2904,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:
@@ -3781,7 +3792,11 @@ ppc_elf_adjust_dynamic_symbol (struct bf
   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)
@@ -3791,8 +3806,6 @@ ppc_elf_adjust_dynamic_symbol (struct bf
 	    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;
@@ -3810,11 +3823,10 @@ ppc_elf_adjust_dynamic_symbol (struct bf
      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;
@@ -3828,7 +3840,7 @@ ppc_elf_adjust_dynamic_symbol (struct bf
     {
       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;
@@ -6265,7 +6277,7 @@ ppc_elf_finish_dynamic_symbol (bfd *outp
 
       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: ld/testsuite/ld-powerpc/powerpc.exp
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-powerpc/powerpc.exp,v
retrieving revision 1.9
diff -u -p -r1.9 powerpc.exp
--- ld/testsuite/ld-powerpc/powerpc.exp	12 May 2005 07:32:07 -0000	1.9
+++ ld/testsuite/ld-powerpc/powerpc.exp	17 May 2005 21:17:30 -0000
@@ -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 {
Index: ld/testsuite/ld-powerpc/sdadyn.d
===================================================================
RCS file: ld/testsuite/ld-powerpc/sdadyn.d
diff -N ld/testsuite/ld-powerpc/sdadyn.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-powerpc/sdadyn.d	17 May 2005 21:17:30 -0000
@@ -0,0 +1,8 @@
+
+.*: +file format elf32-powerpc
+
+DYNAMIC RELOCATION RECORDS
+OFFSET   TYPE              VALUE 
+#...
+.* R_PPC_COPY        lib_var
+#pass
Index: ld/testsuite/ld-powerpc/sdadyn.s
===================================================================
RCS file: ld/testsuite/ld-powerpc/sdadyn.s
diff -N ld/testsuite/ld-powerpc/sdadyn.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-powerpc/sdadyn.s	17 May 2005 21:17:30 -0000
@@ -0,0 +1,3 @@
+	.globl _start
+_start:
+	lwz	3,lib_var@sda21(0)
Index: ld/testsuite/ld-powerpc/sdalib.s
===================================================================
RCS file: ld/testsuite/ld-powerpc/sdalib.s
diff -N ld/testsuite/ld-powerpc/sdalib.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-powerpc/sdalib.s	17 May 2005 21:17:30 -0000
@@ -0,0 +1,4 @@
+	.globl lib_var
+	.type lib_var, @object
+lib_var:
+	.word	1

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: Fix a linker segfault for PPC sdata
  2005-05-17 21:29 Fix a linker segfault for PPC sdata Daniel Jacobowitz
@ 2005-05-19 10:24 ` Alan Modra
  0 siblings, 0 replies; 2+ messages in thread
From: Alan Modra @ 2005-05-19 10:24 UTC (permalink / raw)
  To: binutils

On Tue, May 17, 2005 at 05:28:18PM -0400, Daniel Jacobowitz wrote:
> 2005-05-17  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-17  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.

OK, thanks.

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2005-05-19  8:55 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-05-17 21:29 Fix a linker segfault for PPC sdata Daniel Jacobowitz
2005-05-19 10:24 ` Alan Modra

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).