summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMark Wielaard <[email protected]>2014-11-22 23:08:48 +0100
committerMark Wielaard <[email protected]>2014-11-26 20:17:22 +0100
commit712c8faddc08844fb1f2814c8b6e817f03b0698e (patch)
treedf68a29bd32a009875438dfbbd68cbe6f30425c0 /src
parent2deeb7c51020df07d752107cdc6822d70ae1da4e (diff)
Use elf_getphdrnum instead of accessing ehdr->e_phnum directly.
Using elf_getphdrnum lets us handle ELF files that use more than PN_XNUM phdrs. And guards against some corrupt files. Signed-off-by: Mark Wielaard <[email protected]>
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog12
-rw-r--r--src/elflint.c2
-rw-r--r--src/findtextrel.c14
-rw-r--r--src/readelf.c7
-rw-r--r--src/size.c7
-rw-r--r--src/strip.c13
-rw-r--r--src/unstrip.c28
7 files changed, 56 insertions, 27 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index bab948a1..bace91d5 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,15 @@
+2014-11-22 Mark Wielaard <[email protected]>
+
+ * elflint.c (check_sections): Call ebl_bss_plt_p without ehdr.
+ * findtextrel.c (process_file): Use elf_getphdrnum.
+ * readelf.c (process_elf_file): Remove redundant ehdr->e_phoff check.
+ (print_phdr): Check phnum.
+ * size.c (show_segments): Use elf_getphdrnum.
+ * strip.c (handle_elf): Likewise.
+ * unstrip.c (copy_elf): Likewise.
+ (copy_elided_sections): Likewise.
+ (handle_file): Likewise.
+
2014-11-18 Mark Wielaard <[email protected]>
* readelf.c (print_cfa_program): Fix sanity check of DW_FORM_block
diff --git a/src/elflint.c b/src/elflint.c
index d6a47748..fbc78ede 100644
--- a/src/elflint.c
+++ b/src/elflint.c
@@ -3532,7 +3532,7 @@ cannot get section header for section [%2zu] '%s': %s\n"),
GElf_Word good_type = special_sections[s].type;
if (IS_KNOWN_SPECIAL (s, ".plt", false)
- && ebl_bss_plt_p (ebl, ehdr))
+ && ebl_bss_plt_p (ebl))
good_type = SHT_NOBITS;
/* In a debuginfo file, any normal section can be SHT_NOBITS.
diff --git a/src/findtextrel.c b/src/findtextrel.c
index 9fd81633..264a06bd 100644
--- a/src/findtextrel.c
+++ b/src/findtextrel.c
@@ -1,5 +1,5 @@
/* Locate source files or functions which caused text relocations.
- Copyright (C) 2005-2010, 2012 Red Hat, Inc.
+ Copyright (C) 2005-2010, 2012, 2014 Red Hat, Inc.
This file is part of elfutils.
Written by Ulrich Drepper <[email protected]>, 2005.
@@ -324,14 +324,20 @@ process_file (const char *fname, bool more_than_one)
if (segments == NULL)
error (1, errno, gettext ("while reading ELF file"));
- for (int i = 0; i < ehdr->e_phnum; ++i)
+ size_t phnum;
+ if (elf_getphdrnum (elf, &phnum) != 0)
+ error (1, 0, gettext ("cannot get program header count: %s"),
+ elf_errmsg (-1));
+
+
+ for (size_t i = 0; i < phnum; ++i)
{
GElf_Phdr phdr_mem;
GElf_Phdr *phdr = gelf_getphdr (elf, i, &phdr_mem);
if (phdr == NULL)
{
error (0, 0,
- gettext ("cannot get program header index at offset %d: %s"),
+ gettext ("cannot get program header index at offset %zd: %s"),
i, elf_errmsg (-1));
result = 1;
goto next;
@@ -349,7 +355,7 @@ process_file (const char *fname, bool more_than_one)
if (segments == NULL)
{
error (0, 0, gettext ("\
-cannot get program header index at offset %d: %s"),
+cannot get program header index at offset %zd: %s"),
i, elf_errmsg (-1));
result = 1;
goto next;
diff --git a/src/readelf.c b/src/readelf.c
index 08de7989..3b1f035a 100644
--- a/src/readelf.c
+++ b/src/readelf.c
@@ -835,11 +835,6 @@ process_elf_file (Dwfl_Module *dwflmod, int fd)
gettext ("cannot determine number of program headers: %s"),
elf_errmsg (-1));
- /* If there isn't actually a program header then set phnum to zero.
- Don't do any extra work. gelf_getphdr will always return NULL. */
- if (ehdr->e_phoff == 0)
- phnum = 0;
-
/* For an ET_REL file, libdwfl has adjusted the in-core shdrs
and may have applied relocation to some sections.
So we need to get a fresh Elf handle on the file to display those. */
@@ -1162,7 +1157,7 @@ There are %d section headers, starting at offset %#" PRIx64 ":\n\
static void
print_phdr (Ebl *ebl, GElf_Ehdr *ehdr)
{
- if (ehdr->e_phnum == 0 || ehdr->e_phoff == 0)
+ if (phnum == 0)
/* No program header, this is OK in relocatable objects. */
return;
diff --git a/src/size.c b/src/size.c
index cb67999b..0e7e41e4 100644
--- a/src/size.c
+++ b/src/size.c
@@ -600,14 +600,13 @@ show_bsd_totals (void)
static void
show_segments (Elf *elf, const char *fullname)
{
- GElf_Ehdr ehdr_mem;
- GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem);
- if (ehdr == NULL)
+ size_t phnum;
+ if (elf_getphdrnum (elf, &phnum) != 0)
INTERNAL_ERROR (fullname);
GElf_Off total = 0;
bool first = true;
- for (size_t cnt = 0; cnt < ehdr->e_phnum; ++cnt)
+ for (size_t cnt = 0; cnt < phnum; ++cnt)
{
GElf_Phdr phdr_mem;
GElf_Phdr *phdr;
diff --git a/src/strip.c b/src/strip.c
index c9a1d8df..2b217996 100644
--- a/src/strip.c
+++ b/src/strip.c
@@ -502,6 +502,11 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
error (EXIT_FAILURE, 0,
gettext ("cannot get section header string table index"));
+ /* Get the number of phdrs in the old file. */
+ size_t phnum;
+ if (elf_getphdrnum (elf, &phnum) != 0)
+ error (EXIT_FAILURE, 0, gettext ("cannot get number of phdrs"));
+
/* We now create a new ELF descriptor for the same file. We
construct it almost exactly in the same way with some information
dropped. */
@@ -513,7 +518,7 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
if (unlikely (gelf_newehdr (newelf, gelf_getclass (elf)) == 0)
|| (ehdr->e_type != ET_REL
- && unlikely (gelf_newphdr (newelf, ehdr->e_phnum) == 0)))
+ && unlikely (gelf_newphdr (newelf, phnum) == 0)))
{
error (0, 0, gettext ("cannot create new file '%s': %s"),
output_fname, elf_errmsg (-1));
@@ -522,7 +527,7 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
/* Copy over the old program header if needed. */
if (ehdr->e_type != ET_REL)
- for (cnt = 0; cnt < ehdr->e_phnum; ++cnt)
+ for (cnt = 0; cnt < phnum; ++cnt)
{
GElf_Phdr phdr_mem;
GElf_Phdr *phdr = gelf_getphdr (elf, cnt, &phdr_mem);
@@ -537,7 +542,7 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
debugelf = elf_begin (debug_fd, ELF_C_WRITE_MMAP, NULL);
if (unlikely (gelf_newehdr (debugelf, gelf_getclass (elf)) == 0)
|| (ehdr->e_type != ET_REL
- && unlikely (gelf_newphdr (debugelf, ehdr->e_phnum) == 0)))
+ && unlikely (gelf_newphdr (debugelf, phnum) == 0)))
{
error (0, 0, gettext ("cannot create new file '%s': %s"),
debug_fname, elf_errmsg (-1));
@@ -546,7 +551,7 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
/* Copy over the old program header if needed. */
if (ehdr->e_type != ET_REL)
- for (cnt = 0; cnt < ehdr->e_phnum; ++cnt)
+ for (cnt = 0; cnt < phnum; ++cnt)
{
GElf_Phdr phdr_mem;
GElf_Phdr *phdr = gelf_getphdr (elf, cnt, &phdr_mem);
diff --git a/src/unstrip.c b/src/unstrip.c
index f6af4500..989ac5ff 100644
--- a/src/unstrip.c
+++ b/src/unstrip.c
@@ -241,7 +241,7 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
#define ELF_CHECK(call, msg) \
do \
{ \
- if (!(call)) \
+ if (unlikely (!(call))) \
error (EXIT_FAILURE, 0, msg, elf_errmsg (-1)); \
} while (0)
@@ -257,13 +257,17 @@ copy_elf (Elf *outelf, Elf *inelf)
ELF_CHECK (gelf_update_ehdr (outelf, ehdr),
_("cannot copy ELF header: %s"));
- if (ehdr->e_phnum > 0)
+ size_t phnum;
+ ELF_CHECK (elf_getphdrnum (inelf, &phnum) == 0,
+ _("cannot get number of program headers: %s"));
+
+ if (phnum > 0)
{
- ELF_CHECK (gelf_newphdr (outelf, ehdr->e_phnum),
+ ELF_CHECK (gelf_newphdr (outelf, phnum),
_("cannot create program headers: %s"));
GElf_Phdr phdr_mem;
- for (uint_fast16_t i = 0; i < ehdr->e_phnum; ++i)
+ for (size_t i = 0; i < phnum; ++i)
ELF_CHECK (gelf_update_phdr (outelf, i,
gelf_getphdr (inelf, i, &phdr_mem)),
_("cannot copy program header: %s"));
@@ -1823,12 +1827,16 @@ more sections in stripped file than debug file -- arguments reversed?"));
}
while (skip_reloc);
- if (stripped_ehdr->e_phnum > 0)
- ELF_CHECK (gelf_newphdr (unstripped, stripped_ehdr->e_phnum),
+ size_t phnum;
+ ELF_CHECK (elf_getphdrnum (stripped, &phnum) == 0,
+ _("cannot get number of program headers: %s"));
+
+ if (phnum > 0)
+ ELF_CHECK (gelf_newphdr (unstripped, phnum),
_("cannot create program headers: %s"));
/* Copy each program header from the stripped file. */
- for (uint_fast16_t i = 0; i < stripped_ehdr->e_phnum; ++i)
+ for (size_t i = 0; i < phnum; ++i)
{
GElf_Phdr phdr_mem;
GElf_Phdr *phdr = gelf_getphdr (stripped, i, &phdr_mem);
@@ -1863,11 +1871,15 @@ handle_file (const char *output_file, bool create_dirs,
Elf *stripped, const GElf_Ehdr *stripped_ehdr,
Elf *unstripped)
{
+ size_t phnum;
+ ELF_CHECK (elf_getphdrnum (stripped, &phnum) == 0,
+ _("cannot get number of program headers: %s"));
+
/* Determine the address bias between the debuginfo file and the main
file, which may have been modified by prelinking. */
GElf_Addr bias = 0;
if (unstripped != NULL)
- for (uint_fast16_t i = 0; i < stripped_ehdr->e_phnum; ++i)
+ for (size_t i = 0; i < phnum; ++i)
{
GElf_Phdr phdr_mem;
GElf_Phdr *phdr = gelf_getphdr (stripped, i, &phdr_mem);