Add printing functions for models to ease debugging
authornorly <ny-git@enpas.org>
Tue, 28 May 2013 17:18:55 +0000 (18:18 +0100)
committernorly <ny-git@enpas.org>
Tue, 28 May 2013 17:18:55 +0000 (18:18 +0100)
include/libelfu/modelops.h
src/main.c
src/model/dump.c [new file with mode: 0644]

index 1cfe0b676c89142f57d9c230bf85bcc50b13064f..31a4ed9ac942d89c9db19784ccbf4dd2e8eac1a2 100644 (file)
@@ -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);
 
index 2c6268c6cd9e5a56ae0f1aba511fa60a59f9e219..1672ab41ade4bbbdaaca1766f04f82e3d57b26e7 100644 (file)
@@ -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 (file)
index 0000000..882ba0a
--- /dev/null
@@ -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");
+}