From 9866ffe25a0fe73f5153f2720650baf0dd9cc828 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Thu, 31 Aug 2017 19:39:14 +0930 Subject: 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. --- bfd/elf-eh-frame.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) (limited to 'bfd/elf-eh-frame.c') 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++; -- cgit v1.1