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]

[PATCH 5/7] Fix --gc-sections for C++ MIPS ELF


This patch and the next one reorganise eh_cie_fde so that the CIE-specific
flags are in the new u.cie structure.  I've split them up because this
first one is more involved, and it's quite likely I'm missing something.
(It's also a prerequisite for removing offsets_adjusted, because I'm
getting rid of one of the checks here.)

We currently have two flags: make_lsda_relative, which says that we
can make LSDA relocations relative if want to, and need_lsda_relative,
which says that we've decided to do that.  We need two fields in case
the LSDA is not a pointer:

     http://sourceware.org/ml/binutils/2004-09/msg00313.html

We set need_lsda_relative based on make_lsda_relative in
_bfd_elf_eh_frame_section_offset, but could we do it when
parsing the section instead?  The original patch linked
above used a make/need_* pair for make_relative as well as
make_lsda_relative, whereas we've now dropped need_relative.
This is now the only case where _bfd_elf_eh_frame_section_offset
changes the CIE and FDE information.

Richard


bfd/
	* elf-bfd.h (eh_cie_fde): Remove need_lsda_relative.
	Move make_lsda_relative to u.cie.
	* elf-eh-frame.c (cie): Rename make_lsda_relative to
	can_make_lsda_relative.
	(_bfd_elf_parse_eh_frame): Don't set the old eh_cie_fde
	make_lsda_relative field.  Update after cie renaming.
	Set u.cie.make_lsda_relative if can_make_lsda_relative
	and if we find a relocation against the LSDA.
	(_bfd_elf_discard_section_eh_frame): Copy make_lsda_relative when
	changing a CIE's group representative.
	(_bfd_elf_eh_frame_section_offset): Don't set need_ldsa_relative here.
	(_bfd_elf_write_section_eh_frame): Check u.cie.make_lsda_relative
	rather than need_lsda_relative.

Index: bfd/elf-bfd.h
===================================================================
--- bfd/elf-bfd.h	2007-12-02 17:22:22.000000000 +0000
+++ bfd/elf-bfd.h	2007-12-02 17:40:41.000000000 +0000
@@ -285,6 +285,11 @@ struct eh_cie_fde
 
       /* True if we have marked relocations associated with this CIE.  */
       unsigned int gc_mark : 1;
+
+      /* True if we have decided to turn an absolute LSDA encoding into
+	 a PC-relative one.  It is the group representative's setting
+	 that matters.  */
+      unsigned int make_lsda_relative : 1;
     } cie;
   } u;
   unsigned int reloc_index;
@@ -299,8 +304,6 @@ struct eh_cie_fde
   unsigned int add_augmentation_size : 1;
   unsigned int add_fde_encoding : 1;
   unsigned int make_relative : 1;
-  unsigned int make_lsda_relative : 1;
-  unsigned int need_lsda_relative : 1;
   unsigned int per_encoding_relative : 1;
   unsigned int *set_loc;
 };
Index: bfd/elf-eh-frame.c
===================================================================
--- bfd/elf-eh-frame.c	2007-12-02 17:26:13.000000000 +0000
+++ bfd/elf-eh-frame.c	2007-12-02 17:41:29.000000000 +0000
@@ -50,7 +50,7 @@ struct cie
   unsigned char fde_encoding;
   unsigned char initial_insn_length;
   unsigned char make_relative;
-  unsigned char make_lsda_relative;
+  unsigned char can_make_lsda_relative;
   unsigned char initial_instructions[50];
 };
 
@@ -799,7 +799,7 @@ #define GET_RELOC(buf)					\
 		  ->elf_backend_can_make_lsda_relative_eh_frame
 		  (abfd, info, sec))
 	      && (cie->lsda_encoding & 0xf0) == DW_EH_PE_absptr)
-	    cie->make_lsda_relative = 1;
+	    cie->can_make_lsda_relative = 1;
 
 	  /* If FDE encoding was not specified, it defaults to
 	     DW_EH_absptr.  */
@@ -817,7 +817,6 @@ #define GET_RELOC(buf)					\
 	  ENSURE_NO_RELOCS (buf);
 
 	  this_inf->make_relative = cie->make_relative;
