PATCH: PR ld/14105: Always create PLT eh_frame

Alan Modra amodra@gmail.com
Tue May 22 14:55:00 GMT 2012


This tweaks another place that might cause bfd_elf_discard_info to
prematurely exit when multiple .eh_frame sections exist in a single
BFD.  I've also set up ppc32 PLT .eh_frame contents early to benefit
from CIE merging.  I don't intend to do the same for ppc64 as it is
difficult to make the .eh_frame contents available early enough.

	* elflink.c (bfd_elf_discard_info): Look for next .eh_frame if
	first one is zero size or discarded.
	* elf32-ppc.c (ppc_elf_size_dynamic_sections): Set most of
	glink_eh_frame contents here..
	(ppc_elf_finish_dynamic_sections): ..rather than here.  Just set
	offset to .glink.

Index: bfd/elflink.c
===================================================================
RCS file: /cvs/src/src/bfd/elflink.c,v
retrieving revision 1.442
diff -u -p -r1.442 elflink.c
--- bfd/elflink.c	22 May 2012 12:09:26 -0000	1.442
+++ bfd/elflink.c	22 May 2012 13:44:38 -0000
@@ -12489,10 +12489,10 @@ bfd_elf_discard_info (bfd *output_bfd, s
       if (!info->relocatable)
 	{
 	  eh = bfd_get_section_by_name (abfd, ".eh_frame");
-	  if (eh != NULL
-	      && (eh->size == 0
-		  || bfd_is_abs_section (eh->output_section)))
-	    eh = NULL;
+	  while (eh != NULL
+		 && (eh->size == 0
+		     || bfd_is_abs_section (eh->output_section)))
+	    eh = bfd_get_next_section_by_name (eh);
 	}
 
       stab = bfd_get_section_by_name (abfd, ".stab");
Index: bfd/elf32-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-ppc.c,v
retrieving revision 1.315
diff -u -p -r1.315 elf32-ppc.c
--- bfd/elf32-ppc.c	19 May 2012 06:58:45 -0000	1.315
+++ bfd/elf32-ppc.c	22 May 2012 13:44:35 -0000
@@ -6393,6 +6393,66 @@ ppc_elf_size_dynamic_sections (bfd *outp
    }
 #undef add_dynamic_entry
 
+  if (htab->glink_eh_frame != NULL
+      && htab->glink_eh_frame->contents != NULL)
+    {
+      unsigned char *p = htab->glink_eh_frame->contents;
+      bfd_vma val;
+
+      memcpy (p, glink_eh_frame_cie, sizeof (glink_eh_frame_cie));
+      /* CIE length (rewrite in case little-endian).  */
+      bfd_put_32 (htab->elf.dynobj, sizeof (glink_eh_frame_cie) - 4, p);
+      p += sizeof (glink_eh_frame_cie);
+      /* FDE length.  */
+      val = htab->glink_eh_frame->size - 4 - sizeof (glink_eh_frame_cie);
+      bfd_put_32 (htab->elf.dynobj, val, p);
+      p += 4;
+      /* CIE pointer.  */
+      val = p - htab->glink_eh_frame->contents;
+      bfd_put_32 (htab->elf.dynobj, val, p);
+      p += 4;
+      /* Offset to .glink.  Set later.  */
+      p += 4;
+      /* .glink size.  */
+      bfd_put_32 (htab->elf.dynobj, htab->glink->size, p);
+      p += 4;
+      /* Augmentation.  */
+      p += 1;
+
+      if (info->shared
+	  && htab->elf.dynamic_sections_created)
+	{
+	  bfd_vma adv = (htab->glink->size - GLINK_PLTRESOLVE + 8) >> 2;
+	  if (adv < 64)
+	    *p++ = DW_CFA_advance_loc + adv;
+	  else if (adv < 256)
+	    {
+	      *p++ = DW_CFA_advance_loc1;
+	      *p++ = adv;
+	    }
+	  else if (adv < 65536)
+	    {
+	      *p++ = DW_CFA_advance_loc2;
+	      bfd_put_16 (htab->elf.dynobj, adv, p);
+	      p += 2;
+	    }
+	  else
+	    {
+	      *p++ = DW_CFA_advance_loc4;
+	      bfd_put_32 (htab->elf.dynobj, adv, p);
+	      p += 4;
+	    }
+	  *p++ = DW_CFA_register;
+	  *p++ = 65;
+	  p++;
+	  *p++ = DW_CFA_advance_loc + 4;
+	  *p++ = DW_CFA_restore_extended;
+	  *p++ = 65;
+	}
+      BFD_ASSERT ((bfd_vma) ((p + 3 - htab->glink_eh_frame->contents) & -4)
+		  == htab->glink_eh_frame->size);
+    }
+
   return TRUE;
 }
 
