FreeCalypso > hg > freecalypso-reveng
view objgrep/dumpmatch.c @ 173:77cd647375e5
objgrep -r: dump symbols in other sections recovered through relocs
author | Michael Spacefalcon <msokolov@ivan.Harhan.ORG> |
---|---|
date | Fri, 04 Jul 2014 06:34:33 +0000 |
parents | 452baa748747 |
children |
line wrap: on
line source
/* * objgrep: output on matches */ #include <sys/types.h> #include <stdio.h> #include <stdint.h> #include <stdlib.h> #include <string.h> #include <strings.h> #include "intstruct.h" #include "coffconst.h" #include "globals.h" extern unsigned get_u16(), get_u32(); dump_symtab_on_match() { unsigned n; struct internal_syment *sym; printf("\nThis source section's symbols:\n\n"); for (n = 0; n < nsymtab; n++) { sym = symtab[n]; if (!sym) continue; if (sym->section != grep_section) continue; switch (sym->class) { case C_EXT: printf("%s = %08X\n", sym->name, sym->value + match_offset); continue; case C_STAT: printf("%s:%s = %08X\n", objfilename, sym->name, sym->value + match_offset); continue; } } } static unsigned arm_branch_reloc(location) unsigned location; { unsigned word, dest; word = get_u32(binfilemap + location); dest = (word & 0x00FFFFFF) << 2; if (dest & 0x02000000) dest |= 0xFC000000; dest += location + 8; return(dest); } static unsigned thumb_bl_reloc(location) unsigned location; { unsigned ins1, ins2; unsigned dest; ins1 = get_u16(binfilemap + location); ins2 = get_u16(binfilemap + location + 2); dest = ((ins1 & 0x7FF) << 12) | ((ins2 & 0x7FF) << 1); if (dest & 0x00400000) dest |= 0xFF800000; dest += location + 4; return(dest); } process_relocs_on_match() { unsigned n, value; struct internal_reloc *rel; for (n = 0, rel = relocs; n < grep_section->nreloc; n++, rel++) { switch (rel->type) { case RTYPE_LONG: value = get_u32(binfilemap + match_offset + rel->location); break; case RTYPE_ARM_B: value = arm_branch_reloc(match_offset + rel->location); break; case RTYPE_THUMB_BL: value = thumb_bl_reloc(match_offset + rel->location); break; default: fprintf(stderr, "BUG in dump_relocs_on_match(): bad reloc type\n"); abort(); } value -= rel->addend; rel->symvalue = value; if (rel->secbase) { if (!rel->secbase->recov_flag) { rel->secbase->recov_flag = 1; rel->secbase->recov_addr = value; } else if (rel->secbase->recov_addr != value) printf("Multiple addresses for %s:%s: %08X, %08X\n", objfilename, rel->secbase->name, rel->secbase->recov_addr, value); } } } dump_ext_relocs_on_match() { unsigned n; struct internal_reloc *rel; printf("\nExternals deduced from relocs:\n\n"); for (n = 0, rel = relocs; n < grep_section->nreloc; n++, rel++) if (rel->extsym) printf("%s = %08X\n", rel->extsym->name, rel->symvalue); } dump_reloc_symtab_on_match() { unsigned n; struct internal_syment *sym; printf("\nThis module's symbols deduced from section relocs:\n\n"); for (n = 0; n < nsymtab; n++) { sym = symtab[n]; if (!sym || !sym->section) continue; if (!sym->section->recov_flag) continue; switch (sym->class) { case C_EXT: printf("%s = %08X\n", sym->name, sym->value + sym->section->recov_addr); continue; case C_STAT: printf("%s:%s = %08X\n", objfilename, sym->name, sym->value + sym->section->recov_addr); continue; } } }