-	  this_inf->make_lsda_relative = cie->make_lsda_relative;
 	  this_inf->per_encoding_relative
 	    = (cie->per_encoding & 0x70) == DW_EH_PE_pcrel;
 	}
@@ -862,6 +861,9 @@ #define GET_RELOC(buf)					\
 	     be adjusted if any future augmentations do the same thing.  */
 	  if (cie->lsda_encoding != DW_EH_PE_omit)
 	    {
+	      SKIP_RELOCS (buf);
+	      if (cie->can_make_lsda_relative && GET_RELOC (buf))
+		cie->cie_inf->u.cie.make_lsda_relative = 1;
 	      this_inf->lsda_offset = buf - start;
 	      /* If there's no 'z' augmentation, we don't know where the
 		 CFA insns begin.  Assume no padding.  */
@@ -1097,6 +1099,8 @@ _bfd_elf_gc_mark_fdes (struct bfd_link_i
 		    /* Make the local CIE represent the merged group.  */
 		    merged->u.cie.merged = cie;
 		    cie->removed = 0;
+		    cie->u.cie.make_lsda_relative
+		      = merged->u.cie.make_lsda_relative;
 		  }
 	      }
 	  }
@@ -1248,15 +1252,10 @@ _bfd_elf_eh_frame_section_offset (bfd *o
   /* If converting LSDA pointers to DW_EH_PE_pcrel, there will be no need
      for run-time relocation against LSDA field.  */
   if (!sec_info->entry[mid].cie
-      && sec_info->entry[mid].u.fde.cie_inf->make_lsda_relative
-      && (offset == (sec_info->entry[mid].offset + 8
-		     + sec_info->entry[mid].lsda_offset))
-      && (sec_info->entry[mid].u.fde.cie_inf->need_lsda_relative
-	  || !hdr_info->offsets_adjusted))
-    {
-      sec_info->entry[mid].u.fde.cie_inf->need_lsda_relative = 1;
-      return (bfd_vma) -2;
-    }
+      && sec_info->entry[mid].u.fde.cie_inf->u.cie.make_lsda_relative
+      && offset == (sec_info->entry[mid].offset + 8
+		    + sec_info->entry[mid].lsda_offset))
+    return (bfd_vma) -2;
 
   /* If converting to DW_EH_PE_pcrel, there will be no need for run-time
      relocation against DW_CFA_set_loc's arguments.  */
@@ -1394,7 +1393,7 @@ _bfd_elf_write_section_eh_frame (bfd *ab
 	{
 	  /* CIE */
 	  if (ent->make_relative
-	      || ent->need_lsda_relative
+	      || ent->u.cie.make_lsda_relative
 	      || ent->per_encoding_relative)
 	    {
 	      char *aug;
@@ -1404,7 +1403,7 @@ _bfd_elf_write_section_eh_frame (bfd *ab
 	      /* Need to find 'R' or 'L' augmentation's argument and modify
 		 DW_EH_PE_* value.  */
 	      action = ((ent->make_relative ? 1 : 0)
-			| (ent->need_lsda_relative ? 2 : 0)
+			| (ent->u.cie.make_lsda_relative ? 2 : 0)
 			| (ent->per_encoding_relative ? 4 : 0));
 	      extra_string = extra_augmentation_string_bytes (ent);
 	      extra_data = extra_augmentation_data_bytes (ent);
@@ -1548,7 +1547,7 @@ _bfd_elf_write_section_eh_frame (bfd *ab
 	    }
 
 	  if ((ent->lsda_encoding & 0xf0) == DW_EH_PE_pcrel
-	      || cie->need_lsda_relative)
+	      || cie->u.cie.make_lsda_relative)
 	    {
 	      buf += ent->lsda_offset;
 	      width = get_DW_EH_PE_width (ent->lsda_encoding, ptr_size);
@@ -1558,7 +1557,7 @@ _bfd_elf_write_section_eh_frame (bfd *ab
 		{
 		  if ((ent->lsda_encoding & 0xf0) == DW_EH_PE_pcrel)
 		    value += ent->offset - ent->new_offset;
-		  else if (cie->need_lsda_relative)
+		  else if (cie->u.cie.make_lsda_relative)
 		    value -= (sec->output_section->vma + ent->new_offset + 8
 			      + ent->lsda_offset);
 		  write_value (abfd, buf, value, width);


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