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