diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2006-05-24 02:37:47 +0000 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2006-05-24 02:37:47 +0000 |
commit | a34a056a10ca131c7392436a957cdee41758fa95 (patch) | |
tree | f52ffe360bd91c8dd64690ed0f7750e9bec3b6f1 /bfd/elf-eh-frame.c | |
parent | a3ce7aa2eef9ceab3d5a80048ec8e9b3d921c0de (diff) | |
download | gdb-a34a056a10ca131c7392436a957cdee41758fa95.zip gdb-a34a056a10ca131c7392436a957cdee41758fa95.tar.gz gdb-a34a056a10ca131c7392436a957cdee41758fa95.tar.bz2 |
2006-05-23 H.J. Lu <hongjiu.lu@intel.com>
PR ld/2655
PR ld/2657
* elf-eh-frame.c (_bfd_elf_write_section_eh_frame): Properly
update CIE/FDE length. Don't pad to the section alignment.
Diffstat (limited to 'bfd/elf-eh-frame.c')
-rw-r--r-- | bfd/elf-eh-frame.c | 51 |
1 files changed, 12 insertions, 39 deletions
diff --git a/bfd/elf-eh-frame.c b/bfd/elf-eh-frame.c index 4f9ed4a..b430b8b 100644 --- a/bfd/elf-eh-frame.c +++ b/bfd/elf-eh-frame.c @@ -1075,12 +1075,12 @@ _bfd_elf_write_section_eh_frame (bfd *abfd, 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. It may be shrinked. */ + 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) { @@ -1262,40 +1262,13 @@ _bfd_elf_write_section_eh_frame (bfd *abfd, } } - { - unsigned int alignment = 1 << sec->alignment_power; - unsigned int pad = sec->size % alignment; - - /* Don't pad beyond the raw size of the output section. It - can happen at the last input section. */ - if (pad - && ((sec->output_offset + sec->size + pad) - <= sec->output_section->size)) - { - bfd_byte *buf; - unsigned int new_size; - - /* Find the last CIE/FDE. */ - ent = sec_info->entry + sec_info->count; - while (--ent != sec_info->entry) - if (!ent->removed) - break; - - /* The size of the last CIE/FDE must be at least 4. */ - if (ent->removed || ent->size < 4) - abort (); - - pad = alignment - pad; - buf = contents + ent->new_offset - sec->output_offset; - new_size = size_of_output_cie_fde (ent, ptr_size); - - /* Pad it with DW_CFA_nop */ - memset (buf + new_size, 0, pad); - bfd_put_32 (abfd, new_size + pad - 4, buf); - - sec->size += pad; - } - } + /* We don't align the section to its section alignment since the + runtime library only expects all CIE/FDE records aligned at + the pointer size. _bfd_elf_discard_section_eh_frame should + have padded CIE/FDE records to multiple of pointer size with + size_of_output_cie_fde. */ + if ((sec->size % ptr_size) != 0) + abort (); return bfd_set_section_contents (abfd, sec->output_section, contents, (file_ptr) sec->output_offset, |