This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

powerpc64 ld --emit-relocs generates exe that segfaults


Fixes a problem with --emit-relocs on powerpc64.  When a large binary
required (really) long branch trampolines, --emit-relocs created
dynamic relocs, which result in relocation of a read-only section.
DT_TEXTREL wasn't set either, so ld.so segfaulted.

bfd/
	* elf64-ppc.c (create_linkage_sections): Don't create
	.rela.rodata.brlt for --emit-relocs.
	(ppc_build_one_stub): Create relocs for brlt --emit-relocs here.
	(ppc_size_one_stub): Count them.  Simplify test of stub type
	when counting stub relocs.  Set SEC_RELOC too.
	(ppc64_elf_size_stubs): Clear reloc_count and SEC_RELOC.
	(ppc64_elf_finish_dynamic_sections): Output brlt relocs.

ld/testsuite/
	* ld-powerpc/relbrlt.d: Update.

Index: bfd/elf64-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-ppc.c,v
retrieving revision 1.255
diff -u -p -r1.255 elf64-ppc.c
--- bfd/elf64-ppc.c	1 Feb 2007 05:35:58 -0000	1.255
+++ bfd/elf64-ppc.c	12 Feb 2007 08:39:39 -0000
@@ -3846,14 +3846,6 @@ create_linkage_sections (bfd *dynobj, st
 	= bfd_make_section_anyway_with_flags (dynobj, ".rela.data.rel.ro.brlt",
 					      flags);
     }
-  else if (info->emitrelocations)
-    {
-      flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY
-	       | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_LINKER_CREATED);
-      htab->relbrlt
-	= bfd_make_section_anyway_with_flags (dynobj, ".rela.rodata.brlt",
-					      flags);
-    }
   else
     return TRUE;
 
@@ -8394,6 +8386,33 @@ ppc_build_one_stub (struct bfd_hash_entr
 	  rl += htab->relbrlt->reloc_count++ * sizeof (Elf64_External_Rela);
 	  bfd_elf64_swap_reloca_out (htab->relbrlt->owner, &rela, rl);
 	}
+      else if (info->emitrelocations)
+	{
+	  Elf_Internal_Rela *relocs, *r;
+	  struct bfd_elf_section_data *elfsec_data;
+
+	  elfsec_data = elf_section_data (htab->brlt);
+	  relocs = elfsec_data->relocs;
+	  if (relocs == NULL)
+	    {
+	      bfd_size_type relsize;
+	      relsize = htab->brlt->reloc_count * sizeof (*relocs);
+	      relocs = bfd_alloc (htab->brlt->owner, relsize);
+	      if (relocs == NULL)
+		return FALSE;
+	      elfsec_data->relocs = relocs;
+	      elfsec_data->rel_hdr.sh_size = relsize;
+	      elfsec_data->rel_hdr.sh_entsize = 24;
+	      htab->brlt->reloc_count = 0;
+	    }
+	  r = relocs + htab->brlt->reloc_count;
+	  htab->brlt->reloc_count += 1;
+	  r->r_offset = (br_entry->offset
+			 + htab->brlt->output_offset
+			 + htab->brlt->output_section->vma);
+	  r->r_info = ELF64_R_INFO (0, R_PPC64_RELATIVE);
+	  r->r_addend = off;
+	}
 
       off = (br_entry->offset
 	     + htab->brlt->output_offset
@@ -8623,6 +8642,11 @@ ppc_size_one_stub (struct bfd_hash_entry
 
 	      if (htab->relbrlt != NULL)
 		htab->relbrlt->size += sizeof (Elf64_External_Rela);
+	      else if (info->emitrelocations)
+		{
+		  htab->brlt->reloc_count += 1;
+		  htab->brlt->flags |= SEC_RELOC;
+		}
 	    }
 
 	  stub_entry->stub_type += ppc_stub_plt_branch - ppc_stub_long_branch;
@@ -8630,11 +8654,11 @@ ppc_size_one_stub (struct bfd_hash_entry
 	  if (stub_entry->stub_type != ppc_stub_plt_branch)
 	    size = 28;
 	}
-
-      if (info->emitrelocations
-	  && (stub_entry->stub_type == ppc_stub_long_branch
-	      || stub_entry->stub_type == ppc_stub_long_branch_r2off))
-	stub_entry->stub_sec->reloc_count += 1;
+      else if (info->emitrelocations)
+	{
+	  stub_entry->stub_sec->reloc_count += 1;
+	  stub_entry->stub_sec->flags |= SEC_RELOC;
+	}
     }
 
   stub_entry->stub_sec->size += size;
@@ -9426,9 +9450,12 @@ ppc64_elf_size_stubs (bfd *output_bfd,
 	    stub_sec->rawsize = stub_sec->size;
 	    stub_sec->size = 0;
 	    stub_sec->reloc_count = 0;
+	    stub_sec->flags &= ~SEC_RELOC;
 	  }
 
       htab->brlt->size = 0;
+      htab->brlt->reloc_count = 0;
+      htab->brlt->flags &= ~SEC_RELOC;
       if (htab->relbrlt != NULL)
 	htab->relbrlt->size = 0;
 
@@ -11442,6 +11469,17 @@ ppc64_elf_finish_dynamic_sections (bfd *
 	= PLT_ENTRY_SIZE;
     }
 
