From d4d9322d7cf4d157602293e20a67961339224b6d Mon Sep 17 00:00:00 2001 From: norly Date: Tue, 28 May 2013 18:18:55 +0100 Subject: [PATCH] Add printing functions for models to ease debugging --- include/libelfu/modelops.h | 5 + src/main.c | 3 + src/model/dump.c | 222 +++++++++++++++++++++++++++++++++++++ 3 files changed, 230 insertions(+) create mode 100644 src/model/dump.c diff --git a/include/libelfu/modelops.h b/include/libelfu/modelops.h index 1cfe0b6..31a4ed9 100644 --- a/include/libelfu/modelops.h +++ b/include/libelfu/modelops.h @@ -23,6 +23,11 @@ int elfu_mCheck(ElfuElf *me); ElfuScn* elfu_mCloneScn(ElfuScn *ms); +void elfu_mDumpPhdr(ElfuElf *me, ElfuPhdr *mp); +void elfu_mDumpScn(ElfuElf *me, ElfuScn *ms); +void elfu_mDumpElf(ElfuElf *me); + + ElfuElf* elfu_mFromElf(Elf *e); void elfu_mToElf(ElfuElf *me, Elf *e); diff --git a/src/main.c b/src/main.c index 2c6268c..1672ab4 100644 --- a/src/main.c +++ b/src/main.c @@ -58,6 +58,9 @@ int main(int argc, char **argv) if (me) { closeElf(&hIn); printf("Model successfully loaded.\n"); + + elfu_mDumpElf(me); + elfu_mCheck(me); printf("Input model checked.\n"); } else { diff --git a/src/model/dump.c b/src/model/dump.c new file mode 100644 index 0000000..882ba0a --- /dev/null +++ b/src/model/dump.c @@ -0,0 +1,222 @@ +#include +#include + + +static char* segmentTypeStr(Elf32_Word p_type) +{ + switch(p_type) { + case PT_NULL: /* 0 */ + return "NULL"; + case PT_LOAD: /* 1 */ + return "LOAD"; + case PT_DYNAMIC: /* 2 */ + return "DYNAMIC"; + case PT_INTERP: /* 3 */ + return "INTERP"; + case PT_NOTE: /* 4 */ + return "NOTE"; + case PT_SHLIB: /* 5 */ + return "SHLIB"; + case PT_PHDR: /* 6 */ + return "PHDR"; + case PT_TLS: /* 7 */ + return "TLS"; + case PT_NUM: /* 8 */ + return "NUM"; + case PT_GNU_EH_FRAME: /* 0x6474e550 */ + return "GNU_EH_FRAME"; + case PT_GNU_STACK: /* 0x6474e551 */ + return "GNU_STACK"; + case PT_GNU_RELRO: /* 0x6474e552 */ + return "GNU_RELRO"; + } + + return "-?-"; +} + +static char* sectionTypeStr(Elf32_Word sh_type) +{ + switch(sh_type) { + case SHT_NULL: /* 0 */ + return "NULL"; + case SHT_PROGBITS: /* 1 */ + return "PROGBITS"; + case SHT_SYMTAB: /* 2 */ + return "SYMTAB"; + case SHT_STRTAB: /* 3 */ + return "STRTAB"; + case SHT_RELA: /* 4 */ + return "RELA"; + case SHT_HASH: /* 5 */ + return "HASH"; + case SHT_DYNAMIC: /* 6 */ + return "DYNAMIC"; + case SHT_NOTE: /* 7 */ + return "NOTE"; + case SHT_NOBITS: /* 8 */ + return "NOBITS"; + case SHT_REL: /* 9 */ + return "REL"; + case SHT_SHLIB: /* 10 */ + return "SHLIB"; + case SHT_DYNSYM: /* 11 */ + return "DYNSYM"; + case SHT_INIT_ARRAY: /* 14 */ + return "INIT_ARRAY"; + case SHT_FINI_ARRAY: /* 15 */ + return "FINI_ARRAY"; + case SHT_PREINIT_ARRAY: /* 16 */ + return "PREINIT_ARRAY"; + case SHT_GROUP: /* 17 */ + return "SHT_GROUP"; + case SHT_SYMTAB_SHNDX: /* 18 */ + return "SYMTAB_SHNDX"; + case SHT_NUM: /* 19 */ + return "NUM"; + + case SHT_GNU_ATTRIBUTES: /* 0x6ffffff5 */ + return "GNU_ATTRIBUTES"; + case SHT_GNU_HASH: /* 0x6ffffff6 */ + return "GNU_HASH"; + case SHT_GNU_LIBLIST: /* 0x6ffffff7 */ + return "GNU_LIBLIST"; + case SHT_GNU_verdef: /* 0x6ffffffd */ + return "GNU_verdef"; + case SHT_GNU_verneed: /* 0x6ffffffe */ + return "GNU_verneed"; + case SHT_GNU_versym: /* 0x6fffffff */ + return "GNU_versym"; + } + + return "-?-"; +} + + + + +void elfu_mDumpPhdr(ElfuElf *me, ElfuPhdr *mp) +{ + assert(me); + assert(mp); + + ELFU_INFO("%12s %8jx %8jx %8jx %8jx %8jx %8jx %8jx %8jx\n", + segmentTypeStr(mp->phdr.p_type), + (uintmax_t) mp->phdr.p_type, + (uintmax_t) mp->phdr.p_offset, + (uintmax_t) mp->phdr.p_vaddr, + (uintmax_t) mp->phdr.p_paddr, + (uintmax_t) mp->phdr.p_filesz, + (uintmax_t) mp->phdr.p_memsz, + (uintmax_t) mp->phdr.p_flags, + (uintmax_t) mp->phdr.p_align); + + if (!CIRCLEQ_EMPTY(&mp->childPhdrList)) { + ElfuPhdr *mpc; + + ELFU_INFO(" -> Child PHDRs:\n"); + CIRCLEQ_FOREACH(mpc, &mp->childPhdrList, elemChildPhdr) { + ELFU_INFO(" * %-8s @ %8jx\n", + segmentTypeStr(mpc->phdr.p_type), + mpc->phdr.p_vaddr); + } + } + + if (!CIRCLEQ_EMPTY(&mp->childScnList)) { + ElfuScn *msc; + + ELFU_INFO(" -> Child sections:\n"); + CIRCLEQ_FOREACH(msc, &mp->childScnList, elemChildScn) { + ELFU_INFO(" * %-17s @ %8jx\n", + elfu_mScnName(me, msc), + msc->shdr.sh_addr); + } + } +} + + +void elfu_mDumpScn(ElfuElf *me, ElfuScn *ms) +{ + char *namestr, *typestr, *linkstr, *infostr; + + assert(me); + assert(ms); + + namestr = elfu_mScnName(me, ms); + typestr = sectionTypeStr(ms->shdr.sh_type); + linkstr = ms->linkptr ? elfu_mScnName(me, ms->linkptr) : ""; + infostr = ms->infoptr ? elfu_mScnName(me, ms->infoptr) : ""; + + ELFU_INFO("%-17s %-15s %8jx %9jx %8jx %2jx %2jx %2jd %-17s %-17s\n", + namestr, + typestr, + ms->shdr.sh_addr, + ms->shdr.sh_offset, + ms->shdr.sh_size, + ms->shdr.sh_entsize, + ms->shdr.sh_flags, + ms->shdr.sh_addralign, + linkstr, + infostr); +} + + +void elfu_mDumpEhdr(ElfuElf *me) +{ + assert(me); + + ELFU_INFO("ELF header:\n"); + ELFU_INFO(" %d-bit ELF object\n", me->elfclass == ELFCLASS32 ? 32 : 64); + + ELFU_INFO(" EHDR:\n"); + + ELFU_INFO(" e_type %8x\n", me->ehdr.e_type); + ELFU_INFO(" e_machine %8x\n", me->ehdr.e_machine); + ELFU_INFO(" e_version %8x\n", me->ehdr.e_version); + ELFU_INFO(" e_entry %8jx\n", me->ehdr.e_entry); + ELFU_INFO(" e_phoff %8jx\n", me->ehdr.e_phoff); + ELFU_INFO(" e_shoff %8jx\n", me->ehdr.e_shoff); + ELFU_INFO(" e_flags %8x\n", me->ehdr.e_flags); + ELFU_INFO(" e_ehsize %8x\n", me->ehdr.e_ehsize); + ELFU_INFO(" e_phentsize %8x\n", me->ehdr.e_phentsize); + ELFU_INFO(" e_shentsize %8x\n", me->ehdr.e_shentsize); + + ELFU_INFO(" shstrtab: %s\n", me->shstrtab ? elfu_mScnName(me, me->shstrtab) : "(none)"); +} + + +void elfu_mDumpElf(ElfuElf *me) +{ + ElfuPhdr *mp; + ElfuScn *ms; + size_t i; + + assert(me); + + + elfu_mDumpEhdr(me); + ELFU_INFO("\n"); + + + ELFU_INFO("Segments:\n"); + ELFU_INFO(" # (type) p_type p_offset p_vaddr p_paddr p_filesz p_memsz p_flags p_align\n"); + ELFU_INFO(" | | | | | | | | | \n"); + i = 0; + CIRCLEQ_FOREACH(mp, &me->phdrList, elem) { + printf(" [%4d] ", i); + elfu_mDumpPhdr(me, mp); + i++; + } + ELFU_INFO("\n"); + + + ELFU_INFO("Sections:\n"); + ELFU_INFO(" # Name sh_type sh_addr sh_offset sh_size ES Fl Al sh_link sh_info \n"); + ELFU_INFO(" | | | | | | | | | | \n"); + i = 1; + CIRCLEQ_FOREACH(ms, &me->scnList, elem) { + printf(" [%4d] ", i); + elfu_mDumpScn(me, ms); + i++; + } + ELFU_INFO("\n"); +} -- 2.30.2