diff options
author | sjg <sjg@FreeBSD.org> | 2014-08-19 06:50:54 +0000 |
---|---|---|
committer | sjg <sjg@FreeBSD.org> | 2014-08-19 06:50:54 +0000 |
commit | d7cd1d425cc1ea9451fa235e3af9b6625c3e0de2 (patch) | |
tree | b04f4bd7cd887f50e7d98af35f46b9834ff86c80 /usr.bin/elfdump | |
parent | 3c8e37b1d04827f33c0c9a7594bd1b1ef7cdb3d3 (diff) | |
parent | 4fbde208c6460d576f64d6dc3cdc6cab085a4283 (diff) | |
download | FreeBSD-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.1 | 4 | ||||
-rw-r--r-- | usr.bin/elfdump/elfdump.c | 161 |
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); |