+  /* brlt is SEC_LINKER_CREATED, so we need to write out relocs for
+     brlt ourselves if emitrelocations.  */
+  if (htab->brlt != NULL
+      && htab->brlt->reloc_count != 0
+      && !_bfd_elf_link_output_relocs (output_bfd,
+				       htab->brlt,
+				       &elf_section_data (htab->brlt)->rel_hdr,
+				       elf_section_data (htab->brlt)->relocs,
+				       NULL))
+    return FALSE;
+
   /* We need to handle writing out multiple GOT sections ourselves,
      since we didn't add them to DYNOBJ.  We know dynobj is the first
      bfd.  */
Index: ld/testsuite/ld-powerpc/relbrlt.d
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-powerpc/relbrlt.d,v
retrieving revision 1.1
diff -u -p -r1.1 relbrlt.d
--- ld/testsuite/ld-powerpc/relbrlt.d	24 Oct 2006 13:29:37 -0000	1.1
+++ ld/testsuite/ld-powerpc/relbrlt.d	12 Feb 2007 11:56:07 -0000
@@ -7,44 +7,44 @@
 
 Disassembly of section \.text:
 
-0*100000a8 <_start>:
-    100000a8:	49 bf 00 31 	bl      11bf00d8 .*
-			100000a8: R_PPC64_REL24	\.text\+0x37e0044
-    100000ac:	60 00 00 00 	nop
-    100000b0:	49 bf 00 19 	bl      11bf00c8 .*
-			100000b0: R_PPC64_REL24	\.text\+0x3bf0020
-    100000b4:	60 00 00 00 	nop
-    100000b8:	49 bf 00 25 	bl      11bf00dc .*
-			100000b8: R_PPC64_REL24	\.text\+0x57e0024
-    100000bc:	60 00 00 00 	nop
-    100000c0:	00 00 00 00 	\.long 0x0
-    100000c4:	4b ff ff e4 	b       100000a8 <_start>
+0*10000078 <_start>:
+    10000078:	49 bf 00 31 	bl      11bf00a8 .*
+			10000078: R_PPC64_REL24	\.text\+0x37e0044
+    1000007c:	60 00 00 00 	nop
+    10000080:	49 bf 00 19 	bl      11bf0098 .*
+			10000080: R_PPC64_REL24	\.text\+0x3bf0020
+    10000084:	60 00 00 00 	nop
+    10000088:	49 bf 00 25 	bl      11bf00ac .*
+			10000088: R_PPC64_REL24	\.text\+0x57e0024
+    1000008c:	60 00 00 00 	nop
+    10000090:	00 00 00 00 	\.long 0x0
+    10000094:	4b ff ff e4 	b       10000078 <_start>
 	\.\.\.
 
-0*11bf00c8 <.*plt_branch.*>:
-    11bf00c8:	3d 82 05 7e 	addis   r12,r2,1406
-    11bf00cc:	e9 6c 80 58 	ld      r11,-32680\(r12\)
-    11bf00d0:	7d 69 03 a6 	mtctr   r11
-    11bf00d4:	4e 80 04 20 	bctr
-
-0*11bf00d8 <.*long_branch.*>:
-    11bf00d8:	49 bf 00 14 	b       137e00ec <far>
-			11bf00d8: R_PPC64_REL24	\*ABS\*\+0x137e00ec
-
-0*11bf00dc <.*plt_branch.*>:
-    11bf00dc:	3d 82 05 7e 	addis   r12,r2,1406
-    11bf00e0:	e9 6c 80 60 	ld      r11,-32672\(r12\)
-    11bf00e4:	7d 69 03 a6 	mtctr   r11
-    11bf00e8:	4e 80 04 20 	bctr
+0*11bf0098 <.*plt_branch.*>:
+    11bf0098:	3d 82 05 7e 	addis   r12,r2,1406
+    11bf009c:	e9 6c 80 28 	ld      r11,-32728\(r12\)
+    11bf00a0:	7d 69 03 a6 	mtctr   r11
+    11bf00a4:	4e 80 04 20 	bctr
+
+0*11bf00a8 <.*long_branch.*>:
+    11bf00a8:	49 bf 00 14 	b       137e00bc <far>
+			11bf00a8: R_PPC64_REL24	\*ABS\*\+0x137e00bc
+
+0*11bf00ac <.*plt_branch.*>:
+    11bf00ac:	3d 82 05 7e 	addis   r12,r2,1406
+    11bf00b0:	e9 6c 80 30 	ld      r11,-32720\(r12\)
+    11bf00b4:	7d 69 03 a6 	mtctr   r11
+    11bf00b8:	4e 80 04 20 	bctr
 	\.\.\.
 
-0*137e00ec <far>:
-    137e00ec:	4e 80 00 20 	blr
+0*137e00bc <far>:
+    137e00bc:	4e 80 00 20 	blr
 	\.\.\.
 
-0*13bf00c8 <far2far>:
-    13bf00c8:	4e 80 00 20 	blr
+0*13bf0098 <far2far>:
+    13bf0098:	4e 80 00 20 	blr
 	\.\.\.
 
-0*157e00cc <huge>:
-    157e00cc:	4e 80 00 20 	blr
+0*157e009c <huge>:
+    157e009c:	4e 80 00 20 	blr

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]