X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=bfd%2Felf.c;h=d3e391e182810ef8182ff0162d04bd801ea99cb1;hb=0e41bebb938dbe9eae7063f5321429194bfc5ab7;hp=764c61f04458a790ff2cc85440964ae7c5eabe6d;hpb=ac85e67c053f1555def2c111962f4e68740794f9;p=binutils-gdb.git diff --git a/bfd/elf.c b/bfd/elf.c index 764c61f0445..d3e391e1828 100644 --- a/bfd/elf.c +++ b/bfd/elf.c @@ -35,6 +35,7 @@ SECTION /* For sparc64-cross-sparc32. */ #define _SYSCALL32 #include "sysdep.h" +#include #include "bfd.h" #include "bfdlink.h" #include "libbfd.h" @@ -1177,11 +1178,12 @@ _bfd_elf_make_section_from_shdr (bfd *abfd, enum { nothing, compress, decompress } action = nothing; int compression_header_size; bfd_size_type uncompressed_size; + unsigned int uncompressed_align_power; bfd_boolean compressed = bfd_is_section_compressed_with_header (abfd, newsect, &compression_header_size, - &uncompressed_size); - + &uncompressed_size, + &uncompressed_align_power); if (compressed) { /* Compressed section. Check if we should decompress. */ @@ -2384,15 +2386,18 @@ bfd_section_from_shdr (bfd *abfd, unsigned int shindex) && ! bfd_section_from_shdr (abfd, hdr->sh_link)) goto fail; - /* If this reloc section does not use the main symbol table we - don't treat it as a reloc section. BFD can't adequately - represent such a section, so at least for now, we don't - try. We just present it as a normal section. We also - can't use it as a reloc section if it points to the null - section, an invalid section, another reloc section, or its - sh_link points to the null section. */ - if (hdr->sh_link != elf_onesymtab (abfd) + /* If this is an alloc section in an executable or shared + library, or the reloc section does not use the main symbol + table we don't treat it as a reloc section. BFD can't + adequately represent such a section, so at least for now, + we don't try. We just present it as a normal section. We + also can't use it as a reloc section if it points to the + null section, an invalid section, another reloc section, or + its sh_link points to the null section. */ + if (((abfd->flags & (DYNAMIC | EXEC_P)) != 0 + && (hdr->sh_flags & SHF_ALLOC) != 0) || hdr->sh_link == SHN_UNDEF + || hdr->sh_link != elf_onesymtab (abfd) || hdr->sh_info == SHN_UNDEF || hdr->sh_info >= num_sec || elf_elfsections (abfd)[hdr->sh_info]->sh_type == SHT_REL @@ -3122,7 +3127,7 @@ _bfd_elf_init_reloc_shdr (bfd *abfd, int bfd_elf_get_default_section_type (flagword flags) { - if ((flags & SEC_ALLOC) != 0 + if ((flags & (SEC_ALLOC | SEC_IS_COMMON)) != 0 && (flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0) return SHT_NOBITS; return SHT_PROGBITS; @@ -4368,6 +4373,14 @@ get_program_header_size (bfd *abfd, struct bfd_link_info *info) ++segs; } + s = bfd_get_section_by_name (abfd, + NOTE_GNU_PROPERTY_SECTION_NAME); + if (s != NULL && s->size != 0) + { + /* We need a PT_GNU_PROPERTY segment. */ + ++segs; + } + for (s = abfd->sections; s != NULL; s = s->next) { if ((s->flags & SEC_LOAD) != 0 @@ -5051,6 +5064,24 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info) pm = &m->next; } + s = bfd_get_section_by_name (abfd, + NOTE_GNU_PROPERTY_SECTION_NAME); + if (s != NULL && s->size != 0) + { + amt = sizeof (struct elf_segment_map) + sizeof (asection *); + m = bfd_zalloc (abfd, amt); + if (m == NULL) + goto error_return; + m->next = NULL; + m->p_type = PT_GNU_PROPERTY; + m->count = 1; + m->p_flags_valid = 1; + m->sections[0] = s; + m->p_flags = PF_R; + *pm = m; + pm = &m->next; + } + /* If there is a .eh_frame_hdr section, throw in a PT_GNU_EH_FRAME segment. */ eh_frame_hdr = elf_eh_frame_hdr (abfd); @@ -6640,6 +6671,7 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd) the given segment. LMA addresses are compared. */ #define IS_CONTAINED_BY_LMA(section, segment, base) \ (section->lma >= base \ + && (section->lma + SECTION_SIZE (section, segment) >= section->lma) \ && (section->lma + SECTION_SIZE (section, segment) \ <= SEGMENT_END (segment, base))) @@ -7163,7 +7195,15 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd) suggested_lma = output_section; } - BFD_ASSERT (map->count > 0); + /* PR 23932. A corrupt input file may contain sections that cannot + be assigned to any segment - because for example they have a + negative size - or segments that do not contain any sections. */ + if (map->count == 0) + { + bfd_set_error (bfd_error_bad_value); + free (sections); + return FALSE; + } /* Add the current segment to the list of built segments. */ *pointer_to_map = map; @@ -8176,11 +8216,16 @@ error_return: long _bfd_elf_get_symtab_upper_bound (bfd *abfd) { - long symcount; + bfd_size_type symcount; long symtab_size; Elf_Internal_Shdr *hdr = &elf_tdata (abfd)->symtab_hdr; symcount = hdr->sh_size / get_elf_backend_data (abfd)->s->sizeof_sym; + if (symcount >= LONG_MAX / sizeof (asymbol *)) + { + bfd_set_error (bfd_error_file_too_big); + return -1; + } symtab_size = (symcount + 1) * (sizeof (asymbol *)); if (symcount > 0) symtab_size -= sizeof (asymbol *); @@ -8191,7 +8236,7 @@ _bfd_elf_get_symtab_upper_bound (bfd *abfd) long _bfd_elf_get_dynamic_symtab_upper_bound (bfd *abfd) { - long symcount; + bfd_size_type symcount; long symtab_size; Elf_Internal_Shdr *hdr = &elf_tdata (abfd)->dynsymtab_hdr; @@ -8202,6 +8247,11 @@ _bfd_elf_get_dynamic_symtab_upper_bound (bfd *abfd) } symcount = hdr->sh_size / get_elf_backend_data (abfd)->s->sizeof_sym; + if (symcount >= LONG_MAX / sizeof (asymbol *)) + { + bfd_set_error (bfd_error_file_too_big); + return -1; + } symtab_size = (symcount + 1) * (sizeof (asymbol *)); if (symcount > 0) symtab_size -= sizeof (asymbol *); @@ -8271,7 +8321,7 @@ _bfd_elf_canonicalize_dynamic_symtab (bfd *abfd, long _bfd_elf_get_dynamic_reloc_upper_bound (bfd *abfd) { - long ret; + bfd_size_type count; asection *s; if (elf_dynsymtab (abfd) == 0) @@ -8280,15 +8330,20 @@ _bfd_elf_get_dynamic_reloc_upper_bound (bfd *abfd) return -1; } - ret = sizeof (arelent *); + count = 1; for (s = abfd->sections; s != NULL; s = s->next) if (elf_section_data (s)->this_hdr.sh_link == elf_dynsymtab (abfd) && (elf_section_data (s)->this_hdr.sh_type == SHT_REL || elf_section_data (s)->this_hdr.sh_type == SHT_RELA)) - ret += ((s->size / elf_section_data (s)->this_hdr.sh_entsize) - * sizeof (arelent *)); - - return ret; + { + count += s->size / elf_section_data (s)->this_hdr.sh_entsize; + if (count > LONG_MAX / sizeof (arelent *)) + { + bfd_set_error (bfd_error_file_too_big); + return -1; + } + } + return count * sizeof (arelent *); } /* Canonicalize the dynamic relocation entries. Note that we return the