diff options
Diffstat (limited to 'src/elflint.c')
-rw-r--r-- | src/elflint.c | 57 |
1 files changed, 44 insertions, 13 deletions
diff --git a/src/elflint.c b/src/elflint.c index 7d72a1f7..eae77614 100644 --- a/src/elflint.c +++ b/src/elflint.c @@ -1,5 +1,5 @@ /* Pedantic checking of ELF files compliance with gABI/psABI spec. - Copyright (C) 2001-2014 Red Hat, Inc. + Copyright (C) 2001-2015 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 2001. @@ -380,9 +380,11 @@ check_elf_header (Ebl *ebl, GElf_Ehdr *ehdr, size_t size) ERROR (gettext ("unknown ELF header version number e_ident[%d] == %d\n"), EI_VERSION, ehdr->e_ident[EI_VERSION]); - /* We currently don't handle any OS ABIs other than Linux. */ + /* We currently don't handle any OS ABIs other than Linux and the + kFreeBSD variant of Debian. */ if (ehdr->e_ident[EI_OSABI] != ELFOSABI_NONE - && ehdr->e_ident[EI_OSABI] != ELFOSABI_LINUX) + && ehdr->e_ident[EI_OSABI] != ELFOSABI_LINUX + && ehdr->e_ident[EI_OSABI] != ELFOSABI_FREEBSD) ERROR (gettext ("unsupported OS ABI e_ident[%d] == '%s'\n"), EI_OSABI, ebl_osabi_name (ebl, ehdr->e_ident[EI_OSABI], buf, sizeof (buf))); @@ -801,7 +803,11 @@ section [%2d] '%s': symbol %zu: function in COMMON section is nonsense\n"), && strcmp (name, "__bss_start") != 0 && strcmp (name, "__bss_start__") != 0 && strcmp (name, "__TMC_END__") != 0 - && strcmp (name, ".TOC.") != 0)) + && strcmp (name, ".TOC.") != 0 + && strcmp (name, "_edata") != 0 + && strcmp (name, "__edata") != 0 + && strcmp (name, "_end") != 0 + && strcmp (name, "__end") != 0)) ERROR (gettext ("\ section [%2d] '%s': symbol %zu: st_value out of bounds\n"), idx, section_name (ebl, idx), cnt); @@ -2746,7 +2752,8 @@ section_flags_string (GElf_Word flags, char *buf, size_t len) NEWFLAG (LINK_ORDER), NEWFLAG (OS_NONCONFORMING), NEWFLAG (GROUP), - NEWFLAG (TLS) + NEWFLAG (TLS), + NEWFLAG (COMPRESSED) }; #undef NEWFLAG const size_t nknown_flags = sizeof (known_flags) / sizeof (known_flags[0]); @@ -3694,7 +3701,8 @@ zeroth section has nonzero link value while ELF header does not signal overflow size_t versym_scnndx = 0; for (size_t cnt = 1; cnt < shnum; ++cnt) { - shdr = gelf_getshdr (elf_getscn (ebl->elf, cnt), &shdr_mem); + Elf_Scn *scn = elf_getscn (ebl->elf, cnt); + shdr = gelf_getshdr (scn, &shdr_mem); if (shdr == NULL) { ERROR (gettext ("\ @@ -3744,9 +3752,11 @@ section [%2d] '%s' has wrong type: expected %s, is %s\n"), if (special_sections[s].attrflag == exact || special_sections[s].attrflag == exact_or_gnuld) { - /* Except for the link order and group bit all the - other bits should match exactly. */ - if ((shdr->sh_flags & ~(SHF_LINK_ORDER | SHF_GROUP)) + /* Except for the link order, group bit and + compression flag all the other bits should + match exactly. */ + if ((shdr->sh_flags + & ~(SHF_LINK_ORDER | SHF_GROUP | SHF_COMPRESSED)) != special_sections[s].attr && (special_sections[s].attrflag == exact || !gnuld)) ERROR (gettext ("\ @@ -3762,9 +3772,10 @@ section [%2zu] '%s' has wrong flags: expected %s, is %s\n"), { if ((shdr->sh_flags & special_sections[s].attr) != special_sections[s].attr - || ((shdr->sh_flags & ~(SHF_LINK_ORDER | SHF_GROUP - | special_sections[s].attr - | special_sections[s].attr2)) + || ((shdr->sh_flags + & ~(SHF_LINK_ORDER | SHF_GROUP | SHF_COMPRESSED + | special_sections[s].attr + | special_sections[s].attr2)) != 0)) ERROR (gettext ("\ section [%2zu] '%s' has wrong flags: expected %s and possibly %s, is %s\n"), @@ -3867,7 +3878,8 @@ section [%2zu] '%s': size not multiple of entry size\n"), #define ALL_SH_FLAGS (SHF_WRITE | SHF_ALLOC | SHF_EXECINSTR | SHF_MERGE \ | SHF_STRINGS | SHF_INFO_LINK | SHF_LINK_ORDER \ - | SHF_OS_NONCONFORMING | SHF_GROUP | SHF_TLS) + | SHF_OS_NONCONFORMING | SHF_GROUP | SHF_TLS \ + | SHF_COMPRESSED) if (shdr->sh_flags & ~(GElf_Xword) ALL_SH_FLAGS) { GElf_Xword sh_flags = shdr->sh_flags & ~(GElf_Xword) ALL_SH_FLAGS; @@ -3897,6 +3909,25 @@ section [%2zu] '%s': thread-local data sections address not zero\n"), // XXX TODO more tests!? } + if (shdr->sh_flags & SHF_COMPRESSED) + { + if (shdr->sh_flags & SHF_ALLOC) + ERROR (gettext ("\ +section [%2zu] '%s': allocated section cannot be compressed\n"), + cnt, section_name (ebl, cnt)); + + if (shdr->sh_type == SHT_NOBITS) + ERROR (gettext ("\ +section [%2zu] '%s': nobits section cannot be compressed\n"), + cnt, section_name (ebl, cnt)); + + GElf_Chdr chdr; + if (gelf_getchdr (scn, &chdr) == NULL) + ERROR (gettext ("\ +section [%2zu] '%s': compressed section with no compression header: %s\n"), + cnt, section_name (ebl, cnt), elf_errmsg (-1)); + } + if (shdr->sh_link >= shnum) ERROR (gettext ("\ section [%2zu] '%s': invalid section reference in link value\n"), |