Remove .eh_frame zero terminators
The machinery to do this was there, but not enabled if the terminator was the only thing in the section. bfd/ * elf-eh-frame.c (_bfd_elf_parse_eh_frame): Don't exit early for a section containing just a terminator. Allow multiple terminators at end of section. * elflink.c (bfd_elf_discard_info): Iterate over .eh_frame sections when not adding alignment. Assert on terminator in the middle of FDEs. ld/ * testsuite/ld-elf/eh3.d: Update. * testsuite/ld-elf/eh4.d: Update.
This commit is contained in:
parent
654670a4f0
commit
9866ffe25a
6 changed files with 52 additions and 55 deletions
|
@ -1,3 +1,12 @@
|
|||
2017-08-31 Alan Modra <amodra@gmail.com>
|
||||
|
||||
* elf-eh-frame.c (_bfd_elf_parse_eh_frame): Don't exit early
|
||||
for a section containing just a terminator. Allow multiple
|
||||
terminators at end of section.
|
||||
* elflink.c (bfd_elf_discard_info): Iterate over .eh_frame
|
||||
sections when not adding alignment. Assert on terminator in
|
||||
the middle of FDEs.
|
||||
|
||||
2017-08-31 Alan Modra <amodra@gmail.com>
|
||||
|
||||
PR 21441
|
||||
|
|
|
@ -619,15 +619,6 @@ _bfd_elf_parse_eh_frame (bfd *abfd, struct bfd_link_info *info,
|
|||
|
||||
REQUIRE (bfd_malloc_and_get_section (abfd, sec, &ehbuf));
|
||||
|
||||
if (sec->size >= 4
|
||||
&& bfd_get_32 (abfd, ehbuf) == 0
|
||||
&& cookie->rel == cookie->relend)
|
||||
{
|
||||
/* Empty .eh_frame section. */
|
||||
free (ehbuf);
|
||||
return;
|
||||
}
|
||||
|
||||
/* If .eh_frame section size doesn't fit into int, we cannot handle
|
||||
it (it would need to use 64-bit .eh_frame format anyway). */
|
||||
REQUIRE (sec->size == (unsigned int) sec->size);
|
||||
|
@ -669,8 +660,11 @@ _bfd_elf_parse_eh_frame (bfd *abfd, struct bfd_link_info *info,
|
|||
REQUIRE (sec_info);
|
||||
|
||||
/* We need to have a "struct cie" for each CIE in this section. */
|
||||
local_cies = (struct cie *) bfd_zmalloc (num_cies * sizeof (*local_cies));
|
||||
REQUIRE (local_cies);
|
||||
if (num_cies)
|
||||
{
|
||||
local_cies = (struct cie *) bfd_zmalloc (num_cies * sizeof (*local_cies));
|
||||
REQUIRE (local_cies);
|
||||
}
|
||||
|
||||
/* FIXME: octets_per_byte. */
|
||||
#define ENSURE_NO_RELOCS(buf) \
|
||||
|
@ -724,7 +718,9 @@ _bfd_elf_parse_eh_frame (bfd *abfd, struct bfd_link_info *info,
|
|||
if (hdr_length == 0)
|
||||
{
|
||||
/* A zero-length CIE should only be found at the end of
|
||||
the section. */
|
||||
the section, but allow multiple terminators. */
|
||||
while (skip_bytes (&buf, ehbuf + sec->size, 4))
|
||||
REQUIRE (bfd_get_32 (abfd, buf - 4) == 0);
|
||||
REQUIRE ((bfd_size_type) (buf - ehbuf) == sec->size);
|
||||
ENSURE_NO_RELOCS (buf);
|
||||
sec_info->count++;
|
||||
|
|
|
@ -13862,39 +13862,36 @@ bfd_elf_discard_info (bfd *output_bfd, struct bfd_link_info *info)
|
|||
|
||||
fini_reloc_cookie_for_section (&cookie, i);
|
||||
}
|
||||
|
||||
eh_alignment = 1 << o->alignment_power;
|
||||
if (eh_alignment > 4)
|
||||
{
|
||||
/* Skip over zero terminator, and prevent empty sections
|
||||
from adding alignment padding at the end. */
|
||||
for (i = o->map_tail.s; i != NULL; i = i->map_tail.s)
|
||||
if (i->size == 0)
|
||||
i->flags |= SEC_EXCLUDE;
|
||||
else if (i->size > 4)
|
||||
break;
|
||||
/* The last non-empty eh_frame section doesn't need padding. */
|
||||
if (i != NULL)
|
||||
i = i->map_tail.s;
|
||||
/* Any prior sections must pad the last FDE out to the
|
||||
output section alignment. Otherwise we might have zero
|
||||
padding between sections, which would be seen as a
|
||||
terminator. If there is a terminator in the middle of
|
||||
FDEs, don't increase its size as that will write bogus
|
||||
data of whatever was after the terminator in the input
|
||||
file, to the output file. */
|
||||
for (; i != NULL; i = i->map_tail.s)
|
||||
if (i->size != 4)
|
||||
/* Skip over zero terminator, and prevent empty sections from
|
||||
adding alignment padding at the end. */
|
||||
for (i = o->map_tail.s; i != NULL; i = i->map_tail.s)
|
||||
if (i->size == 0)
|
||||
i->flags |= SEC_EXCLUDE;
|
||||
else if (i->size > 4)
|
||||
break;
|
||||
/* The last non-empty eh_frame section doesn't need padding. */
|
||||
if (i != NULL)
|
||||
i = i->map_tail.s;
|
||||
/* Any prior sections must pad the last FDE out to the output
|
||||
section alignment. Otherwise we might have zero padding
|
||||
between sections, which would be seen as a terminator. */
|
||||
for (; i != NULL; i = i->map_tail.s)
|
||||
if (i->size == 4)
|
||||
/* All but the last zero terminator should have been removed. */
|
||||
BFD_FAIL ();
|
||||
else
|
||||
{
|
||||
bfd_size_type size
|
||||
= (i->size + eh_alignment - 1) & -eh_alignment;
|
||||
if (i->size != size)
|
||||
{
|
||||
bfd_size_type size
|
||||
= (i->size + eh_alignment - 1) & -eh_alignment;
|
||||
if (i->size != size)
|
||||
{
|
||||
i->size = size;
|
||||
changed = 1;
|
||||
eh_changed = 1;
|
||||
}
|
||||
i->size = size;
|
||||
changed = 1;
|
||||
eh_changed = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (eh_changed)
|
||||
elf_link_hash_traverse (elf_hash_table (info),
|
||||
_bfd_elf_adjust_eh_frame_global_symbol, NULL);
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2017-08-31 Alan Modra <amodra@gmail.com>
|
||||
|
||||
* testsuite/ld-elf/eh3.d: Update.
|
||||
* testsuite/ld-elf/eh4.d: Update.
|
||||
|
||||
2017-08-30 Maciej W. Rozycki <macro@imgtec.com>
|
||||
|
||||
* testsuite/ld-elf/orphan-11.ld: Also discard `.MIPS.options'
|
||||
|
|
|
@ -23,20 +23,12 @@ Contents of the .eh_frame section:
|
|||
DW_CFA_nop
|
||||
DW_CFA_nop
|
||||
|
||||
0+0018 0+0024 0+001c FDE cie=0+0000 pc=0+400078\.\.0+400090
|
||||
0+0018 0+001c 0+001c FDE cie=0+0000 pc=0+400078\.\.0+400090
|
||||
DW_CFA_advance_loc: 8 to 0+400080
|
||||
DW_CFA_def_cfa_offset: 16
|
||||
DW_CFA_offset: r6 \(rbp\) at cfa-16
|
||||
DW_CFA_advance_loc: 8 to 0+400088
|
||||
DW_CFA_def_cfa_register: r6 \(rbp\)
|
||||
DW_CFA_nop
|
||||
DW_CFA_nop
|
||||
DW_CFA_nop
|
||||
DW_CFA_nop
|
||||
DW_CFA_nop
|
||||
DW_CFA_nop
|
||||
DW_CFA_nop
|
||||
DW_CFA_nop
|
||||
|
||||
0+0040 ZERO terminator
|
||||
0+0038 ZERO terminator
|
||||
#pass
|
||||
|
|
|
@ -28,14 +28,12 @@ Contents of the .eh_frame section:
|
|||
DW_CFA_set_loc: 0+0417
|
||||
DW_CFA_def_cfa_offset: 80
|
||||
|
||||
0+0048 0+0024 0+004c FDE cie=0+0000 pc=[0-9a-f]+\.\.[0-9a-f]+
|
||||
0+0048 0+002[04] 0+004c FDE cie=0+0000 pc=[0-9a-f]+\.\.[0-9a-f]+
|
||||
DW_CFA_def_cfa_offset: 16
|
||||
DW_CFA_advance_loc: [0-9a-f]+ to [0-9a-f]+
|
||||
DW_CFA_def_cfa_offset: 24
|
||||
DW_CFA_advance_loc: [0-9a-f]+ to [0-9a-f]+
|
||||
DW_CFA_def_cfa_expression \(DW_OP_breg7 \(rsp\): 8; DW_OP_breg16 \(rip\): 0;.*
|
||||
DW_CFA_nop
|
||||
#...
|
||||
|
||||
[0-9a-f]+ ZERO terminator
|
||||
#pass
|
||||
|
|
Loading…
Add table
Reference in a new issue