2 * Object Module Reader for Intel object records
\r
3 * Copyright 1992 R.A. Burgess
\r
5 To build this, use Boralnd or Turbo C as follows:
\r
9 This will give you ReadObj.exe. The -ml is optional and
\r
10 makes this a large model program. I have had so many less problems
\r
11 with pointers and data conversions using it on everything,
\r
12 I just do it out of habit now.
\r
21 /* misc variables */
\r
23 FILE *input_fp = 0, *output_fp = 0;
\r
26 unsigned int reclen;
\r
28 /*********** BEGIN FUNCTIONS **************/
\r
30 void Encode (char *Dest, int x)
\r
41 Dest[i] = (x % 10) + 0x30;
\r
48 /*********************************************/
\r
50 void EncodeHex (char *pDest, unsigned char x)
\r
53 unsigned char nibble;
\r
55 for (i=1; i>=0; i--) {
\r
58 pDest[i] = nibble + 0x30;
\r
60 pDest[i] = nibble + 0x37;
\r
65 /*********************************************/
\r
67 void Copyn(char *dest, char *source, int n)
\r
69 while (n--) *dest++ = *source++;
\r
72 /*********************************************/
\r
74 void ReadRecordLen (unsigned int *pCbRet)
\r
78 cblo = fgetc(input_fp);
\r
79 cbhi = fgetc(input_fp);
\r
80 cb = (cbhi << 8) + cblo;
\r
86 /*********************************************/
\r
88 void WriteRecInfo(void)
\r
94 EncodeHex (&num[0], (lfa >> 24) & 0xff);
\r
95 EncodeHex (&num[2], (lfa >> 16) & 0xff);
\r
96 EncodeHex (&num[4], (lfa >> 8) & 0xff);
\r
97 EncodeHex (&num[6], lfa & 0xff);
\r
99 fputs(num,output_fp);
\r
100 ReadRecordLen (&reclen);
\r
101 fputs(", size: ", output_fp);
\r
102 cb = reclen -1; /* exclude checksum in size display */
\r
103 EncodeHex (&num[0], (cb >> 8) & 0xff);
\r
104 EncodeHex (&num[2], cb & 0xff);
\r
106 fputs(num,output_fp);
\r
109 /*********************************************/
\r
111 void Dump (char *pb, int cb)
\r
119 for (i=0; i<69; i++) line[i] = ' '; /* clear line */
\r
129 Copyn(&line[50], pb, limit + 1);
\r
131 for (i=0; i<=limit; i++) {
\r
133 EncodeHex (&line[(3*i)], b);
\r
134 if ((b < 0x20) || (b > 0x7E)) line[50+i] = '.';
\r
139 fputs(line, output_fp);
\r
144 /*********************************************/
\r
146 void ReadBsRecord(unsigned char *pDest, int nbytes)
\r
152 i = fgetc(input_fp);
\r
153 if (i==EOF) exit(1);
\r
159 /*********************************************/
\r
161 void DumpRecord (void)
\r
169 cb--; /* Get rid of Check Sum */
\r
180 ReadBsRecord (line, len);
\r
183 fputs("\r\n", output_fp);
\r
184 if (fseek(input_fp, lfa, 0)) exit(1);
\r
188 /*********************************************/
\r
190 void UnknownRType (unsigned char RType)
\r
195 EncodeHex (num, RType);
\r
197 fputs("Unknown Record Type ", output_fp);
\r
198 fputs(num, output_fp);
\r
199 fputs(" at lfa ", output_fp);
\r
201 fputs("\r\n", output_fp);
\r
204 /*********************************************/
\r
206 void ReadIndex (unsigned int *pIndex, int *pCb)
\r
211 i = fgetc(input_fp);
\r
212 if (i==EOF) exit(1);
\r
219 *pIndex = i * 0x100;
\r
220 i = fgetc(input_fp);
\r
221 if (i==EOF) exit(1);
\r
228 /*********************************************/
\r
230 void ThreadRecord (unsigned char FType, int *pCb)
\r
232 unsigned char Thread[8]; /* ARRAY [WRD (0)..7] OF BYTE */
\r
233 unsigned int TIndex[8]; /* ARRAY [WRD (0)..7] OF WORD */
\r
234 unsigned int method;
\r
238 if (FType & 0x40) i += 4;
\r
239 method = (FType / 4) & 7;
\r
240 Thread[i] = method;
\r
241 if ((i <= 4) || (method < 4))
\r
242 ReadIndex (&TIndex[i], pCb);
\r
248 /*********************************************/
\r
250 void FixupRecord (unsigned char FType, int *pCb)
\r
252 unsigned char Thread[8]; /* ARRAY [WRD (0)..7] OF BYTE */
\r
253 unsigned int TIndex[8]; /* ARRAY [WRD (0)..7] OF WORD */
\r
254 unsigned char DataOffset;
\r
256 unsigned int sData;
\r
257 unsigned char FixData;
\r
258 unsigned char frame;
\r
259 unsigned int fDatum;
\r
260 unsigned char target;
\r
261 unsigned int tDatum;
\r
264 if (!(FType & 0x40))
\r
265 fputs("Self relative ", output_fp);
\r
267 fputs("Segment relative ", output_fp);
\r
268 switch ((FType / 4) & 7) {
\r
269 case 0: fputs("lobyte ", output_fp); break;
\r
270 case 1: fputs("offset ", output_fp); break;
\r
271 case 2: fputs("base ", output_fp); break;
\r
272 case 3: fputs("pointer ", output_fp); break;
\r
273 case 4: fputs("hibyte ", output_fp); break;
\r
277 DataOffset = fgetc(input_fp);
\r
279 EncodeHex (Number, FType & 3);
\r
281 fputs(Number,output_fp);
\r
282 EncodeHex (Number, DataOffset);
\r
283 fputs(Number,output_fp);
\r
284 FixData = fgetc(input_fp);
\r
286 if (!(FixData & 0x80)) {
\r
287 frame = (FixData / 0x10) & 7;
\r
289 ReadIndex (&fDatum, pCb);
\r
294 /* WRITE (' frame thread '); */
\r
295 frame = Thread [4 + ((FixData / 16) & 3)];
\r
296 fDatum = TIndex [4 + ((FixData / 16) & 3)];
\r
298 if (!(FixData & 8)) {
\r
299 target = FixData & 7;
\r
300 ReadIndex (&tDatum, pCb);
\r
303 /* WRITE (' target thread'); */
\r
304 target = Thread[FixData & 3] | (FixData & 4);
\r
305 tDatum = TIndex[FixData & 3];
\r
307 fputs(" , F", output_fp);
\r
308 fputc(frame + 0x30, output_fp);
\r
310 fputc(' ', output_fp);
\r
311 EncodeHex (Number, (fDatum >> 8));
\r
313 fputs(Number,output_fp);
\r
315 EncodeHex (Number, (fDatum & 0xff));
\r
317 fputs(Number,output_fp);
\r
319 fputs(" , T", output_fp);
\r
320 fputc(target + 0x30, output_fp);
\r
321 fputc(' ', output_fp);
\r
323 EncodeHex (Number, (tDatum >> 8));
\r
325 fputs(Number,output_fp);
\r
327 EncodeHex (Number, (tDatum & 0xff));
\r
329 fputs(Number,output_fp);
\r
331 if (!(FixData & 4)) {
\r
333 fputc(' ', output_fp);
\r
334 if (!(FType & 2)) {
\r
335 ReadBsRecord (&displacement, 2);
\r
339 ReadBsRecord (&displacement, 3);
\r
342 EncodeHex (Number, (displacement >> 16) & 0xff);
\r
343 fputs(Number,output_fp);
\r
345 EncodeHex (Number, (displacement >> 8) & 0xff);
\r
346 fputs(Number,output_fp);
\r
347 EncodeHex (Number, displacement& 0xff);
\r
348 fputs(Number,output_fp);
\r
350 fputs("\r\n",output_fp);
\r
354 /*********************************************/
\r
359 unsigned char FType;
\r
360 unsigned int sData;
\r
362 fputs("\r\n",output_fp);
\r
366 FType = fgetc(input_fp);
\r
368 if (!(FType & 0x80)) ThreadRecord (FType, &cb);
\r
369 else FixupRecord (FType, &cb);
\r
371 if (fseek(input_fp, lfa, 0)) exit(1);
\r
375 /****************************************
\r
376 * Write a line to the output file
\r
377 *****************************************/
\r
379 void write_line(char *pstr)
\r
381 fputs(pstr, output_fp);
\r
382 fputs("\r\n", output_fp);
\r
385 /*******************************************
\r
386 * Report a non-recoverable error
\r
387 ********************************************/
\r
389 void fatal_error(char *string)
\r
391 fputs("Fatal error, object dump aborted\r\n", stderr);
\r
392 fputs(string,stderr);
\r
397 /*********************
\r
399 **********************/
\r
401 void main(int argc, char *argv[])
\r
406 /* first process any filenames and command line options */
\r
407 for(i=1; i < argc; ++i) {
\r
409 switch((*ptr++ << 8) | *ptr++) {
\r
412 if(!(input_fp = fopen(argv[i], "rb")))
\r
413 fatal_error("Cannot open input file\n"); }
\r
414 else if(!output_fp) {
\r
415 if(!(output_fp = fopen(argv[i], "w")))
\r
416 fatal_error("Cannot open output file\n"); }
\r
418 fatal_error("Too many parameters\n");
\r
422 /* any files not explicitly named default to standard I/O */
\r
423 if(!input_fp) /* default to standard input */
\r
425 printf("No input file specified...");
\r
428 if(!output_fp) /* default to standard output */
\r
429 output_fp = stdout;
\r
431 fputs("Object Module Reader V1.0\r\n", stderr);
\r
432 fputs("\r\n", output_fp);
\r
435 RType = fgetc(input_fp);
\r
436 if (RType == EOF) erc = 1;
\r
441 fputs("RHEADR ",output_fp);
\r
443 fputs("\r\n", output_fp);
\r
447 fputs("REGINT ",output_fp);
\r
449 fputs("\r\n", output_fp);
\r
453 fputs("REDATA ",output_fp);
\r
455 fputs("\r\n", output_fp);
\r
459 fputs("RIDATA ",output_fp);
\r
461 fputs("\r\n", output_fp);
\r
465 fputs("OVLDEF ",output_fp);
\r
467 fputs("\r\n", output_fp);
\r
471 fputs("ENDREC ",output_fp);
\r
473 fputs("\r\n", output_fp);
\r
477 fputs("BLKDEF ",output_fp);
\r
479 fputs("\r\n", output_fp);
\r
483 fputs("BLKEND ",output_fp);
\r
485 fputs("\r\n", output_fp);
\r
489 fputs("DEBSYM ",output_fp);
\r
491 fputs("\r\n", output_fp);
\r
495 fputs("THEADR ",output_fp);
\r
497 fputs("\r\n", output_fp);
\r
501 fputs("LHEADR ",output_fp);
\r
503 fputs("\r\n", output_fp);
\r
507 fputs("PEDATA ",output_fp);
\r
509 fputs("\r\n", output_fp);
\r
513 fputs("PIDATA ",output_fp);
\r
515 fputs("\r\n", output_fp);
\r
519 fputs("COMENT ",output_fp);
\r
521 fputs("\r\n", output_fp);
\r
525 fputs("MODEND ",output_fp);
\r
529 fputs("EXTDEF ",output_fp);
\r
531 fputs("\r\n", output_fp);
\r
535 fputs("TYPDEF ",output_fp);
\r
537 fputs("\r\n", output_fp);
\r
541 fputs("PUBDEF ",output_fp);
\r
543 fputs("\r\n", output_fp);
\r
547 fputs("PUBDEF32 ",output_fp);
\r
549 fputs("\r\n", output_fp);
\r
553 fputs("LOCSYM ",output_fp);
\r
555 fputs("\r\n", output_fp);
\r
559 fputs("LINNUM ",output_fp);
\r
561 fputs("\r\n", output_fp);
\r
565 fputs("LNAMES ",output_fp);
\r
567 fputs("\r\n", output_fp);
\r
571 fputs("SEGDEF ",output_fp);
\r
573 fputs("\r\n", output_fp);
\r
577 fputs("SEGDEF32 ",output_fp);
\r
579 fputs("\r\n", output_fp);
\r
583 fputs("GRPDEF ",output_fp);
\r
585 fputs("\r\n", output_fp);
\r
589 fputs("FIXUPP ",output_fp);
\r
592 fputs("\r\n", output_fp);
\r
595 fputs("FIXUPP32 ",output_fp);
\r
598 fputs("\r\n", output_fp);
\r
600 fputs("\r\n", output_fp);
\r
603 fputs("LEDATA ",output_fp);
\r
605 fputs("\r\n", output_fp);
\r
609 fputs("LEDATA32 ",output_fp);
\r
611 fputs("\r\n", output_fp);
\r
615 fputs("LIDATA ",output_fp);
\r
617 fputs("\r\n", output_fp);
\r
621 fputs("LIBHED ",output_fp);
\r
623 fputs("\r\n", output_fp);
\r
627 fputs("LIBNAM ",output_fp);
\r
629 fputs("\r\n", output_fp);
\r
633 fputs("LIBLOC ",output_fp);
\r
635 fputs("\r\n", output_fp);
\r
639 fputs("LIBDIC ",output_fp);
\r
641 fputs("\r\n", output_fp);
\r
645 fputs("COMDEF ",output_fp);
\r
647 fputs("\r\n", output_fp);
\r
651 fputs("FORREF ",output_fp);
\r
653 fputs("\r\n", output_fp);
\r
657 fputs("MODEXT ",output_fp);
\r
659 fputs("\r\n", output_fp);
\r
663 fputs("MODPUB ",output_fp);
\r
665 fputs("\r\n", output_fp);
\r
669 UnknownRType(RType);
\r
670 fputs("\r\n", output_fp);
\r
674 RType = fgetc(input_fp);
\r
675 if (RType == EOF) erc = 1;
\r