summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/libelfu/modelops.h5
-rw-r--r--src/main.c3
-rw-r--r--src/model/dump.c222
3 files changed, 230 insertions, 0 deletions
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 <assert.h>
+#include <libelfu/libelfu.h>
+
+
+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");
+}