summaryrefslogtreecommitdiffstats
path: root/src/elflint.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/elflint.c')
-rw-r--r--src/elflint.c57
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"),