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 Sat, Oct 04, 2003 at 12:01:56AM +0200, Jakub Jelinek wrote:
> 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.
> 
> Actually, I'm not sure about this:
> 
> struct dwarf_cie
> {
>   uword length;
>   sword CIE_id;
>   ubyte version;
>   unsigned char augmentation[];
> } __attribute__ ((packed, aligned (__alignof__ (void *))));
> 
> struct dwarf_fde
> {
>   uword length;
>   sword CIE_delta;
>   unsigned char pc_begin[];
> } __attribute__ ((packed, aligned (__alignof__ (void *))));
> 
> (current GCC, but used to be there in the GCC 2.x era too).
> 

In this case, I'd like to check in this patch first. We can optimize
it later.


H.J.
----
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
@@ -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]