This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
PATCH: PR ld/2655/2657: Incorrrect padding for .eh_frame section
- From: "H. J. Lu" <hjl at lucon dot org>
- To: binutils at sources dot redhat dot com
- Cc: richard at codesourcery dot com
- Date: Fri, 12 May 2006 13:54:13 -0700
- Subject: PATCH: PR ld/2655/2657: Incorrrect padding for .eh_frame section
- References: <20060512170511.GA30942@lucon.org>
On Fri, May 12, 2006 at 10:05:12AM -0700, H. J. Lu wrote:
> Hi Richard,
>
> Your patch:
>
> http://sourceware.org/ml/binutils/2004-11/msg00226.html
>
> assumes that CIE/FDE are aligned at the pointer size. But it isn't
> necessarily true. See
>
> http://sources.redhat.com/bugzilla/show_bug.cgi?id=2657
>
This patch fixes 2 PRs 2655/2657. PR 2655 is a gcc bug
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=27576
PR 2657 is we don't properly shrink CIE/FDE.
H.J.
-----
2006-05-12 H.J. Lu <hongjiu.lu@intel.com>
PR ld/2657
* elf-eh-frame.c (_bfd_elf_write_section_eh_frame): Properly
update CIE/FDE length.
PR ld/2655
* elf.c (_bfd_elf_make_section_from_shdr): Enforce pointer
alignment on .eh_frame sections.
--- bfd/elf-eh-frame.c.eh 2006-05-02 06:49:58.000000000 -0700
+++ bfd/elf-eh-frame.c 2006-05-12 12:30:12.000000000 -0700
@@ -1075,12 +1075,14 @@ _bfd_elf_write_section_eh_frame (bfd *ab
end = buf + ent->size;
new_size = size_of_output_cie_fde (ent, ptr_size);
- /* Install the new size, filling the extra bytes with DW_CFA_nops. */
+ /* Update the size. We may have shrinked it. */
+ bfd_put_32 (abfd, new_size - 4, buf);
+
+ /* Filling the extra bytes with DW_CFA_nops. */
if (new_size != ent->size)
- {
- memset (end, 0, new_size - ent->size);
- bfd_put_32 (abfd, new_size - 4, buf);
- }
+ memset (end, 0, new_size - ent->size);
+
+
if (ent->cie)
{
--- bfd/elf.c.eh 2006-05-11 09:26:36.000000000 -0700
+++ bfd/elf.c 2006-05-12 11:26:19.000000000 -0700
@@ -731,6 +731,7 @@ _bfd_elf_make_section_from_shdr (bfd *ab
{
asection *newsect;
flagword flags;
+ bfd_vma alignment;
const struct elf_backend_data *bed;
if (hdr->bfd_section != NULL)
@@ -754,10 +755,24 @@ _bfd_elf_make_section_from_shdr (bfd *ab
newsect->filepos = hdr->sh_offset;
+ bed = get_elf_backend_data (abfd);
+
+ alignment = hdr->sh_addralign;
+ if (hdr->sh_type == SHT_PROGBITS && strcmp (name, ".eh_frame") == 0)
+ {
+ /* The .eh_frame sections in crtend.o from gcc on 64bit targets
+ may be aligned at 4 byte. But the runtime library and linker
+ expect it is aligned at 8. We adjust the section alignment if
+ it is too small. PR 2655. */
+ bfd_vma eh_frame_alignment = bed->s->arch_size / 8;
+ if (alignment < eh_frame_alignment)
+ alignment = eh_frame_alignment;
+ }
+
if (! bfd_set_section_vma (abfd, newsect, hdr->sh_addr)
|| ! bfd_set_section_size (abfd, newsect, hdr->sh_size)
|| ! bfd_set_section_alignment (abfd, newsect,
- bfd_log2 ((bfd_vma) hdr->sh_addralign)))
+ bfd_log2 (alignment)))
return FALSE;
flags = SEC_NO_FLAGS;
@@ -840,7 +855,6 @@ _bfd_elf_make_section_from_shdr (bfd *ab
&& elf_next_in_group (newsect) == NULL)
flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
- bed = get_elf_backend_data (abfd);
if (bed->elf_backend_section_flags)
if (! bed->elf_backend_section_flags (&flags, hdr))
return FALSE;