summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Wielaard <[email protected]>2015-08-12 00:11:26 +0200
committerMark Wielaard <[email protected]>2015-08-17 14:33:24 +0200
commit0292aefb4c813d41fb1b2dd2d3a3c857a5c6349d (patch)
treec03242dd682ab49f50a1b01b8bb3e60f49bfe60b
parentc689d90c6eff870c85d381faed933a550a58dc0a (diff)
elflint: Add gnuld check when a NOBITS section falls inside a segment.
gnuld has a really bad bug where it can place a NOBITS section inside a PT_LOAD segment. Normally that would not work. But it also makes sure that the contents of the file is all zeros. So in practice it is actually a PROGBITS section with all zero data. Except that other tools will think there is an unused gap in the ELF file after the NOBITS section. Recognize and check this pattern in elflint when --gnu is given. Signed-off-by: Mark Wielaard <[email protected]>
-rw-r--r--src/ChangeLog5
-rw-r--r--src/elflint.c34
2 files changed, 37 insertions, 2 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index a0c32fa2..5be10750 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,8 @@
+2015-08-11 Mark Wielaard <[email protected]>
+
+ * elflint.c (check_sections): When gnuld and a NOBITS section falls
+ inside a segment make sure any ELF file contents is zero.
+
2015-07-29 Mark Wielaard <[email protected]>
* unstrip.c (sections_flags_match): New function.
diff --git a/src/elflint.c b/src/elflint.c
index a9168862..0d5f34d4 100644
--- a/src/elflint.c
+++ b/src/elflint.c
@@ -3978,9 +3978,39 @@ section [%2zu] '%s' not fully contained in segment of program header entry %d\n"
{
if (shdr->sh_offset < phdr->p_offset + phdr->p_filesz
&& !is_debuginfo)
- ERROR (gettext ("\
+ {
+ if (!gnuld)
+ ERROR (gettext ("\
section [%2zu] '%s' has type NOBITS but is read from the file in segment of program header entry %d\n"),
- cnt, section_name (ebl, cnt), pcnt);
+ cnt, section_name (ebl, cnt), pcnt);
+ else
+ {
+ /* This is truly horrible. GNU ld might put a
+ NOBITS section in the middle of a PT_LOAD
+ segment, assuming the next gap in the file
+ actually consists of zero bits...
+ So it really is like a PROGBITS section
+ where the data is all zeros. Check those
+ zero bytes are really there. */
+ bool bad;
+ Elf_Data *databits;
+ databits = elf_getdata_rawchunk (ebl->elf,
+ shdr->sh_offset,
+ shdr->sh_size,
+ ELF_T_BYTE);
+ bad = (databits == NULL
+ || databits->d_size != shdr->sh_size);
+ for (size_t idx = 0;
+ idx < databits->d_size && ! bad;
+ idx++)
+ bad = ((char *) databits->d_buf)[idx] != 0;
+
+ if (bad)
+ ERROR (gettext ("\
+section [%2zu] '%s' has type NOBITS but is read from the file in segment of program header entry %d and file contents is non-zero\n"),
+ cnt, section_name (ebl, cnt), pcnt);
+ }
+ }
}
else
{