Date: Wed, 7 May 2014 21:16:48 +0000 (UTC) From: Ed Maste <emaste@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r265613 - head/usr.bin/elfdump Message-ID: <201405072116.s47LGmlp092039@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201405072116.s47LGmlp092039>