svn commit: r265613 - head/usr.bin/elfdump
Ed Maste
emaste at FreeBSD.org
Wed May 7 21:16:48 UTC 2014
Author: emaste
Date: Wed May 7 21:16:47 2014
New Revision: 265613
URL: http://svnweb.freebsd.org/changeset/base/265613
Log:
Handle ELF files with 65280 or more sections
If e_shnum or e_shstrndx are at least SHN_LORESERVE (0xff00) then an
escape value is used to indicate that the actual value is found in one
of section 0's fields.
Sponsored by: DARPA, AFRL
Modified:
head/usr.bin/elfdump/elfdump.c
Modified: head/usr.bin/elfdump/elfdump.c
==============================================================================
--- head/usr.bin/elfdump/elfdump.c Wed May 7 21:01:35 2014 (r265612)
+++ head/usr.bin/elfdump/elfdump.c Wed May 7 21:16:47 2014 (r265613)
@@ -368,7 +368,7 @@ static u_int64_t elf_get_half(Elf32_Ehdr
static u_int64_t elf_get_word(Elf32_Ehdr *e, void *base, elf_member_t member);
static u_int64_t elf_get_quad(Elf32_Ehdr *e, void *base, elf_member_t member);
-static void elf_print_ehdr(Elf32_Ehdr *e);
+static void elf_print_ehdr(Elf32_Ehdr *e, void *sh);
static void elf_print_phdr(Elf32_Ehdr *e, void *p);
static void elf_print_shdr(Elf32_Ehdr *e, void *sh);
static void elf_print_symtab(Elf32_Ehdr *e, void *sh, char *str);
@@ -382,6 +382,33 @@ static void elf_print_note(Elf32_Ehdr *e
static void usage(void);
+/*
+ * Helpers for ELF files with shnum or shstrndx values that don't fit in the
+ * ELF header. If the values are too large then an escape value is used to
+ * indicate that the actual value is found in one of section 0's fields.
+ */
+static uint64_t
+elf_get_shnum(Elf32_Ehdr *e, void *sh)
+{
+ uint64_t shnum;
+
+ shnum = elf_get_quarter(e, e, E_SHNUM);
+ if (shnum == 0)
+ shnum = elf_get_word(e, (char *)sh, SH_SIZE);
+ return shnum;
+}
+
+static uint64_t
+elf_get_shstrndx(Elf32_Ehdr *e, void *sh)
+{
+ uint64_t shstrndx;
+
+ shstrndx = elf_get_quarter(e, e, E_SHSTRNDX);
+ if (shstrndx == SHN_XINDEX)
+ shstrndx = elf_get_word(e, (char *)sh, SH_LINK);
+ return shstrndx;
+}
+
int
main(int ac, char **av)
{
@@ -467,10 +494,10 @@ main(int ac, char **av)
phentsize = elf_get_quarter(e, e, E_PHENTSIZE);
phnum = elf_get_quarter(e, e, E_PHNUM);
shentsize = elf_get_quarter(e, e, E_SHENTSIZE);
- shnum = elf_get_quarter(e, e, E_SHNUM);
- shstrndx = elf_get_quarter(e, e, E_SHSTRNDX);
p = (char *)e + phoff;
sh = (char *)e + shoff;
+ shnum = elf_get_shnum(e, sh);
+ shstrndx = elf_get_shstrndx(e, sh);
offset = elf_get_off(e, (char *)sh + shstrndx * shentsize, SH_OFFSET);
shstrtab = (char *)e + offset;
for (i = 0; (u_int64_t)i < shnum; i++) {
@@ -482,7 +509,7 @@ main(int ac, char **av)
dynstr = (char *)e + offset;
}
if (flags & ED_EHDR)
- elf_print_ehdr(e);
+ elf_print_ehdr(e, sh);
if (flags & ED_PHDR)
elf_print_phdr(e, p);
if (flags & ED_SHDR)
@@ -556,7 +583,7 @@ main(int ac, char **av)
}
static void
-elf_print_ehdr(Elf32_Ehdr *e)
+elf_print_ehdr(Elf32_Ehdr *e, void *sh)
{
u_int64_t class;
u_int64_t data;
@@ -589,8 +616,8 @@ elf_print_ehdr(Elf32_Ehdr *e)
phentsize = elf_get_quarter(e, e, E_PHENTSIZE);
phnum = elf_get_quarter(e, e, E_PHNUM);
shentsize = elf_get_quarter(e, e, E_SHENTSIZE);
- shnum = elf_get_quarter(e, e, E_SHNUM);
- shstrndx = elf_get_quarter(e, e, E_SHSTRNDX);
+ shnum = elf_get_shnum(e, sh);
+ shstrndx = elf_get_shstrndx(e, sh);
fprintf(out, "\nelf header:\n");
fprintf(out, "\n");
fprintf(out, "\te_ident: %s %s %s\n", ei_classes[class], ei_data[data],
@@ -671,7 +698,7 @@ elf_print_shdr(Elf32_Ehdr *e, void *sh)
int i;
shentsize = elf_get_quarter(e, e, E_SHENTSIZE);
- shnum = elf_get_quarter(e, e, E_SHNUM);
+ shnum = elf_get_shnum(e, sh);
fprintf(out, "\nsection header:\n");
for (i = 0; (u_int64_t)i < shnum; i++) {
v = (char *)sh + i * shentsize;
More information about the svn-src-all
mailing list