changeset 130:87b82398a08b

leo-obj project subtree started, tiobjd tool moved into it
author Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
date Sun, 06 Apr 2014 22:14:39 +0000
parents 597143ba1c37
children 1209ef15374f
files .hgignore leo-obj/README leo-obj/tool/Makefile leo-obj/tool/README leo-obj/tool/armdis.c leo-obj/tool/atcommon.c leo-obj/tool/basics.c leo-obj/tool/coffconst.h leo-obj/tool/disasm.c leo-obj/tool/filestruct.h leo-obj/tool/globals.c leo-obj/tool/globals.h leo-obj/tool/hints.c leo-obj/tool/intstruct.h leo-obj/tool/lowlevel.c leo-obj/tool/main.c leo-obj/tool/profile.c leo-obj/tool/reloc.c leo-obj/tool/symtab.c leo-obj/tool/tables.c leo-obj/tool/thumbdis.c ticoff/Makefile ticoff/README ticoff/armdis.c ticoff/atcommon.c ticoff/basics.c ticoff/coffconst.h ticoff/disasm.c ticoff/filestruct.h ticoff/globals.c ticoff/globals.h ticoff/hints.c ticoff/intstruct.h ticoff/lowlevel.c ticoff/main.c ticoff/profile.c ticoff/reloc.c ticoff/symtab.c ticoff/tables.c ticoff/thumbdis.c
diffstat 40 files changed, 2620 insertions(+), 2609 deletions(-) [+]
line wrap: on
line diff
--- a/.hgignore	Sun Apr 06 20:20:39 2014 +0000
+++ b/.hgignore	Sun Apr 06 22:14:39 2014 +0000
@@ -10,6 +10,8 @@
 ^compal/c156-boot\.
 ^compal/osmovoodoo
 
+^leo-obj/tool/tiobjd$
+
 ^miscprog/atsc$
 ^miscprog/factdiff$
 ^miscprog/imeibrute$
@@ -31,5 +33,3 @@
 ^pirollback/dumpjournal$
 ^pirollback/inopath$
 ^pirollback/rollback$
