diff options
Diffstat (limited to 'bfd/elf-eh-frame.c')
-rw-r--r-- | bfd/elf-eh-frame.c | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/bfd/elf-eh-frame.c b/bfd/elf-eh-frame.c index 78b3ecb..4eda3c9 100644 --- a/bfd/elf-eh-frame.c +++ b/bfd/elf-eh-frame.c @@ -737,6 +737,7 @@ _bfd_elf_parse_eh_frame (bfd *abfd, struct bfd_link_info *info, if (hdr_id == 0) { unsigned int initial_insn_length; + char *null_byte; /* CIE */ this_inf->cie = 1; @@ -753,10 +754,14 @@ _bfd_elf_parse_eh_frame (bfd *abfd, struct bfd_link_info *info, REQUIRE (cie->version == 1 || cie->version == 3 || cie->version == 4); - REQUIRE (strlen ((char *) buf) < sizeof (cie->augmentation)); + null_byte = memchr ((char *) buf, 0, end - buf); + REQUIRE (null_byte != NULL); + REQUIRE ((size_t) (null_byte - (char *) buf) + < sizeof (cie->augmentation)); strcpy (cie->augmentation, (char *) buf); - buf = (bfd_byte *) strchr ((char *) buf, '\0') + 1; + buf = (bfd_byte *) null_byte + 1; + REQUIRE (buf + 1 < end); this_inf->u.cie.aug_str_len = buf - start - 1; ENSURE_NO_RELOCS (buf); if (buf[0] == 'e' && buf[1] == 'h') @@ -802,6 +807,9 @@ _bfd_elf_parse_eh_frame (bfd *abfd, struct bfd_link_info *info, switch (*aug++) { case 'B': + case 'G': + if (abfd->arch_info->arch != bfd_arch_aarch64) + goto unrecognized; break; case 'L': REQUIRE (read_byte (&buf, end, &cie->lsda_encoding)); @@ -843,6 +851,7 @@ _bfd_elf_parse_eh_frame (bfd *abfd, struct bfd_link_info *info, REQUIRE (skip_bytes (&buf, end, per_width)); } break; + unrecognized: default: /* Unrecognized augmentation. Better bail out. */ goto free_no_table; @@ -2506,7 +2515,7 @@ write_dwarf_eh_frame_hdr (bfd *abfd, struct bfd_link_info *info) /* FIXME: octets_per_byte. */ if (!bfd_set_section_contents (abfd, sec->output_section, contents, (file_ptr) sec->output_offset, - sec->size)) + size)) retval = false; out: free (contents); |