This is the mail archive of the binutils@sources.redhat.com 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: Re: EH frame optimization bug


On Fri, Oct 03, 2003 at 04:04:53PM -0700, Richard Henderson wrote:
> On Fri, Oct 03, 2003 at 01:05:11PM -0700, H. J. Lu wrote:
> > Does unwind routine have any alignment requirement?
> 
> No.
> 

Then. Can we apply this patch?


H.J.
---
2003-10-03  Jakub Jelinek  <jakub@redhat.com>

	* elf-eh-frame.c (_bfd_elf_discard_section_eh_frame): If .eh_frame
	section doesn't use "eh" CIEs nor DW_EH_PE_aligned encoding,
	decrease section alignment to byte alignment.

2003-10-03  H.J. Lu  <hongjiu.lu@intel.com>

	* elf-eh-frame.c (_bfd_elf_write_section_eh_frame): Pad the
	last CIE/FDE if needed.

--- bfd/elf-eh-frame.c.pad	2003-08-07 09:04:30.000000000 -0700
+++ bfd/elf-eh-frame.c	2003-10-03 16:38:17.000000000 -0700
@@ -223,6 +223,7 @@ _bfd_elf_discard_section_eh_frame
   unsigned int make_relative, make_lsda_relative;
   bfd_size_type new_size;
   unsigned int ptr_size;
+  bfd_boolean needs_alignment = FALSE;
 
   if (sec->_raw_size == 0)
     {
@@ -256,6 +257,11 @@ _bfd_elf_discard_section_eh_frame
     {
       /* Empty .eh_frame section.  */
       free (ehbuf);
+      if (hdr_info->table && sec->alignment_power)
+	{
+	  sec->alignment_power = 0;
+	  return TRUE;
+	}
       return FALSE;
     }
 
@@ -423,6 +429,7 @@ _bfd_elf_discard_section_eh_frame
 		 Just skip it.  */
 	      buf += ptr_size;
 	      SKIP_RELOCS (buf);
+	      needs_alignment = TRUE;
 	    }
 	  read_uleb128 (cie.code_align, buf);
 	  read_sleb128 (cie.data_align, buf);
@@ -527,6 +534,11 @@ _bfd_elf_discard_section_eh_frame
 	  if (cie.fde_encoding == DW_EH_PE_omit)
 	    cie.fde_encoding = DW_EH_PE_absptr;
 
+	  if (cie.fde_encoding == DW_EH_PE_aligned
+	      || cie.lsda_encoding == DW_EH_PE_aligned
+	      || cie.per_encoding == DW_EH_PE_aligned)
+	    needs_alignment = TRUE;
+
 	  initial_insn_length = cie.hdr.length - (buf - last_fde - 4);
 	  if (initial_insn_length <= 50)
 	    {
@@ -644,6 +656,11 @@ _bfd_elf_discard_section_eh_frame
     sec->flags |= SEC_EXCLUDE;
 
   free (ehbuf);
+  if (!needs_alignment && sec->alignment_power)
+    {
+      sec->alignment_power = 0;
+      return TRUE;
+    }
   return new_size != sec->_raw_size;
 
 free_no_table:
@@ -1026,6 +1043,38 @@ _bfd_elf_write_section_eh_frame (bfd *ab
 					   and 3xDW_CFA_nop as pad  */
       p += 16;
     }
+  else
+    {
+      unsigned int alignment = 1 << sec->alignment_power;
+      unsigned int pad = sec->_cooked_size % alignment;
+
+      if (pad)
+	{
+	  /* Find the last CIE/FDE.  */
+	  for (i = sec_info->count - 1; i > 0; i--)
+	    if (! sec_info->entry[i].removed)
+	      break;
+
+	  /* The size of the last CIE/FDE must be at least 4.  */
+	  if (sec_info->entry[i].removed
+	      || sec_info->entry[i].size < 4)
+	    abort ();
+
+	  pad = alignment - pad;
+
+	  buf = contents + sec_info->entry[i].new_offset;
+
+	  /* Update length.  */
+	  sec_info->entry[i].size += pad;
+	  bfd_put_32 (abfd, sec_info->entry[i].size - 4, buf);
+
+	  /* Pad it with DW_CFA_nop  */
+	  memset (p, 0, pad);
+	  p += pad;
+
+	  sec->_cooked_size += pad;
+	}
+    }
 
   BFD_ASSERT ((bfd_size_type) (p - contents) == sec->_cooked_size);
 


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