--- /dev/null
+/*\r
+ * Object Module Reader for Intel object records\r
+ * Copyright 1992 R.A. Burgess\r
+\r
+To build this, use Boralnd or Turbo C as follows:\r
+\r
+ BCC -ml ReadObj.c\r
+\r
+This will give you ReadObj.exe. The -ml is optional and\r
+makes this a large model program. I have had so many less problems\r
+with pointers and data conversions using it on everything,\r
+I just do it out of habit now.\r
+\r
+\r
+ */\r
+#include <ctype.h>\r
+#include <stdio.h>\r
+#include <string.h>\r
+#include <stdlib.h>\r
+\r
+/* misc variables */\r
+\r
+FILE *input_fp = 0, *output_fp = 0;\r
+int RType, erc;\r
+unsigned long lfa;\r
+unsigned int reclen;\r
+\r
+/*********** BEGIN FUNCTIONS **************/\r
+\r
+void Encode (char *Dest, int x)\r
+{\r
+int i;\r
+\r
+Dest[0] = ' ';\r
+Dest[1] = ' ';\r
+Dest[2] = ' ';\r
+Dest[3] = ' ';\r
+Dest[4] = ' ';\r
+i = 4;\r
+do {\r
+ Dest[i] = (x % 10) + 0x30;\r
+ x /= 10;\r
+ i--;\r
+}\r
+while (x);\r
+}\r
+\r
+/*********************************************/\r
+\r
+void EncodeHex (char *pDest, unsigned char x)\r
+{\r
+int i;\r
+unsigned char nibble;\r
+\r
+for (i=1; i>=0; i--) {\r
+ nibble = x & 0x0f;\r
+ if (nibble < 0x0A)\r
+ pDest[i] = nibble + 0x30;\r
+ else\r
+ pDest[i] = nibble + 0x37;\r
+ x /= 0x10;\r
+ }\r
+}\r
+\r
+/*********************************************/\r
+\r
+void Copyn(char *dest, char *source, int n)\r
+{\r
+while (n--) *dest++ = *source++;\r
+}\r
+\r
+/*********************************************/\r
+\r
+void ReadRecordLen (unsigned int *pCbRet)\r
+{\r
+int cblo, cbhi, cb;\r
+\r
+cblo = fgetc(input_fp);\r
+cbhi = fgetc(input_fp);\r
+cb = (cbhi << 8) + cblo;\r
+lfa = lfa + cb + 3;\r
+*pCbRet = cb;\r
+}\r
+\r
+\r
+/*********************************************/\r
+\r
+void WriteRecInfo(void)\r
+{\r
+char num[9];\r
+int sData;\r
+unsigned int cb;\r
+\r
+EncodeHex (&num[0], (lfa >> 24) & 0xff);\r
+EncodeHex (&num[2], (lfa >> 16) & 0xff);\r
+EncodeHex (&num[4], (lfa >> 8) & 0xff);\r
+EncodeHex (&num[6], lfa & 0xff);\r
+num[8] = 0;\r
+fputs(num,output_fp);\r
+ReadRecordLen (&reclen);\r
+fputs(", size: ", output_fp);\r
+cb = reclen -1; /* exclude checksum in size display */\r
+EncodeHex (&num[0], (cb >> 8) & 0xff);\r
+EncodeHex (&num[2], cb & 0xff);\r
+num[4] = 0;\r
+fputs(num,output_fp);\r
+}\r
+\r
+/*********************************************/\r
+\r
+void Dump (char *pb, int cb)\r
+{\r
+char line[70];\r
+int sDataRet;\r
+int i;\r
+char b;\r
+int limit;\r
+\r
+for (i=0; i<69; i++) line[i] = ' '; /* clear line */\r
+while (cb) {\r
+ if (cb >= 16) {\r
+ limit = 15;\r
+ cb -= 16;\r
+ }\r
+ else {\r
+ limit = cb - 1;\r
+ cb = 0;\r
+ }\r
+ Copyn(&line[50], pb, limit + 1);\r
+ pb += 16;\r
+ for (i=0; i<=limit; i++) {\r
+ b = line[50 + i];\r
+ EncodeHex (&line[(3*i)], b);\r
+ if ((b < 0x20) || (b > 0x7E)) line[50+i] = '.';\r
+ }\r
+ line [67] = '\r';\r
+ line [68] = '\n';\r
+ line [69] = 0;\r
+ fputs(line, output_fp);\r
+ }\r
+}\r
+\r
+\r
+/*********************************************/\r
+\r
+void ReadBsRecord(unsigned char *pDest, int nbytes)\r
+{\r
+int i;\r
+unsigned char b;\r
+\r
+while (nbytes--) {\r
+ i = fgetc(input_fp);\r
+ if (i==EOF) exit(1);\r
+ b = i & 0xff;\r
+ *pDest++ = b;\r
+ }\r
+}\r
+\r
+/*********************************************/\r
+\r
+void DumpRecord (void)\r
+{\r
+int cb;\r
+char line[16];\r
+int len;\r
+int sData;\r
+\r
+ cb = reclen;\r
+ cb--; /* Get rid of Check Sum */\r
+ while (cb) {\r
+ if (cb > 16) {\r
+ len = 16;\r
+ cb -= 16;\r
+ }\r
+ else {\r
+ len = cb;\r
+ cb = 0;\r
+ }\r
+\r
+ ReadBsRecord (line, len);\r
+ Dump (line, len);\r
+ }\r
+ fputs("\r\n", output_fp);\r
+ if (fseek(input_fp, lfa, 0)) exit(1);\r
+}\r
+\r
+\r
+/*********************************************/\r
+\r
+void UnknownRType (unsigned char RType)\r
+{\r
+char num[3];\r
+int sData;\r
+\r
+EncodeHex (num, RType);\r
+num[2] = 0;\r
+fputs("Unknown Record Type ", output_fp);\r
+fputs(num, output_fp);\r
+fputs(" at lfa ", output_fp);\r
+WriteRecInfo ();\r
+fputs("\r\n", output_fp);\r
+}\r
+\r
+/*********************************************/\r
+\r
+void ReadIndex (unsigned int *pIndex, int *pCb)\r
+{\r
+unsigned char b;\r
+int i;\r
+\r
+i = fgetc(input_fp);\r
+if (i==EOF) exit(1);\r
+b = i & 0xff;\r
+--*pCb;\r
+if (!(b & 0x80))\r
+ *pIndex = b;\r
+else {\r
+ i = b & 0x7F;\r
+ *pIndex = i * 0x100;\r
+ i = fgetc(input_fp);\r
+ if (i==EOF) exit(1);\r
+ b = i & 0xff;\r
+ --*pCb;\r
+ *pIndex += b;\r
+ }\r
+}\r
+\r
+/*********************************************/\r
+\r
+void ThreadRecord (unsigned char FType, int *pCb)\r
+{\r
+unsigned char Thread[8]; /* ARRAY [WRD (0)..7] OF BYTE */\r
+unsigned int TIndex[8]; /* ARRAY [WRD (0)..7] OF WORD */\r
+unsigned int method;\r
+unsigned char i;\r
+\r
+ i = FType & 3;\r
+ if (FType & 0x40) i += 4;\r
+ method = (FType / 4) & 7;\r
+ Thread[i] = method;\r
+ if ((i <= 4) || (method < 4))\r
+ ReadIndex (&TIndex[i], pCb);\r
+ else\r
+ TIndex[i] = 0;\r
+}\r
+\r
+\r
+/*********************************************/\r
+\r
+void FixupRecord (unsigned char FType, int *pCb)\r
+{\r
+unsigned char Thread[8]; /* ARRAY [WRD (0)..7] OF BYTE */\r
+unsigned int TIndex[8]; /* ARRAY [WRD (0)..7] OF WORD */\r
+unsigned char DataOffset;\r
+char Number[3];\r
+unsigned int sData;\r
+unsigned char FixData;\r
+unsigned char frame;\r
+unsigned int fDatum;\r
+unsigned char target;\r
+unsigned int tDatum;\r
+long displacement;\r
+\r
+if (!(FType & 0x40))\r
+ fputs("Self relative ", output_fp);\r
+else\r
+ fputs("Segment relative ", output_fp);\r
+switch ((FType / 4) & 7) {\r
+ case 0: fputs("lobyte ", output_fp); break;\r
+ case 1: fputs("offset ", output_fp); break;\r
+ case 2: fputs("base ", output_fp); break;\r
+ case 3: fputs("pointer ", output_fp); break;\r
+ case 4: fputs("hibyte ", output_fp); break;\r
+ default: ;\r
+ }\r
+\r
+DataOffset = fgetc(input_fp);\r
+--*pCb;\r
+EncodeHex (Number, FType & 3);\r
+Number[2] = 0;\r
+fputs(Number,output_fp);\r
+EncodeHex (Number, DataOffset);\r
+fputs(Number,output_fp);\r
+FixData = fgetc(input_fp);\r
+--*pCb;\r
+if (!(FixData & 0x80)) {\r
+ frame = (FixData / 0x10) & 7;\r
+ if (frame < 4)\r
+ ReadIndex (&fDatum, pCb);\r
+ else\r
+ fDatum = 0;\r
+}\r
+else {\r
+/* WRITE (' frame thread '); */\r
+ frame = Thread [4 + ((FixData / 16) & 3)];\r
+ fDatum = TIndex [4 + ((FixData / 16) & 3)];\r
+ }\r
+if (!(FixData & 8)) {\r
+ target = FixData & 7;\r
+ ReadIndex (&tDatum, pCb);\r
+}\r
+else {\r
+ /* WRITE (' target thread'); */\r
+ target = Thread[FixData & 3] | (FixData & 4);\r
+ tDatum = TIndex[FixData & 3];\r
+}\r
+fputs(" , F", output_fp);\r
+fputc(frame + 0x30, output_fp);\r
+if (fDatum) {\r
+ fputc(' ', output_fp);\r
+ EncodeHex (Number, (fDatum >> 8));\r
+ Number[2] = 0;\r
+ fputs(Number,output_fp);\r
+\r
+ EncodeHex (Number, (fDatum & 0xff));\r
+ Number[2] = 0;\r
+ fputs(Number,output_fp);\r
+}\r
+fputs(" , T", output_fp);\r
+fputc(target + 0x30, output_fp);\r
+fputc(' ', output_fp);\r
+\r
+EncodeHex (Number, (tDatum >> 8));\r
+Number[2] = 0;\r
+fputs(Number,output_fp);\r
+\r
+EncodeHex (Number, (tDatum & 0xff));\r
+Number[2] = 0;\r
+fputs(Number,output_fp);\r
+\r
+if (!(FixData & 4)) {\r
+ displacement = 0;\r
+ fputc(' ', output_fp);\r
+ if (!(FType & 2)) {\r
+ ReadBsRecord (&displacement, 2);\r
+ *pCb -= 2;\r
+ }\r
+ else {\r
+ ReadBsRecord (&displacement, 3);\r
+ *pCb -= 3;\r
+ Number[2] = 0;\r
+ EncodeHex (Number, (displacement >> 16) & 0xff);\r
+ fputs(Number,output_fp);\r
+ }\r
+ EncodeHex (Number, (displacement >> 8) & 0xff);\r
+ fputs(Number,output_fp);\r
+ EncodeHex (Number, displacement& 0xff);\r
+ fputs(Number,output_fp);\r
+}\r
+fputs("\r\n",output_fp);\r
+}\r
+\r
+\r
+/*********************************************/\r
+\r
+void FIXUPP (void)\r
+{\r
+int cb;\r
+unsigned char FType;\r
+unsigned int sData;\r
+\r
+fputs("\r\n",output_fp);\r
+cb = reclen;\r
+cb--;\r
+while (cb) {\r
+ FType = fgetc(input_fp);\r
+ cb--;\r
+ if (!(FType & 0x80)) ThreadRecord (FType, &cb);\r
+ else FixupRecord (FType, &cb);\r
+ }\r
+if (fseek(input_fp, lfa, 0)) exit(1);\r
+}\r
+\r
+\r
+/****************************************\r
+* Write a line to the output file\r
+*****************************************/\r
+\r
+void write_line(char *pstr)\r
+{\r
+ fputs(pstr, output_fp);\r
+ fputs("\r\n", output_fp);\r
+}\r
+\r
+/*******************************************\r
+* Report a non-recoverable error\r
+********************************************/\r
+\r
+void fatal_error(char *string)\r
+{\r
+ fputs("Fatal error, object dump aborted\r\n", stderr);\r
+ fputs(string,stderr);\r
+ exit(-1);\r
+}\r
+\r
+\r
+/*********************\r
+* Main program\r
+**********************/\r
+\r
+void main(int argc, char *argv[])\r
+{\r
+ int i, j, fdone;\r
+ char *ptr;\r
+\r
+/* first process any filenames and command line options */\r
+ for(i=1; i < argc; ++i) {\r
+ ptr = argv[i];\r
+ switch((*ptr++ << 8) | *ptr++) {\r
+ default:\r
+ if(!input_fp) {\r
+ if(!(input_fp = fopen(argv[i], "rb")))\r
+ fatal_error("Cannot open input file\n"); }\r
+ else if(!output_fp) {\r
+ if(!(output_fp = fopen(argv[i], "w")))\r
+ fatal_error("Cannot open output file\n"); }\r
+ else\r
+ fatal_error("Too many parameters\n");\r
+ }\r
+ }\r
+\r
+/* any files not explicitly named default to standard I/O */\r
+ if(!input_fp) /* default to standard input */\r
+ {\r
+ printf("No input file specified...");\r
+ exit(1);\r
+ }\r
+ if(!output_fp) /* default to standard output */\r
+ output_fp = stdout;\r
+\r
+ fputs("Object Module Reader V1.0\r\n", stderr);\r
+ fputs("\r\n", output_fp);\r
+\r
+\r
+RType = fgetc(input_fp);\r
+if (RType == EOF) erc = 1;\r
+\r
+while (!erc) {\r
+ switch (RType) {\r
+ case 0x6E :\r
+ fputs("RHEADR ",output_fp);\r
+ WriteRecInfo();\r
+ fputs("\r\n", output_fp);\r
+ DumpRecord();\r
+ break;\r
+ case 0x70 :\r
+ fputs("REGINT ",output_fp);\r
+ WriteRecInfo();\r
+ fputs("\r\n", output_fp);\r
+ DumpRecord();\r
+ break;\r
+ case 0x72 :\r
+ fputs("REDATA ",output_fp);\r
+ WriteRecInfo();\r
+ fputs("\r\n", output_fp);\r
+ DumpRecord();\r
+ break;\r
+ case 0x74 :\r
+ fputs("RIDATA ",output_fp);\r
+ WriteRecInfo();\r
+ fputs("\r\n", output_fp);\r
+ DumpRecord();\r
+ break;\r
+ case 0x76 :\r
+ fputs("OVLDEF ",output_fp);\r
+ WriteRecInfo();\r
+ fputs("\r\n", output_fp);\r
+ DumpRecord();\r
+ break;\r
+ case 0x78 :\r
+ fputs("ENDREC ",output_fp);\r
+ WriteRecInfo();\r
+ fputs("\r\n", output_fp);\r
+ DumpRecord();\r
+ break;\r
+ case 0x7A :\r
+ fputs("BLKDEF ",output_fp);\r
+ WriteRecInfo();\r
+ fputs("\r\n", output_fp);\r
+ DumpRecord();\r
+ break;\r
+ case 0x7C :\r
+ fputs("BLKEND ",output_fp);\r
+ WriteRecInfo();\r
+ fputs("\r\n", output_fp);\r
+ DumpRecord();\r
+ break;\r
+ case 0x7E :\r
+ fputs("DEBSYM ",output_fp);\r
+ WriteRecInfo();\r
+ fputs("\r\n", output_fp);\r
+ DumpRecord();\r
+ break;\r
+ case 0x80 :\r
+ fputs("THEADR ",output_fp);\r
+ WriteRecInfo();\r
+ fputs("\r\n", output_fp);\r
+ DumpRecord();\r
+ break;\r
+ case 0x82 :\r
+ fputs("LHEADR ",output_fp);\r
+ WriteRecInfo();\r
+ fputs("\r\n", output_fp);\r
+ DumpRecord();\r
+ break;\r
+ case 0x84 :\r
+ fputs("PEDATA ",output_fp);\r
+ WriteRecInfo();\r
+ fputs("\r\n", output_fp);\r
+ DumpRecord();\r
+ break;\r
+ case 0x86 :\r
+ fputs("PIDATA ",output_fp);\r
+ WriteRecInfo();\r
+ fputs("\r\n", output_fp);\r
+ DumpRecord();\r
+ break;\r
+ case 0x88 :\r
+ fputs("COMENT ",output_fp);\r
+ WriteRecInfo();\r
+ fputs("\r\n", output_fp);\r
+ DumpRecord();\r
+ break;\r
+ case 0x8A :\r
+ fputs("MODEND ",output_fp);\r
+ exit(1);\r
+ break;\r
+ case 0x8C :\r
+ fputs("EXTDEF ",output_fp);\r
+ WriteRecInfo();\r
+ fputs("\r\n", output_fp);\r
+ DumpRecord();\r
+ break;\r
+ case 0x8E :\r
+ fputs("TYPDEF ",output_fp);\r
+ WriteRecInfo();\r
+ fputs("\r\n", output_fp);\r
+ DumpRecord();\r
+ break;\r
+ case 0x90 :\r
+ fputs("PUBDEF ",output_fp);\r
+ WriteRecInfo();\r
+ fputs("\r\n", output_fp);\r
+ DumpRecord();\r
+ break;\r
+ case 0x91 :\r
+ fputs("PUBDEF32 ",output_fp);\r
+ WriteRecInfo();\r
+ fputs("\r\n", output_fp);\r
+ DumpRecord();\r
+ break;\r
+ case 0x92 :\r
+ fputs("LOCSYM ",output_fp);\r
+ WriteRecInfo();\r
+ fputs("\r\n", output_fp);\r
+ DumpRecord();\r
+ break;\r
+ case 0x94 :\r
+ fputs("LINNUM ",output_fp);\r
+ WriteRecInfo();\r
+ fputs("\r\n", output_fp);\r
+ DumpRecord();\r
+ break;\r
+ case 0x96 :\r
+ fputs("LNAMES ",output_fp);\r
+ WriteRecInfo();\r
+ fputs("\r\n", output_fp);\r
+ DumpRecord();\r
+ break;\r
+ case 0x98 :\r
+ fputs("SEGDEF ",output_fp);\r
+ WriteRecInfo();\r
+ fputs("\r\n", output_fp);\r
+ DumpRecord();\r
+ break;\r
+ case 0x99 :\r
+ fputs("SEGDEF32 ",output_fp);\r
+ WriteRecInfo();\r
+ fputs("\r\n", output_fp);\r
+ DumpRecord();\r
+ break;\r
+ case 0x9A :\r
+ fputs("GRPDEF ",output_fp);\r
+ WriteRecInfo();\r
+ fputs("\r\n", output_fp);\r
+ DumpRecord();\r
+ break;\r
+ case 0x9C :\r
+ fputs("FIXUPP ",output_fp);\r
+ WriteRecInfo();\r
+ FIXUPP();\r
+ fputs("\r\n", output_fp);\r
+ break;\r
+ case 0x9D :\r
+ fputs("FIXUPP32 ",output_fp);\r
+ WriteRecInfo();\r
+/* FIXUPP(); */\r
+ fputs("\r\n", output_fp);\r
+ DumpRecord();\r
+ fputs("\r\n", output_fp);\r
+ break;\r
+ case 0xA0 :\r
+ fputs("LEDATA ",output_fp);\r
+ WriteRecInfo();\r
+ fputs("\r\n", output_fp);\r
+ DumpRecord();\r
+ break;\r
+ case 0xA1 :\r
+ fputs("LEDATA32 ",output_fp);\r
+ WriteRecInfo();\r
+ fputs("\r\n", output_fp);\r
+ DumpRecord();\r
+ break;\r
+ case 0xA2 :\r
+ fputs("LIDATA ",output_fp);\r
+ WriteRecInfo();\r
+ fputs("\r\n", output_fp);\r
+ DumpRecord();\r
+ break;\r
+ case 0xA4 :\r
+ fputs("LIBHED ",output_fp);\r
+ WriteRecInfo();\r
+ fputs("\r\n", output_fp);\r
+ DumpRecord();\r
+ break;\r
+ case 0xA6 :\r
+ fputs("LIBNAM ",output_fp);\r
+ WriteRecInfo();\r
+ fputs("\r\n", output_fp);\r
+ DumpRecord();\r
+ break;\r
+ case 0xA8 :\r
+ fputs("LIBLOC ",output_fp);\r
+ WriteRecInfo();\r
+ fputs("\r\n", output_fp);\r
+ DumpRecord();\r
+ break;\r
+ case 0xAA :\r
+ fputs("LIBDIC ",output_fp);\r
+ WriteRecInfo();\r
+ fputs("\r\n", output_fp);\r
+ DumpRecord();\r
+ break;\r
+ case 0xB0 :\r
+ fputs("COMDEF ",output_fp);\r
+ WriteRecInfo();\r
+ fputs("\r\n", output_fp);\r
+ DumpRecord();\r
+ break;\r
+ case 0xB2 :\r
+ fputs("FORREF ",output_fp);\r
+ WriteRecInfo();\r
+ fputs("\r\n", output_fp);\r
+ DumpRecord();\r
+ break;\r
+ case 0xB4 :\r
+ fputs("MODEXT ",output_fp);\r
+ WriteRecInfo();\r
+ fputs("\r\n", output_fp);\r
+ DumpRecord();\r
+ break;\r
+ case 0xB6 :\r
+ fputs("MODPUB ",output_fp);\r
+ WriteRecInfo();\r
+ fputs("\r\n", output_fp);\r
+ DumpRecord();\r
+ break;\r
+ default:\r
+ UnknownRType(RType);\r
+ fputs("\r\n", output_fp);\r
+ DumpRecord();\r
+ break;\r
+ }\r
+ RType = fgetc(input_fp);\r
+ if (RType == EOF) erc = 1;\r
+\r
+ }\r
+\r
+}\r