]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
elflint: Recognize and check SHF_COMPRESSED section flag.
authorMark Wielaard <mjw@redhat.com>
Fri, 18 Dec 2015 14:51:37 +0000 (15:51 +0100)
committerMark Wielaard <mjw@redhat.com>
Wed, 6 Jan 2016 13:27:10 +0000 (14:27 +0100)
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>
src/ChangeLog
src/elflint.c

index 1b5be54c350019852c9253d3903c1c46ef8ed42f..a6d4a975c0d737f5606f2d06a7f6bf8c5506f46d 100644 (file)
@@ -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.
index bb97f5985d397447c86022ae9b0914e74bd9f154..7a7b9ce424241b21e6dd58e288e476114799fd9b 100644 (file)
@@ -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"),