summaryrefslogtreecommitdiffstats
path: root/usr.bin/elfdump
diff options
context:
space:
mode:
authorsjg <sjg@FreeBSD.org>2014-08-19 06:50:54 +0000
committersjg <sjg@FreeBSD.org>2014-08-19 06:50:54 +0000
commitd7cd1d425cc1ea9451fa235e3af9b6625c3e0de2 (patch)
treeb04f4bd7cd887f50e7d98af35f46b9834ff86c80 /usr.bin/elfdump
parent3c8e37b1d04827f33c0c9a7594bd1b1ef7cdb3d3 (diff)
parent4fbde208c6460d576f64d6dc3cdc6cab085a4283 (diff)
downloadFreeBSD-src-d7cd1d425cc1ea9451fa235e3af9b6625c3e0de2.zip
FreeBSD-src-d7cd1d425cc1ea9451fa235e3af9b6625c3e0de2.tar.gz
Merge head from 7/28
Diffstat (limited to 'usr.bin/elfdump')
-rw-r--r--usr.bin/elfdump/elfdump.14
-rw-r--r--usr.bin/elfdump/elfdump.c161
2 files changed, 117 insertions, 48 deletions
diff --git a/usr.bin/elfdump/elfdump.1 b/usr.bin/elfdump/elfdump.1
index 5818297..dbb3171 100644
--- a/usr.bin/elfdump/elfdump.1
+++ b/usr.bin/elfdump/elfdump.1
@@ -102,10 +102,10 @@ The
.Nm
utility
was written by
-.An Jake Burkholder Aq jake@FreeBSD.org .
+.An Jake Burkholder Aq Mt jake@FreeBSD.org .
This
manual page was written by
-.An David O'Brien Aq obrien@FreeBSD.org .
+.An David O'Brien Aq Mt obrien@FreeBSD.org .
.Sh BUGS
Does not fully implement the
.Tn ELF
diff --git a/usr.bin/elfdump/elfdump.c b/usr.bin/elfdump/elfdump.c
index c86e6fc..4ba4529 100644
--- a/usr.bin/elfdump/elfdump.c
+++ b/usr.bin/elfdump/elfdump.c
@@ -167,7 +167,10 @@ static int elf64_offsets[] = {
/* http://www.sco.com/developers/gabi/latest/ch5.dynamic.html#tag_encodings */
static const char *
-d_tags(u_int64_t tag) {
+d_tags(u_int64_t tag)
+{
+ static char unknown_tag[48];
+
switch (tag) {
case 0: return "DT_NULL";
case 1: return "DT_NEEDED";
@@ -215,6 +218,7 @@ d_tags(u_int64_t tag) {
case 0x6ffffdfe: return "DT_SYMINSZ";
case 0x6ffffdff: return "DT_SYMINENT (DT_VALRNGHI)";
case 0x6ffffe00: return "DT_ADDRRNGLO";
+ case 0x6ffffef5: return "DT_GNU_HASH";
case 0x6ffffef8: return "DT_GNU_CONFLICT";
case 0x6ffffef9: return "DT_GNU_LIBLIST";
case 0x6ffffefa: return "DT_SUNW_CONFIG";
@@ -236,8 +240,10 @@ d_tags(u_int64_t tag) {
case 0x7ffffffd: return "DT_SUNW_AUXILIARY";
case 0x7ffffffe: return "DT_SUNW_USED";
case 0x7fffffff: return "DT_SUNW_FILTER";
- default: return "ERROR: TAG NOT DEFINED";
}
+ snprintf(unknown_tag, sizeof(unknown_tag),
+ "ERROR: TAG NOT DEFINED -- tag 0x%jx", (uintmax_t)tag);
+ return (unknown_tag);
}
static const char *
@@ -303,40 +309,86 @@ static const char *p_flags[] = {
/* http://www.sco.com/developers/gabi/latest/ch4.sheader.html#sh_type */
static const char *
-sh_types(u_int64_t sht) {
- switch (sht) {
- case 0: return "SHT_NULL";
- case 1: return "SHT_PROGBITS";
- case 2: return "SHT_SYMTAB";
- case 3: return "SHT_STRTAB";
- case 4: return "SHT_RELA";
- case 5: return "SHT_HASH";
- case 6: return "SHT_DYNAMIC";
- case 7: return "SHT_NOTE";
- case 8: return "SHT_NOBITS";
- case 9: return "SHT_REL";
- case 10: return "SHT_SHLIB";
- case 11: return "SHT_DYNSYM";
- case 14: return "SHT_INIT_ARRAY";
- case 15: return "SHT_FINI_ARRAY";
- case 16: return "SHT_PREINIT_ARRAY";
- case 17: return "SHT_GROUP";
- case 18: return "SHT_SYMTAB_SHNDX";
- /* 0x60000000 - 0x6fffffff operating system-specific semantics */
- case 0x6ffffff0: return "XXX:VERSYM";
- case 0x6ffffff4: return "SHT_SUNW_dof";
- case 0x6ffffff7: return "SHT_GNU_LIBLIST";
- case 0x6ffffffc: return "XXX:VERDEF";
- case 0x6ffffffd: return "SHT_SUNW(GNU)_verdef";
- case 0x6ffffffe: return "SHT_SUNW(GNU)_verneed";
- case 0x6fffffff: return "SHT_SUNW(GNU)_versym";
- /* 0x70000000 - 0x7fffffff processor-specific semantics */
- case 0x70000000: return "SHT_IA_64_EXT";
- case 0x70000001: return "SHT_IA_64_UNWIND";
- case 0x7ffffffd: return "XXX:AUXILIARY";
- case 0x7fffffff: return "XXX:FILTER";
- /* 0x80000000 - 0xffffffff application programs */
- default: return "ERROR: SHT NOT DEFINED";
+sh_types(uint64_t machine, uint64_t sht) {
+ static char unknown_buf[64];
+
+ if (sht < 0x60000000) {
+ switch (sht) {
+ case 0: return "SHT_NULL";
+ case 1: return "SHT_PROGBITS";
+ case 2: return "SHT_SYMTAB";
+ case 3: return "SHT_STRTAB";
+ case 4: return "SHT_RELA";
+ case 5: return "SHT_HASH";
+ case 6: return "SHT_DYNAMIC";
+ case 7: return "SHT_NOTE";
+ case 8: return "SHT_NOBITS";
+ case 9: return "SHT_REL";
+ case 10: return "SHT_SHLIB";
+ case 11: return "SHT_DYNSYM";
+ case 14: return "SHT_INIT_ARRAY";
+ case 15: return "SHT_FINI_ARRAY";
+ case 16: return "SHT_PREINIT_ARRAY";
+ case 17: return "SHT_GROUP";
+ case 18: return "SHT_SYMTAB_SHNDX";
+ }
+ snprintf(unknown_buf, sizeof(unknown_buf),
+ "ERROR: SHT %ju NOT DEFINED", (uintmax_t)sht);
+ return (unknown_buf);
+ } else if (sht < 0x70000000) {
+ /* 0x60000000-0x6fffffff operating system-specific semantics */
+ switch (sht) {
+ case 0x6ffffff0: return "XXX:VERSYM";
+ case 0x6ffffff4: return "SHT_SUNW_dof";
+ case 0x6ffffff6: return "SHT_GNU_HASH";
+ case 0x6ffffff7: return "SHT_GNU_LIBLIST";
+ case 0x6ffffffc: return "XXX:VERDEF";
+ case 0x6ffffffd: return "SHT_SUNW(GNU)_verdef";
+ case 0x6ffffffe: return "SHT_SUNW(GNU)_verneed";
+ case 0x6fffffff: return "SHT_SUNW(GNU)_versym";
+ }
+ snprintf(unknown_buf, sizeof(unknown_buf),
+ "ERROR: OS-SPECIFIC SHT 0x%jx NOT DEFINED",
+ (uintmax_t)sht);
+ return (unknown_buf);
+ } else if (sht < 0x80000000) {
+ /* 0x70000000-0x7fffffff processor-specific semantics */
+ switch (machine) {
+ case EM_ARM:
+ switch (sht) {
+ case 0x70000001: return "SHT_ARM_EXIDX";
+ case 0x70000002: return "SHT_ARM_PREEMPTMAP";
+ case 0x70000003: return "SHT_ARM_ATTRIBUTES";
+ case 0x70000004: return "SHT_ARM_DEBUGOVERLAY";
+ case 0x70000005: return "SHT_ARM_OVERLAYSECTION";
+ }
+ break;
+ case EM_MIPS:
+ switch (sht) {
+ case 0x7000000d: return "SHT_MIPS_OPTIONS";
+ }
+ break;
+ case EM_IA_64:
+ switch (sht) {
+ case 0x70000000: return "SHT_IA_64_EXT";
+ case 0x70000001: return "SHT_IA_64_UNWIND";
+ }
+ break;
+ }
+ switch (sht) {
+ case 0x7ffffffd: return "XXX:AUXILIARY";
+ case 0x7fffffff: return "XXX:FILTER";
+ }
+ snprintf(unknown_buf, sizeof(unknown_buf),
+ "ERROR: PROCESSOR-SPECIFIC SHT 0x%jx NOT DEFINED",
+ (uintmax_t)sht);
+ return (unknown_buf);
+ } else {
+ /* 0x80000000-0xffffffff application programs */
+ snprintf(unknown_buf, sizeof(unknown_buf),
+ "ERROR: SHT 0x%jx NOT DEFINED",
+ (uintmax_t)sht);
+ return (unknown_buf);
}
}
@@ -495,11 +547,19 @@ main(int ac, char **av)
phnum = elf_get_quarter(e, e, E_PHNUM);
shentsize = elf_get_quarter(e, e, E_SHENTSIZE);
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;
+ if (shoff > 0) {
+ 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;
+ } else {
+ sh = NULL;
+ shnum = 0;
+ shstrndx = 0;
+ shstrtab = NULL;
+ }
for (i = 0; (u_int64_t)i < shnum; i++) {
name = elf_get_word(e, (char *)sh + i * shentsize, SH_NAME);
offset = elf_get_off(e, (char *)sh + i * shentsize, SH_OFFSET);
@@ -616,8 +676,6 @@ elf_print_ehdr(Elf32_Ehdr *e, void *sh)
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_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],
@@ -633,8 +691,12 @@ elf_print_ehdr(Elf32_Ehdr *e, void *sh)
fprintf(out, "\te_phentsize: %jd\n", (intmax_t)phentsize);
fprintf(out, "\te_phnum: %jd\n", (intmax_t)phnum);
fprintf(out, "\te_shentsize: %jd\n", (intmax_t)shentsize);
- fprintf(out, "\te_shnum: %jd\n", (intmax_t)shnum);
- fprintf(out, "\te_shstrndx: %jd\n", (intmax_t)shstrndx);
+ if (sh != NULL) {
+ shnum = elf_get_shnum(e, sh);
+ shstrndx = elf_get_shstrndx(e, sh);
+ fprintf(out, "\te_shnum: %jd\n", (intmax_t)shnum);
+ fprintf(out, "\te_shstrndx: %jd\n", (intmax_t)shstrndx);
+ }
}
static void
@@ -694,9 +756,16 @@ elf_print_shdr(Elf32_Ehdr *e, void *sh)
u_int64_t info;
u_int64_t addralign;
u_int64_t entsize;
+ u_int64_t machine;
void *v;
int i;
+ if (sh == NULL) {
+ fprintf(out, "\nNo section headers\n");
+ return;
+ }
+
+ machine = elf_get_quarter(e, e, E_MACHINE);
shentsize = elf_get_quarter(e, e, E_SHENTSIZE);
shnum = elf_get_shnum(e, sh);
fprintf(out, "\nsection header:\n");
@@ -715,7 +784,7 @@ elf_print_shdr(Elf32_Ehdr *e, void *sh)
fprintf(out, "\n");
fprintf(out, "entry: %d\n", i);
fprintf(out, "\tsh_name: %s\n", shstrtab + name);
- fprintf(out, "\tsh_type: %s\n", sh_types(type));
+ fprintf(out, "\tsh_type: %s\n", sh_types(machine, type));
fprintf(out, "\tsh_flags: %s\n", sh_flags[flags & 0x7]);
fprintf(out, "\tsh_addr: %#jx\n", addr);
fprintf(out, "\tsh_offset: %jd\n", (intmax_t)offset);
OpenPOWER on IntegriCloud