# HG changeset patch # User Michael Spacefalcon # Date 1404435273 0 # Node ID c25367bb7656ba55e679438c0e723f2f65417d72 # Parent 861f5ca49581e8c1837670af2299ce0ec3561c74 objgrep: written, compiles diff -r 861f5ca49581 -r c25367bb7656 .hgignore --- a/.hgignore Mon Jun 30 18:00:09 2014 +0000 +++ b/.hgignore Fri Jul 04 00:54:33 2014 +0000 @@ -36,6 +36,8 @@ ^mysteryffs/extract$ ^mysteryffs/scan1$ +^objgrep/objgrep$ + ^pirollback/analyze$ ^pirollback/catino$ ^pirollback/dumpjournal$ diff -r 861f5ca49581 -r c25367bb7656 objgrep/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/objgrep/Makefile Fri Jul 04 00:54:33 2014 +0000 @@ -0,0 +1,18 @@ +CC= gcc +CFLAGS= -O2 +PROG= objgrep +OBJS= globals.o grep.o lowlevel.o main.o mkpattern.o tables.o +HDRS= coffconst.h filestruct.h globals.h intstruct.h + +all: ${PROG} + +${PROG}: ${OBJS} + ${CC} -o $@ ${OBJS} + +${OBJS}: ${HDRS} + +install: + install -c -o bin -g bin -m 755 ${PROG} /usr/local/bin + +clean: + rm -f *.o ${PROG} *errs diff -r 861f5ca49581 -r c25367bb7656 objgrep/coffconst.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/objgrep/coffconst.h Fri Jul 04 00:54:33 2014 +0000 @@ -0,0 +1,62 @@ +/********************** STORAGE CLASSES **********************/ + +#define C_NULL 0 +#define C_AUTO 1 /* automatic variable */ +#define C_EXT 2 /* external symbol */ +#define C_STAT 3 /* static */ +#define C_REG 4 /* register variable */ +#define C_EXTREF 5 /* external reference */ +#define C_LABEL 6 /* label */ +#define C_ULABEL 7 /* undefined label */ +#define C_MOS 8 /* member of structure */ +#define C_ARG 9 /* function argument */ +#define C_STRTAG 10 /* structure tag */ +#define C_MOU 11 /* member of union */ +#define C_UNTAG 12 /* union tag */ +#define C_TPDEF 13 /* type definition */ +#define C_USTATIC 14 /* undefined static */ +#define C_ENTAG 15 /* enumeration tag */ +#define C_MOE 16 /* member of enumeration */ +#define C_REGPARM 17 /* register parameter */ +#define C_FIELD 18 /* bit field */ +#define C_UEXT 19 /* Tentative external definition */ +#define C_STATLAB 20 /* Static load time label */ +#define C_EXTLAB 21 /* External load time label */ +#define C_SYSTEM 23 /* System Wide variable */ +#define C_VARARG 27 /* from TI's spraao8.pdf */ +#define C_BLOCK 100 /* ".bb" or ".eb" */ +#define C_FCN 101 /* ".bf" or ".ef" */ +#define C_EOS 102 /* end of structure */ +#define C_FILE 103 /* file name */ +#define C_LINE 104 /* line # reformatted as symbol table entry */ + +/* Type of a symbol, in low 4 bits of the word. */ + +#define T_VOID 0 /* seen in void ptrs in our objects */ +#define T_CHAR 2 /* character */ +#define T_SHORT 3 /* short integer */ +#define T_INT 4 /* integer */ +#define T_LONG 5 /* long integer */ +#define T_FLOAT 6 /* floating point */ +#define T_DOUBLE 7 /* double word */ +#define T_STRUCT 8 /* structure */ +#define T_UNION 9 /* union */ +#define T_ENUM 10 /* enumeration */ +#define T_MOE 11 /* member of enumeration*/ +#define T_UCHAR 12 /* unsigned character */ +#define T_USHORT 13 /* unsigned short */ +#define T_UINT 14 /* unsigned integer */ +#define T_ULONG 15 /* unsigned long */ + +/* Derived types, in n_type. */ + +#define DT_NON 0 /* no derived type */ +#define DT_PTR 1 /* pointer */ +#define DT_FCN 2 /* function */ +#define DT_ARY 3 /* array */ + +/* Reloc types */ + +#define RTYPE_LONG 0x11 +#define RTYPE_THUMB_BL 0x16 +#define RTYPE_ARM_B 0x17 diff -r 861f5ca49581 -r c25367bb7656 objgrep/filestruct.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/objgrep/filestruct.h Fri Jul 04 00:54:33 2014 +0000 @@ -0,0 +1,46 @@ +/* + * Here we are going to define the structures found in the COFF artifact + * file to be analyzed. + */ + +struct external_filehdr { + u_char f_magic[2]; /* magic number */ + u_char f_nscns[2]; /* number of sections */ + u_char f_timdat[4]; /* time & date stamp */ + u_char f_symptr[4]; /* file pointer to symtab */ + u_char f_nsyms[4]; /* number of symtab entries */ + u_char f_opthdr[2]; /* sizeof(optional hdr) */ + u_char f_flags[2]; /* flags */ + u_char f_target_id[2]; /* magic no. (TI COFF-specific) */ +}; + +struct external_scnhdr { + u_char s_name[8]; /* section name */ + u_char s_paddr[4]; /* physical address, aliased s_nlib */ + u_char s_vaddr[4]; /* virtual address */ + u_char s_size[4]; /* section size (in WORDS) */ + u_char s_scnptr[4]; /* file ptr to raw data for section */ + u_char s_relptr[4]; /* file ptr to relocation */ + u_char s_lnnoptr[4]; /* file ptr to line numbers */ + u_char s_nreloc[4]; /* number of relocation entries */ + u_char s_nlnno[4]; /* number of line number entries*/ + u_char s_flags[4]; /* flags */ + u_char s_reserved[2]; /* reserved */ + u_char s_page[2]; /* section page number (LOAD) */ +}; + +struct external_syment { + u_char e_name[8]; + u_char e_value[4]; + u_char e_scnum[2]; + u_char e_type[2]; + u_char e_sclass; + u_char e_numaux; +}; + +struct external_reloc { + u_char r_vaddr[4]; + u_char r_symndx[4]; + u_char r_reserved[2]; /* extended pmad byte for COFF2 */ + u_char r_type[2]; +}; diff -r 861f5ca49581 -r c25367bb7656 objgrep/globals.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/objgrep/globals.c Fri Jul 04 00:54:33 2014 +0000 @@ -0,0 +1,23 @@ +/* + * Definitions of global vars for the objgrep program, based on tiobjd. + */ + +#include + +char *objfilename, *binfilename; +u_char *objfilemap, *binfilemap; +size_t objfile_tot_size, binfile_tot_size; + +struct external_filehdr *filehdr_struct; +struct external_scnhdr *sections_raw; +unsigned nsections; +struct external_syment *symtab_raw; +unsigned nsymtab; +unsigned strtab_offset; + +struct internal_scnhdr *sections, *grep_section; +struct internal_syment **symtab; +u_char *pattern_match, *pattern_mask; +unsigned pattern_len; +struct internal_reloc *relocs; +unsigned match_offset; diff -r 861f5ca49581 -r c25367bb7656 objgrep/globals.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/objgrep/globals.h Fri Jul 04 00:54:33 2014 +0000 @@ -0,0 +1,21 @@ +/* + * extern declarations of global vars for the objgrep program, based on tiobjd. + */ + +extern char *objfilename, *binfilename; +extern u_char *objfilemap, *binfilemap; +extern size_t objfile_tot_size, binfile_tot_size; + +extern struct external_filehdr *filehdr_struct; +extern struct external_scnhdr *sections_raw; +extern unsigned nsections; +extern struct external_syment *symtab_raw; +extern unsigned nsymtab; +extern unsigned strtab_offset; + +extern struct internal_scnhdr *sections, *grep_section; +extern struct internal_syment **symtab; +extern u_char *pattern_match, *pattern_mask; +extern unsigned pattern_len; +extern struct internal_reloc *relocs; +extern unsigned match_offset; diff -r 861f5ca49581 -r c25367bb7656 objgrep/grep.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/objgrep/grep.c Fri Jul 04 00:54:33 2014 +0000 @@ -0,0 +1,35 @@ +/* + * objgrep: the actual grep operation + */ + +#include +#include +#include +#include +#include +#include +#include "globals.h" + +do_grep() +{ + uint32_t *match, *mask, *haystack; + unsigned matchlen_words, haystack_len_words, haystack_limit; + unsigned i, j; + + match = (uint32_t *)pattern_match; + mask = (uint32_t *)pattern_mask; + haystack = (uint32_t *)binfilemap; + matchlen_words = pattern_len >> 2; + haystack_len_words = binfile_tot_size >> 2; + haystack_limit = haystack_len_words - matchlen_words; + for (i = 0; i <= haystack_limit; i++) { + for (j = 0; j < matchlen_words; j++) + if ((haystack[i+j] & mask[j]) != match[j]) + goto haystack_next; + /* got a match! */ + match_offset = i << 2; + return(1); +haystack_next: continue; + } + return(0); +} diff -r 861f5ca49581 -r c25367bb7656 objgrep/intstruct.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/objgrep/intstruct.h Fri Jul 04 00:54:33 2014 +0000 @@ -0,0 +1,35 @@ +/* + * The structures defined in this header file + * are internal to our utility. + */ + +struct internal_scnhdr { + char *name; + unsigned size; + unsigned data_offset; + unsigned reloc_offset; + unsigned line_offset; + unsigned nreloc; + unsigned nlineent; + unsigned flags; + unsigned nsymbols; +}; + +struct internal_syment { + unsigned number; + char *name; + unsigned value; + int scnum; + int type; + int class; + u_char *aux; + struct internal_scnhdr *section; +}; + +struct internal_reloc { + unsigned location; + struct internal_scnhdr *secbase; + struct internal_syment *extsym; + int type; + unsigned addend; +}; diff -r 861f5ca49581 -r c25367bb7656 objgrep/lowlevel.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/objgrep/lowlevel.c Fri Jul 04 00:54:33 2014 +0000 @@ -0,0 +1,89 @@ +/* + * This C module implements the low-level steps of file mapping and access. + */ + +#include +#include +#include +#include +#include +#include +#include +#include "globals.h" + +mmap_objfile() +{ + int fd; + struct stat st; + + fd = open(objfilename, O_RDONLY); + if (fd < 0) { + perror(objfilename); + exit(2); + } + fstat(fd, &st); + if (!S_ISREG(st.st_mode)) { + fprintf(stderr, "error: %s is not a regular file\n", + objfilename); + exit(2); + } + objfile_tot_size = st.st_size; + objfilemap = mmap(NULL, objfile_tot_size, PROT_READ, MAP_PRIVATE, + fd, 0L); + if (objfilemap == MAP_FAILED) { + perror("mmap"); + exit(2); + } + close(fd); +} + +mmap_binfile() +{ + int fd; + struct stat st; + + fd = open(binfilename, O_RDONLY); + if (fd < 0) { + perror(binfilename); + exit(2); + } + fstat(fd, &st); + if (!S_ISREG(st.st_mode)) { + fprintf(stderr, "error: %s is not a regular file\n", + binfilename); + exit(2); + } + binfile_tot_size = st.st_size; + binfilemap = mmap(NULL, binfile_tot_size, PROT_READ, MAP_PRIVATE, + fd, 0L); + if (binfilemap == MAP_FAILED) { + perror("mmap"); + exit(2); + } + close(fd); +} + +unsigned +get_u16(ptr) + u_char *ptr; +{ + return ptr[0] | ptr[1] << 8; +} + +get_s16(ptr) + u_char *ptr; +{ + int i; + + i = ptr[0] | ptr[1] << 8; + if (i >= 32768) + i -= 65536; + return(i); +} + +unsigned +get_u32(ptr) + u_char *ptr; +{ + return ptr[0] | ptr[1] << 8 | ptr[2] << 16 | ptr[3] << 24; +} diff -r 861f5ca49581 -r c25367bb7656 objgrep/main.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/objgrep/main.c Fri Jul 04 00:54:33 2014 +0000 @@ -0,0 +1,48 @@ +/* + * objgrep main() function + */ + +#include +#include +#include +#include +#include +#include "globals.h" +#include "intstruct.h" + +main(argc, argv) + char **argv; +{ + unsigned n; + + if (argc != 4) { + fprintf(stderr, "usage: %s
\n", + argv[0]); + exit(2); + } + objfilename = argv[1]; + mmap_objfile(); + initial_parse_hdr(); + get_int_section_table(); + for (n = 0; n < nsections; n++) + if (!strcmp(sections[n].name, argv[2])) { + grep_section = sections + n; + break; + } + if (!grep_section) { + fprintf(stderr, "no section named \"%s\" found in %s\n", + argv[2], objfilename); + exit(2); + } + get_int_symbol_table(); + prepare_pattern(); + binfilename = argv[3]; + mmap_binfile(); + if (!do_grep()) { + printf("no match\n"); + exit(1); + } + printf("%s:%s found in %s at 0x%x\n", objfilename, grep_section->name, + binfilename, match_offset); + exit(0); +} diff -r 861f5ca49581 -r c25367bb7656 objgrep/mkpattern.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/objgrep/mkpattern.c Fri Jul 04 00:54:33 2014 +0000 @@ -0,0 +1,178 @@ +/* + * objgrep: preparation of matching pattern + */ + +#include +#include +#include +#include +#include +#include +#include "filestruct.h" +#include "intstruct.h" +#include "coffconst.h" +#include "globals.h" + +extern unsigned get_u16(), get_u32(); + +static unsigned +arm_branch_reloc(origbits, location) + u_char *origbits; + unsigned location; +{ + unsigned word, dest; + + word = get_u32(origbits + location); + if ((word & 0x0E000000) != 0x0A000000) { + fprintf(stderr, + "error: invalid ARM_B reloc: opcode not B or BL\n"); + exit(2); + } + dest = (word & 0x00FFFFFF) << 2; + if (dest & 0x02000000) + dest |= 0xFC000000; + dest += location + 8; + return(dest); +} + +static unsigned +thumb_bl_reloc(origbits, location) + u_char *origbits; + unsigned location; +{ + unsigned ins1, ins2; + unsigned dest; + + ins1 = get_u16(origbits + location); + ins2 = get_u16(origbits + location + 2); + if ((ins1 & 0xF800) != 0xF000 || (ins2 & 0xF800) != 0xF800) { + fprintf(stderr, + "error: invalid Thumb_BL reloc: opcode not BL\n"); + exit(2); + } + dest = ((ins1 & 0x7FF) << 12) | ((ins2 & 0x7FF) << 1); + if (dest & 0x00400000) + dest |= 0xFF800000; + dest += location + 4; + return(dest); +} + +prepare_pattern() +{ + u_char *origbits; + unsigned pad, n; + struct internal_reloc *irel; + struct external_reloc *xrel; + unsigned lastloc, symidx; + struct internal_syment *sym; + + origbits = objfilemap + grep_section->data_offset; + pattern_len = (grep_section->size + 3) & ~3; + pattern_match = malloc(pattern_len); + if (!pattern_match) { + perror("malloc"); + exit(2); + } + bcopy(origbits, pattern_match, grep_section->size); + pattern_mask = malloc(pattern_len); + if (!pattern_mask) { + perror("malloc"); + exit(2); + } + memset(pattern_mask, 0xFF, grep_section->size); + pad = pattern_len - grep_section->size; + if (pad) { + bzero(pattern_match + grep_section->size, pad); + bzero(pattern_mask + grep_section->size, pad); + } + if (!grep_section->nreloc) + return(0); + xrel = (struct external_reloc *) + (objfilemap + grep_section->reloc_offset); + irel = malloc(sizeof(struct internal_reloc) * grep_section->nreloc); + if (!irel) { + perror("malloc"); + exit(2); + } + relocs = irel; + for (n = 0; n < grep_section->nreloc; n++, xrel++, irel++) { + irel->location = get_u32(xrel->r_vaddr); + if (n && irel->location < lastloc) { + fprintf(stderr, "error: non-increasing reloc order\n"); + exit(2); + } + lastloc = irel->location + 4; + if (lastloc > grep_section->size) { + fprintf(stderr, + "error: reloc spills past the end of the section\n"); + exit(2); + } + symidx = get_u32(xrel->r_symndx); + if (symidx == 0xFFFFFFFF) + sym = 0; + else if (symidx >= nsymtab || !symtab[symidx]) { + fprintf(stderr, + "error: reloc references invalid symbol #%u\n", + symidx); + exit(2); + } else + sym = symtab[symidx]; + if (sym && sym->value) { + fprintf(stderr, + "error: symbol #%u referenced by reloc has nonzero value\n"); + exit(2); + } + if (!sym) { + irel->secbase = grep_section; + irel->extsym = 0; + } else if (sym->class == C_EXT && !sym->scnum == 0) { + irel->extsym = sym; + irel->secbase = 0; + } else if (sym->class == C_STAT && sym->section && + !strcmp(sym->name, sym->section->name)) { + irel->secbase = sym->section; + irel->extsym = 0; + } else { + fprintf(stderr, "error: unable to grok reloc\n"); + exit(2); + } + irel->type = get_u16(xrel->r_type); + switch (irel->type) { + case RTYPE_LONG: + if (irel->location & 3) { +align_error: fprintf(stderr, "error: misaligned reloc\n"); + exit(2); + } + irel->addend = get_u32(origbits + irel->location); + *(uint32_t *)(pattern_match + irel->location) = 0; + *(uint32_t *)(pattern_mask + irel->location) = 0; + break; + case RTYPE_ARM_B: + if (irel->location & 3) + goto align_error; + irel->addend = arm_branch_reloc(origbits, + irel->location); + bzero(pattern_match + irel->location, 3); + bzero(pattern_mask + irel->location, 3); + break; + case RTYPE_THUMB_BL: + if (irel->location & 1) + goto align_error; + irel->addend = thumb_bl_reloc(origbits, irel->location); + pattern_match[irel->location+0] = 0; + pattern_match[irel->location+1] &= 0xF8; + pattern_match[irel->location+2] = 0; + pattern_match[irel->location+3] &= 0xF8; + pattern_mask[irel->location+0] = 0; + pattern_mask[irel->location+1] = 0xF8; + pattern_mask[irel->location+2] = 0; + pattern_mask[irel->location+3] = 0xF8; + break; + default: + fprintf(stderr, "error: reloc type 0x%x unsupported\n", + irel->type); + exit(2); + } + } + return(1); +} diff -r 861f5ca49581 -r c25367bb7656 objgrep/tables.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/objgrep/tables.c Fri Jul 04 00:54:33 2014 +0000 @@ -0,0 +1,171 @@ +/* + * This C module contains functions for the initial parsing + * of the section and symbol tables. + */ + +#include +#include +#include +#include +#include +#include "filestruct.h" +#include "intstruct.h" +#include "globals.h" + +extern unsigned get_u16(), get_u32(); + +initial_parse_hdr() +{ + unsigned symtab_offset; + + filehdr_struct = (struct external_filehdr *) objfilemap; + if (get_u16(filehdr_struct->f_magic) != 0xC2) { + fprintf(stderr, "error: %s is not a TI COFF2 object\n", + objfilename); + exit(2); + } + if (get_u16(filehdr_struct->f_target_id) != 0x97) { + fprintf(stderr, "error: TI COFF object %s is not for TMS470\n", + objfilename); + exit(2); + } + if (get_u16(filehdr_struct->f_opthdr)) { + fprintf(stderr, + "error: %s has the \"optional\" header present\n", + objfilename); + exit(2); + } + sections_raw = (struct external_scnhdr *) + (objfilemap + sizeof(struct external_filehdr)); + nsections = get_u16(filehdr_struct->f_nscns); + symtab_offset = get_u32(filehdr_struct->f_symptr); + symtab_raw = (struct external_syment *)(objfilemap + symtab_offset); + nsymtab = get_u32(filehdr_struct->f_nsyms); + strtab_offset = symtab_offset + + sizeof(struct external_syment) * nsymtab; +} + +static char * +get_secorsym_name(ptr) + u_char *ptr; +{ + char *alloc; + + if (ptr[0]) { + if (ptr[7]) { + alloc = malloc(9); + if (!alloc) { + perror("malloc"); + exit(2); + } + bcopy(ptr, alloc, 8); + alloc[8] = '\0'; + return(alloc); + } else + return((char *) ptr); + } + if (ptr[1] || ptr[2] || ptr[3]) { + fprintf(stderr, "error: malformed name in %s at offset 0x%x\n", + objfilename, ptr - objfilemap); + exit(2); + } + return(objfilemap + strtab_offset + get_u32(ptr+4)); +} + +get_int_section_table() +{ + unsigned n; + + sections = malloc(sizeof(struct internal_scnhdr) * nsections); + if (!sections) { + perror("malloc"); + exit(2); + } + for (n = 0; n < nsections; n++) { + sections[n].name = get_secorsym_name(sections_raw[n].s_name); + if (get_u32(sections_raw[n].s_paddr)) + fprintf(stderr, + "warning: section #%u (%s) has nonzero paddr\n", + n, sections[n].name); + if (get_u32(sections_raw[n].s_vaddr)) + fprintf(stderr, + "warning: section #%u (%s) has nonzero vaddr\n", + n, sections[n].name); + sections[n].size = get_u32(sections_raw[n].s_size); + sections[n].data_offset = get_u32(sections_raw[n].s_scnptr); + sections[n].reloc_offset = get_u32(sections_raw[n].s_relptr); + sections[n].line_offset = get_u32(sections_raw[n].s_lnnoptr); + sections[n].nreloc = get_u32(sections_raw[n].s_nreloc); + sections[n].nlineent = get_u32(sections_raw[n].s_nlnno); + sections[n].flags = get_u32(sections_raw[n].s_flags); + if (get_u16(sections_raw[n].s_reserved)) + fprintf(stderr, + "warning: section #%u (%s): some nonzero value in s_reserved bytes\n", + n, sections[n].name); + if (get_u16(sections_raw[n].s_page)) + fprintf(stderr, + "warning: section #%u (%s): some nonzero value in s_page bytes\n", + n, sections[n].name); + sections[n].nsymbols = 0; + } +} + +get_int_symbol_table() +{ + unsigned n; + struct internal_syment *in; + + symtab = malloc(sizeof(struct internal_syment *) * nsymtab); + if (!symtab) { + perror("malloc"); + exit(2); + } + for (n = 0; n < nsymtab; ) { + in = malloc(sizeof(struct internal_syment)); + if (!in) { + perror("malloc"); + exit(2); + } + symtab[n] = in; + in->number = n; + in->name = get_secorsym_name(symtab_raw[n].e_name); + in->value = get_u32(symtab_raw[n].e_value); + in->scnum = get_s16(symtab_raw[n].e_scnum); + if (in->scnum > 0) { + if (in->scnum > nsections) { + fprintf(stderr, + "symtab entry #%u: scnum too big\n", n); + exit(2); + } + in->section = sections + in->scnum - 1; + in->section->nsymbols++; + } else if (in->scnum < -2) { + fprintf(stderr, + "symtab entry #%u: scnum < -2\n", n); + exit(2); + } else + in->section = 0; + in->type = get_u16(symtab_raw[n].e_type); + in->class = symtab_raw[n].e_sclass; + switch (symtab_raw[n++].e_numaux) { + case 0: + in->aux = 0; + continue; + case 1: + if (n >= nsymtab) { + fprintf(stderr, + "error: last symbol's aux spills over\n"); + exit(2); + } + symtab[n] = 0; + in->aux = (u_char *)(symtab_raw + n); + n++; + continue; + default: + n--; + fprintf(stderr, "symtab entry #%u: invalid numaux\n", + n); + exit(2); + } + } +}