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: PATCH: PR ld/13909: PR ld/12570 causes eh_frame_hdr section to be sometimes too large


On Wed, May 23, 2012 at 04:59:13AM -0700, H.J. Lu wrote:
> Shouldn't we ignore linker created .eh_frame section?

Why?  It's eh data like any other .eh_frame.

> Current trunk gave me:

>   [ 4] .eh_frame_hdr     PROGBITS        0000013c 00013c 00000c 00   A  0   0  4
>   [ 5] .eh_frame         PROGBITS        00000148 000148 000000 00   A  0   0  4

Your PLT eh_frame is discarded because it is not being set up early
enough.  elf-eh-frame.c:1166 "keep = value != 0;" gets a value of 0.

PowerPC has a problem with ordering too, in that .eh_frame_hdr is
stripped when only PLT/glink has eh_frame info.  I want to allow
sizing of the PLT/glink .eh_frame in elf_backend_size_dynamic_sections,
rather than sizing and filling in some data early like x86 does.
The following fixes the PowerPC problem, and should also fix the above
x86 problem.  You'll also be able to size plt_eh_frame to zero when
no plt section is needed.  I'm not going to commit this tonight
though.  It needs testing and I need sleep.

bfd/
	* elflink.c (bfd_elf_size_dynamic_sections): Let the backend
	size dynamic sections before stripping eh_frame_hdr.
	(bfd_elf_gc_sections): Handle multiple .eh_frame sections.
ld/
	* emultempl/elf32.em (gld${EMULATION_NAME}_after_open): Handle
	multiple .eh_frame sections attached to bfd.

Index: bfd/elflink.c
===================================================================
RCS file: /cvs/src/src/bfd/elflink.c,v
retrieving revision 1.444
diff -u -p -r1.444 elflink.c
--- bfd/elflink.c	23 May 2012 04:35:31 -0000	1.444
+++ bfd/elflink.c	23 May 2012 13:31:03 -0000
@@ -5584,17 +5584,9 @@ bfd_elf_size_dynamic_sections (bfd *outp
       && ! (*bed->elf_backend_always_size_sections) (output_bfd, info))
     return FALSE;
 
-  if (! _bfd_elf_maybe_strip_eh_frame_hdr (info))
-    return FALSE;
-
   dynobj = elf_hash_table (info)->dynobj;
 
-  /* If there were no dynamic objects in the link, there is nothing to
-     do here.  */
-  if (dynobj == NULL)
-    return TRUE;
-
-  if (elf_hash_table (info)->dynamic_sections_created)
+  if (dynobj != NULL && elf_hash_table (info)->dynamic_sections_created)
     {
       struct elf_info_failed eif;
       struct elf_link_hash_entry *h;
@@ -5897,11 +5889,15 @@ bfd_elf_size_dynamic_sections (bfd *outp
 
   /* The backend must work out the sizes of all the other dynamic
      sections.  */
-  if (bed->elf_backend_size_dynamic_sections
+  if (dynobj != NULL
+      && bed->elf_backend_size_dynamic_sections != NULL
       && ! (*bed->elf_backend_size_dynamic_sections) (output_bfd, info))
     return FALSE;
 
-  if (elf_hash_table (info)->dynamic_sections_created)
+  if (! _bfd_elf_maybe_strip_eh_frame_hdr (info))
+    return FALSE;
+
+  if (dynobj != NULL && elf_hash_table (info)->dynamic_sections_created)
     {
       unsigned long section_sym_count;
       struct bfd_elf_version_tree *verdefs;
@@ -12002,12 +11998,14 @@ bfd_elf_gc_sections (bfd *abfd, struct b
       struct elf_reloc_cookie cookie;
 
       sec = bfd_get_section_by_name (sub, ".eh_frame");
-      if (sec && init_reloc_cookie_for_section (&cookie, info, sec))
+      while (sec && init_reloc_cookie_for_section (&cookie, info, sec))
 	{
 	  _bfd_elf_parse_eh_frame (sub, info, sec, &cookie);
-	  if (elf_section_data (sec)->sec_info)
+	  if (elf_section_data (sec)->sec_info
+	      && (sec->flags & SEC_LINKER_CREATED) == 0)
 	    elf_eh_frame_section (sub) = sec;
 	  fini_reloc_cookie_for_section (&cookie, sec);
+	  sec = bfd_get_next_section_by_name (sec);
 	}
     }
   _bfd_elf_end_eh_frame_parsing (info);
Index: ld/emultempl/elf32.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/elf32.em,v
retrieving revision 1.227
diff -u -p -r1.227 elf32.em
--- ld/emultempl/elf32.em	16 May 2012 10:43:41 -0000	1.227
+++ ld/emultempl/elf32.em	23 May 2012 13:31:26 -0000
@@ -1142,10 +1142,11 @@ gld${EMULATION_NAME}_after_open (void)
 	  if (!warn_eh_frame)
 	    {
 	      s = bfd_get_section_by_name (abfd, ".eh_frame");
-	      warn_eh_frame
-		= (s
-		   && s->size > 8
-		   && !bfd_is_abs_section (s->output_section));
+	      while (s != NULL
+		     && (s->size <= 8
+			 || bfd_is_abs_section (s->output_section)))
+		s = bfd_get_next_section_by_name (s);
+	      warn_eh_frame = s != NULL;
 	    }
 	  if (elfbfd && warn_eh_frame)
 	    break;

-- 
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]