summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Wielaard <mjw@redhat.com>2015-12-18 15:51:37 +0100
committerMark Wielaard <mjw@redhat.com>2016-01-06 14:27:10 +0100
commite5f976bcb1b3a27bd89d8d32c0cebb0c14c0e6d2 (patch)
treeeb7bd69ea448746a1a3c356e99087cdf5a9e89f1
parent519c13c9c7fc591609eed405a3e952707c60ec7e (diff)
downloadelfutils-e5f976bcb1b3a27bd89d8d32c0cebb0c14c0e6d2.tar.gz
elfutils-e5f976bcb1b3a27bd89d8d32c0cebb0c14c0e6d2.tar.xz
elflint: Recognize and check SHF_COMPRESSED section flag.
SHF_COMPRESSED is a valid section flag, it can optionally be on any special section, but it cannot be used on NOBITS sections or together with SHF_ALLOC. A section that has SHF_COMPRESSED set must have a valid Chdr. Signed-off-by: Mark Wielaard <mjw@redhat.com>
-rw-r--r--src/ChangeLog8
-rw-r--r--src/elflint.c45
2 files changed, 43 insertions, 10 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 1b5be54..a6d4a97 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,11 @@
+2015-12-18 Mark Wielaard <mjw@redhat.com>
+
+ * elflint.c (section_flags_string): Add NEWFLAG COMPRESSED.
+ (check_sections): SHF_COMPRESSED can be on any special section.
+ SHF_COMPRESSED is a valid section flag. SHF_COMPRESSED cannot
+ be used together with SHF_ALLOC or with SHT_NOBITS. Should have
+ a valid Chdr.
+
2015-10-20 Mark Wielaard <mjw@redhat.com>
* readelf.c (options): Expand -z help text.
diff --git a/src/elflint.c b/src/elflint.c
index bb97f59..7a7b9ce 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.
@@ -2750,7 +2750,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]);
@@ -3698,7 +3699,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 ("\
@@ -3748,9 +3750,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 ("\
@@ -3766,9 +3770,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"),
@@ -3871,7 +3876,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;
@@ -3901,6 +3907,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"),