-
-^ticoff/tiobjd$
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/leo-obj/README	Sun Apr 06 22:14:39 2014 +0000
@@ -0,0 +1,11 @@
+TI's TCS211 aka Leonardo firmware is a mixture of C sources and linkable object
+modules (packaged into archive libraries) in the COFF format used by TI's TMS470
+compiler toolchain.  One of the goals of the FreeCalypso project is to transform
+this firmware into full C source by analyzing the COFF object blobs with a tool
+that groks the symbolic information present therein, then replacing each blob
+either with a matching source piece from another TI firmware leak (e.g., the one
+in ftp.ifctf.org:/pub/GSM/LoCosto) or with newly written C code that exports
+the same functions and global variables etc, with logic inside matching the
+disassembly of the original.
+
+The present directory tree will hold the just-described project.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/leo-obj/tool/Makefile	Sun Apr 06 22:14:39 2014 +0000
@@ -0,0 +1,19 @@
+CC=	gcc
+CFLAGS=	-O2
+PROG=	tiobjd
+OBJS=	armdis.o atcommon.o basics.o disasm.o globals.o hints.o lowlevel.o \
+	main.o profile.o reloc.o symtab.o tables.o thumbdis.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} *err
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/leo-obj/tool/README	Sun Apr 06 22:14:39 2014 +0000
@@ -0,0 +1,6 @@
+Here I'm going to build a standalone tool that reads linkable (not final)
+object modules produced by TI's TMS470 toolchain, as found in GSM firmware
+semi-sources, and produces disassembly listings that are well-fit for
+understanding the function and interfaces of each object blob, and ultimately
+replacing each of these blobs with functionally and interface-equivalent
+new C code.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/leo-obj/tool/armdis.c	Sun Apr 06 22:14:39 2014 +0000
@@ -0,0 +1,522 @@
+/*
+ * ARM state disassembly
+ */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include "intstruct.h"
+#include "globals.h"
+
+extern unsigned get_u16(), get_u32();
+extern struct internal_reloc *find_word32_reloc();
+
+extern char *regnames[16], *condition_decode[16], *shift_types[4];
+
+static char *dataproc_ops[16] = {"and", "eor", "sub", "rsb",
+				 "add", "adc", "sbc", "rsc",
+				 "tst", "teq", "cmp", "cmn",
+				 "orr", "mov", "bic", "mvn"};
+
+static void
+arm_branch(off, word)
+	unsigned off, word;
+{
+	unsigned dest;
+
+	dest = (word & 0x00FFFFFF) << 2;
+	if (dest & 0x02000000)
+		dest |= 0xFC000000;
+	dest += off + 8;
+	printf("b%s%s\t0x%x\n", word&0x1000000 ? "l" : "",
+		condition_decode[word>>28], dest);
+}
+
+static void
+op2_immed(word)
+	unsigned word;
+{
+	unsigned low8, rot, val;
+
+	low8 = word & 0xFF;
+	rot = (word & 0xF00) >> 7;
+	val = (low8 << (32 - rot)) | (low8 >> rot);
+	if (val <= 9)
+		printf("#%u\n", val);
+	else
+		printf("#%u\t; 0x%x\n", val, val);
+}
+
+static void
+op2_regbyconst(word)
+	unsigned word;
+{
+	unsigned c, t;
+
+	c = (word >> 7) & 0x1F;
+	t = (word >> 5) & 3;
+	if (!c) {
+		switch (t) {
+		case 0:
+			printf("%s", regnames[word&0xF]);
+			return;
+		case 3:
+			printf("%s, rrx", regnames[word&0xF]);
+			return;
+		default:
+			c = 32;
+		}
+	}
+	printf("%s, %s #%u", regnames[word&0xF], shift_types[t], c);
+}
+
+static void
+op2_regbyreg(word)
+	unsigned word;
+{
+	printf("%s, %s %s", regnames[word&0xF], shift_types[(word>>5)&3],
+		regnames[(word>>8)&0xF]);
+}
+
+static void
+op2_regshift(word)
+	unsigned word;
+{
+	if (word & 0x10)
+		op2_regbyreg(word);
+	else
+		op2_regbyconst(word);
+	putchar('\n');
+}
+
+static void
+dataproc_op2(word)
+	unsigned word;
+{
+	if (word & 0x02000000)
+		op2_immed(word);
+	else
+		op2_regshift(word);
+}
+
+static void
+dataproc_tstcmp_overlay(word)
+	unsigned word;
+{
+	char msrmask[5], *cp;
+
+	if ((word & 0x0FFFFFF0) == 0x012FFF10) {
+		printf("bx%s\t%s\n", condition_decode[word>>28],
+			regnames[word&0xF]);
+		return;
+	} else if ((word & 0x0FBF0FFF) == 0x010F0000) {
+		printf("mrs%s\t%s, %cPSR\n", condition_decode[word>>28],
+			regnames[(word>>12)&0xF], word&0x400000 ? 'S' : 'C');
+		return;
+	} else if ((word & 0x0DB0F000) == 0x0120F000) {
+		if (!(word & 0x02000000) && (word & 0xFF0)) {
+			printf("<invalid MSR>\n");
+			return;
+		}
+		if (word & 0xF0000) {
+			cp = msrmask;
+			if (word & 0x80000)
+				*cp++ = 'f';
+			if (word & 0x40000)
+				*cp++ = 's';
+			if (word & 0x20000)
+				*cp++ = 'x';
+			if (word & 0x10000)
+				*cp++ = 'c';
+			*cp = '\0';
+		} else
+			strcpy(msrmask, "null");
+		printf("msr%s\t%cPSR_%s, ", condition_decode[word>>28],
+			word&0x400000 ? 'S' : 'C', msrmask);
+		dataproc_op2(word);
+		return;
+	}
+	printf("<invalid BX/MRS/MSR>\n");
+}
+
+static void
+dataproc(word)
+	unsigned word;
+{
+	unsigned opc;
+
+	opc = (word >> 21) & 0xF;
+	switch (opc) {
+	case 0:
+	case 1:
+	case 2:
+	case 3:
+	case 4:
+	case 5:
+	case 6:
+	case 7:
+	case 0xC:
+	case 0xE:
+		printf("%s%s%s\t%s, %s, ", dataproc_ops[opc],
+			condition_decode[word>>28], word&0x100000 ? "s" : "",
+			regnames[(word>>12)&0xF], regnames[(word>>16)&0xF]);
+		dataproc_op2(word);
+		return;
+	case 0xD:
+	case 0xF:
+		printf("%s%s%s\t%s, ", dataproc_ops[opc],
+			condition_decode[word>>28], word&0x100000 ? "s" : "",
+			regnames[(word>>12)&0xF]);
+		dataproc_op2(word);
+		return;
+	case 8:
+	case 9:
+	case 0xA:
+	case 0xB:
+		if (word & 0x100000) {
+			printf("%s%s\t%s, ", dataproc_ops[opc],
+				condition_decode[word>>28],
+				regnames[(word>>16)&0xF]);
+			dataproc_op2(word);
+		} else
+			dataproc_tstcmp_overlay(word);
+		return;
+	}
+}
+
+static void
+multiply(word)
+	unsigned word;
+{
+	if ((word & 0x0FE000F0) == 0x90)
+		printf("mul%s%s\t%s, %s, %s\n", condition_decode[word>>28],
+			word&0x100000 ? "s" : "", regnames[(word>>16)&0xF],
+			regnames[word&0xF], regnames[(word>>8)&0xF]);
+	else if ((word & 0x0FE000F0) == 0x00200090)
+		printf("mla%s%s\t%s, %s, %s, %s\n", condition_decode[word>>28],
+			word&0x100000 ? "s" : "", regnames[(word>>16)&0xF],
+			regnames[word&0xF], regnames[(word>>8)&0xF],
+			regnames[(word>>12)&0xF]);
+	else if ((word & 0x0F8000F0) == 0x00800090)
+		printf("%c%sl%s%s\t%s, %s, %s, %s\n",
+			word&0x400000 ? 's' : 'u',
+			word&0x200000 ? "mla" : "mul",
+			condition_decode[word>>28],
+			word&0x100000 ? "s" : "",
+			regnames[(word>>12)&0xF], regnames[(word>>16)&0xF],
+			regnames[word&0xF], regnames[(word>>8)&0xF]);
+	else if ((word & 0x0FB00FF0) == 0x01000090)
+		printf("swp%s%s\t%s, %s, [%s]\n", condition_decode[word>>28],
+			word&0x400000, "b", "", regnames[(word>>12)&0xF],
+			regnames[word&0xF], regnames[(word>>16)&0xF]);
+	else
+		printf("<invalid multiply>\n");
+}
+
+static int
+check_ldr_litpool(sec, off, word, loff, size)
+	struct internal_scnhdr *sec;
+	unsigned off, word, loff;
+{
+	unsigned litoff, datum;
+	struct internal_reloc *rel;
+
+	/* base reg must be 15 */
+	if (((word >> 16) & 0xF) != 15)
+		return(0);
+	/* must be a load */
+	if (!(word & 0x100000))
+		return(0);
+	/* no writeback allowed */
+	if (word & 0x200000)
+		return(0);
+	/* alignment */
+	if (loff & (size - 1))
+		return(0);
+	/* range */
+	off += 8;
+	if (word & 0x800000)
+		litoff = off + loff;
+	else {
+		if (loff > off)
+			return(0);
+		litoff = off - loff;
+	}
+	if (litoff >= sec->size)
+		return(0);
+	/* all checks passed, proceed */
+	rel = find_word32_reloc(sec, litoff);
+	switch (size) {
+	case 1:
+		datum = filemap[sec->data_offset + litoff];
+		break;
+	case 2:
+		datum = get_u16(filemap + sec->data_offset + litoff);
+		break;
+	case 4:
+		datum = get_u32(filemap + sec->data_offset + litoff);
+		break;
+	}
+	putchar('=');
+	if (rel)
+		disasm_reloc_target(sec, rel, datum);
+	else
+		printf("0x%x", datum);
+	printf("\t; via 0x%x\n", litoff);
+	return(1);
+}
+
+static void
+ldr_str_imm_pre(sec, off, word)
+	struct internal_scnhdr *sec;
+	unsigned off, word;
+{
+	unsigned loff = word & 0xFFF;
+
+	printf("%s%s%s\t%s, ", word&0x100000 ? "ldr" : "str",
+		condition_decode[word>>28], word&0x400000 ? "b" : "",
+		regnames[(word>>12)&0xF]);
+	if (check_ldr_litpool(sec, off, word, loff, word&0x400000 ? 1 : 4))
+		return;
+	printf("[%s", regnames[(word>>16)&0xF]);
+	if (loff || word&0x200000)
+		printf(", #%s%u", word&0x800000 ? "" : "-", loff);
+	putchar(']');
+	if (word & 0x200000)
+		putchar('!');
+	if (loff >= 10)
+		printf("\t; 0x%x", loff);
+	putchar('\n');
+}
+
+static void
+ldr_str_imm_post(word)
+	unsigned word;
+{
+	unsigned loff = word & 0xFFF;
+
+	printf("%s%s%s%s\t%s, [%s], #%s%u", word&0x100000 ? "ldr" : "str",
+		condition_decode[word>>28], word&0x400000 ? "b" : "",
+		word&0x200000 ? "t" : "",
+		regnames[(word>>12)&0xF], regnames[(word>>16)&0xF],
+		word&0x800000 ? "" : "-", loff);
+	if (loff >= 10)
+		printf("\t; 0x%x", loff);
+	putchar('\n');
+}
+
+static void
+ldr_str_reg_pre(word)
+	unsigned word;
+{
+	if (word & 0x10) {
+		printf("<invalid ldr/str: offset reg shift by reg>\n");
+		return;
+	}
+	printf("%s%s%s\t%s, [%s, ", word&0x100000 ? "ldr" : "str",
+		condition_decode[word>>28], word&0x400000 ? "b" : "",
+		regnames[(word>>12)&0xF], regnames[(word>>16)&0xF]);
+	if (!(word & 0x800000))
+		putchar('-');
+	op2_regbyconst(word);
+	putchar(']');
+	if (word & 0x200000)
+		putchar('!');
+	putchar('\n');
+}
+
+static void
+ldr_str_reg_post(word)
+	unsigned word;
+{
+	if (word & 0x10) {
+		printf("<invalid ldr/str: offset reg shift by reg>\n");
+		return;
+	}
+	printf("%s%s%s%s\t%s, [%s], ", word&0x100000 ? "ldr" : "str",
+		condition_decode[word>>28], word&0x400000 ? "b" : "",
+		word&0x200000 ? "t" : "",
+		regnames[(word>>12)&0xF], regnames[(word>>16)&0xF]);
+	if (!(word & 0x800000))
+		putchar('-');
+	op2_regbyconst(word);
+	putchar('\n');
+}
+
+static void
+ldr_str_ext(sec, off, word)
+	struct internal_scnhdr *sec;
+	unsigned off, word;
+{
+	unsigned loff;
+
+	if (!(word&0x01000000) && word&0x200000) {
+		printf("<invalid ldrh/strh: P=0, W=1>\n");
+		return;
+	}
+	if (!(word&0x400000) && word&0xF00) {
+		printf("<invalid ldrh/strh: SBZ!=0>\n");
+		return;
+	}
+	printf("%s%s%s%c\t%s, ", word&0x100000 ? "ldr" : "str",
+		condition_decode[word>>28],
+		word&0x40 ? "s" : "",
+		word&0x20 ? 'h' : 'b',
+		regnames[(word>>12)&0xF]);
+	if (word & 0x400000)
+		loff = ((word & 0xF00) >> 4) | (word & 0xF);
+	switch (word & 0x01400000) {
+	case 0:
+		/* reg post */
+		printf("[%s], %s%s", regnames[(word>>16)&0xF],
+			word&0x800000 ? "" : "-", regnames[word&0xF]);
+		break;
+	case 0x400000:
+		/* imm post */
+		printf("[%s], #%s%u", regnames[(word>>16)&0xF],
+			word&0x800000 ? "" : "-", loff);
+		if (loff >= 10)
+			printf("\t; 0x%x", loff);
+		break;
+	case 0x01000000:
+		/* reg pre */
+		printf("[%s, %s%s]%s", regnames[(word>>16)&0xF],
+			word&0x800000 ? "" : "-", regnames[word&0xF],
+			word&0x200000 ? "!" : "");
+		break;
+	case 0x01400000:
+		/* imm pre */
+		if (check_ldr_litpool(sec, off, word, loff, word&0x20 ? 2 : 1))
+			return;
+		printf("[%s", regnames[(word>>16)&0xF]);
+		if (loff || word&0x200000)
+			printf(", #%s%u", word&0x800000 ? "" : "-", loff);
+		putchar(']');
+		if (word & 0x200000)
+			putchar('!');
+		if (loff >= 10)
+			printf("\t; 0x%x", loff);
+		break;
+	}
+	putchar('\n');
+}
+
+static void
+dataproc_74_overlay(sec, off, word)
+	struct internal_scnhdr *sec;
+	unsigned off, word;
+{
+	if (word & 0x60)
+		ldr_str_ext(sec, off, word);
+	else
+		multiply(word);
+}
+
+static void
+ldm_stm(word)
+	unsigned word;
+{
+	int r, flag;
+
+	printf("%s%s%c%c\t%s", word&0x100000 ? "ldm" : "stm",
+		condition_decode[word>>28],
+		word&0x800000 ? 'i' : 'd', word&0x01000000 ? 'b' : 'a',
+		regnames[(word>>16)&0xF]);
+	if (word & 0x200000)
+		putchar('!');
+	fputs(", {", stdout);
+	flag = 0;
+	for (r = 0; r < 16; r++)
+		if (word & (1 << r)) {
+			if (flag)
+				fputs(", ", stdout);
+			fputs(regnames[r], stdout);
+			flag = 1;
+		}
+	putchar('}');
+	if (word & 0x400000)
+		putchar('^');
+	putchar('\n');
+}
+
+void
+arm_disasm_line(sec, off)
+	struct internal_scnhdr *sec;
+	unsigned off;
+{
+	unsigned word;
+
+	word = get_u32(filemap + sec->data_offset + off);
+	printf("%08x\t", word);
+	if ((word >> 28) == 0xF) {
+		printf("<invalid-F>\n");
+		return;
+	}
+	switch ((word >> 24) & 0xF) {
+	case 0:
+	case 1:
+		if ((word & 0x90) == 0x90)
+			dataproc_74_overlay(sec, off, word);
+		else
+			dataproc(word);
+		return;
+	case 2:
+	case 3:
+		dataproc(word);
+		return;
+	case 4:
+		ldr_str_imm_post(word);
+		return;
+	case 5:
+		ldr_str_imm_pre(sec, off, word);
+		return;
+	case 6:
+		ldr_str_reg_post(word);
+		return;
+	case 7:
+		ldr_str_reg_pre(word);
+		return;
+	case 8:
+	case 9:
+		ldm_stm(word);
+		return;
+	case 0xA:
+	case 0xB:
+		arm_branch(off, word);
+		return;
+	case 0xC:
+	case 0xD:
+	case 0xE:
+		printf("<COPROCESSOR>\n");
+		return;
+	case 0xF:
+		printf("swi%s\t0x%x\n", condition_decode[word>>28],
+			word & 0xFFFFFF);
+		return;
+	}
+}
+
+void
+arm_branch_reloc(sec, rel)
+	struct internal_scnhdr *sec;
+	struct internal_reloc *rel;
+{
+	unsigned word, dest;
+
+	word = get_u32(filemap + sec->data_offset + rel->location);
+	printf("%08x R\t", word);
+	if ((word & 0x0E000000) != 0x0A000000) {
+		printf("<invalid ARM_B reloc: opcode not B or BL>\n");
+		return;
+	}
+	dest = (word & 0x00FFFFFF) << 2;
+	if (dest & 0x02000000)
+		dest |= 0xFC000000;
+	dest += rel->location + 8;
+	printf("b%s%s\t", word&0x1000000 ? "l" : "",
+		condition_decode[word>>28]);
+	disasm_reloc_target(sec, rel, dest);
+	putchar('\n');
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/leo-obj/tool/atcommon.c	Sun Apr 06 22:14:39 2014 +0000
@@ -0,0 +1,14 @@
+/*
+ * Lean and mean ARM7TDMI disassembler
+ * Written by Spacefalcon the Outlaw
+ */
+
+/* a few disassembly bits common between ARM and Thumb */
+
+char *regnames[16] = {"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+			"r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc"};
+
+char *condition_decode[16] = {"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
+				"hi", "ls", "ge", "lt", "gt", "le", "", "INV"};
+
+char *shift_types[4] = {"lsl", "lsr", "asr", "ror"};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/leo-obj/tool/basics.c	Sun Apr 06 22:14:39 2014 +0000
@@ -0,0 +1,74 @@
+/*
+ * This C module implements some "basic" dump commands
+ */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include "filestruct.h"
+#include "intstruct.h"
+#include "globals.h"
+
+extern unsigned get_u16(), get_u32();
+
+dump_filehdr_info()
+{
+	time_t timestamp;
+	struct tm *timedec;
+
+	timestamp = get_u32(filehdr_struct->f_timdat);
+	timedec = gmtime(&timestamp);
+	printf("timestamp: %d-%02d-%02dT%02d:%02d:%02dZ\n",
+		timedec->tm_year + 1900, timedec->tm_mon + 1, timedec->tm_mday,
+		timedec->tm_hour, timedec->tm_min, timedec->tm_sec);
+	printf("file flags: 0x%x\n", get_u16(filehdr_struct->f_flags));
+	printf("%u sections, %u symtab entries\n", nsections, nsymtab);
+	return(0);
+}
+
+dump_sechdr()
+{
+	unsigned n;
+	struct internal_scnhdr *inf;
+
+	for (n = 0; n < nsections; n++) {
+		inf = sections + n;
+		printf("#%d: %s size=%u, flags=0x%x\n", n, inf->name,
+			inf->size, inf->flags);
+		printf("\t%u reloc, %u line entries\n",
+			inf->nreloc, inf->nlineent);
+	}
+	return(0);
+}
+
+cmd_sechdr()
+{
+	get_int_section_table();
+	dump_sechdr();
+	exit(0);
+}
+
+cmd_symtab()
+{
+	get_int_section_table();
+	get_int_symbol_table();
+	dump_symtab();
+	exit(0);
+}
+
+cmd_basics()
+{
+	printf("%s:\n", objfilename);
+	dump_filehdr_info();
+	putchar('\n');
+	get_int_section_table();
+	printf("Sections:\n\n");
+	dump_sechdr();
+	putchar('\n');
+	get_int_symbol_table();
+	printf("Symbol table:\n\n");
+	dump_symtab();
+	putchar('\n');
+	exit(0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/leo-obj/tool/coffconst.h	Sun Apr 06 22:14:39 2014 +0000
@@ -0,0 +1,37 @@
+/********************** 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 */
+
+/* Reloc types */
+
+#define	RTYPE_LONG	0x11
+#define	RTYPE_THUMB_BL	0x16
+#define	RTYPE_ARM_B	0x17
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/leo-obj/tool/disasm.c	Sun Apr 06 22:14:39 2014 +0000
@@ -0,0 +1,414 @@
+/*
+ * Putting it all together: section-, symbol- and reloc-aware disassembly
+ */
+
+#include <sys/types.h>
+#include <stdio.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();
+extern char *storage_class_to_string();
+
+static int auto_xlat_section_relocs = 1;
+
+static void
+find_better_symbol(sec, symp, addp)
+	struct internal_scnhdr *sec;
+	struct internal_syment **symp;
+	unsigned *addp;
+{
+	unsigned addr, delta;
+	struct internal_syment *sym;
+	unsigned n;
+
+	addr = *addp;
+	for (n = 0; n < sec->nsymbols; n++) {
+		sym = sec->sorted_symbols[n];
+		if (sym->value > addr)
+			return;
+		if (sym->class != C_EXT && sym->class != C_STAT)
+			continue;
+		delta = addr - sym->value;
+		if (sym->name[0] == '_' && !delta ||
+		    sym->name[0] == '$' && delta <= 1) {
+			*symp = sym;
+			*addp = delta;
+		}
+	}
+}
+
+void
+disasm_reloc_target(sec, rel, addend)
+	struct internal_scnhdr *sec;
+	struct internal_reloc *rel;
+	unsigned addend;
+{
+	struct internal_syment *sym = rel->sym;
+
+	if (sym)
+		addend -= sym->value;
+	if (auto_xlat_section_relocs &&
+	    (!sym || sym->section && !strcmp(sym->name, sym->section->name)))
+		find_better_symbol(sym ? sym->section : sec, &sym, &addend);
+	if (sym)
+		fputs(sym->name, stdout);
+	else
+		fputs(sec->name, stdout);
+	if (addend >= 10)
+		printf("+0x%x", addend);
+	else if (addend)
+		printf("+%u", addend);
+}
+
+void
+disasm_word32_reloc(sec, rel)
+	struct internal_scnhdr *sec;
+	struct internal_reloc *rel;
+{
+	unsigned word;
+
+	word = get_u32(filemap + sec->data_offset + rel->location);
+	printf("%08x R\t.word\t", word);
+	disasm_reloc_target(sec, rel, word);
+	putchar('\n');
+}
+
+void
+disasm_end_of_section(sec, symnum)
+	struct internal_scnhdr *sec;
+	unsigned symnum;
+{
+	struct internal_syment *sym;
+	char *sym_comment;
+
+	putchar('\n');
+	while (symnum < sec->nsymbols) {
+		sym = sec->sorted_symbols[symnum];
+		if (sym->value != sec->size) {
+			printf("error: expecting symbol at end of section\n");
+			return;
+		}
+		switch (sym->class) {
+		case C_EXT:
+			sym_comment = "Global";
+			break;
+		case C_STAT:
+			sym_comment = "static";
+			break;
+		case C_LABEL:
+			sym_comment = "label";
+			break;
+		default:
+			sym_comment = "unexpected class!";
+		}
+		printf("%s:\t; %s\n", sym->name, sym_comment);
+		symnum++;
+	}
+	printf("%8x:\t<end of section>\n", sec->size);
+}
+
+void
+disasm_text_section(sec)
+	struct internal_scnhdr *sec;
+{
+	unsigned symnum, relnum;
+	unsigned pos, incr, headroom;
+	int state = -1, linebrk = 0;
+	struct internal_syment *sym;
+	struct internal_reloc *rel;
+	char *sym_comment;
+
+	printf("Disassembling code section:\n");
+	if (sec->nsymbols)
+		sort_symbols_of_sec(sec);
+	if (sec->nreloc)
+		get_relocs_of_sec(sec);
+	symnum = relnum = 0;
+	for (pos = 0; pos < sec->size; pos += incr) {
+		headroom = sec->size - pos;
+		while (symnum < sec->nsymbols) {
+			sym = sec->sorted_symbols[symnum];
+			if (sym->value > pos) {
+				if (sym->value - pos < headroom)
+					headroom = sym->value - pos;
+				break;
+			}
+			/* hit symbol */
+			if (!linebrk) {
+				putchar('\n');
+				linebrk = 1;
+			}
+			switch (sym->class) {
+			case C_EXT:
+				sym_comment = "Global";
+				break;
+			case C_STAT:
+				sym_comment = "static";
+				break;
+			case C_LABEL:
+				sym_comment = "label";
+				if (!strcmp(sym->name, "$CODE16"))
+					state = 1;
+				else if (!strcmp(sym->name, "$CODE32"))
+					state = 0;
+				break;
+			default:
+				sym_comment = "unexpected class!";
+			}
+			printf("%s:\t; %s\n", sym->name, sym_comment);
+			symnum++;
+		}
+		if (relnum < sec->nreloc) {
+			rel = sec->int_relocs + relnum;
+			if (rel->location == pos)
+				relnum++;	/* it's ours */
+			else {
+				if (rel->location - pos < headroom)
+					headroom = rel->location - pos;
+				rel = 0;	/* no reloc for current pos */
+			}
+		} else
+			rel = 0;
+		printf("%8x:\t", pos);
+		if (rel && rel->type == RTYPE_LONG) {
+			if (pos & 3) {
+			  printf("MISALIGNED pos for word32 reloc, aborting\n");
+				return;
+			}
+			disasm_word32_reloc(sec, rel);
+			incr = 4;
+			goto next;
+		}
+		if (pos & 1 || headroom < 2) {
+			if (rel) {
+				printf("error: reloc at byte pos, aborting\n");
+				return;
+			}
+			printf("%02x\n", filemap[sec->data_offset + pos]);
+			incr = 1;
+			goto next;
+		}
+		switch (state) {
+		case 0:		/* ARM */
+			if (pos & 3) {
+			   printf("MISALIGNED pos in CODE32 state, aborting\n");
+				return;
+			}
+			if (rel) {
+				if (rel->type != RTYPE_ARM_B) {
+			printf("Wrong reloc type in CODE32 state, aborting\n");
+					return;
+				}
+				arm_branch_reloc(sec, rel);
+			} else
+				arm_disasm_line(sec, pos);
+			incr = 4;
+			break;
+		case 1:		/* Thumb */
+			if (pos & 1) {
+			   printf("MISALIGNED pos in CODE16 state, aborting\n");
+				return;
+			}
+			if (rel) {
+				if (rel->type != RTYPE_THUMB_BL) {
+			printf("Wrong reloc type in CODE16 state, aborting\n");
+					return;
+				}
+				thumb_bl_reloc(sec, rel);
+				incr = 4;
+			} else if (headroom >= 4 && thumb_check_bl(sec, pos))
+				incr = 4;
+			else {
+				thumb_disasm_line(sec, pos);
+				incr = 2;
+			}
+			break;
+		default:
+			printf("UNKNOWN T state, aborting\n");
+			return;
+		}
+next:		linebrk = 0;
+		if (incr > headroom) {
+			printf("error: increment %u > headroom %u, aborting\n",
+				incr, headroom);
+			return;
+		}
+	}
+	if (symnum < sec->nsymbols)
+		disasm_end_of_section(sec, symnum);
+}
+
+void
+disasm_data_section(sec)
+	struct internal_scnhdr *sec;
+{
+	unsigned symnum, relnum;
+	unsigned pos, incr, headroom;
+	int linebrk = 0;
+	struct internal_syment *sym;
+	struct internal_reloc *rel;
+	char *sym_comment;
+
+	printf("Disassembling data section:\n");
+	if (sec->nsymbols)
+		sort_symbols_of_sec(sec);
+	if (sec->nreloc)
+		get_relocs_of_sec(sec);
+	symnum = relnum = 0;
+	for (pos = 0; pos < sec->size; pos += incr) {
+		headroom = sec->size - pos;
+		while (symnum < sec->nsymbols) {
+			sym = sec->sorted_symbols[symnum];
+			if (sym->value > pos) {
+				if (sym->value - pos < headroom)
+					headroom = sym->value - pos;
+				break;
+			}
+			/* hit symbol */
+			if (!linebrk) {
+				putchar('\n');
+				linebrk = 1;
+			}
+			switch (sym->class) {
+			case C_EXT:
+				sym_comment = "Global";
+				break;
+			case C_STAT:
+				sym_comment = "static";
+				break;
+			case C_LABEL:
+				sym_comment = "label";
+				break;
+			default:
+				sym_comment = "unexpected class!";
+			}
+			printf("%s:\t; %s\n", sym->name, sym_comment);
+			symnum++;
+		}
+		if (relnum < sec->nreloc) {
+			rel = sec->int_relocs + relnum;
+			if (rel->location == pos)
+				relnum++;	/* it's ours */
+			else {
+				if (rel->location - pos < headroom)
+					headroom = rel->location - pos;
+				rel = 0;	/* no reloc for current pos */
+			}
+		} else
+			rel = 0;
+		printf("%8x:\t", pos);
+		if (rel) {
+			if (rel->type != RTYPE_LONG) {
+		printf("error: reloc other than word32 in data section\n");
+				return;
+			}
+			if (pos & 3) {
+			  printf("MISALIGNED pos for word32 reloc, aborting\n");
+				return;
+			}
+			disasm_word32_reloc(sec, rel);
+			incr = 4;
+		} else if (pos & 1 || headroom < 2) {
+			printf("%02x\n", filemap[sec->data_offset + pos]);
+			incr = 1;
+		} else if (pos & 2 || headroom < 4) {
+			printf("%04x\n",
+				get_u16(filemap + sec->data_offset + pos));
+			incr = 2;
+		} else {
+			printf("%08x\n",
+				get_u32(filemap + sec->data_offset + pos));
+			incr = 4;
+		}
+		linebrk = 0;
+		if (incr > headroom) {
+			printf("error: increment %u > headroom %u, aborting\n",
+				incr, headroom);
+			return;
+		}
+	}
+	if (symnum < sec->nsymbols)
+		disasm_end_of_section(sec, symnum);
+}
+
+void
+disasm_bss(sec)
+	struct internal_scnhdr *sec;
+{
+	unsigned m;
+	struct internal_syment *sym;
+	char classbuf[8];
+
+	putchar('\n');
+	for (m = 0; m < sec->nsymbols; m++) {
+		sym = sec->sorted_symbols[m];
+		printf("%08X %-7s %s\n", sym->value,
+			storage_class_to_string(sym->class, classbuf),
+			sym->name);
+	}
+	printf("%08X <end of section>\n", sec->size);
+}
+
+void
+disasm_sec_by_type(sec)
+	struct internal_scnhdr *sec;
+{
+	switch (sec->disasm_mode) {
+	case DISASM_MODE_CODE:
+		disasm_text_section(sec);
+		return;
+	case DISASM_MODE_DATA:
+		disasm_data_section(sec);
+		return;
+	case DISASM_MODE_BSS:
+		disasm_bss(sec);
+		return;
+	default:
+		printf("Unrecognized section type, skipped\n");
+	}
+}
+
+cmd_disasm(argc, argv)
+	char **argv;
+{
+	extern char *optarg;
+	char *hintsfile = 0;
+	struct internal_scnhdr *sec;
+	unsigned secnum;
+	int c;
+
+	while ((c = getopt(argc, argv, "h:s")) != EOF)
+		switch (c) {
+		case 'h':
+			hintsfile = optarg;
+			continue;
+		case 's':
+			auto_xlat_section_relocs = 0;
+			continue;
+		default:
+			/* error msg already printed */
+			exit(1);
+		}
+
+	printf("%s:\n", objfilename);
+	dump_filehdr_info();
+	putchar('\n');
+	get_int_section_table();
+	get_int_symbol_table();
+	if (hintsfile)
+		read_hints_file(hintsfile);
+	extern_profile_report("Module");
+	sort_symbols_of_all_sec();
+	for (secnum = 0; secnum < nsections; secnum++) {
+		sec = sections + secnum;
+		printf("=== %s ===\n", sec->name);
+		disasm_sec_by_type(sec);
+		putchar('\n');
+	}
+	exit(0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/leo-obj/tool/filestruct.h	Sun Apr 06 22:14:39 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];
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/leo-obj/tool/globals.c	Sun Apr 06 22:14:39 2014 +0000
@@ -0,0 +1,19 @@
+/*
+ * Definitions of global vars for the tiobjd program.
+ */
+
+#include <sys/types.h>
+
+char *objfilename;
+u_char *filemap;
+size_t objfile_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;
+struct internal_syment **symtab;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/leo-obj/tool/globals.h	Sun Apr 06 22:14:39 2014 +0000
@@ -0,0 +1,17 @@
+/*
+ * extern declarations of global vars for the tiobjd program.
+ */
+
+extern char *objfilename;
+extern u_char *filemap;
+extern size_t objfile_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;
+extern struct internal_syment **symtab;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/leo-obj/tool/hints.c	Sun Apr 06 22:14:39 2014 +0000
@@ -0,0 +1,131 @@
+/*
+ * Parsing of the disassembly hints file
+ */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+#include <strings.h>
+#include "intstruct.h"
+#include "globals.h"
+
+static char *filename_for_err;
+static int lineno;
+static struct internal_scnhdr *section;
+static struct hint *lasthint;
+
+static void
+set_section(name)
+	char *name;
+{
+	unsigned n;
+	struct internal_scnhdr *sec = 0;
+
+	for (n = 0; n < nsections; n++)
+		if (!strcmp(sections[n].name, name)) {
+			sec = sections + n;
+			break;
+		}
+	if (!sec) {
+		fprintf(stderr, "%s line %d: no section named \"%s\" in %s\n",
+			filename_for_err, lineno, name, objfilename);
+		exit(1);
+	}
+	if (sec->hints) {
+		fprintf(stderr, "%s line %d: [%s] given more than once\n",
+			filename_for_err, lineno, name);
+		exit(1);
+	}
+	section = sec;
+	lasthint = 0;
+}
+
+static void
+set_mode(arg)
+	char *arg;
+{
+	char *cp;
+
+	if (!section) {
+		fprintf(stderr,
+			"%s line %d: error: mode line outside of section\n",
+			filename_for_err, lineno);
+		exit(1);
+	}
+	while (isspace(*arg))
+		arg++;
+	if (!*arg) {
+		fprintf(stderr, "%s line %d: mode line: missing argument\n",
+			filename_for_err, lineno);
+		exit(1);
+	}
+	for (cp = arg; *cp && !isspace(*cp); cp++)
+		;
+	if (*cp)
+		*cp++ = '\0';
+	if (!strcmp(arg, "code"))
+		section->disasm_mode = DISASM_MODE_CODE;
+	else if (!strcmp(arg, "data"))
+		section->disasm_mode = DISASM_MODE_DATA;
+	else if (!strcmp(arg, "bss"))
+		section->disasm_mode = DISASM_MODE_BSS;
+	else {
+		fprintf(stderr, "%s line %d: unknown mode \"%s\"\n",
+			filename_for_err, lineno, arg);
+		exit(1);
+	}
+}
+
+static void
+regular_hint(arg1, arg2)
+	char *arg1, *arg2;
+{
+	fprintf(stderr, "error: regular hints not implemented yet\n");
+	exit(1);
+}
+
+read_hints_file(filename)
+	char *filename;
+{
+	FILE *f;
+	char linebuf[128], *cp, *np;
+
+	f = fopen(filename, "r");
+	if (!f) {
+		perror(filename);
+		exit(1);
+	}
+	filename_for_err = filename;
+	for (lineno = 1; fgets(linebuf, sizeof linebuf, f); lineno++) {
+		for (cp = linebuf; isspace(*cp); cp++)
+			;
+		if (!*cp || *cp == '#')
+			continue;
+		if (*cp == '[') {
+			np = ++cp;
+			cp = index(cp, ']');
+			if (!cp) {
+				fprintf(stderr,
+					"%s line %d: invalid section syntax\n",
+					filename, lineno);
+				exit(1);
+			}
+			*cp = '\0';
+			set_section(np);
+			continue;
+		}
+		for (np = cp; *cp && !isspace(*cp); cp++)
+			;
+		if (*cp)
+			*cp++ = '\0';
+		if (!strcmp(np, "mode")) {
+			set_mode(cp);
+			continue;
+		}
+		regular_hint(np, cp);
+	}
+	fclose(f);
+	return(0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/leo-obj/tool/intstruct.h	Sun Apr 06 22:14:39 2014 +0000
@@ -0,0 +1,56 @@
+/*
+ * 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 **sorted_symbols;
+	struct internal_reloc *int_relocs;
+	int		disasm_mode;
+	struct hint	*hints;
+};
+
+#define	DISASM_MODE_UNKNOWN	0
+#define	DISASM_MODE_CODE	1
+#define	DISASM_MODE_DATA	2
+#define	DISASM_MODE_BSS		3
+
+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_syment *sym;
+	int		type;
+	char		*typestr;
+};
+
+struct hint {
+	unsigned	pos;
+	int		type;
+	unsigned	nitems;
+	int		linebrk;
+	struct hint	*next;
+};
+
+#define	HINT_D8		1
+#define	HINT_D16	2
+#define	HINT_ASCIZ	3
+#define	HINT_D32	4
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/leo-obj/tool/lowlevel.c	Sun Apr 06 22:14:39 2014 +0000
@@ -0,0 +1,94 @@
+/*
+ * This C module implements the low-level steps of TI COFF image analysis.
+ */
+
+#include <sys/types.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include "filestruct.h"
+#include "globals.h"
+
+mmap_objfile()
+{
+	int fd;
+	struct stat st;
+
+	fd = open(objfilename, O_RDONLY);
+	if (fd < 0) {
+		perror(objfilename);
+		exit(1);
+	}
+	fstat(fd, &st);
+	if (!S_ISREG(st.st_mode)) {
+		fprintf(stderr, "error: %s is not a regular file\n",
+			objfilename);
+		exit(1);
+	}
+	objfile_tot_size = st.st_size;
+	filemap = mmap(NULL, objfile_tot_size, PROT_READ, MAP_PRIVATE, fd, 0L);
+	if (filemap == MAP_FAILED) {
+		perror("mmap");
+		exit(1);
+	}
+	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;
+}
+
+initial_parse_hdr()
+{
+	unsigned symtab_offset;
+
+	filehdr_struct = (struct external_filehdr *) filemap;
+	if (get_u16(filehdr_struct->f_magic) != 0xC2) {
+		fprintf(stderr, "error: %s is not a TI COFF2 object\n",
+			objfilename);
+		exit(1);
+	}
+	if (get_u16(filehdr_struct->f_target_id) != 0x97) {
+		fprintf(stderr, "error: TI COFF object %s is not for TMS470\n",
+			objfilename);
+		exit(1);
+	}
+	if (get_u16(filehdr_struct->f_opthdr)) {
+		fprintf(stderr,
+			"error: %s has the \"optional\" header present\n",
+			objfilename);
+		exit(1);
+	}
+	sections_raw = (struct external_scnhdr *)
+				(filemap + sizeof(struct external_filehdr));
+	nsections = get_u16(filehdr_struct->f_nscns);
+	symtab_offset = get_u32(filehdr_struct->f_symptr);
+	symtab_raw = (struct external_syment *)(filemap + symtab_offset);
+	nsymtab = get_u32(filehdr_struct->f_nsyms);
+	strtab_offset = symtab_offset +
+				sizeof(struct external_syment) * nsymtab;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/leo-obj/tool/main.c	Sun Apr 06 22:14:39 2014 +0000
@@ -0,0 +1,60 @@
+/*
+ * tiobjd main() function and command dispatch
+ */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include "globals.h"
+
+extern int cmd_basics();
+extern int cmd_disasm();
+extern int cmd_nm();
+extern int cmd_profile();
+extern int cmd_rawrel();
+extern int cmd_reloc();
+extern int cmd_sechdr();
+extern int cmd_symtab();
+extern int dump_filehdr_info();
+
+static struct cmdtab {
+	char	*cmd;
+	int	(*func)();
+} cmdtab[] = {
+	{"basics", cmd_basics},
+	{"disasm", cmd_disasm},
+	{"dumpsym", cmd_symtab},	/* backward compat */
+	{"hdr", dump_filehdr_info},
+	{"nm", cmd_nm},
+	{"profile", cmd_profile},
+	{"rawrel", cmd_rawrel},
+	{"reloc", cmd_reloc},
+	{"sechdr", cmd_sechdr},
+	{"symtab", cmd_symtab},
+	{0, 0}
+};
+
+main(argc, argv)
+	char **argv;
+{
+	struct cmdtab *tp;
+
+	if (argc < 3) {
+		fprintf(stderr, "usage: %s <objfile> <op> [args]\n", argv[0]);
+		exit(1);
+	}
+	objfilename = argv[1];
+	mmap_objfile();
+	initial_parse_hdr();
+	for (tp = cmdtab; tp->cmd; tp++)
+		if (!strcmp(tp->cmd, argv[2]))
+			break;
+	if (!tp->func) {
+		fprintf(stderr, "\"%s\": unknown or unimplemented command\n",
+			argv[2]);
+		exit(1);
+	}
+	return tp->func(argc - 2, argv + 2);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/leo-obj/tool/profile.c	Sun Apr 06 22:14:39 2014 +0000
@@ -0,0 +1,158 @@
+/*
+ * It is handy to have a "profile" of what functions and variables
+ * a given module defines (presents to the rest of the fw) and what
+ * it references.  This profile is constructed from the symbol table.
+ *
+ * Experience indicates that the order of these symbols in the
+ * artifact symtab is often "random", and an alphabetic sort is
+ * expected to improve readability.  This module contains the
+ * messy code.
+ */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include "intstruct.h"
+#include "coffconst.h"
+#include "globals.h"
+
+static int
+is_symbol_text_def(sym)
+	struct internal_syment *sym;
+{
+	if (!sym->section)
+		return(0);
+	if (!strncmp(sym->section->name, ".text", 5))
+		return(1);
+	else
+		return(0);
+}
+
+static int
+is_symbol_nontext_def(sym)
+	struct internal_syment *sym;
+{
+	if (!sym->section)
+		return(0);
+	if (!strncmp(sym->section->name, ".text", 5))
+		return(0);
+	else
+		return(1);
+}
+
+static int
+is_symbol_extref(sym)
+	struct internal_syment *sym;
+{
+	if (sym->section)
+		return(0);
+	else
+		return(1);
+}
+
+static int
+compare_for_sort(p1, p2)
+	struct internal_syment **p1, **p2;
+{
+	return strcmp((*p1)->name, (*p2)->name);
+}
+
+static void
+list_class(firstidx, lastidx, total, checkfunc, printsec)
+	unsigned firstidx, lastidx, total;
+	int (*checkfunc)();
+{
+	struct internal_syment **array, *sym;
+	unsigned n, m;
+
+	array = malloc(sizeof(void *) * total);
+	if (!array) {
+		perror("malloc");
+		exit(1);
+	}
+	m = 0;
+	for (n = firstidx; n <= lastidx; n++) {
+		sym = symtab[n];
+		if (!sym)
+			continue;
+		if (sym->class != C_EXT)
+			continue;
+		if (!checkfunc(sym))
+			continue;
+		array[m++] = sym;
+	}
+	if (m != total) {
+		fprintf(stderr, "BUG: symbol class miscount in profile gen\n");
+		exit(1);
+	}
+	qsort(array, total, sizeof(void *), compare_for_sort);
+	for (n = 0; n < total; n++) {
+		sym = array[n];
+		if (printsec)
+			printf("%s (%s)\n", sym->name, sym->section->name);
+		else
+			printf("%s\n", sym->name);
+	}
+	free(array);
+	putchar('\n');
+}
+
+extern_profile_report(heading)
+	char *heading;
+{
+	unsigned n;
+	int first_extern = -1, last_extern;
+	struct internal_syment *sym;
+	unsigned defs_text = 0, defs_nontext = 0, extrefs = 0;
+
+	for (n = 0; n < nsymtab; n++) {
+		sym = symtab[n];
+		if (!sym)
+			continue;
+		if (sym->class != C_EXT)
+			continue;
+		if (first_extern < 0)
+			first_extern = n;
+		last_extern = n;
+		if (sym->scnum < 0) {
+			fprintf(stderr,
+		"symbol entry #%u: unexpected negative scnum for C_EXT\n", n);
+			exit(1);
+		}
+		if (sym->scnum == 0)
+			extrefs++;
+		else if (!strncmp(sym->section->name, ".text", 5))
+			defs_text++;
+		else
+			defs_nontext++;
+	}
+	if (first_extern < 0) {
+		printf("%s has no external symbols!\n", heading);
+		return(1);
+	}
+	if (defs_text || defs_nontext) {
+		printf("%s defines:\n\n", heading);
+		if (defs_text)
+			list_class(first_extern, last_extern, defs_text,
+					is_symbol_text_def, 1);
+		if (defs_nontext)
+			list_class(first_extern, last_extern, defs_nontext,
+					is_symbol_nontext_def, 1);
+	}
+	if (extrefs) {
+		printf("%s references:\n\n", heading);
+		list_class(first_extern, last_extern, extrefs,
+				is_symbol_extref, 0);
+	}
+	return(0);
+}
+
+cmd_profile()
+{
+	get_int_section_table();
+	get_int_symbol_table();
+	extern_profile_report(objfilename);
+	exit(0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/leo-obj/tool/reloc.c	Sun Apr 06 22:14:39 2014 +0000
@@ -0,0 +1,164 @@
+/*
+ * Handling of relocation records
+ */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "filestruct.h"
+#include "intstruct.h"
+#include "coffconst.h"
+#include "globals.h"
+
+extern unsigned get_u16(), get_u32();
+
+cmd_rawrel()
+{
+	unsigned n, m;
+	struct internal_scnhdr *sec;
+	struct external_reloc *rel;
+
+	get_int_section_table();
+	for (n = 0; n < nsections; n++) {
+		sec = sections + n;
+		if (!sec->nreloc)
+			continue;
+		printf("%s:\n\n", sec->name);
+		rel = (struct external_reloc *)(filemap + sec->reloc_offset);
+		printf("Location  SymIndex  Rsvd  Type\n");
+		for (m = 0; m < sec->nreloc; m++, rel++)
+			printf("%08X  %08X  %04X  %04X\n",
+				get_u32(rel->r_vaddr), get_u32(rel->r_symndx),
+				get_u16(rel->r_reserved), get_u16(rel->r_type));
+		putchar('\n');
+	}
+	exit(0);
+}
+
+void
+get_relocs_of_sec(sec)
+	struct internal_scnhdr *sec;
+{
+	unsigned n;
+	struct external_reloc *extrel;
+	struct internal_reloc *intrel;
+	unsigned lastloc, symidx;
+
+	if (sec->int_relocs)
+		return;
+	if (!sec->nreloc) {
+		fprintf(stderr,
+	"BUG: get_relocs_of_sec() called for section \"%s\" w/o relocs\n",
+			sec->name);
+		exit(1);
+	}
+	intrel = malloc(sizeof(struct internal_reloc) * sec->nreloc);
+	if (!intrel) {
+		perror("malloc");
+		exit(1);
+	}
+	sec->int_relocs = intrel;
+	extrel = (struct external_reloc *)(filemap + sec->reloc_offset);
+	for (n = 0; n < sec->nreloc; n++, extrel++, intrel++) {
+		intrel->location = get_u32(extrel->r_vaddr);
+		if (n && intrel->location <= lastloc) {
+			fprintf(stderr,
+			"error: non-increasing reloc order in section \"%s\"\n",
+				sec->name);
+			exit(1);
+		}
+		lastloc = intrel->location;
+		symidx = get_u32(extrel->r_symndx);
+		if (symidx == 0xFFFFFFFF)
+			intrel->sym = 0;
+		else if (symidx >= nsymtab || !symtab[symidx]) {
+			fprintf(stderr,
+	"error: reloc references invalid symbol #%u in section \"%s\"\n",
+				symidx, sec->name);
+			exit(1);
+		} else
+			intrel->sym = symtab[symidx];
+		intrel->type = get_u16(extrel->r_type);
+		switch (intrel->type) {
+		case RTYPE_LONG:
+			intrel->typestr = "Word32";
+			break;
+		case RTYPE_THUMB_BL:
+			intrel->typestr = "Thumb_BL";
+			break;
+		case RTYPE_ARM_B:
+			intrel->typestr = "ARM_B";
+			break;
+		default:
+			fprintf(stderr,
+		"error: reloc in section \"%s\" of unexpected type 0x%x\n",
+				sec->name, intrel->type);
+			exit(1);
+		}
+		if (get_u16(extrel->r_reserved))
+			fprintf(stderr,
+	"warning: reloc in section \"%s\" has non-zero reserved field\n",
+				sec->name);
+	}
+}
+
+cmd_reloc()
+{
+	unsigned n, m;
+	struct internal_scnhdr *sec;
+	struct internal_reloc *rel;
+	char *symname;
+
+	get_int_section_table();
+	get_int_symbol_table();
+	for (n = 0; n < nsections; n++) {
+		sec = sections + n;
+		if (!sec->nreloc)
+			continue;
+		printf("%s:\n\n", sec->name);
+		get_relocs_of_sec(sec);
+		rel = sec->int_relocs;
+		printf("Location  Type      Symbol relative to\n");
+		for (m = 0; m < sec->nreloc; m++, rel++) {
+			if (rel->sym)
+				symname = rel->sym->name;
+			else
+				symname = "<none>";
+			printf("%08X  %-8s  %s\n", rel->location, rel->typestr,
+				symname);
+		}
+		putchar('\n');
+	}
+	exit(0);
+}
+
+struct internal_reloc *
+find_reloc(sec, loc)
+	struct internal_scnhdr *sec;
+	unsigned loc;
+{
+	struct internal_reloc *rel;
+	unsigned m;
+
+	rel = sec->int_relocs;
+	for (m = 0; m < sec->nreloc; m++, rel++) {
+		if (rel->location == loc)
+			return(rel);
+		if (rel->location > loc)
+			return(0);
+	}
+	return(0);
+}
+
+struct internal_reloc *
+find_word32_reloc(sec, loc)
+	struct internal_scnhdr *sec;
+	unsigned loc;
+{
+	struct internal_reloc *rel;
+
+	rel = find_reloc(sec, loc);
+	if (rel && rel->type != RTYPE_LONG)
+		rel = 0;
+	return(rel);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/leo-obj/tool/symtab.c	Sun Apr 06 22:14:39 2014 +0000
@@ -0,0 +1,185 @@
+/*
+ * Code for working with the symbol table
+ */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "filestruct.h"
+#include "intstruct.h"
+#include "coffconst.h"
+#include "globals.h"
+
+static struct classmap {
+	int	code;
+	char	*str;
+} classtab[] = {
+	{C_NULL, "NULL"},
+	{C_AUTO, "AUTO"},
+	{C_EXT, "EXT"},
+	{C_STAT, "STAT"},
+	{C_REG, "REG"},
+	{C_EXTREF, "EXTREF"},
+	{C_LABEL, "LABEL"},
+	{C_ULABEL, "ULABEL"},
+	{C_MOS, "MOS"},
+	{C_ARG, "ARG"},
+	{C_STRTAG, "STRTAG"},
+	{C_MOU, "MOU"},
+	{C_UNTAG, "UNTAG"},
+	{C_TPDEF, "TPDEF"},
+	{C_USTATIC, "USTATIC"},
+	{C_ENTAG, "ENTAG"},
+	{C_MOE, "MOE"},
+	{C_REGPARM, "REGPARM"},
+	{C_FIELD, "FIELD"},
+	{C_UEXT, "UEXT"},
+	{C_STATLAB, "STATLAB"},
+	{C_EXTLAB, "EXTLAB"},
+	{C_SYSTEM, "SYSTEM"},
+	{C_VARARG, "VARARG"},
+	{C_BLOCK, "BLOCK"},
+	{C_FCN, "FCN"},
+	{C_EOS, "EOS"},
+	{C_FILE, "FILE"},
+	{C_LINE, "LINE"},
+	{0, 0}
+};
+
+char *
+storage_class_to_string(code, numbuf)
+	char *numbuf;
+{
+	struct classmap *tp;
+
+	for (tp = classtab; tp->str; tp++)
+		if (tp->code == code)
+			return(tp->str);
+	sprintf(numbuf, "%d", code);
+	return(numbuf);
+}
+
+dump_symtab()
+{
+	unsigned n;
+	struct internal_syment *sym;
+	char *sec, secstr[8];
+	char *class, classbuf[8];
+
+	printf("%-5s %-30s %-4s %-7s %-12s %-8s\n",
+		"Num", "Name", "Type", "Class", "Section", "Value");
+	for (n = 0; n < nsymtab; n++) {
+		sym = symtab[n];
+		if (!sym)
+			continue;
+		if (sym->section)
+			sec = sym->section->name;
+		else {
+			sprintf(secstr, "%d", sym->scnum);
+			sec = secstr;
+		}
+		class = storage_class_to_string(sym->class, classbuf);
+		printf("%-5u %-30s %04X %-7s %-12s %08X%s\n",
+			n, sym->name, sym->type, class,
+			sec, sym->value, sym->aux ? " Aux" : "");
+	}
+	return(0);
+}
+
+static void
+initial_fill_for_sort(sec)
+	struct internal_scnhdr *sec;
+{
+	unsigned n, m;
+	struct internal_syment *sym;
+
+	m = 0;
+	for (n = 0; n < nsymtab; n++) {
+		sym = symtab[n];
+		if (!sym)
+			continue;
+		if (sym->section != sec)
+			continue;
+		sec->sorted_symbols[m++] = sym;
+	}
+}
+
+static int
+compare_for_sort(p1, p2)
+	struct internal_syment **p1, **p2;
+{
+	/* sort by value first */
+	if ((*p1)->value < (*p2)->value)
+		return(-1);
+	if ((*p1)->value > (*p2)->value)
+		return(1);
+	/* if same value, retain the original symtab order */
+	if ((*p1)->number < (*p2)->number)
+		return(-1);
+	if ((*p1)->number > (*p2)->number)
+		return(1);
+	else
+		return(0);
+}
+
+void
+sort_symbols_of_sec(sec)
+	struct internal_scnhdr *sec;
+{
+	if (sec->sorted_symbols)
+		return;
+	if (!sec->nsymbols) {
+		fprintf(stderr,
+	"BUG: sort_symbols_of_sec() called for section \"%s\" w/o symbols\n",
+			sec->name);
+		exit(1);
+	}
+	sec->sorted_symbols = malloc(sizeof(void *) * sec->nsymbols);
+	if (!sec->sorted_symbols) {
+		perror("malloc");
+		exit(1);
+	}
+	initial_fill_for_sort(sec);
+	qsort(sec->sorted_symbols, sec->nsymbols, sizeof(void *),
+		compare_for_sort);
+}
+
+void
+sort_symbols_of_all_sec()
+{
+	unsigned n;
+	struct internal_scnhdr *sec;
+
+	for (n = 0; n < nsections; n++) {
+		sec = sections + n;
+		if (!sec->nsymbols)
+			continue;
+		sort_symbols_of_sec(sec);
+	}
+}
+
+cmd_nm()
+{
+	unsigned n, m;
+	struct internal_scnhdr *sec;
+	struct internal_syment *sym;
+	char classbuf[8];
+
+	get_int_section_table();
+	get_int_symbol_table();
+	for (n = 0; n < nsections; n++) {
+		sec = sections + n;
+		if (!sec->nsymbols)
+			continue;
+		printf("%s:\n\n", sec->name);
+		sort_symbols_of_sec(sec);
+		for (m = 0; m < sec->nsymbols; m++) {
+			sym = sec->sorted_symbols[m];
+			printf("%08X %-7s %s\n", sym->value,
+				storage_class_to_string(sym->class, classbuf),
+				sym->name);
+		}
+		putchar('\n');
+	}
+	exit(0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/leo-obj/tool/tables.c	Sun Apr 06 22:14:39 2014 +0000
@@ -0,0 +1,155 @@
+/*
+ * This C module will contain functions for the initial parsing
+ * of the section and symbol tables.
+ */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include "filestruct.h"
+#include "intstruct.h"
+#include "globals.h"
+
+extern unsigned get_u16(), get_u32();
+
+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(1);
+			}
+			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 - filemap);
+		exit(1);
+	}
+	return(filemap + strtab_offset + get_u32(ptr+4));
+}
+
+get_int_section_table()
+{
+	unsigned n;
+
+	sections = malloc(sizeof(struct internal_scnhdr) * nsections);
+	if (!sections) {
+		perror("malloc");
+		exit(1);
+	}
+	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;
+		sections[n].sorted_symbols = 0;
+		sections[n].int_relocs = 0;
+		if (!strncmp(sections[n].name, ".text", 5))
+			sections[n].disasm_mode = DISASM_MODE_CODE;
+		else if (!strcmp(sections[n].name, ".const"))
+			sections[n].disasm_mode = DISASM_MODE_DATA;
+		else if (!strcmp(sections[n].name, ".cinit"))
+			sections[n].disasm_mode = DISASM_MODE_DATA;
+		else if (!strcmp(sections[n].name, ".data"))
+			sections[n].disasm_mode = DISASM_MODE_DATA;
+		else if (!strcmp(sections[n].name, ".bss"))
+			sections[n].disasm_mode = DISASM_MODE_BSS;
+		else
+			sections[n].disasm_mode = DISASM_MODE_UNKNOWN;
+		sections[n].hints = 0;
+	}
+}
+
+get_int_symbol_table()
+{
+	unsigned n;
+	struct internal_syment *in;
+
+	symtab = malloc(sizeof(struct internal_syment *) * nsymtab);
+	if (!symtab) {
+		perror("malloc");
+		exit(1);
+	}
+	for (n = 0; n < nsymtab; ) {
+		in = malloc(sizeof(struct internal_syment));
+		if (!in) {
+			perror("malloc");
+			exit(1);
+		}
+		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(1);
+			}
+			in->section = sections + in->scnum - 1;
+			in->section->nsymbols++;
+		} else if (in->scnum < -2) {
+			fprintf(stderr,
+				"symtab entry #%u: scnum < -2\n", n);
+			exit(1);
+		} 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(1);
+			}
+			symtab[n] = 0;
+			in->aux = (u_char *)(symtab_raw + n);
+			n++;
+			continue;
+		default:
+			n--;
+			fprintf(stderr, "symtab entry #%u: invalid numaux\n",
+				n);
+			exit(1);
+		}
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/leo-obj/tool/thumbdis.c	Sun Apr 06 22:14:39 2014 +0000
@@ -0,0 +1,436 @@
+/*
+ * Thumb state disassembly
+ */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include "intstruct.h"
+#include "globals.h"
+
+extern unsigned get_u16(), get_u32();
+extern struct internal_reloc *find_word32_reloc();
+
+extern char *regnames[16], *condition_decode[16], *shift_types[4];
+
+static void
+format_1_2(word)
+	unsigned word;
+{
+	unsigned op, imm;
+
+	op = (word >> 11) & 3;
+	if (op != 3) {
+		/* format 1 */
+		imm = (word >> 6) & 0x1F;
+		if (op != 0 && imm == 0)
+			imm = 32;
+		printf("%s\t%s, %s, #%u\n", shift_types[op], regnames[word&7],
+			regnames[(word>>3)&7], imm);
+		return;
+	}
+	/* format 2 */
+	printf("%s\t%s, %s, ", word&0x200 ? "sub" : "add", regnames[word&7],
+		regnames[(word>>3)&7]);
+	if (word & 0x400)
+		printf("#%u\n", (word >> 6) & 7);
+	else
+		printf("%s\n", regnames[(word >> 6) & 7]);
+}
+
+static void
+format_3(word)
+	unsigned word;
+{
+	static char *opctab[4] = {"mov", "cmp", "add", "sub"};
+	unsigned imm;
+
+	imm = word & 0xFF;
+	printf("%s\t%s, #%u", opctab[(word>>11)&3], regnames[(word>>8)&7], imm);
+	if (imm > 9)
+		printf("\t; 0x%x", imm);
+	putchar('\n');
+}
+
+static void
+format_4(word)
+	unsigned word;
+{
+	static char *opc[16] = {"and", "eor", "lsl", "lsr",
+				"asr", "adc", "sbc", "ror",
+				"tst", "neg", "cmp", "cmn",
+				"orr", "mul", "bic", "mvn"};
+
+	printf("%s\t%s, %s\n", opc[(word>>6)&0xF], regnames[word&7],
+		regnames[(word>>3)&7]);
+}
+
+static void
+format_5_bx(word)
+	unsigned word;
+{
+	if (word & 0x80)
+		printf("<invalid: blx instead of bx>\n");
+	else
+		printf("bx\t%s\n", regnames[(word>>3)&0xF]);
+}
+
+static void
+format_5_hiops(word)
+	unsigned word;
+{
+	static char *opctab[3] = {"add", "cmp", "mov"};
+	int reg1, reg2, op;
+
+	if (word & 0xC0) {
+		reg1 = word & 7;
+		if (word & 0x80)
+			reg1 += 8;
+		reg2 = (word >> 3) & 0xF;
+		op = (word >> 8) & 3;
+		if (op == 2 && reg1 == reg2 && reg1 != 15)
+			printf("nop\t\t\t(mov %s, %s)\n",
+				regnames[reg1], regnames[reg2]);
+		else
+			printf("%s\t%s, %s\n", opctab[op],
+				regnames[reg1], regnames[reg2]);
+	} else
+		printf("<invalid: hi-reg format with both low regs>\n");
+}
+
+static void
+format_5(word)
+	unsigned word;
+{
+	if ((word & 0x300) == 0x300)
+		format_5_bx(word);
+	else
+		format_5_hiops(word);
+}
+
+static void
+format_6(sec, off, word)
+	struct internal_scnhdr *sec;
+	unsigned off, word;
+{
+	unsigned loff, litoff, datum;
+	struct internal_reloc *rel;
+
+	loff = (word & 0xFF) << 2;
+	off &= ~3;
+	off += 4;
+	litoff = off + loff;
+	if (litoff+4 <= sec->size) {
+		rel = find_word32_reloc(sec, litoff);
+		datum = get_u32(filemap + sec->data_offset + litoff);
+		printf("ldr\t%s, =", regnames[(word>>8)&7]);
+		if (rel)
+			disasm_reloc_target(sec, rel, datum);
+		else
+			printf("0x%x", datum);
+		printf("\t; via 0x%x\n", litoff);
+	} else
+		printf("ldr\t%s, [pc, #%u]\t(0x%x)\n", regnames[(word>>8)&7],
+			loff, litoff);
+}
+
+static void
+format_7(word)
+	unsigned word;
+{
+	printf("%s%s\t%s, [%s, %s]\n", word&0x800 ? "ldr" : "str",
+		word&0x400 ? "b" : "", regnames[word&7],
+		regnames[(word>>3)&7], regnames[(word>>6)&7]);
+}
+
+static void
+format_8(word)
+	unsigned word;
+{
+	static char *opc[4] = {"strh", "ldrsb", "ldrh", "ldrsh"};
+
+	printf("%s\t%s, [%s, %s]\n", opc[(word>>10)&3], regnames[word&7],
+		regnames[(word>>3)&7], regnames[(word>>6)&7]);
+}
+
+static void
+format_9(word)
+	unsigned word;
+{
+	unsigned loff;
+
+	loff = (word >> 6) & 0x1F;
+	if (!(word & 0x1000))
+		loff <<= 2;
+	printf("%s%s\t%s, [%s, #%u]", word&0x800 ? "ldr" : "str",
+		word&0x1000 ? "b" : "", regnames[word&7],
+		regnames[(word>>3)&7], loff);
+	if (loff >= 10)
+		printf("\t; 0x%x", loff);
+	putchar('\n');
+}
+
+static void
+format_10(word)
+	unsigned word;
+{
+	unsigned loff;
+
+	loff = (word >> 6) & 0x1F;
+		loff <<= 1;
+	printf("%sh\t%s, [%s, #%u]", word&0x800 ? "ldr" : "str",
+		regnames[word&7], regnames[(word>>3)&7], loff);
+	if (loff >= 10)
+		printf("\t; 0x%x", loff);
+	putchar('\n');
+}
+
+static void
+format_11(word)
+	unsigned word;
+{
+	unsigned loff;
+
+	loff = (word & 0xFF) << 2;
+	printf("%s\t%s, [sp, #%u]", word&0x800 ? "ldr" : "str",
+		regnames[(word>>8)&7], loff);
+	if (loff >= 10)
+		printf("\t; 0x%x", loff);
+	putchar('\n');
+}
+
+static void
+format_12(off, word)
+	unsigned off, word;
+{
+	unsigned loff;
+
+	loff = (word & 0xFF) << 2;
+	printf("add\t%s, ", regnames[(word>>8)&7]);
+	if (word & 0x800) {
+		printf("sp, #%u", loff);
+		if (loff >= 10)
+			printf("\t; 0x%x", loff);
+		putchar('\n');
+	} else {
+		off &= ~3;
+		printf("pc, #%u\t; 0x%x\n", loff, off + 4 + loff);
+	}
+}
+
+static void
+format_13(word)
+	unsigned word;
+{
+	unsigned loff;
+
+	if ((word & 0xFF00) != 0xB000) {
+		printf("<invalid format 13>\n");
+		return;
+	}
+	loff = (word & 0x7F) << 2;
+	printf("%s\tsp, #%u", word&0x80 ? "sub" : "add", loff);
+	if (loff >= 10)
+		printf("\t; 0x%x", loff);
+	putchar('\n');
+}
+
+static void
+format_14(word)
+	unsigned word;
+{
+	int r, flag;
+
+	if ((word & 0xF600) != 0xB400) {
+		printf("<invalid format 14>\n");
+		return;
+	}
+	printf("%s\t{", word&0x800 ? "pop" : "push");
+	flag = 0;
+	for (r = 0; r < 9; r++)
+		if (word & (1 << r)) {
+			if (flag)
+				fputs(", ", stdout);
+			if (r == 8)
+				fputs(word&0x800 ? "pc" : "lr", stdout);
+			else
+				fputs(regnames[r], stdout);
+			flag = 1;
+		}
+	putchar('}');
+	putchar('\n');
+}
+
+static void
+format_15(word)
+	unsigned word;
+{
+	int r, flag;
+
+	printf("%sia\t%s!, {", word&0x800 ? "ldm" : "stm",
+		regnames[(word>>8)&7]);
+	flag = 0;
+	for (r = 0; r < 8; r++)
+		if (word & (1 << r)) {
+			if (flag)
+				fputs(", ", stdout);
+			fputs(regnames[r], stdout);
+			flag = 1;
+		}
+	putchar('}');
+	putchar('\n');
+}
+
+static void
+format_16_17(off, word)
+	unsigned off, word;
+{
+	unsigned cond;
+	unsigned dest;
+
+	cond = (word >> 8) & 0xF;
+	switch (cond) {
+	case 0xE:
+		printf("<invalid: bal>\n");
+		return;
+	case 0xF:
+		printf("swi\t0x%x\n", word & 0xFF);
+		return;
+	}
+	dest = (word & 0xFF) << 1;
+	if (dest & 0x00000100)
+		dest |= 0xFFFFFE00;
+	dest += off + 4;
+	printf("b%s\t0x%x\n", condition_decode[cond], dest);
+}
+
+static void
+format_18(off, word)
+	unsigned off, word;
+{
+	unsigned dest;
+
+	if (word & 0x800) {
+		printf("<invalid format 18>\n");
+		return;
+	}
+	dest = (word & 0x7FF) << 1;
+	if (dest & 0x00000800)
+		dest |= 0xFFFFF000;
+	dest += off + 4;
+	printf("b\t0x%x\n", dest);
+}
+
+void
+thumb_disasm_line(sec, off)
+	struct internal_scnhdr *sec;
+	unsigned off;
+{
+	unsigned word;
+
+	word = get_u16(filemap + sec->data_offset + off);
+	printf("%04x\t\t", word);
+	switch (word >> 12) {
+	case 0:
+	case 1:
+		format_1_2(word);
+		return;
+	case 2:
+	case 3:
+		format_3(word);
+		return;
+	case 4:
+		if (word & 0x800)
+			format_6(sec, off, word);
+		else if (word & 0x400)
+			format_5(word);
+		else
+			format_4(word);
+		return;
+	case 5:
+		if (word & 0x200)
+			format_8(word);
+		else
+			format_7(word);
+		return;
+	case 6:
+	case 7:
+		format_9(word);
+		return;
+	case 8:
+		format_10(word);
+		return;
+	case 9:
+		format_11(word);
+		return;
+	case 0xA:
+		format_12(off, word);
+		return;
+	case 0xB:
+		if (word & 0x400)
+			format_14(word);
+		else
+			format_13(word);
+		return;
+	case 0xC:
+		format_15(word);
+		return;
+	case 0xD:
+		format_16_17(off, word);
+		return;
+	case 0xE:
+		format_18(off, word);
+		return;
+	case 0xF:
+		printf("<half-bl>\n");
+		return;
+	}
+}
+
+thumb_check_bl(sec, off)
+	struct internal_scnhdr *sec;
+	unsigned off;
+{
+	unsigned ins1, ins2;
+	unsigned dest;
+
+	ins1 = get_u16(filemap + sec->data_offset + off);
+	if ((ins1 & 0xF800) != 0xF000)
+		return(0);
+	ins2 = get_u16(filemap + sec->data_offset + off + 2);
+	if ((ins2 & 0xF800) != 0xF800)
+		return(0);
+	/* match */
+	dest = ((ins1 & 0x7FF) << 12) | ((ins2 & 0x7FF) << 1);
+	if (dest & 0x00400000)
+		dest |= 0xFF800000;
+	dest += off + 4;
+	printf("%04x %04x\tbl\t0x%x\n", ins1, ins2, dest);
+	return(1);
+}
+
+void
+thumb_bl_reloc(sec, rel)
+	struct internal_scnhdr *sec;
+	struct internal_reloc *rel;
+{
+	unsigned ins1, ins2;
+	unsigned dest;
+
+	ins1 = get_u16(filemap + sec->data_offset + rel->location);
+	ins2 = get_u16(filemap + sec->data_offset + rel->location + 2);
+	printf("%04x %04x R\t", ins1, ins2);
+	if ((ins1 & 0xF800) != 0xF000 || (ins2 & 0xF800) != 0xF800) {
+		printf("<invalid Thumb_BL reloc: opcode not BL>\n");
+		return;
+	}
+	dest = ((ins1 & 0x7FF) << 12) | ((ins2 & 0x7FF) << 1);
+	if (dest & 0x00400000)
+		dest |= 0xFF800000;
+	dest += rel->location + 4;
+	fputs("bl\t", stdout);
+	disasm_reloc_target(sec, rel, dest);
+	putchar('\n');
+}
--- a/ticoff/Makefile	Sun Apr 06 20:20:39 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,19 +0,0 @@
-CC=	gcc
-CFLAGS=	-O2
-PROG=	tiobjd
-OBJS=	armdis.o atcommon.o basics.o disasm.o globals.o hints.o lowlevel.o \
-	main.o profile.o reloc.o symtab.o tables.o thumbdis.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} *err
--- a/ticoff/README	Sun Apr 06 20:20:39 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,6 +0,0 @@
-Here I'm going to build a standalone tool that reads linkable (not final)
-object modules produced by TI's TMS470 toolchain, as found in GSM firmware
-semi-sources, and produces disassembly listings that are well-fit for
-understanding the function and interfaces of each object blob, and ultimately
-replacing each of these blobs with functionally and interface-equivalent
-new C code.
--- a/ticoff/armdis.c	Sun Apr 06 20:20:39 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,522 +0,0 @@
-/*
- * ARM state disassembly
- */
-
-#include <sys/types.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <strings.h>
-#include "intstruct.h"
-#include "globals.h"
-
-extern unsigned get_u16(), get_u32();
-extern struct internal_reloc *find_word32_reloc();
-
-extern char *regnames[16], *condition_decode[16], *shift_types[4];
-
-static char *dataproc_ops[16] = {"and", "eor", "sub", "rsb",
-				 "add", "adc", "sbc", "rsc",
-				 "tst", "teq", "cmp", "cmn",
-				 "orr", "mov", "bic", "mvn"};
-
-static void
-arm_branch(off, word)
-	unsigned off, word;
-{
-	unsigned dest;
-
-	dest = (word & 0x00FFFFFF) << 2;
-	if (dest & 0x02000000)
-		dest |= 0xFC000000;
-	dest += off + 8;
-	printf("b%s%s\t0x%x\n", word&0x1000000 ? "l" : "",
-		condition_decode[word>>28], dest);
-}
-
-static void
-op2_immed(word)
-	unsigned word;
-{
-	unsigned low8, rot, val;
-
-	low8 = word & 0xFF;
-	rot = (word & 0xF00) >> 7;
-	val = (low8 << (32 - rot)) | (low8 >> rot);
-	if (val <= 9)
-		printf("#%u\n", val);
-	else
-		printf("#%u\t; 0x%x\n", val, val);
-}
-
-static void
-op2_regbyconst(word)
-	unsigned word;
-{
-	unsigned c, t;
-
-	c = (word >> 7) & 0x1F;
-	t = (word >> 5) & 3;
-	if (!c) {
-		switch (t) {
-		case 0:
-			printf("%s", regnames[word&0xF]);
-			return;
-		case 3:
-			printf("%s, rrx", regnames[word&0xF]);
-			return;
-		default:
-			c = 32;
-		}
-	}
-	printf("%s, %s #%u", regnames[word&0xF], shift_types[t], c);
-}
-
-static void
-op2_regbyreg(word)
-	unsigned word;
-{
-	printf("%s, %s %s", regnames[word&0xF], shift_types[(word>>5)&3],
-		regnames[(word>>8)&0xF]);
-}
-
-static void
-op2_regshift(word)
-	unsigned word;
-{
-	if (word & 0x10)
-		op2_regbyreg(word);
-	else
-		op2_regbyconst(word);
-	putchar('\n');
-}
-
-static void
-dataproc_op2(word)
-	unsigned word;
-{
-	if (word & 0x02000000)
-		op2_immed(word);
-	else
-		op2_regshift(word);
-}
-
-static void
-dataproc_tstcmp_overlay(word)
-	unsigned word;
-{
-	char msrmask[5], *cp;
-
-	if ((word & 0x0FFFFFF0) == 0x012FFF10) {
-		printf("bx%s\t%s\n", condition_decode[word>>28],
-			regnames[word&0xF]);
-		return;
-	} else if ((word & 0x0FBF0FFF) == 0x010F0000) {
-		printf("mrs%s\t%s, %cPSR\n", condition_decode[word>>28],
-			regnames[(word>>12)&0xF], word&0x400000 ? 'S' : 'C');
-		return;
-	} else if ((word & 0x0DB0F000) == 0x0120F000) {
-		if (!(word & 0x02000000) && (word & 0xFF0)) {
-			printf("<invalid MSR>\n");
-			return;
-		}
-		if (word & 0xF0000) {
-			cp = msrmask;
-			if (word & 0x80000)
-				*cp++ = 'f';
-			if (word & 0x40000)
-				*cp++ = 's';
-			if (word & 0x20000)
-				*cp++ = 'x';
-			if (word & 0x10000)
-				*cp++ = 'c';
-			*cp = '\0';
-		} else
-			strcpy(msrmask, "null");
-		printf("msr%s\t%cPSR_%s, ", condition_decode[word>>28],
-			word&0x400000 ? 'S' : 'C', msrmask);
-		dataproc_op2(word);
-		return;
-	}
-	printf("<invalid BX/MRS/MSR>\n");
-}
-
-static void
-dataproc(word)
-	unsigned word;
-{
-	unsigned opc;
-
-	opc = (word >> 21) & 0xF;
-	switch (opc) {
-	case 0:
-	case 1:
-	case 2:
-	case 3:
-	case 4:
-	case 5:
-	case 6:
-	case 7:
-	case 0xC:
-	case 0xE:
-		printf("%s%s%s\t%s, %s, ", dataproc_ops[opc],
-			condition_decode[word>>28], word&0x100000 ? "s" : "",
-			regnames[(word>>12)&0xF], regnames[(word>>16)&0xF]);
-		dataproc_op2(word);
-		return;
-	case 0xD:
-	case 0xF:
-		printf("%s%s%s\t%s, ", dataproc_ops[opc],
-			condition_decode[word>>28], word&0x100000 ? "s" : "",
-			regnames[(word>>12)&0xF]);
-		dataproc_op2(word);
-		return;
-	case 8:
-	case 9:
-	case 0xA:
-	case 0xB:
-		if (word & 0x100000) {
-			printf("%s%s\t%s, ", dataproc_ops[opc],
-				condition_decode[word>>28],
-				regnames[(word>>16)&0xF]);
-			dataproc_op2(word);
-		} else
-			dataproc_tstcmp_overlay(word);
-		return;
-	}
-}
-
-static void
-multiply(word)
-	unsigned word;
-{
-	if ((word & 0x0FE000F0) == 0x90)
-		printf("mul%s%s\t%s, %s, %s\n", condition_decode[word>>28],
-			word&0x100000 ? "s" : "", regnames[(word>>16)&0xF],
-			regnames[word&0xF], regnames[(word>>8)&0xF]);
-	else if ((word & 0x0FE000F0) == 0x00200090)
-		printf("mla%s%s\t%s, %s, %s, %s\n", condition_decode[word>>28],
-			word&0x100000 ? "s" : "", regnames[(word>>16)&0xF],
-			regnames[word&0xF], regnames[(word>>8)&0xF],
-			regnames[(word>>12)&0xF]);
-	else if ((word & 0x0F8000F0) == 0x00800090)
-		printf("%c%sl%s%s\t%s, %s, %s, %s\n",
-			word&0x400000 ? 's' : 'u',
-			word&0x200000 ? "mla" : "mul",
-			condition_decode[word>>28],
-			word&0x100000 ? "s" : "",
-			regnames[(word>>12)&0xF], regnames[(word>>16)&0xF],
-			regnames[word&0xF], regnames[(word>>8)&0xF]);
-	else if ((word & 0x0FB00FF0) == 0x01000090)
-		printf("swp%s%s\t%s, %s, [%s]\n", condition_decode[word>>28],
-			word&0x400000, "b", "", regnames[(word>>12)&0xF],
-			regnames[word&0xF], regnames[(word>>16)&0xF]);
-	else
-		printf("<invalid multiply>\n");
-}
-
-static int
-check_ldr_litpool(sec, off, word, loff, size)
-	struct internal_scnhdr *sec;
-	unsigned off, word, loff;
-{
-	unsigned litoff, datum;
-	struct internal_reloc *rel;
-
-	/* base reg must be 15 */
-	if (((word >> 16) & 0xF) != 15)
-		return(0);
-	/* must be a load */
-	if (!(word & 0x100000))
-		return(0);
-	/* no writeback allowed */
-	if (word & 0x200000)
-		return(0);
-	/* alignment */
-	if (loff & (size - 1))
-		return(0);
-	/* range */
-	off += 8;
-	if (word & 0x800000)
-		litoff = off + loff;
-	else {
-		if (loff > off)
-			return(0);
-		litoff = off - loff;
-	}
-	if (litoff >= sec->size)
-		return(0);
-	/* all checks passed, proceed */
-	rel = find_word32_reloc(sec, litoff);
-	switch (size) {
-	case 1:
-		datum = filemap[sec->data_offset + litoff];
-		break;
-	case 2:
-		datum = get_u16(filemap + sec->data_offset + litoff);
-		break;
-	case 4:
-		datum = get_u32(filemap + sec->data_offset + litoff);
-		break;
-	}
-	putchar('=');
-	if (rel)
-		disasm_reloc_target(sec, rel, datum);
-	else
-		printf("0x%x", datum);
-	printf("\t; via 0x%x\n", litoff);
-	return(1);
-}
-
-static void
-ldr_str_imm_pre(sec, off, word)
-	struct internal_scnhdr *sec;
-	unsigned off, word;
-{
-	unsigned loff = word & 0xFFF;
-
-	printf("%s%s%s\t%s, ", word&0x100000 ? "ldr" : "str",
-		condition_decode[word>>28], word&0x400000 ? "b" : "",
-		regnames[(word>>12)&0xF]);
-	if (check_ldr_litpool(sec, off, word, loff, word&0x400000 ? 1 : 4))
-		return;
-	printf("[%s", regnames[(word>>16)&0xF]);
-	if (loff || word&0x200000)
-		printf(", #%s%u", word&0x800000 ? "" : "-", loff);
-	putchar(']');
-	if (word & 0x200000)
-		putchar('!');
-	if (loff >= 10)
-		printf("\t; 0x%x", loff);
-	putchar('\n');
-}
-
-static void
-ldr_str_imm_post(word)
-	unsigned word;
-{
-	unsigned loff = word & 0xFFF;
-
-	printf("%s%s%s%s\t%s, [%s], #%s%u", word&0x100000 ? "ldr" : "str",
-		condition_decode[word>>28], word&0x400000 ? "b" : "",
-		word&0x200000 ? "t" : "",
-		regnames[(word>>12)&0xF], regnames[(word>>16)&0xF],
-		word&0x800000 ? "" : "-", loff);
-	if (loff >= 10)
-		printf("\t; 0x%x", loff);
-	putchar('\n');
-}
-
-static void
-ldr_str_reg_pre(word)
-	unsigned word;
-{
-	if (word & 0x10) {
-		printf("<invalid ldr/str: offset reg shift by reg>\n");
-		return;
-	}
-	printf("%s%s%s\t%s, [%s, ", word&0x100000 ? "ldr" : "str",
-		condition_decode[word>>28], word&0x400000 ? "b" : "",
-		regnames[(word>>12)&0xF], regnames[(word>>16)&0xF]);
-	if (!(word & 0x800000))
-		putchar('-');
-	op2_regbyconst(word);
-	putchar(']');
-	if (word & 0x200000)
-		putchar('!');
-	putchar('\n');
-}
-
-static void
-ldr_str_reg_post(word)
-	unsigned word;
-{
-	if (word & 0x10) {
-		printf("<invalid ldr/str: offset reg shift by reg>\n");
-		return;
-	}
-	printf("%s%s%s%s\t%s, [%s], ", word&0x100000 ? "ldr" : "str",
-		condition_decode[word>>28], word&0x400000 ? "b" : "",
-		word&0x200000 ? "t" : "",
-		regnames[(word>>12)&0xF], regnames[(word>>16)&0xF]);
-	if (!(word & 0x800000))
-		putchar('-');
-	op2_regbyconst(word);
-	putchar('\n');
-}
-
-static void
-ldr_str_ext(sec, off, word)
-	struct internal_scnhdr *sec;
-	unsigned off, word;
-{
-	unsigned loff;
-
-	if (!(word&0x01000000) && word&0x200000) {
-		printf("<invalid ldrh/strh: P=0, W=1>\n");
-		return;
-	}
-	if (!(word&0x400000) && word&0xF00) {
-		printf("<invalid ldrh/strh: SBZ!=0>\n");
-		return;
-	}
-	printf("%s%s%s%c\t%s, ", word&0x100000 ? "ldr" : "str",
-		condition_decode[word>>28],
-		word&0x40 ? "s" : "",
-		word&0x20 ? 'h' : 'b',
-		regnames[(word>>12)&0xF]);
-	if (word & 0x400000)
-		loff = ((word & 0xF00) >> 4) | (word & 0xF);
-	switch (word & 0x01400000) {
-	case 0:
-		/* reg post */
-		printf("[%s], %s%s", regnames[(word>>16)&0xF],
-			word&0x800000 ? "" : "-", regnames[word&0xF]);
-		break;
-	case 0x400000:
-		/* imm post */
-		printf("[%s], #%s%u", regnames[(word>>16)&0xF],
-			word&0x800000 ? "" : "-", loff);
-		if (loff >= 10)
-			printf("\t; 0x%x", loff);
-		break;
-	case 0x01000000:
-		/* reg pre */
-		printf("[%s, %s%s]%s", regnames[(word>>16)&0xF],
-			word&0x800000 ? "" : "-", regnames[word&0xF],
-			word&0x200000 ? "!" : "");
-		break;
-	case 0x01400000:
-		/* imm pre */
-		if (check_ldr_litpool(sec, off, word, loff, word&0x20 ? 2 : 1))
-			return;
-		printf("[%s", regnames[(word>>16)&0xF]);
-		if (loff || word&0x200000)
-			printf(", #%s%u", word&0x800000 ? "" : "-", loff);
-		putchar(']');
-		if (word & 0x200000)
-			putchar('!');
-		if (loff >= 10)
-			printf("\t; 0x%x", loff);
-		break;
-	}
-	putchar('\n');
-}
-
-static void
-dataproc_74_overlay(sec, off, word)
-	struct internal_scnhdr *sec;
-	unsigned off, word;
-{
-	if (word & 0x60)
-		ldr_str_ext(sec, off, word);
-	else
-		multiply(word);
-}
-
-static void
-ldm_stm(word)
-	unsigned word;
-{
-	int r, flag;
-
-	printf("%s%s%c%c\t%s", word&0x100000 ? "ldm" : "stm",
-		condition_decode[word>>28],
-		word&0x800000 ? 'i' : 'd', word&0x01000000 ? 'b' : 'a',
-		regnames[(word>>16)&0xF]);
-	if (word & 0x200000)
-		putchar('!');
-	fputs(", {", stdout);
-	flag = 0;
-	for (r = 0; r < 16; r++)
-		if (word & (1 << r)) {
-			if (flag)
-				fputs(", ", stdout);
-			fputs(regnames[r], stdout);
-			flag = 1;
-		}
-	putchar('}');
-	if (word & 0x400000)
-		putchar('^');
-	putchar('\n');
-}
-
-void
-arm_disasm_line(sec, off)
-	struct internal_scnhdr *sec;
-	unsigned off;
-{
-	unsigned word;
-
-	word = get_u32(filemap + sec->data_offset + off);
-	printf("%08x\t", word);
-	if ((word >> 28) == 0xF) {
-		printf("<invalid-F>\n");
-		return;
-	}
-	switch ((word >> 24) & 0xF) {
-	case 0:
-	case 1:
-		if ((word & 0x90) == 0x90)
-			dataproc_74_overlay(sec, off, word);
-		else
-			dataproc(word);
-		return;
-	case 2:
-	case 3:
-		dataproc(word);
-		return;
-	case 4:
-		ldr_str_imm_post(word);
-		return;
-	case 5:
-		ldr_str_imm_pre(sec, off, word);
-		return;
-	case 6:
-		ldr_str_reg_post(word);
-		return;
-	case 7:
-		ldr_str_reg_pre(word);
-		return;
-	case 8:
-	case 9:
-		ldm_stm(word);
-		return;
-	case 0xA:
-	case 0xB:
-		arm_branch(off, word);
-		return;
-	case 0xC:
-	case 0xD:
-	case 0xE:
-		printf("<COPROCESSOR>\n");
-		return;
-	case 0xF:
-		printf("swi%s\t0x%x\n", condition_decode[word>>28],
-			word & 0xFFFFFF);
-		return;
-	}
-}
-
-void
-arm_branch_reloc(sec, rel)
-	struct internal_scnhdr *sec;
-	struct internal_reloc *rel;
-{
-	unsigned word, dest;
-
-	word = get_u32(filemap + sec->data_offset + rel->location);
-	printf("%08x R\t", word);
-	if ((word & 0x0E000000) != 0x0A000000) {
-		printf("<invalid ARM_B reloc: opcode not B or BL>\n");
-		return;
-	}
-	dest = (word & 0x00FFFFFF) << 2;
-	if (dest & 0x02000000)
-		dest |= 0xFC000000;
-	dest += rel->location + 8;
-	printf("b%s%s\t", word&0x1000000 ? "l" : "",
-		condition_decode[word>>28]);
-	disasm_reloc_target(sec, rel, dest);
-	putchar('\n');
-}
--- a/ticoff/atcommon.c	Sun Apr 06 20:20:39 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,14 +0,0 @@
-/*
- * Lean and mean ARM7TDMI disassembler
- * Written by Spacefalcon the Outlaw
- */
-
-/* a few disassembly bits common between ARM and Thumb */
-
-char *regnames[16] = {"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
-			"r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc"};
-
-char *condition_decode[16] = {"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
-				"hi", "ls", "ge", "lt", "gt", "le", "", "INV"};
-
-char *shift_types[4] = {"lsl", "lsr", "asr", "ror"};
--- a/ticoff/basics.c	Sun Apr 06 20:20:39 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,74 +0,0 @@
-/*
- * This C module implements some "basic" dump commands
- */
-
-#include <sys/types.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <time.h>
-#include "filestruct.h"
-#include "intstruct.h"
-#include "globals.h"
-
-extern unsigned get_u16(), get_u32();
-
-dump_filehdr_info()
-{
-	time_t timestamp;
-	struct tm *timedec;
-
-	timestamp = get_u32(filehdr_struct->f_timdat);
-	timedec = gmtime(&timestamp);
-	printf("timestamp: %d-%02d-%02dT%02d:%02d:%02dZ\n",
-		timedec->tm_year + 1900, timedec->tm_mon + 1, timedec->tm_mday,
-		timedec->tm_hour, timedec->tm_min, timedec->tm_sec);
-	printf("file flags: 0x%x\n", get_u16(filehdr_struct->f_flags));
-	printf("%u sections, %u symtab entries\n", nsections, nsymtab);
-	return(0);
-}
-
-dump_sechdr()
-{
-	unsigned n;
-	struct internal_scnhdr *inf;
-
-	for (n = 0; n < nsections; n++) {
-		inf = sections + n;
-		printf("#%d: %s size=%u, flags=0x%x\n", n, inf->name,
-			inf->size, inf->flags);
-		printf("\t%u reloc, %u line entries\n",
-			inf->nreloc, inf->nlineent);
-	}
-	return(0);
-}
-
-cmd_sechdr()
-{
-	get_int_section_table();
-	dump_sechdr();
-	exit(0);
-}
-
-cmd_symtab()
-{
-	get_int_section_table();
-	get_int_symbol_table();
-	dump_symtab();
-	exit(0);
-}
-
-cmd_basics()
-{
-	printf("%s:\n", objfilename);
-	dump_filehdr_info();
-	putchar('\n');
-	get_int_section_table();
-	printf("Sections:\n\n");
-	dump_sechdr();
-	putchar('\n');
-	get_int_symbol_table();
-	printf("Symbol table:\n\n");
-	dump_symtab();
-	putchar('\n');
-	exit(0);
-}
--- a/ticoff/coffconst.h	Sun Apr 06 20:20:39 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-/********************** 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 */
-
-/* Reloc types */
-
-#define	RTYPE_LONG	0x11
-#define	RTYPE_THUMB_BL	0x16
-#define	RTYPE_ARM_B	0x17
--- a/ticoff/disasm.c	Sun Apr 06 20:20:39 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,414 +0,0 @@
-/*
- * Putting it all together: section-, symbol- and reloc-aware disassembly
- */
-
-#include <sys/types.h>
-#include <stdio.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();
-extern char *storage_class_to_string();
-
-static int auto_xlat_section_relocs = 1;
-
-static void
-find_better_symbol(sec, symp, addp)
-	struct internal_scnhdr *sec;
-	struct internal_syment **symp;
-	unsigned *addp;
-{
-	unsigned addr, delta;
-	struct internal_syment *sym;
-	unsigned n;
-
-	addr = *addp;
-	for (n = 0; n < sec->nsymbols; n++) {
-		sym = sec->sorted_symbols[n];
-		if (sym->value > addr)
-			return;
-		if (sym->class != C_EXT && sym->class != C_STAT)
-			continue;
-		delta = addr - sym->value;
-		if (sym->name[0] == '_' && !delta ||
-		    sym->name[0] == '$' && delta <= 1) {
-			*symp = sym;
-			*addp = delta;
-		}
-	}
-}
-
-void
-disasm_reloc_target(sec, rel, addend)
-	struct internal_scnhdr *sec;
-	struct internal_reloc *rel;
-	unsigned addend;
-{
-	struct internal_syment *sym = rel->sym;
-
-	if (sym)
-		addend -= sym->value;
-	if (auto_xlat_section_relocs &&
-	    (!sym || sym->section && !strcmp(sym->name, sym->section->name)))
-		find_better_symbol(sym ? sym->section : sec, &sym, &addend);
-	if (sym)
-		fputs(sym->name, stdout);
-	else
-		fputs(sec->name, stdout);
-	if (addend >= 10)
-		printf("+0x%x", addend);
-	else if (addend)
-		printf("+%u", addend);
-}
-
-void
-disasm_word32_reloc(sec, rel)
-	struct internal_scnhdr *sec;
-	struct internal_reloc *rel;
-{
-	unsigned word;
-
-	word = get_u32(filemap + sec->data_offset + rel->location);
-	printf("%08x R\t.word\t", word);
-	disasm_reloc_target(sec, rel, word);
-	putchar('\n');
-}
-
-void
-disasm_end_of_section(sec, symnum)
-	struct internal_scnhdr *sec;
-	unsigned symnum;
-{
-	struct internal_syment *sym;
-	char *sym_comment;
-
-	putchar('\n');
-	while (symnum < sec->nsymbols) {
-		sym = sec->sorted_symbols[symnum];
-		if (sym->value != sec->size) {
-			printf("error: expecting symbol at end of section\n");
-			return;
-		}
-		switch (sym->class) {
-		case C_EXT:
-			sym_comment = "Global";
-			break;
-		case C_STAT:
-			sym_comment = "static";
-			break;
-		case C_LABEL:
-			sym_comment = "label";
-			break;
-		default:
-			sym_comment = "unexpected class!";
-		}
-		printf("%s:\t; %s\n", sym->name, sym_comment);
-		symnum++;
-	}
-	printf("%8x:\t<end of section>\n", sec->size);
-}
-
-void
-disasm_text_section(sec)
-	struct internal_scnhdr *sec;
-{
-	unsigned symnum, relnum;
-	unsigned pos, incr, headroom;
-	int state = -1, linebrk = 0;
-	struct internal_syment *sym;
-	struct internal_reloc *rel;
-	char *sym_comment;
-
-	printf("Disassembling code section:\n");
-	if (sec->nsymbols)
-		sort_symbols_of_sec(sec);
-	if (sec->nreloc)
-		get_relocs_of_sec(sec);
-	symnum = relnum = 0;
-	for (pos = 0; pos < sec->size; pos += incr) {
-		headroom = sec->size - pos;
-		while (symnum < sec->nsymbols) {
-			sym = sec->sorted_symbols[symnum];
-			if (sym->value > pos) {
-				if (sym->value - pos < headroom)
-					headroom = sym->value - pos;
-				break;
-			}
-			/* hit symbol */
-			if (!linebrk) {
-				putchar('\n');
-				linebrk = 1;
-			}
-			switch (sym->class) {
-			case C_EXT:
-				sym_comment = "Global";
-				break;
-			case C_STAT:
-				sym_comment = "static";
-				break;
-			case C_LABEL:
-				sym_comment = "label";
-				if (!strcmp(sym->name, "$CODE16"))
-					state = 1;
-				else if (!strcmp(sym->name, "$CODE32"))
-					state = 0;
-				break;
-			default:
-				sym_comment = "unexpected class!";
-			}
-			printf("%s:\t; %s\n", sym->name, sym_comment);
-			symnum++;
-		}
-		if (relnum < sec->nreloc) {
-			rel = sec->int_relocs + relnum;
-			if (rel->location == pos)
-				relnum++;	/* it's ours */
-			else {
-				if (rel->location - pos < headroom)
-					headroom = rel->location - pos;
-				rel = 0;	/* no reloc for current pos */
-			}
-		} else
-			rel = 0;
-		printf("%8x:\t", pos);
-		if (rel && rel->type == RTYPE_LONG) {
-			if (pos & 3) {
-			  printf("MISALIGNED pos for word32 reloc, aborting\n");
-				return;
-			}
-			disasm_word32_reloc(sec, rel);
-			incr = 4;
-			goto next;
-		}
-		if (pos & 1 || headroom < 2) {
-			if (rel) {
-				printf("error: reloc at byte pos, aborting\n");
-				return;
-			}
-			printf("%02x\n", filemap[sec->data_offset + pos]);
-			incr = 1;
-			goto next;
-		}
-		switch (state) {
-		case 0:		/* ARM */
-			if (pos & 3) {
-			   printf("MISALIGNED pos in CODE32 state, aborting\n");
-				return;
-			}
-			if (rel) {
-				if (rel->type != RTYPE_ARM_B) {
-			printf("Wrong reloc type in CODE32 state, aborting\n");
-					return;
-				}
-				arm_branch_reloc(sec, rel);
-			} else
-				arm_disasm_line(sec, pos);
-			incr = 4;
-			break;
-		case 1:		/* Thumb */
-			if (pos & 1) {
-			   printf("MISALIGNED pos in CODE16 state, aborting\n");
-				return;
-			}
-			if (rel) {
-				if (rel->type != RTYPE_THUMB_BL) {
-			printf("Wrong reloc type in CODE16 state, aborting\n");
-					return;
-				}
-				thumb_bl_reloc(sec, rel);
-				incr = 4;
-			} else if (headroom >= 4 && thumb_check_bl(sec, pos))
-				incr = 4;
-			else {
-				thumb_disasm_line(sec, pos);
-				incr = 2;
-			}
-			break;
-		default:
-			printf("UNKNOWN T state, aborting\n");
-			return;
-		}
-next:		linebrk = 0;
-		if (incr > headroom) {
-			printf("error: increment %u > headroom %u, aborting\n",
-				incr, headroom);
-			return;
-		}
-	}
-	if (symnum < sec->nsymbols)
-		disasm_end_of_section(sec, symnum);
-}
-
-void
-disasm_data_section(sec)
-	struct internal_scnhdr *sec;
-{
-	unsigned symnum, relnum;
-	unsigned pos, incr, headroom;
-	int linebrk = 0;
-	struct internal_syment *sym;
-	struct internal_reloc *rel;
-	char *sym_comment;
-
-	printf("Disassembling data section:\n");
-	if (sec->nsymbols)
-		sort_symbols_of_sec(sec);
-	if (sec->nreloc)
-		get_relocs_of_sec(sec);
-	symnum = relnum = 0;
-	for (pos = 0; pos < sec->size; pos += incr) {
-		headroom = sec->size - pos;
-		while (symnum < sec->nsymbols) {
-			sym = sec->sorted_symbols[symnum];
-			if (sym->value > pos) {
-				if (sym->value - pos < headroom)
-					headroom = sym->value - pos;
-				break;
-			}
-			/* hit symbol */
-			if (!linebrk) {
-				putchar('\n');
-				linebrk = 1;
-			}
-			switch (sym->class) {
-			case C_EXT:
-				sym_comment = "Global";
-				break;
-			case C_STAT:
-				sym_comment = "static";
-				break;
-			case C_LABEL:
-				sym_comment = "label";
-				break;
-			default:
-				sym_comment = "unexpected class!";
-			}
-			printf("%s:\t; %s\n", sym->name, sym_comment);
-			symnum++;
-		}
-		if (relnum < sec->nreloc) {
-			rel = sec->int_relocs + relnum;
-			if (rel->location == pos)
-				relnum++;	/* it's ours */
-			else {
-				if (rel->location - pos < headroom)
-					headroom = rel->location - pos;
-				rel = 0;	/* no reloc for current pos */
-			}
-		} else
-			rel = 0;
-		printf("%8x:\t", pos);
-		if (rel) {
-			if (rel->type != RTYPE_LONG) {
-		printf("error: reloc other than word32 in data section\n");
-				return;
-			}
-			if (pos & 3) {
-			  printf("MISALIGNED pos for word32 reloc, aborting\n");
-				return;
-			}
-			disasm_word32_reloc(sec, rel);
-			incr = 4;
-		} else if (pos & 1 || headroom < 2) {
-			printf("%02x\n", filemap[sec->data_offset + pos]);
-			incr = 1;
-		} else if (pos & 2 || headroom < 4) {
-			printf("%04x\n",
-				get_u16(filemap + sec->data_offset + pos));
-			incr = 2;
-		} else {
-			printf("%08x\n",
-				get_u32(filemap + sec->data_offset + pos));
-			incr = 4;
-		}
-		linebrk = 0;
-		if (incr > headroom) {
-			printf("error: increment %u > headroom %u, aborting\n",
-				incr, headroom);
-			return;
-		}
-	}
-	if (symnum < sec->nsymbols)
-		disasm_end_of_section(sec, symnum);
-}
-
-void
-disasm_bss(sec)
-	struct internal_scnhdr *sec;
-{
-	unsigned m;
-	struct internal_syment *sym;
-	char classbuf[8];
-
-	putchar('\n');
-	for (m = 0; m < sec->nsymbols; m++) {
-		sym = sec->sorted_symbols[m];
-		printf("%08X %-7s %s\n", sym->value,
-			storage_class_to_string(sym->class, classbuf),
-			sym->name);
-	}
-	printf("%08X <end of section>\n", sec->size);
-}
-
-void
-disasm_sec_by_type(sec)
-	struct internal_scnhdr *sec;
-{
-	switch (sec->disasm_mode) {
-	case DISASM_MODE_CODE:
-		disasm_text_section(sec);
-		return;
-	case DISASM_MODE_DATA:
-		disasm_data_section(sec);
-		return;
-	case DISASM_MODE_BSS:
-		disasm_bss(sec);
-		return;
-	default:
-		printf("Unrecognized section type, skipped\n");
-	}
-}
-
-cmd_disasm(argc, argv)
-	char **argv;
-{
-	extern char *optarg;
-	char *hintsfile = 0;
-	struct internal_scnhdr *sec;
-	unsigned secnum;
-	int c;
-
-	while ((c = getopt(argc, argv, "h:s")) != EOF)
-		switch (c) {
-		case 'h':
-			hintsfile = optarg;
-			continue;
-		case 's':
-			auto_xlat_section_relocs = 0;
-			continue;
-		default:
-			/* error msg already printed */
-			exit(1);
-		}
-
-	printf("%s:\n", objfilename);
-	dump_filehdr_info();
-	putchar('\n');
-	get_int_section_table();
-	get_int_symbol_table();
-	if (hintsfile)
-		read_hints_file(hintsfile);
-	extern_profile_report("Module");
-	sort_symbols_of_all_sec();
-	for (secnum = 0; secnum < nsections; secnum++) {
-		sec = sections + secnum;
-		printf("=== %s ===\n", sec->name);
-		disasm_sec_by_type(sec);
-		putchar('\n');
-	}
-	exit(0);
-}
--- a/ticoff/filestruct.h	Sun Apr 06 20:20:39 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-/*
- * 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];
-};
--- a/ticoff/globals.c	Sun Apr 06 20:20:39 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,19 +0,0 @@
-/*
- * Definitions of global vars for the tiobjd program.
- */
-
-#include <sys/types.h>
-
-char *objfilename;
-u_char *filemap;
-size_t objfile_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;
-struct internal_syment **symtab;
--- a/ticoff/globals.h	Sun Apr 06 20:20:39 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,17 +0,0 @@
-/*
- * extern declarations of global vars for the tiobjd program.
- */
-
-extern char *objfilename;
-extern u_char *filemap;
-extern size_t objfile_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;
-extern struct internal_syment **symtab;
--- a/ticoff/hints.c	Sun Apr 06 20:20:39 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,131 +0,0 @@
-/*
- * Parsing of the disassembly hints file
- */
-
-#include <sys/types.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <string.h>
-#include <strings.h>
-#include "intstruct.h"
-#include "globals.h"
-
-static char *filename_for_err;
-static int lineno;
-static struct internal_scnhdr *section;
-static struct hint *lasthint;
-
-static void
-set_section(name)
-	char *name;
-{
-	unsigned n;
-	struct internal_scnhdr *sec = 0;
-
-	for (n = 0; n < nsections; n++)
-		if (!strcmp(sections[n].name, name)) {
-			sec = sections + n;
-			break;
-		}
-	if (!sec) {
-		fprintf(stderr, "%s line %d: no section named \"%s\" in %s\n",
-			filename_for_err, lineno, name, objfilename);
-		exit(1);
-	}
-	if (sec->hints) {
-		fprintf(stderr, "%s line %d: [%s] given more than once\n",
-			filename_for_err, lineno, name);
-		exit(1);
-	}
-	section = sec;
-	lasthint = 0;
-}
-
-static void
-set_mode(arg)
-	char *arg;
-{
-	char *cp;
-
-	if (!section) {
-		fprintf(stderr,
-			"%s line %d: error: mode line outside of section\n",
-			filename_for_err, lineno);
-		exit(1);
-	}
-	while (isspace(*arg))
-		arg++;
-	if (!*arg) {
-		fprintf(stderr, "%s line %d: mode line: missing argument\n",
-			filename_for_err, lineno);
-		exit(1);
-	}
-	for (cp = arg; *cp && !isspace(*cp); cp++)
-		;
-	if (*cp)
-		*cp++ = '\0';
-	if (!strcmp(arg, "code"))
-		section->disasm_mode = DISASM_MODE_CODE;
-	else if (!strcmp(arg, "data"))
-		section->disasm_mode = DISASM_MODE_DATA;
-	else if (!strcmp(arg, "bss"))
-		section->disasm_mode = DISASM_MODE_BSS;
-	else {
-		fprintf(stderr, "%s line %d: unknown mode \"%s\"\n",
-			filename_for_err, lineno, arg);
-		exit(1);
-	}
-}
-
-static void
-regular_hint(arg1, arg2)
-	char *arg1, *arg2;
-{
-	fprintf(stderr, "error: regular hints not implemented yet\n");
-	exit(1);
-}
-
-read_hints_file(filename)
-	char *filename;
-{
-	FILE *f;
-	char linebuf[128], *cp, *np;
-
-	f = fopen(filename, "r");
-	if (!f) {
-		perror(filename);
-		exit(1);
-	}
-	filename_for_err = filename;
-	for (lineno = 1; fgets(linebuf, sizeof linebuf, f); lineno++) {
-		for (cp = linebuf; isspace(*cp); cp++)
-			;
-		if (!*cp || *cp == '#')
-			continue;
-		if (*cp == '[') {
-			np = ++cp;
-			cp = index(cp, ']');
-			if (!cp) {
-				fprintf(stderr,
-					"%s line %d: invalid section syntax\n",
-					filename, lineno);
-				exit(1);
-			}
-			*cp = '\0';
-			set_section(np);
-			continue;
-		}
-		for (np = cp; *cp && !isspace(*cp); cp++)
-			;
-		if (*cp)
-			*cp++ = '\0';
-		if (!strcmp(np, "mode")) {
-			set_mode(cp);
-			continue;
-		}
-		regular_hint(np, cp);
-	}
-	fclose(f);
-	return(0);
-}
--- a/ticoff/intstruct.h	Sun Apr 06 20:20:39 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-/*
- * 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 **sorted_symbols;
-	struct internal_reloc *int_relocs;
-	int		disasm_mode;
-	struct hint	*hints;
-};
-
-#define	DISASM_MODE_UNKNOWN	0
-#define	DISASM_MODE_CODE	1
-#define	DISASM_MODE_DATA	2
-#define	DISASM_MODE_BSS		3
-
-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_syment *sym;
-	int		type;
-	char		*typestr;
-};
-
-struct hint {
-	unsigned	pos;
-	int		type;
-	unsigned	nitems;
-	int		linebrk;
-	struct hint	*next;
-};
-
-#define	HINT_D8		1
-#define	HINT_D16	2
-#define	HINT_ASCIZ	3
-#define	HINT_D32	4
--- a/ticoff/lowlevel.c	Sun Apr 06 20:20:39 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,94 +0,0 @@
-/*
- * This C module implements the low-level steps of TI COFF image analysis.
- */
-
-#include <sys/types.h>
-#include <sys/file.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include "filestruct.h"
-#include "globals.h"
-
-mmap_objfile()
-{
-	int fd;
-	struct stat st;
-
-	fd = open(objfilename, O_RDONLY);
-	if (fd < 0) {
-		perror(objfilename);
-		exit(1);
-	}
-	fstat(fd, &st);
-	if (!S_ISREG(st.st_mode)) {
-		fprintf(stderr, "error: %s is not a regular file\n",
-			objfilename);
-		exit(1);
-	}
-	objfile_tot_size = st.st_size;
-	filemap = mmap(NULL, objfile_tot_size, PROT_READ, MAP_PRIVATE, fd, 0L);
-	if (filemap == MAP_FAILED) {
-		perror("mmap");
-		exit(1);
-	}
-	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;
-}
-
-initial_parse_hdr()
-{
-	unsigned symtab_offset;
-
-	filehdr_struct = (struct external_filehdr *) filemap;
-	if (get_u16(filehdr_struct->f_magic) != 0xC2) {
-		fprintf(stderr, "error: %s is not a TI COFF2 object\n",
-			objfilename);
-		exit(1);
-	}
-	if (get_u16(filehdr_struct->f_target_id) != 0x97) {
-		fprintf(stderr, "error: TI COFF object %s is not for TMS470\n",
-			objfilename);
-		exit(1);
-	}
-	if (get_u16(filehdr_struct->f_opthdr)) {
-		fprintf(stderr,
-			"error: %s has the \"optional\" header present\n",
-			objfilename);
-		exit(1);
-	}
-	sections_raw = (struct external_scnhdr *)
-				(filemap + sizeof(struct external_filehdr));
-	nsections = get_u16(filehdr_struct->f_nscns);
-	symtab_offset = get_u32(filehdr_struct->f_symptr);
-	symtab_raw = (struct external_syment *)(filemap + symtab_offset);
-	nsymtab = get_u32(filehdr_struct->f_nsyms);
-	strtab_offset = symtab_offset +
-				sizeof(struct external_syment) * nsymtab;
-}
--- a/ticoff/main.c	Sun Apr 06 20:20:39 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,60 +0,0 @@
-/*
- * tiobjd main() function and command dispatch
- */
-
-#include <sys/types.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <strings.h>
-#include "globals.h"
-
-extern int cmd_basics();
-extern int cmd_disasm();
-extern int cmd_nm();
-extern int cmd_profile();
-extern int cmd_rawrel();
-extern int cmd_reloc();
-extern int cmd_sechdr();
-extern int cmd_symtab();
-extern int dump_filehdr_info();
-
-static struct cmdtab {
-	char	*cmd;
-	int	(*func)();
-} cmdtab[] = {
-	{"basics", cmd_basics},
-	{"disasm", cmd_disasm},
-	{"dumpsym", cmd_symtab},	/* backward compat */
-	{"hdr", dump_filehdr_info},
-	{"nm", cmd_nm},
-	{"profile", cmd_profile},
-	{"rawrel", cmd_rawrel},
-	{"reloc", cmd_reloc},
-	{"sechdr", cmd_sechdr},
-	{"symtab", cmd_symtab},
-	{0, 0}
-};
-
-main(argc, argv)
-	char **argv;
-{
-	struct cmdtab *tp;
-
-	if (argc < 3) {
-		fprintf(stderr, "usage: %s <objfile> <op> [args]\n", argv[0]);
-		exit(1);
-	}
-	objfilename = argv[1];
-	mmap_objfile();
-	initial_parse_hdr();
-	for (tp = cmdtab; tp->cmd; tp++)
-		if (!strcmp(tp->cmd, argv[2]))
-			break;
-	if (!tp->func) {
-		fprintf(stderr, "\"%s\": unknown or unimplemented command\n",
-			argv[2]);
-		exit(1);
-	}
-	return tp->func(argc - 2, argv + 2);
-}
--- a/ticoff/profile.c	Sun Apr 06 20:20:39 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,158 +0,0 @@
-/*
- * It is handy to have a "profile" of what functions and variables
- * a given module defines (presents to the rest of the fw) and what
- * it references.  This profile is constructed from the symbol table.
- *
- * Experience indicates that the order of these symbols in the
- * artifact symtab is often "random", and an alphabetic sort is
- * expected to improve readability.  This module contains the
- * messy code.
- */
-
-#include <sys/types.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <strings.h>
-#include "intstruct.h"
-#include "coffconst.h"
-#include "globals.h"
-
-static int
-is_symbol_text_def(sym)
-	struct internal_syment *sym;
-{
-	if (!sym->section)
-		return(0);
-	if (!strncmp(sym->section->name, ".text", 5))
-		return(1);
-	else
-		return(0);
-}
-
-static int
-is_symbol_nontext_def(sym)
-	struct internal_syment *sym;
-{
-	if (!sym->section)
-		return(0);
-	if (!strncmp(sym->section->name, ".text", 5))
-		return(0);
-	else
-		return(1);
-}
-
-static int
-is_symbol_extref(sym)
-	struct internal_syment *sym;
-{
-	if (sym->section)
-		return(0);
-	else
-		return(1);
-}
-
-static int
-compare_for_sort(p1, p2)
-	struct internal_syment **p1, **p2;
-{
-	return strcmp((*p1)->name, (*p2)->name);
-}
-
-static void
-list_class(firstidx, lastidx, total, checkfunc, printsec)
-	unsigned firstidx, lastidx, total;
-	int (*checkfunc)();
-{
-	struct internal_syment **array, *sym;
-	unsigned n, m;
-
-	array = malloc(sizeof(void *) * total);
-	if (!array) {
-		perror("malloc");
-		exit(1);
-	}
-	m = 0;
-	for (n = firstidx; n <= lastidx; n++) {
-		sym = symtab[n];
-		if (!sym)
-			continue;
-		if (sym->class != C_EXT)
-			continue;
-		if (!checkfunc(sym))
-			continue;
-		array[m++] = sym;
-	}
-	if (m != total) {
-		fprintf(stderr, "BUG: symbol class miscount in profile gen\n");
-		exit(1);
-	}
-	qsort(array, total, sizeof(void *), compare_for_sort);
-	for (n = 0; n < total; n++) {
-		sym = array[n];
-		if (printsec)
-			printf("%s (%s)\n", sym->name, sym->section->name);
-		else
-			printf("%s\n", sym->name);
-	}
-	free(array);
-	putchar('\n');
-}
-
-extern_profile_report(heading)
-	char *heading;
-{
-	unsigned n;
-	int first_extern = -1, last_extern;
-	struct internal_syment *sym;
-	unsigned defs_text = 0, defs_nontext = 0, extrefs = 0;
-
-	for (n = 0; n < nsymtab; n++) {
-		sym = symtab[n];
-		if (!sym)
-			continue;
-		if (sym->class != C_EXT)
-			continue;
-		if (first_extern < 0)
-			first_extern = n;
-		last_extern = n;
-		if (sym->scnum < 0) {
-			fprintf(stderr,
-		"symbol entry #%u: unexpected negative scnum for C_EXT\n", n);
-			exit(1);
-		}
-		if (sym->scnum == 0)
-			extrefs++;
-		else if (!strncmp(sym->section->name, ".text", 5))
-			defs_text++;
-		else
-			defs_nontext++;
-	}
-	if (first_extern < 0) {
-		printf("%s has no external symbols!\n", heading);
-		return(1);
-	}
-	if (defs_text || defs_nontext) {
-		printf("%s defines:\n\n", heading);
-		if (defs_text)
-			list_class(first_extern, last_extern, defs_text,
-					is_symbol_text_def, 1);
-		if (defs_nontext)
-			list_class(first_extern, last_extern, defs_nontext,
-					is_symbol_nontext_def, 1);
-	}
-	if (extrefs) {
-		printf("%s references:\n\n", heading);
-		list_class(first_extern, last_extern, extrefs,
-				is_symbol_extref, 0);
-	}
-	return(0);
-}
-
-cmd_profile()
-{
-	get_int_section_table();
-	get_int_symbol_table();
-	extern_profile_report(objfilename);
-	exit(0);
-}
--- a/ticoff/reloc.c	Sun Apr 06 20:20:39 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,164 +0,0 @@
-/*
- * Handling of relocation records
- */
-
-#include <sys/types.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include "filestruct.h"
-#include "intstruct.h"
-#include "coffconst.h"
-#include "globals.h"
-
-extern unsigned get_u16(), get_u32();
-
-cmd_rawrel()
-{
-	unsigned n, m;
-	struct internal_scnhdr *sec;
-	struct external_reloc *rel;
-
-	get_int_section_table();
-	for (n = 0; n < nsections; n++) {
-		sec = sections + n;
-		if (!sec->nreloc)
-			continue;
-		printf("%s:\n\n", sec->name);
-		rel = (struct external_reloc *)(filemap + sec->reloc_offset);
-		printf("Location  SymIndex  Rsvd  Type\n");
-		for (m = 0; m < sec->nreloc; m++, rel++)
-			printf("%08X  %08X  %04X  %04X\n",
-				get_u32(rel->r_vaddr), get_u32(rel->r_symndx),
-				get_u16(rel->r_reserved), get_u16(rel->r_type));
-		putchar('\n');
-	}
-	exit(0);
-}
-
-void
-get_relocs_of_sec(sec)
-	struct internal_scnhdr *sec;
-{
-	unsigned n;
-	struct external_reloc *extrel;
-	struct internal_reloc *intrel;
-	unsigned lastloc, symidx;
-
-	if (sec->int_relocs)
-		return;
-	if (!sec->nreloc) {
-		fprintf(stderr,
-	"BUG: get_relocs_of_sec() called for section \"%s\" w/o relocs\n",
-			sec->name);
-		exit(1);
-	}
-	intrel = malloc(sizeof(struct internal_reloc) * sec->nreloc);
-	if (!intrel) {
-		perror("malloc");
-		exit(1);
-	}
-	sec->int_relocs = intrel;
-	extrel = (struct external_reloc *)(filemap + sec->reloc_offset);
-	for (n = 0; n < sec->nreloc; n++, extrel++, intrel++) {
-		intrel->location = get_u32(extrel->r_vaddr);
-		if (n && intrel->location <= lastloc) {
-			fprintf(stderr,
-			"error: non-increasing reloc order in section \"%s\"\n",
-				sec->name);
-			exit(1);
-		}
-		lastloc = intrel->location;
-		symidx = get_u32(extrel->r_symndx);
-		if (symidx == 0xFFFFFFFF)
-			intrel->sym = 0;
-		else if (symidx >= nsymtab || !symtab[symidx]) {
-			fprintf(stderr,
-	"error: reloc references invalid symbol #%u in section \"%s\"\n",
-				symidx, sec->name);
-			exit(1);
-		} else
-			intrel->sym = symtab[symidx];
-		intrel->type = get_u16(extrel->r_type);
-		switch (intrel->type) {
-		case RTYPE_LONG:
-			intrel->typestr = "Word32";
-			break;
-		case RTYPE_THUMB_BL:
-			intrel->typestr = "Thumb_BL";
-			break;
-		case RTYPE_ARM_B:
-			intrel->typestr = "ARM_B";
-			break;
-		default:
-			fprintf(stderr,
-		"error: reloc in section \"%s\" of unexpected type 0x%x\n",
-				sec->name, intrel->type);
-			exit(1);
-		}
-		if (get_u16(extrel->r_reserved))
-			fprintf(stderr,
-	"warning: reloc in section \"%s\" has non-zero reserved field\n",
-				sec->name);
-	}
-}
-
-cmd_reloc()
-{
-	unsigned n, m;
-	struct internal_scnhdr *sec;
-	struct internal_reloc *rel;
-	char *symname;
-
-	get_int_section_table();
-	get_int_symbol_table();
-	for (n = 0; n < nsections; n++) {
-		sec = sections + n;
-		if (!sec->nreloc)
-			continue;
-		printf("%s:\n\n", sec->name);
-		get_relocs_of_sec(sec);
-		rel = sec->int_relocs;
-		printf("Location  Type      Symbol relative to\n");
-		for (m = 0; m < sec->nreloc; m++, rel++) {
-			if (rel->sym)
-				symname = rel->sym->name;
-			else
-				symname = "<none>";
-			printf("%08X  %-8s  %s\n", rel->location, rel->typestr,
-				symname);
-		}
-		putchar('\n');
-	}
-	exit(0);
-}
-
-struct internal_reloc *
-find_reloc(sec, loc)
-	struct internal_scnhdr *sec;
-	unsigned loc;
-{
-	struct internal_reloc *rel;
-	unsigned m;
-
-	rel = sec->int_relocs;
-	for (m = 0; m < sec->nreloc; m++, rel++) {
-		if (rel->location == loc)
-			return(rel);
-		if (rel->location > loc)
-			return(0);
-	}
-	return(0);
-}
-
-struct internal_reloc *
-find_word32_reloc(sec, loc)
-	struct internal_scnhdr *sec;
-	unsigned loc;
-{
-	struct internal_reloc *rel;
-
-	rel = find_reloc(sec, loc);
-	if (rel && rel->type != RTYPE_LONG)
-		rel = 0;
-	return(rel);
-}
--- a/ticoff/symtab.c	Sun Apr 06 20:20:39 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,185 +0,0 @@
-/*
- * Code for working with the symbol table
- */
-
-#include <sys/types.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include "filestruct.h"
-#include "intstruct.h"
-#include "coffconst.h"
-#include "globals.h"
-
-static struct classmap {
-	int	code;
-	char	*str;
-} classtab[] = {
-	{C_NULL, "NULL"},
-	{C_AUTO, "AUTO"},
-	{C_EXT, "EXT"},
-	{C_STAT, "STAT"},
-	{C_REG, "REG"},
-	{C_EXTREF, "EXTREF"},
-	{C_LABEL, "LABEL"},
-	{C_ULABEL, "ULABEL"},
-	{C_MOS, "MOS"},
-	{C_ARG, "ARG"},
-	{C_STRTAG, "STRTAG"},
-	{C_MOU, "MOU"},
-	{C_UNTAG, "UNTAG"},
-	{C_TPDEF, "TPDEF"},
-	{C_USTATIC, "USTATIC"},
-	{C_ENTAG, "ENTAG"},
-	{C_MOE, "MOE"},
-	{C_REGPARM, "REGPARM"},
-	{C_FIELD, "FIELD"},
-	{C_UEXT, "UEXT"},
-	{C_STATLAB, "STATLAB"},
-	{C_EXTLAB, "EXTLAB"},
-	{C_SYSTEM, "SYSTEM"},
-	{C_VARARG, "VARARG"},
-	{C_BLOCK, "BLOCK"},
-	{C_FCN, "FCN"},
-	{C_EOS, "EOS"},
-	{C_FILE, "FILE"},
-	{C_LINE, "LINE"},
-	{0, 0}
-};
-
-char *
-storage_class_to_string(code, numbuf)
-	char *numbuf;
-{
-	struct classmap *tp;
-
-	for (tp = classtab; tp->str; tp++)
-		if (tp->code == code)
-			return(tp->str);
-	sprintf(numbuf, "%d", code);
-	return(numbuf);
-}
-
-dump_symtab()
-{
-	unsigned n;
-	struct internal_syment *sym;
-	char *sec, secstr[8];
-	char *class, classbuf[8];
-
-	printf("%-5s %-30s %-4s %-7s %-12s %-8s\n",
-		"Num", "Name", "Type", "Class", "Section", "Value");
-	for (n = 0; n < nsymtab; n++) {
-		sym = symtab[n];
-		if (!sym)
-			continue;
-		if (sym->section)
-			sec = sym->section->name;
-		else {
-			sprintf(secstr, "%d", sym->scnum);
-			sec = secstr;
-		}
-		class = storage_class_to_string(sym->class, classbuf);
-		printf("%-5u %-30s %04X %-7s %-12s %08X%s\n",
-			n, sym->name, sym->type, class,
-			sec, sym->value, sym->aux ? " Aux" : "");
-	}
-	return(0);
-}
-
-static void
-initial_fill_for_sort(sec)
-	struct internal_scnhdr *sec;
-{
-	unsigned n, m;
-	struct internal_syment *sym;
-
-	m = 0;
-	for (n = 0; n < nsymtab; n++) {
-		sym = symtab[n];
-		if (!sym)
-			continue;
-		if (sym->section != sec)
-			continue;
-		sec->sorted_symbols[m++] = sym;
-	}
-}
-
-static int
-compare_for_sort(p1, p2)
-	struct internal_syment **p1, **p2;
-{
-	/* sort by value first */
-	if ((*p1)->value < (*p2)->value)
-		return(-1);
-	if ((*p1)->value > (*p2)->value)
-		return(1);
-	/* if same value, retain the original symtab order */
-	if ((*p1)->number < (*p2)->number)
-		return(-1);
-	if ((*p1)->number > (*p2)->number)
-		return(1);
-	else
-		return(0);
-}
-
-void
-sort_symbols_of_sec(sec)
-	struct internal_scnhdr *sec;
-{
-	if (sec->sorted_symbols)
-		return;
-	if (!sec->nsymbols) {
-		fprintf(stderr,
-	"BUG: sort_symbols_of_sec() called for section \"%s\" w/o symbols\n",
-			sec->name);
-		exit(1);
-	}
-	sec->sorted_symbols = malloc(sizeof(void *) * sec->nsymbols);
-	if (!sec->sorted_symbols) {
-		perror("malloc");
-		exit(1);
-	}
-	initial_fill_for_sort(sec);
-	qsort(sec->sorted_symbols, sec->nsymbols, sizeof(void *),
-		compare_for_sort);
-}
-
-void
-sort_symbols_of_all_sec()
-{
-	unsigned n;
-	struct internal_scnhdr *sec;
-
-	for (n = 0; n < nsections; n++) {
-		sec = sections + n;
-		if (!sec->nsymbols)
-			continue;
-		sort_symbols_of_sec(sec);
-	}
-}
-
-cmd_nm()
-{
-	unsigned n, m;
-	struct internal_scnhdr *sec;
-	struct internal_syment *sym;
-	char classbuf[8];
-
-	get_int_section_table();
-	get_int_symbol_table();
-	for (n = 0; n < nsections; n++) {
-		sec = sections + n;
-		if (!sec->nsymbols)
-			continue;
-		printf("%s:\n\n", sec->name);
-		sort_symbols_of_sec(sec);
-		for (m = 0; m < sec->nsymbols; m++) {
-			sym = sec->sorted_symbols[m];
-			printf("%08X %-7s %s\n", sym->value,
-				storage_class_to_string(sym->class, classbuf),
-				sym->name);
-		}
-		putchar('\n');
-	}
-	exit(0);
-}
--- a/ticoff/tables.c	Sun Apr 06 20:20:39 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,155 +0,0 @@
-/*
- * This C module will contain functions for the initial parsing
- * of the section and symbol tables.
- */
-
-#include <sys/types.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <strings.h>
-#include "filestruct.h"
-#include "intstruct.h"
-#include "globals.h"
-
-extern unsigned get_u16(), get_u32();
-
-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(1);
-			}
-			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 - filemap);
-		exit(1);
-	}
-	return(filemap + strtab_offset + get_u32(ptr+4));
-}
-
-get_int_section_table()
-{
-	unsigned n;
-
-	sections = malloc(sizeof(struct internal_scnhdr) * nsections);
-	if (!sections) {
-		perror("malloc");
-		exit(1);
-	}
-	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;
-		sections[n].sorted_symbols = 0;
-		sections[n].int_relocs = 0;
-		if (!strncmp(sections[n].name, ".text", 5))
-			sections[n].disasm_mode = DISASM_MODE_CODE;
-		else if (!strcmp(sections[n].name, ".const"))
-			sections[n].disasm_mode = DISASM_MODE_DATA;
-		else if (!strcmp(sections[n].name, ".cinit"))
-			sections[n].disasm_mode = DISASM_MODE_DATA;
-		else if (!strcmp(sections[n].name, ".data"))
-			sections[n].disasm_mode = DISASM_MODE_DATA;
-		else if (!strcmp(sections[n].name, ".bss"))
-			sections[n].disasm_mode = DISASM_MODE_BSS;
-		else
-			sections[n].disasm_mode = DISASM_MODE_UNKNOWN;
-		sections[n].hints = 0;
-	}
-}
-
-get_int_symbol_table()
-{
-	unsigned n;
-	struct internal_syment *in;
-
-	symtab = malloc(sizeof(struct internal_syment *) * nsymtab);
-	if (!symtab) {
-		perror("malloc");
-		exit(1);
-	}
-	for (n = 0; n < nsymtab; ) {
-		in = malloc(sizeof(struct internal_syment));
-		if (!in) {
-			perror("malloc");
-			exit(1);
-		}
-		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(1);
-			}
-			in->section = sections + in->scnum - 1;
-			in->section->nsymbols++;
-		} else if (in->scnum < -2) {
-			fprintf(stderr,
-				"symtab entry #%u: scnum < -2\n", n);
-			exit(1);
-		} 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(1);
-			}
-			symtab[n] = 0;
-			in->aux = (u_char *)(symtab_raw + n);
-			n++;
-			continue;
-		default:
-			n--;
-			fprintf(stderr, "symtab entry #%u: invalid numaux\n",
-				n);
-			exit(1);
-		}
-	}
-}
--- a/ticoff/thumbdis.c	Sun Apr 06 20:20:39 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,436 +0,0 @@
-/*
- * Thumb state disassembly
- */
-
-#include <sys/types.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <strings.h>
-#include "intstruct.h"
-#include "globals.h"
-
-extern unsigned get_u16(), get_u32();
-extern struct internal_reloc *find_word32_reloc();
-
-extern char *regnames[16], *condition_decode[16], *shift_types[4];
-
-static void
-format_1_2(word)
-	unsigned word;
-{
-	unsigned op, imm;
-
-	op = (word >> 11) & 3;
-	if (op != 3) {
-		/* format 1 */
-		imm = (word >> 6) & 0x1F;
-		if (op != 0 && imm == 0)
-			imm = 32;
-		printf("%s\t%s, %s, #%u\n", shift_types[op], regnames[word&7],
-			regnames[(word>>3)&7], imm);
-		return;
-	}
-	/* format 2 */
-	printf("%s\t%s, %s, ", word&0x200 ? "sub" : "add", regnames[word&7],
-		regnames[(word>>3)&7]);
-	if (word & 0x400)
-		printf("#%u\n", (word >> 6) & 7);
-	else
-		printf("%s\n", regnames[(word >> 6) & 7]);
-}
-
-static void
-format_3(word)
-	unsigned word;
-{
-	static char *opctab[4] = {"mov", "cmp", "add", "sub"};
-	unsigned imm;
-
-	imm = word & 0xFF;
-	printf("%s\t%s, #%u", opctab[(word>>11)&3], regnames[(word>>8)&7], imm);
-	if (imm > 9)
-		printf("\t; 0x%x", imm);
-	putchar('\n');
-}
-
-static void
-format_4(word)
-	unsigned word;
-{
-	static char *opc[16] = {"and", "eor", "lsl", "lsr",
-				"asr", "adc", "sbc", "ror",
-				"tst", "neg", "cmp", "cmn",
-				"orr", "mul", "bic", "mvn"};
-
-	printf("%s\t%s, %s\n", opc[(word>>6)&0xF], regnames[word&7],
-		regnames[(word>>3)&7]);
-}
-
-static void
-format_5_bx(word)
-	unsigned word;
-{
-	if (word & 0x80)
-		printf("<invalid: blx instead of bx>\n");
-	else
-		printf("bx\t%s\n", regnames[(word>>3)&0xF]);
-}
-
-static void
-format_5_hiops(word)
-	unsigned word;
-{
-	static char *opctab[3] = {"add", "cmp", "mov"};
-	int reg1, reg2, op;
-
-	if (word & 0xC0) {
-		reg1 = word & 7;
-		if (word & 0x80)
-			reg1 += 8;
-		reg2 = (word >> 3) & 0xF;
-		op = (word >> 8) & 3;
-		if (op == 2 && reg1 == reg2 && reg1 != 15)
-			printf("nop\t\t\t(mov %s, %s)\n",
-				regnames[reg1], regnames[reg2]);
-		else
-			printf("%s\t%s, %s\n", opctab[op],
-				regnames[reg1], regnames[reg2]);
-	} else
-		printf("<invalid: hi-reg format with both low regs>\n");
-}
-
-static void
-format_5(word)
-	unsigned word;
-{
-	if ((word & 0x300) == 0x300)
-		format_5_bx(word);
-	else
-		format_5_hiops(word);
-}
-
-static void
-format_6(sec, off, word)
-	struct internal_scnhdr *sec;
-	unsigned off, word;
-{
-	unsigned loff, litoff, datum;
-	struct internal_reloc *rel;
-
-	loff = (word & 0xFF) << 2;
-	off &= ~3;
-	off += 4;
-	litoff = off + loff;
-	if (litoff+4 <= sec->size) {
-		rel = find_word32_reloc(sec, litoff);
-		datum = get_u32(filemap + sec->data_offset + litoff);
-		printf("ldr\t%s, =", regnames[(word>>8)&7]);
-		if (rel)
-			disasm_reloc_target(sec, rel, datum);
-		else
-			printf("0x%x", datum);
-		printf("\t; via 0x%x\n", litoff);
-	} else
-		printf("ldr\t%s, [pc, #%u]\t(0x%x)\n", regnames[(word>>8)&7],
-			loff, litoff);
-}
-
-static void
-format_7(word)
-	unsigned word;
-{
-	printf("%s%s\t%s, [%s, %s]\n", word&0x800 ? "ldr" : "str",
-		word&0x400 ? "b" : "", regnames[word&7],
-		regnames[(word>>3)&7], regnames[(word>>6)&7]);
-}
-
-static void
-format_8(word)
-	unsigned word;
-{
-	static char *opc[4] = {"strh", "ldrsb", "ldrh", "ldrsh"};
-
-	printf("%s\t%s, [%s, %s]\n", opc[(word>>10)&3], regnames[word&7],
-		regnames[(word>>3)&7], regnames[(word>>6)&7]);
-}
-
-static void
-format_9(word)
-	unsigned word;
-{
-	unsigned loff;
-
-	loff = (word >> 6) & 0x1F;
-	if (!(word & 0x1000))
-		loff <<= 2;
-	printf("%s%s\t%s, [%s, #%u]", word&0x800 ? "ldr" : "str",
-		word&0x1000 ? "b" : "", regnames[word&7],
-		regnames[(word>>3)&7], loff);
-	if (loff >= 10)
-		printf("\t; 0x%x", loff);
-	putchar('\n');
-}
-
-static void
-format_10(word)
-	unsigned word;
-{
-	unsigned loff;
-
-	loff = (word >> 6) & 0x1F;
-		loff <<= 1;
-	printf("%sh\t%s, [%s, #%u]", word&0x800 ? "ldr" : "str",
-		regnames[word&7], regnames[(word>>3)&7], loff);
-	if (loff >= 10)
-		printf("\t; 0x%x", loff);
-	putchar('\n');
-}
-
-static void
-format_11(word)
-	unsigned word;
-{
-	unsigned loff;
-
-	loff = (word & 0xFF) << 2;
-	printf("%s\t%s, [sp, #%u]", word&0x800 ? "ldr" : "str",
-		regnames[(word>>8)&7], loff);
-	if (loff >= 10)
-		printf("\t; 0x%x", loff);
-	putchar('\n');
-}
-
-static void
-format_12(off, word)
-	unsigned off, word;
-{
-	unsigned loff;
-
-	loff = (word & 0xFF) << 2;
-	printf("add\t%s, ", regnames[(word>>8)&7]);
-	if (word & 0x800) {
-		printf("sp, #%u", loff);
-		if (loff >= 10)
-			printf("\t; 0x%x", loff);
-		putchar('\n');
-	} else {
-		off &= ~3;
-		printf("pc, #%u\t; 0x%x\n", loff, off + 4 + loff);
-	}
-}
-
-static void
-format_13(word)
-	unsigned word;
-{
-	unsigned loff;
-
-	if ((word & 0xFF00) != 0xB000) {
-		printf("<invalid format 13>\n");
-		return;
-	}
-	loff = (word & 0x7F) << 2;
-	printf("%s\tsp, #%u", word&0x80 ? "sub" : "add", loff);
-	if (loff >= 10)
-		printf("\t; 0x%x", loff);
-	putchar('\n');
-}
-
-static void
-format_14(word)
-	unsigned word;
-{
-	int r, flag;
-
-	if ((word & 0xF600) != 0xB400) {
-		printf("<invalid format 14>\n");
-		return;
-	}
-	printf("%s\t{", word&0x800 ? "pop" : "push");
-	flag = 0;
-	for (r = 0; r < 9; r++)
-		if (word & (1 << r)) {
-			if (flag)
-				fputs(", ", stdout);
-			if (r == 8)
-				fputs(word&0x800 ? "pc" : "lr", stdout);
-			else
-				fputs(regnames[r], stdout);
-			flag = 1;
-		}
-	putchar('}');
-	putchar('\n');
-}
-
-static void
-format_15(word)
-	unsigned word;
-{
-	int r, flag;
-
-	printf("%sia\t%s!, {", word&0x800 ? "ldm" : "stm",
-		regnames[(word>>8)&7]);
-	flag = 0;
-	for (r = 0; r < 8; r++)
-		if (word & (1 << r)) {
-			if (flag)
-				fputs(", ", stdout);
-			fputs(regnames[r], stdout);
-			flag = 1;
-		}
-	putchar('}');
-	putchar('\n');
-}
-
-static void
-format_16_17(off, word)
-	unsigned off, word;
-{
-	unsigned cond;
-	unsigned dest;
-
-	cond = (word >> 8) & 0xF;
-	switch (cond) {
-	case 0xE:
-		printf("<invalid: bal>\n");
-		return;
-	case 0xF:
-		printf("swi\t0x%x\n", word & 0xFF);
-		return;
-	}
-	dest = (word & 0xFF) << 1;
-	if (dest & 0x00000100)
-		dest |= 0xFFFFFE00;
-	dest += off + 4;
-	printf("b%s\t0x%x\n", condition_decode[cond], dest);
-}
-
-static void
-format_18(off, word)
-	unsigned off, word;
-{
-	unsigned dest;
-
-	if (word & 0x800) {
-		printf("<invalid format 18>\n");
-		return;
-	}
-	dest = (word & 0x7FF) << 1;
-	if (dest & 0x00000800)
-		dest |= 0xFFFFF000;
-	dest += off + 4;
-	printf("b\t0x%x\n", dest);
-}
-
-void
-thumb_disasm_line(sec, off)
-	struct internal_scnhdr *sec;
-	unsigned off;
-{
-	unsigned word;
-
-	word = get_u16(filemap + sec->data_offset + off);
-	printf("%04x\t\t", word);
-	switch (word >> 12) {
-	case 0:
-	case 1:
-		format_1_2(word);
-		return;
-	case 2:
-	case 3:
-		format_3(word);
-		return;
-	case 4:
-		if (word & 0x800)
-			format_6(sec, off, word);
-		else if (word & 0x400)
-			format_5(word);
-		else
-			format_4(word);
-		return;
-	case 5:
-		if (word & 0x200)
-			format_8(word);
-		else
-			format_7(word);
-		return;
-	case 6:
-	case 7:
-		format_9(word);
-		return;
-	case 8:
-		format_10(word);
-		return;
-	case 9:
-		format_11(word);
-		return;
-	case 0xA:
-		format_12(off, word);
-		return;
-	case 0xB:
-		if (word & 0x400)
-			format_14(word);
-		else
-			format_13(word);
-		return;
-	case 0xC:
-		format_15(word);
-		return;
-	case 0xD:
-		format_16_17(off, word);
-		return;
-	case 0xE:
-		format_18(off, word);
-		return;
-	case 0xF:
-		printf("<half-bl>\n");
-		return;
-	}
-}
-
-thumb_check_bl(sec, off)
-	struct internal_scnhdr *sec;
-	unsigned off;
-{
-	unsigned ins1, ins2;
-	unsigned dest;
-
-	ins1 = get_u16(filemap + sec->data_offset + off);
-	if ((ins1 & 0xF800) != 0xF000)
-		return(0);
-	ins2 = get_u16(filemap + sec->data_offset + off + 2);
-	if ((ins2 & 0xF800) != 0xF800)
-		return(0);
-	/* match */
-	dest = ((ins1 & 0x7FF) << 12) | ((ins2 & 0x7FF) << 1);
-	if (dest & 0x00400000)
-		dest |= 0xFF800000;
-	dest += off + 4;
-	printf("%04x %04x\tbl\t0x%x\n", ins1, ins2, dest);
-	return(1);
-}
-
-void
-thumb_bl_reloc(sec, rel)
-	struct internal_scnhdr *sec;
-	struct internal_reloc *rel;
-{
-	unsigned ins1, ins2;
-	unsigned dest;
-
-	ins1 = get_u16(filemap + sec->data_offset + rel->location);
-	ins2 = get_u16(filemap + sec->data_offset + rel->location + 2);
-	printf("%04x %04x R\t", ins1, ins2);
-	if ((ins1 & 0xF800) != 0xF000 || (ins2 & 0xF800) != 0xF800) {
-		printf("<invalid Thumb_BL reloc: opcode not BL>\n");
-		return;
-	}
-	dest = ((ins1 & 0x7FF) << 12) | ((ins2 & 0x7FF) << 1);
-	if (dest & 0x00400000)
-		dest |= 0xFF800000;
-	dest += rel->location + 4;
-	fputs("bl\t", stdout);
-	disasm_reloc_target(sec, rel, dest);
-	putchar('\n');
-}