diff -urN elfdump/Makefile elfdump.new/Makefile --- elfdump/Makefile Tue Mar 20 13:44:59 2007 +++ elfdump.new/Makefile Mon Mar 19 13:40:10 2007 @@ -3,4 +3,6 @@ PROG= elfdump WARNS?= 5 +LDADD= -lelf + .include diff -urN elfdump/elfdump.1 elfdump.new/elfdump.1 --- elfdump/elfdump.1 Tue Mar 20 13:44:59 2007 +++ elfdump.new/elfdump.1 Mon Mar 19 13:49:59 2007 @@ -103,6 +103,8 @@ utility was written by .An Jake Burkholder Aq jake@FreeBSD.org . +Later it was rewritten based on the +libelf library. This manual page was written by .An David O'Brien Aq obrien@FreeBSD.org . diff -urN elfdump/elfdump.c elfdump.new/elfdump.c --- elfdump/elfdump.c Tue Mar 20 13:44:59 2007 +++ elfdump.new/elfdump.c Tue Mar 20 13:07:06 2007 @@ -28,18 +28,15 @@ #include __FBSDID("$FreeBSD: src/usr.bin/elfdump/elfdump.c,v 1.14 2006/01/28 17:58:22 marcel Exp $"); -#include -#include -#include -#include -#include +#include #include #include #include +#include #include -#include #include #include +#include #include #include @@ -55,116 +52,6 @@ #define ED_SYMTAB (1<<9) #define ED_ALL ((1<<10)-1) -#define elf_get_addr elf_get_quad -#define elf_get_off elf_get_quad -#define elf_get_size elf_get_quad - -enum elf_member { - D_TAG = 1, D_PTR, D_VAL, - - E_CLASS, E_DATA, E_OSABI, E_TYPE, E_MACHINE, E_VERSION, E_ENTRY, - E_PHOFF, E_SHOFF, E_FLAGS, E_EHSIZE, E_PHENTSIZE, E_PHNUM, E_SHENTSIZE, - E_SHNUM, E_SHSTRNDX, - - N_NAMESZ, N_DESCSZ, N_TYPE, - - P_TYPE, P_OFFSET, P_VADDR, P_PADDR, P_FILESZ, P_MEMSZ, P_FLAGS, - P_ALIGN, - - SH_NAME, SH_TYPE, SH_FLAGS, SH_ADDR, SH_OFFSET, SH_SIZE, SH_LINK, - SH_INFO, SH_ADDRALIGN, SH_ENTSIZE, - - ST_NAME, ST_VALUE, ST_SIZE, ST_INFO, ST_SHNDX, - - R_OFFSET, R_INFO, - - RA_OFFSET, RA_INFO, RA_ADDEND -}; - -typedef enum elf_member elf_member_t; - -int elf32_offsets[] = { - 0, - - offsetof(Elf32_Dyn, d_tag), offsetof(Elf32_Dyn, d_un.d_ptr), - offsetof(Elf32_Dyn, d_un.d_val), - - offsetof(Elf32_Ehdr, e_ident[EI_CLASS]), - offsetof(Elf32_Ehdr, e_ident[EI_DATA]), - offsetof(Elf32_Ehdr, e_ident[EI_OSABI]), - offsetof(Elf32_Ehdr, e_type), offsetof(Elf32_Ehdr, e_machine), - offsetof(Elf32_Ehdr, e_version), offsetof(Elf32_Ehdr, e_entry), - offsetof(Elf32_Ehdr, e_phoff), offsetof(Elf32_Ehdr, e_shoff), - offsetof(Elf32_Ehdr, e_flags), offsetof(Elf32_Ehdr, e_ehsize), - offsetof(Elf32_Ehdr, e_phentsize), offsetof(Elf32_Ehdr, e_phnum), - offsetof(Elf32_Ehdr, e_shentsize), offsetof(Elf32_Ehdr, e_shnum), - offsetof(Elf32_Ehdr, e_shstrndx), - - offsetof(Elf_Note, n_namesz), offsetof(Elf_Note, n_descsz), - offsetof(Elf_Note, n_type), - - offsetof(Elf32_Phdr, p_type), offsetof(Elf32_Phdr, p_offset), - offsetof(Elf32_Phdr, p_vaddr), offsetof(Elf32_Phdr, p_paddr), - offsetof(Elf32_Phdr, p_filesz), offsetof(Elf32_Phdr, p_memsz), - offsetof(Elf32_Phdr, p_flags), offsetof(Elf32_Phdr, p_align), - - offsetof(Elf32_Shdr, sh_name), offsetof(Elf32_Shdr, sh_type), - offsetof(Elf32_Shdr, sh_flags), offsetof(Elf32_Shdr, sh_addr), - offsetof(Elf32_Shdr, sh_offset), offsetof(Elf32_Shdr, sh_size), - offsetof(Elf32_Shdr, sh_link), offsetof(Elf32_Shdr, sh_info), - offsetof(Elf32_Shdr, sh_addralign), offsetof(Elf32_Shdr, sh_entsize), - - offsetof(Elf32_Sym, st_name), offsetof(Elf32_Sym, st_value), - offsetof(Elf32_Sym, st_size), offsetof(Elf32_Sym, st_info), - offsetof(Elf32_Sym, st_shndx), - - offsetof(Elf32_Rel, r_offset), offsetof(Elf32_Rel, r_info), - - offsetof(Elf32_Rela, r_offset), offsetof(Elf32_Rela, r_info), - offsetof(Elf32_Rela, r_addend) -}; - -int elf64_offsets[] = { - 0, - - offsetof(Elf64_Dyn, d_tag), offsetof(Elf64_Dyn, d_un.d_ptr), - offsetof(Elf64_Dyn, d_un.d_val), - - offsetof(Elf32_Ehdr, e_ident[EI_CLASS]), - offsetof(Elf32_Ehdr, e_ident[EI_DATA]), - offsetof(Elf32_Ehdr, e_ident[EI_OSABI]), - offsetof(Elf64_Ehdr, e_type), offsetof(Elf64_Ehdr, e_machine), - offsetof(Elf64_Ehdr, e_version), offsetof(Elf64_Ehdr, e_entry), - offsetof(Elf64_Ehdr, e_phoff), offsetof(Elf64_Ehdr, e_shoff), - offsetof(Elf64_Ehdr, e_flags), offsetof(Elf64_Ehdr, e_ehsize), - offsetof(Elf64_Ehdr, e_phentsize), offsetof(Elf64_Ehdr, e_phnum), - offsetof(Elf64_Ehdr, e_shentsize), offsetof(Elf64_Ehdr, e_shnum), - offsetof(Elf64_Ehdr, e_shstrndx), - - offsetof(Elf_Note, n_namesz), offsetof(Elf_Note, n_descsz), - offsetof(Elf_Note, n_type), - - offsetof(Elf64_Phdr, p_type), offsetof(Elf64_Phdr, p_offset), - offsetof(Elf64_Phdr, p_vaddr), offsetof(Elf64_Phdr, p_paddr), - offsetof(Elf64_Phdr, p_filesz), offsetof(Elf64_Phdr, p_memsz), - offsetof(Elf64_Phdr, p_flags), offsetof(Elf64_Phdr, p_align), - - offsetof(Elf64_Shdr, sh_name), offsetof(Elf64_Shdr, sh_type), - offsetof(Elf64_Shdr, sh_flags), offsetof(Elf64_Shdr, sh_addr), - offsetof(Elf64_Shdr, sh_offset), offsetof(Elf64_Shdr, sh_size), - offsetof(Elf64_Shdr, sh_link), offsetof(Elf64_Shdr, sh_info), - offsetof(Elf64_Shdr, sh_addralign), offsetof(Elf64_Shdr, sh_entsize), - - offsetof(Elf64_Sym, st_name), offsetof(Elf64_Sym, st_value), - offsetof(Elf64_Sym, st_size), offsetof(Elf64_Sym, st_info), - offsetof(Elf64_Sym, st_shndx), - - offsetof(Elf64_Rel, r_offset), offsetof(Elf64_Rel, r_info), - - offsetof(Elf64_Rela, r_offset), offsetof(Elf64_Rela, r_info), - offsetof(Elf64_Rela, r_addend) -}; - /* http://www.sco.com/developers/gabi/latest/ch5.dynamic.html#tag_encodings */ static const char * d_tags(u_int64_t tag) { @@ -351,53 +238,40 @@ "STB_LOCAL", "STB_GLOBAL", "STB_WEAK" }; -char *dynstr; -char *shstrtab; -char *strtab; -FILE *out; - -u_int64_t elf_get_byte(Elf32_Ehdr *e, void *base, elf_member_t member); -u_int64_t elf_get_quarter(Elf32_Ehdr *e, void *base, elf_member_t member); -u_int64_t elf_get_half(Elf32_Ehdr *e, void *base, elf_member_t member); -u_int64_t elf_get_word(Elf32_Ehdr *e, void *base, elf_member_t member); -u_int64_t elf_get_quad(Elf32_Ehdr *e, void *base, elf_member_t member); - -void elf_print_ehdr(Elf32_Ehdr *e); -void elf_print_phdr(Elf32_Ehdr *e, void *p); -void elf_print_shdr(Elf32_Ehdr *e, void *sh); -void elf_print_symtab(Elf32_Ehdr *e, void *sh, char *str); -void elf_print_dynamic(Elf32_Ehdr *e, void *sh); -void elf_print_rel(Elf32_Ehdr *e, void *r); -void elf_print_rela(Elf32_Ehdr *e, void *ra); -void elf_print_interp(Elf32_Ehdr *e, void *p); -void elf_print_got(Elf32_Ehdr *e, void *sh); -void elf_print_hash(Elf32_Ehdr *e, void *sh); -void elf_print_note(Elf32_Ehdr *e, void *sh); +size_t shstrndx; +size_t strtab; +size_t dynstr; +FILE *out; + +void elf_print_ehdr(Elf * e); +void elf_print_phdr(Elf * e); +void elf_print_shdr(Elf * e); +void elf_print_symtab(Elf * e, Elf_Scn * scn, size_t strndx); +void elf_print_interp(Elf * e, Elf64_Off p_offset); +void elf_print_dynamic(Elf * e, Elf_Scn * scn); +void elf_print_rela(Elf * e, Elf_Scn * scn); +void elf_print_rel(Elf * e, Elf_Scn * scn); +void elf_print_got(Elf * e, Elf_Scn * scn); +void elf_print_note(Elf * e, Elf_Scn * scn); +void elf_print_hash(Elf * e, Elf_Scn * scn); -void usage(void); +void usage (void); int main(int ac, char **av) { - u_int64_t phoff; - u_int64_t shoff; - u_int64_t phentsize; - u_int64_t phnum; - u_int64_t shentsize; - u_int64_t shnum; - u_int64_t shstrndx; - u_int64_t offset; - u_int64_t name; - u_int64_t type; - struct stat sb; - u_int flags; - Elf32_Ehdr *e; - void *p; - void *sh; - void *v; - int fd; - int ch; - int i; + u_int flags; + Elf *e; + Elf_Scn *scn; + GElf_Phdr phdr; + GElf_Shdr shdr; + struct stat sb; + int ch; + int elferr; + int fd; + int i; + size_t phnum; + char *name; out = stdout; flags = 0; @@ -438,56 +312,73 @@ break; case 'w': if ((out = fopen(optarg, "w")) == NULL) - err(1, "%s", optarg); + err(EX_NOINPUT, "%s", optarg); break; case '?': default: usage(); } + ac -= optind; av += optind; + if (ac == 0 || flags == 0) usage(); + + if (elf_version(EV_CURRENT) == EV_NONE) + errx(EX_SOFTWARE, "ELF library initialization failed: %s", + elf_errmsg(-1)); + if ((fd = open(*av, O_RDONLY)) < 0 || fstat(fd, &sb) < 0) - err(1, "%s", *av); - e = mmap(NULL, sb.st_size, PROT_READ, MAP_SHARED, fd, 0); - if (e == MAP_FAILED) - err(1, NULL); - if (!IS_ELF(*(Elf32_Ehdr *)e)) - errx(1, "not an elf file"); - phoff = elf_get_off(e, e, E_PHOFF); - shoff = elf_get_off(e, e, E_SHOFF); - 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; - offset = elf_get_off(e, (char *)sh + shstrndx * shentsize, SH_OFFSET); - shstrtab = (char *)e + offset; - 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); - if (strcmp(shstrtab + name, ".strtab") == 0) - strtab = (char *)e + offset; - if (strcmp(shstrtab + name, ".dynstr") == 0) - dynstr = (char *)e + offset; - } + err(EX_NOINPUT, "%s", *av); + + if ((e = elf_begin(fd, ELF_C_READ, NULL)) == NULL) + errx(EX_SOFTWARE, "elf_begin() failed: %s", + elf_errmsg(-1)); + + if (elf_kind(e) != ELF_K_ELF) + errx(EX_DATAERR, "not an elf file"); + + if (elf_getshstrndx(e, &shstrndx) == 0) + errx(EX_SOFTWARE, "elf_getshstrndx failed: %s", + elf_errmsg(-1)); + + scn = NULL; + while ((scn = elf_nextscn(e, scn)) != NULL) { + if (gelf_getshdr(scn, &shdr) != &shdr) + errx(EX_SOFTWARE, "elf_getshdr failed: %s", + elf_errmsg(-1)); + if ((name = elf_strptr(e, shstrndx, shdr.sh_name)) == NULL) + errx(EX_SOFTWARE, "elf_strptr failed: %s", + elf_errmsg(-1)); + if (strcmp(name, ".strtab") == 0) + strtab = elf_ndxscn(scn); + if (strcmp(name, ".dynstr") == 0) + dynstr = elf_ndxscn(scn); + } + elferr = elf_errno(); + if (elferr != 0) + errx(EX_SOFTWARE, "elf_nextscn failed: %s", + elf_errmsg(elferr)); + if (flags & ED_EHDR) elf_print_ehdr(e); if (flags & ED_PHDR) - elf_print_phdr(e, p); + elf_print_phdr(e); if (flags & ED_SHDR) - elf_print_shdr(e, sh); + elf_print_shdr(e); + if (elf_getphnum(e, &phnum) == 0) + errx(EX_DATAERR, "elf_getphnum failed: %s", + elf_errmsg(-1)); for (i = 0; (u_int64_t)i < phnum; i++) { - v = (char *)p + i * phentsize; - type = elf_get_word(e, v, P_TYPE); - switch (type) { + if (gelf_getphdr(e, i, &phdr) != &phdr) + errx(EX_SOFTWARE, "elf_getphdr failed: %s", + elf_errmsg(-1)); + switch (phdr.p_type) { case PT_INTERP: if (flags & ED_INTERP) - elf_print_interp(e, v); + elf_print_interp(e, phdr.p_offset); break; case PT_NULL: case PT_LOAD: @@ -498,45 +389,52 @@ break; } } - for (i = 0; (u_int64_t)i < shnum; i++) { - v = (char *)sh + i * shentsize; - type = elf_get_word(e, v, SH_TYPE); - switch (type) { + + scn = NULL; + while ((scn = elf_nextscn(e, scn)) != NULL) { + if (gelf_getshdr(scn, &shdr) != &shdr) + errx(EX_SOFTWARE, "elf_getshdr failed: %s", + elf_errmsg(-1)); + switch (shdr.sh_type) { case SHT_SYMTAB: if (flags & ED_SYMTAB) - elf_print_symtab(e, v, strtab); + elf_print_symtab(e, scn, strtab); break; case SHT_DYNAMIC: if (flags & ED_DYN) - elf_print_dynamic(e, v); + elf_print_dynamic(e, scn); break; case SHT_RELA: if (flags & ED_REL) - elf_print_rela(e, v); + elf_print_rela(e, scn); break; case SHT_REL: if (flags & ED_REL) - elf_print_rel(e, v); + elf_print_rel(e, scn); break; case SHT_NOTE: - name = elf_get_word(e, v, SH_NAME); + if ((name = elf_strptr(e, shstrndx, shdr.sh_name)) == NULL) + errx(EX_SOFTWARE, "elf_strptr failed: %s", + elf_errmsg(-1)); if (flags & ED_NOTE && - strcmp(shstrtab + name, ".note.ABI-tag") == 0) - elf_print_note(e, v); + strcmp(name, ".note.ABI-tag") == 0) + elf_print_note(e, scn); break; case SHT_DYNSYM: if (flags & ED_SYMTAB) - elf_print_symtab(e, v, dynstr); + elf_print_symtab(e, scn, dynstr); break; case SHT_PROGBITS: - name = elf_get_word(e, v, SH_NAME); + if ((name = elf_strptr(e, shstrndx, shdr.sh_name)) == NULL) + errx(EX_SOFTWARE, "elf_strptr failed: %s", + elf_errmsg(-1)); if (flags & ED_GOT && - strcmp(shstrtab + name, ".got") == 0) - elf_print_got(e, v); + strcmp(name, ".got") == 0) + elf_print_got(e, scn); break; case SHT_HASH: if (flags & ED_HASH) - elf_print_hash(e, v); + elf_print_hash(e, scn); break; case SHT_NULL: case SHT_STRTAB: @@ -545,561 +443,494 @@ break; } } - - return 0; + elferr = elf_errno(); + if (elferr != 0) + errx(EX_SOFTWARE, "elf_nextscn failed: %s", + elf_errmsg(elferr)); + return (0); } void -elf_print_ehdr(Elf32_Ehdr *e) +elf_print_ehdr(Elf * e) { - u_int64_t class; - u_int64_t data; - u_int64_t osabi; - u_int64_t type; - u_int64_t machine; - u_int64_t version; - u_int64_t entry; - u_int64_t phoff; - u_int64_t shoff; - u_int64_t flags; - u_int64_t ehsize; - u_int64_t phentsize; - u_int64_t phnum; - u_int64_t shentsize; - u_int64_t shnum; - u_int64_t shstrndx; - - class = elf_get_byte(e, e, E_CLASS); - data = elf_get_byte(e, e, E_DATA); - osabi = elf_get_byte(e, e, E_OSABI); - type = elf_get_quarter(e, e, E_TYPE); - machine = elf_get_quarter(e, e, E_MACHINE); - version = elf_get_word(e, e, E_VERSION); - entry = elf_get_addr(e, e, E_ENTRY); - phoff = elf_get_off(e, e, E_PHOFF); - shoff = elf_get_off(e, e, E_SHOFF); - flags = elf_get_word(e, e, E_FLAGS); - ehsize = elf_get_quarter(e, e, E_EHSIZE); - 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); + GElf_Ehdr ehdr; + + if (gelf_getehdr(e, &ehdr) == NULL) + errx(EX_SOFTWARE, "gelf_getehdr failed: %s", + elf_errmsg(-1)); fprintf(out, "\nelf header:\n"); fprintf(out, "\n"); - fprintf(out, "\te_ident: %s %s %s\n", ei_classes[class], ei_data[data], - ei_abis[osabi]); - fprintf(out, "\te_type: %s\n", e_types[type]); - fprintf(out, "\te_machine: %s\n", e_machines(machine)); - fprintf(out, "\te_version: %s\n", ei_versions[version]); - fprintf(out, "\te_entry: %#jx\n", (intmax_t)entry); - fprintf(out, "\te_phoff: %jd\n", (intmax_t)phoff); - fprintf(out, "\te_shoff: %jd\n", (intmax_t)shoff); - fprintf(out, "\te_flags: %jd\n", (intmax_t)flags); - fprintf(out, "\te_ehsize: %jd\n", (intmax_t)ehsize); - 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); + fprintf(out, "\te_ident: %s %s %s\n", + ei_classes[ehdr.e_ident[EI_CLASS]], + ei_data[ehdr.e_ident[EI_DATA]], + ei_abis[ehdr.e_ident[EI_OSABI]]); + fprintf(out, "\te_type: %s\n", e_types[ehdr.e_type]); + fprintf(out, "\te_machine: %s\n", e_machines(ehdr.e_machine)); + fprintf(out, "\te_version: %s\n", ei_versions[ehdr.e_version]); + fprintf(out, "\te_entry: %#jx\n", (uintmax_t)ehdr.e_entry); + fprintf(out, "\te_phoff: %ju\n", (uintmax_t)ehdr.e_phoff); + fprintf(out, "\te_shoff: %ju\n", (uintmax_t)ehdr.e_shoff); + fprintf(out, "\te_flags: %ju\n", (uintmax_t)ehdr.e_flags); + fprintf(out, "\te_ehsize: %ju\n", (uintmax_t)ehdr.e_ehsize); + fprintf(out, "\te_phentsize: %ju\n", (uintmax_t)ehdr.e_phentsize); + fprintf(out, "\te_phnum: %ju\n", (uintmax_t)ehdr.e_phnum); + fprintf(out, "\te_shentsize: %ju\n", (uintmax_t)ehdr.e_shentsize); + fprintf(out, "\te_shnum: %ju\n", (uintmax_t)ehdr.e_shnum); + fprintf(out, "\te_shstrndx: %ju\n", (uintmax_t)ehdr.e_shstrndx); } void -elf_print_phdr(Elf32_Ehdr *e, void *p) -{ - u_int64_t phentsize; - u_int64_t phnum; - u_int64_t type; - u_int64_t offset; - u_int64_t vaddr; - u_int64_t paddr; - u_int64_t filesz; - u_int64_t memsz; - u_int64_t flags; - u_int64_t align; - void *v; - int i; - - phentsize = elf_get_quarter(e, e, E_PHENTSIZE); - phnum = elf_get_quarter(e, e, E_PHNUM); +elf_print_phdr(Elf * e) +{ + GElf_Phdr phdr; + size_t phnum; + int i; + + if (elf_getphnum(e, &phnum) == 0) + errx(EX_DATAERR, "elf_getphnum failed: %s", + elf_errmsg(-1)); fprintf(out, "\nprogram header:\n"); - for (i = 0; (u_int64_t)i < phnum; i++) { - v = (char *)p + i * phentsize; - type = elf_get_word(e, v, P_TYPE); - offset = elf_get_off(e, v, P_OFFSET); - vaddr = elf_get_addr(e, v, P_VADDR); - paddr = elf_get_addr(e, v, P_PADDR); - filesz = elf_get_size(e, v, P_FILESZ); - memsz = elf_get_size(e, v, P_MEMSZ); - flags = elf_get_word(e, v, P_FLAGS); - align = elf_get_size(e, v, P_ALIGN); + for (i = 0; (u_int64_t) i < phnum; i++) { + if (gelf_getphdr(e, i, &phdr) != &phdr) + errx(EX_SOFTWARE, "elf_getphdr failed: %s", + elf_errmsg(-1)); fprintf(out, "\n"); fprintf(out, "entry: %d\n", i); - fprintf(out, "\tp_type: %s\n", p_types[type & 0x7]); - fprintf(out, "\tp_offset: %jd\n", (intmax_t)offset); - fprintf(out, "\tp_vaddr: %#jx\n", (intmax_t)vaddr); - fprintf(out, "\tp_paddr: %#jx\n", (intmax_t)paddr); - fprintf(out, "\tp_filesz: %jd\n", (intmax_t)filesz); - fprintf(out, "\tp_memsz: %jd\n", (intmax_t)memsz); - fprintf(out, "\tp_flags: %s\n", p_flags[flags]); - fprintf(out, "\tp_align: %jd\n", (intmax_t)align); + fprintf(out, "\tp_type: %s\n", p_types[phdr.p_type & 0x7]); + fprintf(out, "\tp_offset: %ju\n", (uintmax_t)phdr.p_offset); + fprintf(out, "\tp_vaddr: %#jx\n", (uintmax_t)phdr.p_vaddr); + fprintf(out, "\tp_paddr: %#jx\n", (uintmax_t)phdr.p_paddr); + fprintf(out, "\tp_filesz: %ju\n", (uintmax_t)phdr.p_filesz); + fprintf(out, "\tp_memsz: %ju\n", (uintmax_t)phdr.p_memsz); + fprintf(out, "\tp_flags: %s\n", p_flags[phdr.p_flags]); + fprintf(out, "\tp_align: %ju\n", (uintmax_t)phdr.p_align); } } void -elf_print_shdr(Elf32_Ehdr *e, void *sh) +elf_print_shdr(Elf * e) { - u_int64_t shentsize; - u_int64_t shnum; - u_int64_t name; - u_int64_t type; - u_int64_t flags; - u_int64_t addr; - u_int64_t offset; - u_int64_t size; - u_int64_t shlink; - u_int64_t info; - u_int64_t addralign; - u_int64_t entsize; - void *v; - int i; + GElf_Shdr shdr; + Elf_Scn *scn; + char *name; + int elferr; - shentsize = elf_get_quarter(e, e, E_SHENTSIZE); - shnum = elf_get_quarter(e, e, E_SHNUM); fprintf(out, "\nsection header:\n"); - for (i = 0; (u_int64_t)i < shnum; i++) { - v = (char *)sh + i * shentsize; - name = elf_get_word(e, v, SH_NAME); - type = elf_get_word(e, v, SH_TYPE); - flags = elf_get_word(e, v, SH_FLAGS); - addr = elf_get_addr(e, v, SH_ADDR); - offset = elf_get_off(e, v, SH_OFFSET); - size = elf_get_size(e, v, SH_SIZE); - shlink = elf_get_word(e, v, SH_LINK); - info = elf_get_word(e, v, SH_INFO); - addralign = elf_get_size(e, v, SH_ADDRALIGN); - entsize = elf_get_size(e, v, SH_ENTSIZE); + scn = elf_getscn(e, SHN_UNDEF); + do { + if (gelf_getshdr(scn, &shdr) != &shdr) + errx(EX_SOFTWARE, "elf_getshdr failed: %s", + elf_errmsg(-1)); + if ((name = elf_strptr(e, shstrndx, shdr.sh_name)) == NULL) + errx(EX_SOFTWARE, "elf_strptr failed: %s", + elf_errmsg(-1)); 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_flags: %s\n", sh_flags[flags & 0x7]); - fprintf(out, "\tsh_addr: %#jx\n", addr); - fprintf(out, "\tsh_offset: %jd\n", (intmax_t)offset); - fprintf(out, "\tsh_size: %jd\n", (intmax_t)size); - fprintf(out, "\tsh_link: %jd\n", (intmax_t)shlink); - fprintf(out, "\tsh_info: %jd\n", (intmax_t)info); - fprintf(out, "\tsh_addralign: %jd\n", (intmax_t)addralign); - fprintf(out, "\tsh_entsize: %jd\n", (intmax_t)entsize); - } -} - -void -elf_print_symtab(Elf32_Ehdr *e, void *sh, char *str) -{ - u_int64_t offset; - u_int64_t entsize; - u_int64_t size; - u_int64_t name; - u_int64_t value; - u_int64_t info; - u_int64_t shndx; - void *st; - int len; - int i; - - offset = elf_get_off(e, sh, SH_OFFSET); - entsize = elf_get_size(e, sh, SH_ENTSIZE); - size = elf_get_size(e, sh, SH_SIZE); - name = elf_get_word(e, sh, SH_NAME); - len = size / entsize; - fprintf(out, "\nsymbol table (%s):\n", shstrtab + name); - for (i = 0; i < len; i++) { - st = (char *)e + offset + i * entsize; - name = elf_get_word(e, st, ST_NAME); - value = elf_get_addr(e, st, ST_VALUE); - size = elf_get_size(e, st, ST_SIZE); - info = elf_get_byte(e, st, ST_INFO); - shndx = elf_get_quarter(e, st, ST_SHNDX); - fprintf(out, "\n"); - fprintf(out, "entry: %d\n", i); - fprintf(out, "\tst_name: %s\n", str + name); - fprintf(out, "\tst_value: %#jx\n", value); - fprintf(out, "\tst_size: %jd\n", (intmax_t)size); - fprintf(out, "\tst_info: %s %s\n", - st_types[ELF32_ST_TYPE(info)], - st_bindings[ELF32_ST_BIND(info)]); - fprintf(out, "\tst_shndx: %jd\n", (intmax_t)shndx); - } -} - -void -elf_print_dynamic(Elf32_Ehdr *e, void *sh) -{ - u_int64_t offset; - u_int64_t entsize; - u_int64_t size; - int64_t tag; - u_int64_t ptr; - u_int64_t val; - void *d; - int i; - - offset = elf_get_off(e, sh, SH_OFFSET); - entsize = elf_get_size(e, sh, SH_ENTSIZE); - size = elf_get_size(e, sh, SH_SIZE); + fprintf(out, "entry: %ju\n", (uintmax_t)elf_ndxscn(scn)); + fprintf(out, "\tsh_name: %s\n", name); + fprintf(out, "\tsh_type: %s\n", sh_types(shdr.sh_type)); + fprintf(out, "\tsh_flags: %s\n", sh_flags[shdr.sh_flags & 0x7]); + fprintf(out, "\tsh_addr: %#jx\n", shdr.sh_addr); + fprintf(out, "\tsh_offset: %ju\n", (uintmax_t)shdr.sh_offset); + fprintf(out, "\tsh_size: %ju\n", (uintmax_t)shdr.sh_size); + fprintf(out, "\tsh_link: %ju\n", (uintmax_t)shdr.sh_link); + fprintf(out, "\tsh_info: %ju\n", (uintmax_t)shdr.sh_info); + fprintf(out, "\tsh_addralign: %ju\n", (uintmax_t)shdr.sh_addralign); + fprintf(out, "\tsh_entsize: %ju\n", (uintmax_t)shdr.sh_entsize); + } while ((scn = elf_nextscn(e, scn)) != NULL); + elferr = elf_errno(); + if (elferr != 0) + errx(EX_SOFTWARE, "elf_nextscn failed: %s", + elf_errmsg(elferr)); +} + +void +elf_print_symtab(Elf * e, Elf_Scn * scn, size_t strndx) +{ + size_t n; + char *name; + Elf_Data *data; + GElf_Sym sym; + GElf_Shdr shdr; + int elferr; + int i; + int len; + + if (gelf_getshdr(scn, &shdr) != &shdr) + errx(EX_SOFTWARE, "elf_getshdr failed: %s", + elf_errmsg(-1)); + if ((name = elf_strptr(e, shstrndx, shdr.sh_name)) == NULL) + errx(EX_SOFTWARE, "elf_strptr failed: %s", + elf_errmsg(-1)); + fprintf(out, "\nsymbol table (%s):\n", name); + data = NULL; + n = 0; + while (n < shdr.sh_size && (data = elf_getdata(scn, data)) != NULL) { + len = data->d_size / shdr.sh_entsize; + for (i = 0; i < len; i++) { + if (gelf_getsym(data, i, &sym) != &sym) + errx(EX_SOFTWARE, "gelf_getsym failed: %s", + elf_errmsg(-1)); + if ((name = elf_strptr(e, strndx, sym.st_name)) == + NULL) + errx(EX_SOFTWARE, "elf_strptr failed: %s", + elf_errmsg(-1)); + fprintf(out, "\n"); + fprintf(out, "entry: %d\n", i); + fprintf(out, "\tst_name: %s\n", name); + fprintf(out, "\tst_value: %#jx\n", sym.st_value); + fprintf(out, "\tst_size: %ju\n", + (uintmax_t)sym.st_size); + fprintf(out, "\tst_info: %s %s\n", + st_types[GELF_ST_TYPE(sym.st_info)], + st_bindings[GELF_ST_BIND(sym.st_info)]); + fprintf(out, "\tst_shndx: %ju\n", + (uintmax_t)sym.st_shndx); + } + n += data->d_size; + } + elferr = elf_errno(); + if (elferr != 0) + errx(EX_SOFTWARE, "elf_getdata failed: %s", + elf_errmsg(elferr)); +} + +void +elf_print_dynamic(Elf * e, Elf_Scn * scn) +{ + size_t n; + char *name; + Elf_Data *data; + GElf_Dyn dyn; + GElf_Shdr shdr; + int elferr; + int i; + int len; + + if (gelf_getshdr(scn, &shdr) != &shdr) + errx(EX_SOFTWARE, "elf_getshdr failed: %s", + elf_errmsg(-1)); fprintf(out, "\ndynamic:\n"); - for (i = 0; (u_int64_t)i < size / entsize; i++) { - d = (char *)e + offset + i * entsize; - tag = elf_get_size(e, d, D_TAG); - ptr = elf_get_size(e, d, D_PTR); - val = elf_get_addr(e, d, D_VAL); - fprintf(out, "\n"); - fprintf(out, "entry: %d\n", i); - fprintf(out, "\td_tag: %s\n", d_tags(tag)); - switch (tag) { - case DT_NEEDED: - case DT_SONAME: - case DT_RPATH: - fprintf(out, "\td_val: %s\n", dynstr + val); - break; - case DT_PLTRELSZ: - case DT_RELA: - case DT_RELASZ: - case DT_RELAENT: - case DT_STRSZ: - case DT_SYMENT: - case DT_RELSZ: - case DT_RELENT: - case DT_PLTREL: - fprintf(out, "\td_val: %jd\n", (intmax_t)val); - break; - case DT_PLTGOT: - case DT_HASH: - case DT_STRTAB: - case DT_SYMTAB: - case DT_INIT: - case DT_FINI: - case DT_REL: - case DT_JMPREL: - fprintf(out, "\td_ptr: %#jx\n", ptr); - break; - case DT_NULL: - case DT_SYMBOLIC: - case DT_DEBUG: - case DT_TEXTREL: - break; - } - } -} - -void -elf_print_rela(Elf32_Ehdr *e, void *sh) -{ - u_int64_t offset; - u_int64_t entsize; - u_int64_t size; - u_int64_t name; - u_int64_t info; - int64_t addend; - void *ra; - void *v; - int i; - - offset = elf_get_off(e, sh, SH_OFFSET); - entsize = elf_get_size(e, sh, SH_ENTSIZE); - size = elf_get_size(e, sh, SH_SIZE); - name = elf_get_word(e, sh, SH_NAME); - v = (char *)e + offset; - fprintf(out, "\nrelocation with addend (%s):\n", shstrtab + name); - for (i = 0; (u_int64_t)i < size / entsize; i++) { - ra = (char *)v + i * entsize; - offset = elf_get_addr(e, ra, RA_OFFSET); - info = elf_get_word(e, ra, RA_INFO); - addend = elf_get_off(e, ra, RA_ADDEND); - fprintf(out, "\n"); - fprintf(out, "entry: %d\n", i); - fprintf(out, "\tr_offset: %#jx\n", offset); - fprintf(out, "\tr_info: %jd\n", (intmax_t)info); - fprintf(out, "\tr_addend: %jd\n", (intmax_t)addend); - } -} - -void -elf_print_rel(Elf32_Ehdr *e, void *sh) -{ - u_int64_t offset; - u_int64_t entsize; - u_int64_t size; - u_int64_t name; - u_int64_t info; - void *r; - void *v; - int i; - - offset = elf_get_off(e, sh, SH_OFFSET); - entsize = elf_get_size(e, sh, SH_ENTSIZE); - size = elf_get_size(e, sh, SH_SIZE); - name = elf_get_word(e, sh, SH_NAME); - v = (char *)e + offset; - fprintf(out, "\nrelocation (%s):\n", shstrtab + name); - for (i = 0; (u_int64_t)i < size / entsize; i++) { - r = (char *)v + i * entsize; - offset = elf_get_addr(e, r, R_OFFSET); - info = elf_get_word(e, r, R_INFO); - fprintf(out, "\n"); - fprintf(out, "entry: %d\n", i); - fprintf(out, "\tr_offset: %#jx\n", offset); - fprintf(out, "\tr_info: %jd\n", (intmax_t)info); - } -} - -void -elf_print_interp(Elf32_Ehdr *e, void *p) -{ - u_int64_t offset; - char *s; - - offset = elf_get_off(e, p, P_OFFSET); - s = (char *)e + offset; + data = NULL; + n = 0; + while (n < shdr.sh_size && (data = elf_getdata(scn, data)) != NULL) { + len = data->d_size / shdr.sh_entsize; + for (i = 0; i < len; i++) { + if (gelf_getdyn(data, i, &dyn) != &dyn) + errx(EX_SOFTWARE, "gelf_getdyn failed: %s", + elf_errmsg(-1)); + fprintf(out, "\n"); + fprintf(out, "entry: %d\n", i); + fprintf(out, "\td_tag: %s\n", d_tags(dyn.d_tag)); + switch(dyn.d_tag) { + case DT_NEEDED: + case DT_SONAME: + case DT_RPATH: + if ((name = + elf_strptr(e, dynstr, dyn.d_un.d_val)) == + NULL) + errx(EX_SOFTWARE, + "elf_strptr failed: %s", + elf_errmsg(-1)); + fprintf(out, "\td_val: %s\n", name); + break; + case DT_PLTRELSZ: + case DT_RELA: + case DT_RELASZ: + case DT_RELAENT: + case DT_STRSZ: + case DT_SYMENT: + case DT_RELSZ: + case DT_RELENT: + case DT_PLTREL: + fprintf(out, "\td_val: %ju\n", + (uintmax_t)dyn.d_un.d_val); + break; + case DT_PLTGOT: + case DT_HASH: + case DT_STRTAB: + case DT_SYMTAB: + case DT_INIT: + case DT_FINI: + case DT_REL: + case DT_JMPREL: + fprintf(out, "\td_ptr: %#jx\n", + dyn.d_un.d_ptr); + break; + case DT_NULL: + case DT_SYMBOLIC: + case DT_DEBUG: + case DT_TEXTREL: + break; + } + } + n += data->d_size; + } + elferr = elf_errno(); + if (elferr != 0) + errx(EX_SOFTWARE, "elf_getdata failed: %s", + elf_errmsg(elferr)); +} + +void +elf_print_rela(Elf * e, Elf_Scn * scn) +{ + size_t n; + char *name; + Elf_Data *data; + GElf_Rela rela; + GElf_Shdr shdr; + int elferr; + int i; + int len; + + if (gelf_getshdr(scn, &shdr) != &shdr) + errx(EX_SOFTWARE, "elf_getshdr failed: %s", + elf_errmsg(-1)); + if ((name = elf_strptr(e, shstrndx, shdr.sh_name)) == NULL) + errx(EX_SOFTWARE, "elf_strptr failed: %s", + elf_errmsg(-1)); + fprintf(out, "\nrelocation with addend (%s):\n", name); + data = NULL; + n = 0; + while (n < shdr.sh_size && (data = elf_getdata(scn, data)) != NULL) { + len = data->d_size / shdr.sh_entsize; + for (i = 0; i < len; i++) { + if (gelf_getrela(data, i, &rela) != &rela) + errx(EX_SOFTWARE, "gelf_getrela failed: %s", + elf_errmsg(-1)); + fprintf(out, "\n"); + fprintf(out, "entry: %d\n", i); + fprintf(out, "\tr_offset: %#jx\n", + rela.r_offset); + fprintf(out, "\tr_info: %ju\n", + (uintmax_t)rela.r_info); + fprintf(out, "\tr_addend: %jd\n", + (intmax_t)rela.r_addend); + } + n += data->d_size; + } + elferr = elf_errno(); + if (elferr != 0) + errx(EX_SOFTWARE, "elf_getdata failed: %s", + elf_errmsg(elferr)); +} + +void +elf_print_rel(Elf * e, Elf_Scn * scn) +{ + size_t n; + char *name; + Elf_Data *data; + GElf_Rel rel; + GElf_Shdr shdr; + int elferr; + int i; + int len; + + if (gelf_getshdr(scn, &shdr) != &shdr) + errx(EX_SOFTWARE, "elf_getshdr failed: %s", + elf_errmsg(-1)); + if ((name = elf_strptr(e, shstrndx, shdr.sh_name)) == NULL) + errx(EX_SOFTWARE, "elf_strptr failed: %s", + elf_errmsg(-1)); + fprintf(out, "\nrelocation (%s):\n", name); + data = NULL; + n = 0; + while (n < shdr.sh_size && (data = elf_getdata(scn, data)) != NULL) { + len = data->d_size / shdr.sh_entsize; + for (i = 0; i < len; i++) { + if (gelf_getrel(data, i, &rel) != &rel) + errx(EX_SOFTWARE, "gelf_getrel failed: %s", + elf_errmsg(-1)); + fprintf(out, "\n"); + fprintf(out, "entry: %d\n", i); + fprintf(out, "\tr_offset: %#jx\n", + rel.r_offset); + fprintf(out, "\tr_info: %ju\n", + (uintmax_t)rel.r_info); + } + n += data->d_size; + } + elferr = elf_errno(); + if (elferr != 0) + errx(EX_SOFTWARE, "elf_getdata failed: %s", + elf_errmsg(elferr)); +} + +void +elf_print_interp(Elf * e, Elf64_Off p_offset) +{ + char *s; + + if ((s = elf_rawfile(e, NULL)) == NULL) + errx(EX_SOFTWARE, "elf_rawfile failed: %s", + elf_errmsg(-1)); fprintf(out, "\ninterp:\n"); - fprintf(out, "\t%s\n", s); + fprintf(out, "\t%s\n", s + (size_t)p_offset); } void -elf_print_got(Elf32_Ehdr *e, void *sh) +elf_print_got(Elf * e, Elf_Scn * scn) { - u_int64_t offset; - u_int64_t addralign; - u_int64_t size; - u_int64_t addr; - void *v; - int i; - - offset = elf_get_off(e, sh, SH_OFFSET); - addralign = elf_get_size(e, sh, SH_ADDRALIGN); - size = elf_get_size(e, sh, SH_SIZE); - v = (char *)e + offset; + GElf_Ehdr ehdr; + GElf_Shdr shdr; + Elf_Data *data; + Elf_Data *dst; + size_t n; + int ec; + int elferr; + int i; + + if (gelf_getehdr(e, &ehdr) == NULL) + errx(EX_SOFTWARE, "gelf_getehdr failed: %s", + elf_errmsg(-1)); + if (gelf_getshdr(scn, &shdr) != &shdr) + errx(EX_SOFTWARE, "elf_getshdr failed: %s", + elf_errmsg(-1)); + if ((ec = gelf_getclass(e)) == ELFCLASSNONE) + errx(EX_DATAERR, "gelf_getclass failed: %s", + elf_errmsg(-1)); fprintf(out, "\nglobal offset table:\n"); - for (i = 0; (u_int64_t)i < size / addralign; i++) { - addr = elf_get_addr(e, (char *)v + i * addralign, 0); - fprintf(out, "\n"); - fprintf(out, "entry: %d\n", i); - fprintf(out, "\t%#jx\n", addr); - } -} - -void -elf_print_hash(Elf32_Ehdr *e __unused, void *sh __unused) -{ -} - -void -elf_print_note(Elf32_Ehdr *e, void *sh) -{ - u_int64_t offset; - u_int64_t size; - u_int64_t name; - u_int32_t namesz; - u_int32_t descsz; - u_int32_t type; - u_int32_t desc; - char *n, *s; - - offset = elf_get_off(e, sh, SH_OFFSET); - size = elf_get_size(e, sh, SH_SIZE); - name = elf_get_word(e, sh, SH_NAME); - n = (char *)e + offset; - fprintf(out, "\nnote (%s):\n", shstrtab + name); - while (n < ((char *)e + offset + size)) { - namesz = elf_get_word(e, n, N_NAMESZ); - descsz = elf_get_word(e, n, N_DESCSZ); - type = elf_get_word(e, n, N_TYPE); - s = n + sizeof(Elf_Note); - desc = elf_get_word(e, n + sizeof(Elf_Note) + namesz, 0); - fprintf(out, "\t%s %d\n", s, desc); - n += sizeof(Elf_Note) + namesz + descsz; - } -} - -u_int64_t -elf_get_byte(Elf32_Ehdr *e, void *base, elf_member_t member) -{ - u_int64_t val; - - val = 0; - switch (e->e_ident[EI_CLASS]) { - case ELFCLASS32: - val = ((char *)base)[elf32_offsets[member]]; - break; - case ELFCLASS64: - val = ((char *)base)[elf64_offsets[member]]; - break; - case ELFCLASSNONE: - errx(1, "invalid class"); - } - - return val; -} - -u_int64_t -elf_get_quarter(Elf32_Ehdr *e, void *base, elf_member_t member) -{ - u_int64_t val; - - val = 0; - switch (e->e_ident[EI_CLASS]) { - case ELFCLASS32: - base = (char *)base + elf32_offsets[member]; - switch (e->e_ident[EI_DATA]) { - case ELFDATA2MSB: - val = be16dec(base); - break; - case ELFDATA2LSB: - val = le16dec(base); - break; - case ELFDATANONE: - errx(1, "invalid data format"); - } - break; - case ELFCLASS64: - base = (char *)base + elf64_offsets[member]; - switch (e->e_ident[EI_DATA]) { - case ELFDATA2MSB: - val = be16dec(base); - break; - case ELFDATA2LSB: - val = le16dec(base); - break; - case ELFDATANONE: - errx(1, "invalid data format"); - } - break; - case ELFCLASSNONE: - errx(1, "invalid class"); - } - - return val; -} - -u_int64_t -elf_get_half(Elf32_Ehdr *e, void *base, elf_member_t member) -{ - u_int64_t val; - - val = 0; - switch (e->e_ident[EI_CLASS]) { - case ELFCLASS32: - base = (char *)base + elf32_offsets[member]; - switch (e->e_ident[EI_DATA]) { - case ELFDATA2MSB: - val = be16dec(base); - break; - case ELFDATA2LSB: - val = le16dec(base); - break; - case ELFDATANONE: - errx(1, "invalid data format"); - } - break; - case ELFCLASS64: - base = (char *)base + elf64_offsets[member]; - switch (e->e_ident[EI_DATA]) { - case ELFDATA2MSB: - val = be32dec(base); - break; - case ELFDATA2LSB: - val = le32dec(base); - break; - case ELFDATANONE: - errx(1, "invalid data format"); - } - break; - case ELFCLASSNONE: - errx(1, "invalid class"); - } - - return val; -} - -u_int64_t -elf_get_word(Elf32_Ehdr *e, void *base, elf_member_t member) -{ - u_int64_t val; - - val = 0; - switch (e->e_ident[EI_CLASS]) { - case ELFCLASS32: - base = (char *)base + elf32_offsets[member]; - switch (e->e_ident[EI_DATA]) { - case ELFDATA2MSB: - val = be32dec(base); - break; - case ELFDATA2LSB: - val = le32dec(base); - break; - case ELFDATANONE: - errx(1, "invalid data format"); - } - break; - case ELFCLASS64: - base = (char *)base + elf64_offsets[member]; - switch (e->e_ident[EI_DATA]) { - case ELFDATA2MSB: - val = be32dec(base); - break; - case ELFDATA2LSB: - val = le32dec(base); - break; - case ELFDATANONE: - errx(1, "invalid data format"); - } - break; - case ELFCLASSNONE: - errx(1, "invalid class"); - } - - return val; -} - -u_int64_t -elf_get_quad(Elf32_Ehdr *e, void *base, elf_member_t member) -{ - u_int64_t val; - - val = 0; - switch (e->e_ident[EI_CLASS]) { - case ELFCLASS32: - base = (char *)base + elf32_offsets[member]; - switch (e->e_ident[EI_DATA]) { - case ELFDATA2MSB: - val = be32dec(base); - break; - case ELFDATA2LSB: - val = le32dec(base); - break; - case ELFDATANONE: - errx(1, "invalid data format"); - } - break; - case ELFCLASS64: - base = (char *)base + elf64_offsets[member]; - switch (e->e_ident[EI_DATA]) { - case ELFDATA2MSB: - val = be64dec(base); - break; - case ELFDATA2LSB: - val = le64dec(base); - break; - case ELFDATANONE: - errx(1, "invalid data format"); - } - break; - case ELFCLASSNONE: - errx(1, "invalid class"); - } - - return val; + data = NULL; + n = 0; + while (n < shdr.sh_size && (data = elf_getdata(scn, data)) != NULL) { + if (ec == ELFCLASS32) + data->d_type = ELF_T_WORD; + else + data->d_type = ELF_T_XWORD; + if ((dst = malloc(sizeof(Elf_Data))) == NULL) + err(1, "malloc failed: "); + memcpy(dst, data, sizeof(Elf_Data)); + if (gelf_xlatetom(e, dst, data, ehdr.e_ident[EI_DATA]) != dst) + errx(EX_SOFTWARE, "gelf_xlatetom failed: %s", + elf_errmsg(-1)); + for(i = 0; i * dst->d_align < dst->d_size; i++) { + fprintf(out, "\nentry: %d\n", i); + if (ec == ELFCLASS32) + fprintf(out, "\t%#x\n", *((u_int32_t *)dst->d_buf + i)); + else + fprintf(out, "\t%#jx\n", *((u_int64_t *)dst->d_buf + i)); + } + n += data->d_size; + free(dst); + } + elferr = elf_errno(); + if (elferr != 0) + errx(EX_SOFTWARE, "elf_getdata failed: %s", + elf_errmsg(elferr)); +} + +void +elf_print_note(Elf * e, Elf_Scn * scn) +{ + GElf_Shdr shdr; + Elf_Data *data; + u_int32_t namesz; + u_int32_t descsz; + u_int32_t *s; + size_t n; + char *name; + int elferr; + + if (gelf_getshdr(scn, &shdr) != &shdr) + errx(EX_SOFTWARE, "elf_getshdr failed: %s", + elf_errmsg(-1)); + if ((name = elf_strptr(e, shstrndx, shdr.sh_name)) == NULL) + errx(EX_SOFTWARE, "elf_strptr failed: %s", + elf_errmsg(-1)); + fprintf(out, "\nnote (%s):\n", name); + data = NULL; + n = 0; + while (n < shdr.sh_size && (data = elf_getdata(scn, data)) != NULL) { + s = data->d_buf; + while ((char *)s < (char *)data->d_buf + data->d_size) { + namesz = ((Elf_Note *)s)->n_namesz; + descsz = ((Elf_Note *)s)->n_descsz; + fprintf(out, "\t%s %d\n", (char *)s + sizeof(Elf_Note), + *(s + sizeof(Elf_Note)/sizeof(u_int32_t) + + roundup2(namesz, sizeof(u_int32_t)) / + sizeof(u_int32_t))); + s = s + sizeof(Elf_Note)/sizeof(u_int32_t) + + roundup2(namesz,sizeof(u_int32_t)) / + sizeof(u_int32_t) + + roundup2(descsz,sizeof(u_int32_t)) / + sizeof(u_int32_t); + } + n += data->d_size; + } + elferr = elf_errno(); + if (elferr != 0) + errx(EX_SOFTWARE, "elf_getdata failed: %s", + elf_errmsg(elferr)); +} + +void +elf_print_hash(Elf * e, Elf_Scn * scn) +{ + GElf_Ehdr ehdr; + GElf_Shdr shdr; + Elf_Data *data; + Elf_Data *dst; + u_int32_t *s; + u_int64_t i; + u_int64_t nbucket; + u_int64_t nchain; + u_int64_t *s64; + char *name; + int elferr; + + if (gelf_getehdr(e, &ehdr) == NULL) + errx(EX_SOFTWARE, "gelf_getehdr failed: %s", + elf_errmsg(-1)); + if (gelf_getshdr(scn, &shdr) != &shdr) + errx(EX_SOFTWARE, "elf_getshdr failed: %s", + elf_errmsg(-1)); + if ((name = elf_strptr(e, shstrndx, shdr.sh_name)) == NULL) + errx(EX_SOFTWARE, "elf_strptr failed: %s", + elf_errmsg(-1)); + fprintf(out, "\nhash table (%s):\n", name); + data = NULL; + if (ehdr.e_machine == EM_ALPHA) { + /* Alpha uses 64-bit hash entries */ + if ((data = elf_rawdata(scn, data)) != NULL) { + data->d_type = ELF_T_XWORD; + if ((dst = malloc(sizeof(Elf_Data))) == NULL) + err(1, "malloc failed: "); + memcpy(dst, data, sizeof(Elf_Data)); + if (gelf_xlatetom(e, dst, + data, ehdr.e_ident[EI_DATA]) != dst) + errx(EX_SOFTWARE, "gelf_xlatetom failed: %s", + elf_errmsg(-1)); + s64 = dst->d_buf; + nbucket = *s64++; + nchain = *s64++; + fprintf(out, "\nnbucket:\n\t%ju\n", nbucket); + fprintf(out, "\nnchain:\n\t%ju\n\n", nchain); + for(i = 0; i < nbucket; i++, s64++) + fprintf(out, "bucket[%jd]:\n\t%ju\n\n", + i, *s64); + for(i = 0; i < nchain; i++, s64++) + fprintf(out, "chain[%jd]:\n\t%ju\n\n", + i, *s64); + free(dst); + } + } else { + if ((data = elf_getdata(scn, data)) != NULL) { + s = data->d_buf; + nbucket = *s++; + nchain = *s++; + fprintf(out, "\nnbucket:\n\t%ju\n", nbucket); + fprintf(out, "\nnchain:\n\t%ju\n\n", nchain); + for(i = 0; i < nbucket; i++, s++) + fprintf(out, "bucket[%jd]:\n\t%u\n\n", i, *s); + for(i = 0; i < nchain; i++, s++) + fprintf(out, "chain[%jd]:\n\t%u\n\n", i, *s); + } + } + elferr = elf_errno(); + if (elferr != 0) + errx(EX_SOFTWARE, "elf_getdata failed: %s", + elf_errmsg(elferr)); } void