aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/ChangeLog9
-rw-r--r--bfd/elf-eh-frame.c20
-rw-r--r--bfd/elflink.c57
-rw-r--r--ld/ChangeLog5
-rw-r--r--ld/testsuite/ld-elf/eh3.d12
-rw-r--r--ld/testsuite/ld-elf/eh4.d4
6 files changed, 52 insertions, 55 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index edc447e..08dfa79 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,5 +1,14 @@
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
PR 22048
* elflink.c (bfd_elf_discard_info): Don't pad embedded zero
diff --git a/bfd/elf-eh-frame.c b/bfd/elf-eh-frame.c
index 7e0d63f..f0ede2d 100644
--- a/bfd/elf-eh-frame.c
+++ b/bfd/elf-eh-frame.c
@@ -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++;
diff --git a/bfd/elflink.c b/bfd/elflink.c
index f6f57fa..6008915 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -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);
diff --git a/ld/ChangeLog b/ld/ChangeLog
index 1dcb981..670f356 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -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'
diff --git a/ld/testsuite/ld-elf/eh3.d b/ld/testsuite/ld-elf/eh3.d
index 3811341..6ac584a 100644
--- a/ld/testsuite/ld-elf/eh3.d
+++ b/ld/testsuite/ld-elf/eh3.d
@@ -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
diff --git a/ld/testsuite/ld-elf/eh4.d b/ld/testsuite/ld-elf/eh4.d
index b5eec2f..6c1cb32 100644
--- a/ld/testsuite/ld-elf/eh4.d
+++ b/ld/testsuite/ld-elf/eh4.d
@@ -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