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]

Don't use vma to identify eh_frame personality function


On Fri, Mar 14, 2014 at 11:58:42PM +1030, Alan Modra wrote:
> On Thu, Mar 13, 2014 at 10:32:18AM -0700, Roland McGrath wrote:
> > 		.cfi_startproc
> > 		.cfi_personality 0, pers
> > 		.cfi_endproc
> 
> Yes, the classic case of using an absolute encoding for a personality
> function.
> 
> > 	.globl pers
> > 	pers:
> > 	nop
> 
> And for two R_ARM_NONE, make pers hidden.  ;)
> 
> > It's no longer an urgent issue for me, but I think it deserves to be fixed.
> 
> To do that, we need to run the eh_frame parts of bfd_elf_discard_info
> before bfd_elf_size_dynamic_sections.  One of the keys to being able
> to do that is not using a vma anywhere in the eh_frame editing code,
> since at that stage we won't have laid out sections.

This is all we should need to be able to run the eh_frame parts of
bfd_elf_discard_info before bfd_elf_size_dynamic_sections.  Other
places in elf-eh-frame that use VMAs run after final section
placement.

I was intending to also make the discard_info changes but haven't
found time in the last month, so figure I ought to flush this patch
I've had sitting in my local tree for 6 weeks.

	* elf-eh-frame.c (struct cie.personality): Replace val with sym.
	(find_merged_cie): Identify personality functions by (bfd_id,index)
	pair when a local sym is used.

diff --git a/bfd/elf-eh-frame.c b/bfd/elf-eh-frame.c
index 8c3712f..0f0a563 100644
--- a/bfd/elf-eh-frame.c
+++ b/bfd/elf-eh-frame.c
@@ -40,7 +40,10 @@ struct cie
   bfd_vma augmentation_size;
   union {
     struct elf_link_hash_entry *h;
-    bfd_vma val;
+    struct {
+      unsigned int bfd_id;
+      unsigned int index;
+    } sym;
     unsigned int reloc_index;
   } personality;
   asection *output_sec;
@@ -1030,8 +1033,12 @@ find_merged_cie (bfd *abfd, struct bfd_link_info *info, asection *sec,
     {
       bfd_boolean per_binds_local;
 
-      /* Work out the address of personality routine, either as an absolute
-	 value or as a symbol.  */
+      /* Work out the address of personality routine, or at least
+	 enough info that we could calculate the address had we made a
+	 final section layout.  The symbol on the reloc is enough,
+	 either the hash for a global, or (bfd id, index) pair for a
+	 local.  The assumption here is that no one uses addends on
+	 the reloc.  */
       rel = cookie->rels + cie->personality.reloc_index;
       memset (&cie->personality, 0, sizeof (cie->personality));
 #ifdef BFD64
@@ -1071,9 +1078,8 @@ find_merged_cie (bfd *abfd, struct bfd_link_info *info, asection *sec,
 	    return cie_inf;
 
 	  cie->local_personality = 1;
-	  cie->personality.val = (sym->st_value
-				  + sym_sec->output_offset
-				  + sym_sec->output_section->vma);
+	  cie->personality.sym.bfd_id = abfd->id;
+	  cie->personality.sym.index = r_symndx;
 	  per_binds_local = TRUE;
 	}
 
-- 
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]