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]

Re: PowerPC _GLOBAL_OFFSET_TABLE_


On Tue, Sep 16, 2008 at 11:12:48PM +0930, Alan Modra wrote:
> 	(ppc_elf_finish_dynamic_sections): Likewise.  Error if
> 	htab->elf.hgot symbol is not defined in htab->got section.

My 2008-09-16 change resulted in "_GLOBAL_OFFSET_TABLE_ not defined
in linker created .got" errors on powerpc-vxworks, since in that case
the symbol is defined in .got.plt.  However, I think the code setting
up the got header has been broken since the original vxworks commit.
Space for the header is allocated in .got.plt, but the .dynamic
address was being written to .got, overwriting the first .got entry.

I couldn't find details on what vxworks expects in the got header,
so don't really know if this is correct even now..

	* elf32-ppc.c (ppc_elf_finish_dynamic_sections): Handle vxworks
	_GLOBAL_OFFSET_TABLE_ in .got.plt section.  Add BFD_ASSERTs.

Index: bfd/elf32-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-ppc.c,v
retrieving revision 1.245
diff -u -p -r1.245 elf32-ppc.c
--- bfd/elf32-ppc.c	16 Sep 2008 13:43:36 -0000	1.245
+++ bfd/elf32-ppc.c	19 Sep 2008 09:01:06 -0000
@@ -7727,29 +7727,38 @@ ppc_elf_finish_dynamic_sections (bfd *ou
 	}
     }
 
-  /* Add a blrl instruction at _GLOBAL_OFFSET_TABLE_-4 so that a function can
-     easily find the address of the _GLOBAL_OFFSET_TABLE_.  */
   if (htab->got != NULL)
     {
-      if (htab->elf.hgot->root.u.def.section == htab->got)
+      if (htab->elf.hgot->root.u.def.section == htab->got
+	  || htab->elf.hgot->root.u.def.section == htab->sgotplt)
 	{
-	  unsigned char *p = htab->got->contents;
-	  bfd_vma val;
+	  unsigned char *p = htab->elf.hgot->root.u.def.section->contents;
 
 	  p += htab->elf.hgot->root.u.def.value;
 	  if (htab->plt_type == PLT_OLD)
-	    bfd_put_32 (output_bfd, 0x4e800021 /* blrl */, p - 4);
+	    {
+	      /* Add a blrl instruction at _GLOBAL_OFFSET_TABLE_-4
+		 so that a function can easily find the address of
+		 _GLOBAL_OFFSET_TABLE_.  */
+	      BFD_ASSERT (htab->elf.hgot->root.u.def.value - 4
+			  < htab->elf.hgot->root.u.def.section->size);
+	      bfd_put_32 (output_bfd, 0x4e800021, p - 4);
+	    }
 
-	  val = 0;
 	  if (sdyn != NULL)
-	    val = sdyn->output_section->vma + sdyn->output_offset;
-	  bfd_put_32 (output_bfd, val, p);
+	    {
+	      bfd_vma val = sdyn->output_section->vma + sdyn->output_offset;
+	      BFD_ASSERT (htab->elf.hgot->root.u.def.value
+			  < htab->elf.hgot->root.u.def.section->size);
+	      bfd_put_32 (output_bfd, val, p);
+	    }
 	}
       else
 	{
 	  (*_bfd_error_handler) (_("%s not defined in linker created %s"),
 				 htab->elf.hgot->root.root.string,
-				 htab->got->name);
+				 (htab->sgotplt != NULL
+				  ? htab->sgotplt->name : htab->got->name));
 	  bfd_set_error (bfd_error_bad_value);
 	  ret = FALSE;
 	}

-- 
Alan Modra
Australia Development Lab, IBM


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