@@ -9573,17 +9633,10 @@ ppc_elf_finish_dynamic_sections (bfd *ou
       unsigned char *p = htab->glink_eh_frame->contents;
       bfd_vma val;
 
-      memcpy (p, glink_eh_frame_cie, sizeof (glink_eh_frame_cie));
-      /* CIE length (rewrite in case little-endian).  */
-      bfd_put_32 (htab->elf.dynobj, sizeof (glink_eh_frame_cie) - 4, p);
       p += sizeof (glink_eh_frame_cie);
       /* FDE length.  */
-      val = htab->glink_eh_frame->size - 4 - sizeof (glink_eh_frame_cie);
-      bfd_put_32 (htab->elf.dynobj, val, p);
       p += 4;
       /* CIE pointer.  */
-      val = p - htab->glink_eh_frame->contents;
-      bfd_put_32 (htab->elf.dynobj, val, p);
       p += 4;
       /* Offset to .glink.  */
       val = (htab->glink->output_section->vma
@@ -9592,45 +9645,6 @@ ppc_elf_finish_dynamic_sections (bfd *ou
 	      + htab->glink_eh_frame->output_offset);
       val -= p - htab->glink_eh_frame->contents;
       bfd_put_32 (htab->elf.dynobj, val, p);
-      p += 4;
-      /* .glink size.  */
-      bfd_put_32 (htab->elf.dynobj, htab->glink->size, p);
-      p += 4;
-      /* Augmentation.  */
-      p += 1;
-
-      if (info->shared
-	  && htab->elf.dynamic_sections_created)
-	{
-	  bfd_vma adv = (htab->glink->size - GLINK_PLTRESOLVE + 8) >> 2;
-	  if (adv < 64)
-	    *p++ = DW_CFA_advance_loc + adv;
-	  else if (adv < 256)
-	    {
-	      *p++ = DW_CFA_advance_loc1;
-	      *p++ = adv;
-	    }
-	  else if (adv < 65536)
-	    {
-	      *p++ = DW_CFA_advance_loc2;
-	      bfd_put_16 (htab->elf.dynobj, adv, p);
-	      p += 2;
-	    }
-	  else
-	    {
-	      *p++ = DW_CFA_advance_loc4;
-	      bfd_put_32 (htab->elf.dynobj, adv, p);
-	      p += 4;
-	    }
-	  *p++ = DW_CFA_register;
-	  *p++ = 65;
-	  p++;
-	  *p++ = DW_CFA_advance_loc + 4;
-	  *p++ = DW_CFA_restore_extended;
-	  *p++ = 65;
-	}
-      BFD_ASSERT ((bfd_vma) ((p + 3 - htab->glink_eh_frame->contents) & -4)
-		  == htab->glink_eh_frame->size);
 
       if (htab->glink_eh_frame->sec_info_type == SEC_INFO_TYPE_EH_FRAME
 	  && !_bfd_elf_write_section_eh_frame (output_bfd, info,

-- 
Alan Modra
Australia Development Lab, IBM



More information about the Binutils mailing list