]> pd.if.org Git - mmurtl/blob - mscode16/readobj/readobj.c
autocommit for file dated 1995-01-10 09:43:20
[mmurtl] / mscode16 / readobj / readobj.c
1 /*\r
2  * Object Module Reader for Intel object records\r
3  * Copyright 1992 R.A. Burgess\r
4 \r
5 To build this, use Boralnd or Turbo C as follows:\r
6 \r
7    BCC -ml ReadObj.c\r
8 \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
13 \r
14 \r
15  */\r
16 #include <ctype.h>\r
17 #include <stdio.h>\r
18 #include <string.h>\r
19 #include <stdlib.h>\r
20 \r
21 /* misc variables */\r
22 \r
23 FILE *input_fp = 0, *output_fp = 0;\r
24 int RType, erc;\r
25 unsigned long  lfa;\r
26 unsigned int reclen;\r
27 \r
28 /*********** BEGIN FUNCTIONS **************/\r
29 \r
30 void Encode (char *Dest, int x)\r
31 {\r
32 int i;\r
33 \r
34 Dest[0] = ' ';\r
35 Dest[1] = ' ';\r
36 Dest[2] = ' ';\r
37 Dest[3] = ' ';\r
38 Dest[4] = ' ';\r
39 i = 4;\r
40 do {\r
41   Dest[i] = (x % 10) + 0x30;\r
42   x /= 10;\r
43   i--;\r
44 }\r
45 while (x);\r
46 }\r
47 \r
48 /*********************************************/\r
49 \r
50 void EncodeHex (char *pDest, unsigned char x)\r
51 {\r
52 int  i;\r
53 unsigned char nibble;\r
54 \r
55 for (i=1; i>=0; i--) {\r
56   nibble = x & 0x0f;\r
57   if (nibble < 0x0A)\r
58         pDest[i] = nibble + 0x30;\r
59   else\r
60         pDest[i] = nibble + 0x37;\r
61   x /= 0x10;\r
62  }\r
63 }\r
64 \r
65 /*********************************************/\r
66 \r
67 void Copyn(char *dest, char *source, int n)\r
68 {\r
69 while (n--)     *dest++ = *source++;\r
70 }\r
71 \r
72 /*********************************************/\r
73 \r
74 void ReadRecordLen (unsigned int *pCbRet)\r
75 {\r
76 int  cblo, cbhi, cb;\r
77 \r
78 cblo = fgetc(input_fp);\r
79 cbhi = fgetc(input_fp);\r
80 cb = (cbhi << 8) + cblo;\r
81 lfa = lfa + cb + 3;\r
82 *pCbRet = cb;\r
83 }\r
84 \r
85 \r
86 /*********************************************/\r
87 \r
88 void WriteRecInfo(void)\r
89 {\r
90 char num[9];\r
91 int sData;\r
92 unsigned int cb;\r
93 \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
98 num[8] = 0;\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
105 num[4] = 0;\r
106 fputs(num,output_fp);\r
107 }\r
108 \r
109 /*********************************************/\r
110 \r
111 void Dump (char *pb, int cb)\r
112 {\r
113 char   line[70];\r
114 int    sDataRet;\r
115 int    i;\r
116 char   b;\r
117 int    limit;\r
118 \r
119 for (i=0; i<69; i++) line[i] = ' ';             /* clear line */\r
120 while (cb) {\r
121   if (cb >= 16) {\r
122     limit = 15;\r
123     cb -= 16;\r
124         }\r
125   else {\r
126     limit = cb - 1;\r
127     cb = 0;\r
128         }\r
129   Copyn(&line[50], pb, limit + 1);\r
130   pb += 16;\r
131   for (i=0; i<=limit; i++) {\r
132     b = line[50 + i];\r
133     EncodeHex (&line[(3*i)], b);\r
134     if ((b < 0x20) || (b > 0x7E)) line[50+i] = '.';\r
135   }\r
136   line [67] = '\r';\r
137   line [68] = '\n';\r
138   line [69] = 0;\r
139   fputs(line, output_fp);\r
140  }\r
141 }\r
142 \r
143 \r
144 /*********************************************/\r
145 \r
146 void ReadBsRecord(unsigned char *pDest, int nbytes)\r
147 {\r
148 int i;\r
149 unsigned char b;\r
150 \r
151 while (nbytes--) {\r
152   i = fgetc(input_fp);\r
153   if (i==EOF) exit(1);\r
154   b = i & 0xff;\r
155   *pDest++ = b;\r
156   }\r
157 }\r
158 \r
159 /*********************************************/\r
160 \r
161 void DumpRecord (void)\r
162 {\r
163 int  cb;\r
164 char line[16];\r
165 int  len;\r
166 int  sData;\r
167 \r
168  cb = reclen;\r
169  cb--;                          /* Get rid of Check Sum */\r
170  while (cb) {\r
171   if (cb > 16) {\r
172     len = 16;\r
173     cb -= 16;\r
174   }\r
175   else {\r
176     len = cb;\r
177     cb = 0;\r
178   }\r
179 \r
180   ReadBsRecord (line, len);\r
181   Dump (line, len);\r
182  }\r
183  fputs("\r\n", output_fp);\r
184  if (fseek(input_fp, lfa, 0)) exit(1);\r
185 }\r
186 \r
187 \r
188 /*********************************************/\r
189 \r
190 void UnknownRType (unsigned char RType)\r
191 {\r
192 char  num[3];\r
193 int   sData;\r
194 \r
195 EncodeHex (num, RType);\r
196 num[2] = 0;\r
197 fputs("Unknown Record Type ", output_fp);\r
198 fputs(num, output_fp);\r
199 fputs(" at lfa ", output_fp);\r
200 WriteRecInfo ();\r
201 fputs("\r\n", output_fp);\r
202 }\r
203 \r
204 /*********************************************/\r
205 \r
206 void ReadIndex (unsigned int *pIndex, int *pCb)\r
207 {\r
208 unsigned char  b;\r
209 int i;\r
210 \r
211 i = fgetc(input_fp);\r
212 if (i==EOF) exit(1);\r
213 b = i & 0xff;\r
214 --*pCb;\r
215 if (!(b & 0x80))\r
216   *pIndex = b;\r
217 else {\r
218   i = b & 0x7F;\r
219   *pIndex = i * 0x100;\r
220   i = fgetc(input_fp);\r
221   if (i==EOF) exit(1);\r
222   b = i & 0xff;\r
223   --*pCb;\r
224   *pIndex += b;\r
225  }\r
226 }\r
227 \r
228 /*********************************************/\r
229 \r
230 void ThreadRecord (unsigned char FType, int *pCb)\r
231 {\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
235 unsigned char i;\r
236 \r
237  i = FType & 3;\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
243  else\r
244    TIndex[i] = 0;\r
245 }\r
246 \r
247 \r
248 /*********************************************/\r
249 \r
250 void FixupRecord (unsigned char FType, int *pCb)\r
251 {\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
255 char           Number[3];\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
262 long  displacement;\r
263 \r
264 if (!(FType & 0x40))\r
265   fputs("Self relative ", output_fp);\r
266 else\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
274   default: ;\r
275   }\r
276 \r
277 DataOffset = fgetc(input_fp);\r
278 --*pCb;\r
279 EncodeHex (Number, FType & 3);\r
280 Number[2] = 0;\r
281 fputs(Number,output_fp);\r
282 EncodeHex (Number, DataOffset);\r
283 fputs(Number,output_fp);\r
284 FixData = fgetc(input_fp);\r
285 --*pCb;\r
286 if (!(FixData & 0x80)) {\r
287   frame = (FixData / 0x10) & 7;\r
288   if (frame < 4)\r
289         ReadIndex (&fDatum, pCb);\r
290   else\r
291         fDatum = 0;\r
292 }\r
293 else {\r
294 /*  WRITE (' frame thread ');  */\r
295   frame = Thread [4 + ((FixData / 16) & 3)];\r
296   fDatum = TIndex [4 + ((FixData / 16) & 3)];\r
297   }\r
298 if (!(FixData & 8)) {\r
299   target = FixData & 7;\r
300   ReadIndex (&tDatum, pCb);\r
301 }\r
302 else {\r
303   /* WRITE (' target thread');  */\r
304   target = Thread[FixData & 3] | (FixData & 4);\r
305   tDatum = TIndex[FixData & 3];\r
306 }\r
307 fputs(" , F", output_fp);\r
308 fputc(frame + 0x30, output_fp);\r
309 if (fDatum) {\r
310   fputc(' ', output_fp);\r
311   EncodeHex (Number, (fDatum >> 8));\r
312   Number[2] = 0;\r
313   fputs(Number,output_fp);\r
314 \r
315   EncodeHex (Number, (fDatum & 0xff));\r
316   Number[2] = 0;\r
317   fputs(Number,output_fp);\r
318 }\r
319 fputs(" , T", output_fp);\r
320 fputc(target + 0x30, output_fp);\r
321 fputc(' ', output_fp);\r
322 \r
323 EncodeHex (Number, (tDatum >> 8));\r
324 Number[2] = 0;\r
325 fputs(Number,output_fp);\r
326 \r
327 EncodeHex (Number, (tDatum & 0xff));\r
328 Number[2] = 0;\r
329 fputs(Number,output_fp);\r
330 \r
331 if (!(FixData & 4)) {\r
332   displacement = 0;\r
333   fputc(' ', output_fp);\r
334   if (!(FType & 2)) {\r
335     ReadBsRecord (&displacement, 2);\r
336         *pCb -= 2;\r
337   }\r
338   else {\r
339     ReadBsRecord (&displacement, 3);\r
340         *pCb -= 3;\r
341         Number[2] = 0;\r
342         EncodeHex (Number, (displacement >> 16) & 0xff);\r
343     fputs(Number,output_fp);\r
344   }\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
349 }\r
350 fputs("\r\n",output_fp);\r
351 }\r
352 \r
353 \r
354 /*********************************************/\r
355 \r
356 void FIXUPP (void)\r
357 {\r
358 int  cb;\r
359 unsigned char  FType;\r
360 unsigned int   sData;\r
361 \r
362 fputs("\r\n",output_fp);\r
363 cb = reclen;\r
364 cb--;\r
365 while (cb) {\r
366   FType = fgetc(input_fp);\r
367   cb--;\r
368   if (!(FType & 0x80))  ThreadRecord (FType, &cb);\r
369   else FixupRecord (FType, &cb);\r
370   }\r
371 if (fseek(input_fp, lfa, 0)) exit(1);\r
372 }\r
373 \r
374 \r
375 /****************************************\r
376 * Write a line to the output file\r
377 *****************************************/\r
378 \r
379 void write_line(char *pstr)\r
380 {\r
381         fputs(pstr, output_fp);\r
382         fputs("\r\n", output_fp);\r
383 }\r
384 \r
385 /*******************************************\r
386 * Report a non-recoverable error\r
387 ********************************************/\r
388 \r
389 void fatal_error(char *string)\r
390 {\r
391         fputs("Fatal error, object dump aborted\r\n", stderr);\r
392         fputs(string,stderr);\r
393         exit(-1);\r
394 }\r
395 \r
396 \r
397 /*********************\r
398 * Main program\r
399 **********************/\r
400 \r
401 void main(int argc, char *argv[])\r
402 {\r
403         int i, j, fdone;\r
404         char *ptr;\r
405 \r
406 /* first process any filenames and command line options */\r
407         for(i=1; i < argc; ++i) {\r
408                 ptr = argv[i];\r
409                 switch((*ptr++ << 8) | *ptr++) {\r
410                         default:\r
411                                 if(!input_fp) {\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
417                                 else\r
418                                         fatal_error("Too many parameters\n");\r
419                                 }\r
420                 }\r
421 \r
422 /* any files not explicitly named default to standard I/O */\r
423         if(!input_fp)                           /* default to standard input */\r
424         {\r
425                 printf("No input file specified...");\r
426                 exit(1);\r
427         }\r
428         if(!output_fp)                          /* default to standard output */\r
429                 output_fp = stdout;\r
430 \r
431         fputs("Object Module Reader V1.0\r\n", stderr);\r
432         fputs("\r\n", output_fp);\r
433 \r
434 \r
435 RType = fgetc(input_fp);\r
436 if (RType == EOF) erc = 1;\r
437 \r
438 while (!erc) {\r
439   switch (RType) {\r
440     case 0x6E :\r
441                         fputs("RHEADR   ",output_fp);\r
442                         WriteRecInfo();\r
443                         fputs("\r\n", output_fp);\r
444                                 DumpRecord();\r
445                                 break;\r
446     case 0x70 :\r
447                         fputs("REGINT   ",output_fp);\r
448                         WriteRecInfo();\r
449                         fputs("\r\n", output_fp);\r
450                                 DumpRecord();\r
451                                 break;\r
452     case 0x72 :\r
453                         fputs("REDATA   ",output_fp);\r
454                         WriteRecInfo();\r
455                         fputs("\r\n", output_fp);\r
456                                 DumpRecord();\r
457                                 break;\r
458     case 0x74 :\r
459                         fputs("RIDATA   ",output_fp);\r
460                         WriteRecInfo();\r
461                         fputs("\r\n", output_fp);\r
462                                 DumpRecord();\r
463                                 break;\r
464     case 0x76 :\r
465                         fputs("OVLDEF   ",output_fp);\r
466                         WriteRecInfo();\r
467                         fputs("\r\n", output_fp);\r
468                                 DumpRecord();\r
469                                 break;\r
470     case 0x78 :\r
471                         fputs("ENDREC   ",output_fp);\r
472                         WriteRecInfo();\r
473                         fputs("\r\n", output_fp);\r
474                                 DumpRecord();\r
475                                 break;\r
476     case 0x7A :\r
477                         fputs("BLKDEF   ",output_fp);\r
478                         WriteRecInfo();\r
479                         fputs("\r\n", output_fp);\r
480                                 DumpRecord();\r
481                                 break;\r
482     case 0x7C :\r
483                         fputs("BLKEND   ",output_fp);\r
484                         WriteRecInfo();\r
485                         fputs("\r\n", output_fp);\r
486                                 DumpRecord();\r
487                                 break;\r
488     case 0x7E :\r
489                         fputs("DEBSYM   ",output_fp);\r
490                         WriteRecInfo();\r
491                         fputs("\r\n", output_fp);\r
492                                 DumpRecord();\r
493                                 break;\r
494     case 0x80 :\r
495                         fputs("THEADR   ",output_fp);\r
496                         WriteRecInfo();\r
497                         fputs("\r\n", output_fp);\r
498                                 DumpRecord();\r
499                                 break;\r
500     case 0x82 :\r
501                         fputs("LHEADR   ",output_fp);\r
502                         WriteRecInfo();\r
503                         fputs("\r\n", output_fp);\r
504                                 DumpRecord();\r
505                                 break;\r
506     case 0x84 :\r
507                         fputs("PEDATA   ",output_fp);\r
508                         WriteRecInfo();\r
509                         fputs("\r\n", output_fp);\r
510                                 DumpRecord();\r
511                                 break;\r
512     case 0x86 :\r
513                         fputs("PIDATA   ",output_fp);\r
514                         WriteRecInfo();\r
515                         fputs("\r\n", output_fp);\r
516                                 DumpRecord();\r
517                                 break;\r
518     case 0x88 :\r
519                         fputs("COMENT   ",output_fp);\r
520                         WriteRecInfo();\r
521                         fputs("\r\n", output_fp);\r
522                                 DumpRecord();\r
523                                 break;\r
524     case 0x8A :\r
525                         fputs("MODEND   ",output_fp);\r
526                 exit(1);\r
527                                 break;\r
528     case 0x8C :\r
529                         fputs("EXTDEF   ",output_fp);\r
530                         WriteRecInfo();\r
531                         fputs("\r\n", output_fp);\r
532                                 DumpRecord();\r
533                                 break;\r
534     case 0x8E :\r
535                         fputs("TYPDEF   ",output_fp);\r
536                         WriteRecInfo();\r
537                         fputs("\r\n", output_fp);\r
538                                 DumpRecord();\r
539                                 break;\r
540     case 0x90 :\r
541                         fputs("PUBDEF   ",output_fp);\r
542                         WriteRecInfo();\r
543                         fputs("\r\n", output_fp);\r
544                                 DumpRecord();\r
545                                 break;\r
546     case 0x91 :\r
547                         fputs("PUBDEF32 ",output_fp);\r
548                         WriteRecInfo();\r
549                         fputs("\r\n", output_fp);\r
550                                 DumpRecord();\r
551                                 break;\r
552     case 0x92 :\r
553                         fputs("LOCSYM   ",output_fp);\r
554                         WriteRecInfo();\r
555                         fputs("\r\n", output_fp);\r
556                                 DumpRecord();\r
557                                 break;\r
558     case 0x94 :\r
559                         fputs("LINNUM   ",output_fp);\r
560                         WriteRecInfo();\r
561                         fputs("\r\n", output_fp);\r
562                                 DumpRecord();\r
563                                 break;\r
564         case 0x96 :\r
565                         fputs("LNAMES   ",output_fp);\r
566                         WriteRecInfo();\r
567                         fputs("\r\n", output_fp);\r
568                                 DumpRecord();\r
569                                 break;\r
570         case 0x98 :\r
571                         fputs("SEGDEF   ",output_fp);\r
572                         WriteRecInfo();\r
573                         fputs("\r\n", output_fp);\r
574                                 DumpRecord();\r
575                                 break;\r
576         case 0x99 :\r
577                         fputs("SEGDEF32 ",output_fp);\r
578                         WriteRecInfo();\r
579                         fputs("\r\n", output_fp);\r
580                                 DumpRecord();\r
581                                 break;\r
582     case 0x9A :\r
583                         fputs("GRPDEF   ",output_fp);\r
584                         WriteRecInfo();\r
585                         fputs("\r\n", output_fp);\r
586                                 DumpRecord();\r
587                                 break;\r
588         case 0x9C :\r
589                         fputs("FIXUPP   ",output_fp);\r
590                         WriteRecInfo();\r
591                 FIXUPP();\r
592                         fputs("\r\n", output_fp);\r
593                                 break;\r
594         case 0x9D :\r
595                                 fputs("FIXUPP32 ",output_fp);\r
596                                 WriteRecInfo();\r
597 /*                              FIXUPP(); */\r
598                         fputs("\r\n", output_fp);\r
599                                 DumpRecord();\r
600                         fputs("\r\n", output_fp);\r
601                                 break;\r
602         case 0xA0 :\r
603                         fputs("LEDATA   ",output_fp);\r
604                         WriteRecInfo();\r
605                         fputs("\r\n", output_fp);\r
606                                 DumpRecord();\r
607                                 break;\r
608         case 0xA1 :\r
609                         fputs("LEDATA32 ",output_fp);\r
610                         WriteRecInfo();\r
611                         fputs("\r\n", output_fp);\r
612                                 DumpRecord();\r
613                                 break;\r
614     case 0xA2 :\r
615                         fputs("LIDATA   ",output_fp);\r
616                         WriteRecInfo();\r
617                         fputs("\r\n", output_fp);\r
618                                 DumpRecord();\r
619                                 break;\r
620     case 0xA4 :\r
621                         fputs("LIBHED   ",output_fp);\r
622                         WriteRecInfo();\r
623                         fputs("\r\n", output_fp);\r
624                                 DumpRecord();\r
625                                 break;\r
626     case 0xA6 :\r
627                         fputs("LIBNAM   ",output_fp);\r
628                         WriteRecInfo();\r
629                         fputs("\r\n", output_fp);\r
630                                 DumpRecord();\r
631                                 break;\r
632     case 0xA8 :\r
633                         fputs("LIBLOC   ",output_fp);\r
634                         WriteRecInfo();\r
635                         fputs("\r\n", output_fp);\r
636                                 DumpRecord();\r
637                                 break;\r
638         case 0xAA :\r
639                         fputs("LIBDIC   ",output_fp);\r
640                         WriteRecInfo();\r
641                         fputs("\r\n", output_fp);\r
642                                 DumpRecord();\r
643                                 break;\r
644         case 0xB0 :\r
645                         fputs("COMDEF   ",output_fp);\r
646                         WriteRecInfo();\r
647                         fputs("\r\n", output_fp);\r
648                                 DumpRecord();\r
649                                 break;\r
650         case 0xB2 :\r
651                                 fputs("FORREF   ",output_fp);\r
652                                 WriteRecInfo();\r
653                                 fputs("\r\n", output_fp);\r
654                                 DumpRecord();\r
655                                 break;\r
656         case 0xB4 :\r
657                                 fputs("MODEXT   ",output_fp);\r
658                                 WriteRecInfo();\r
659                                 fputs("\r\n", output_fp);\r
660                                 DumpRecord();\r
661                                 break;\r
662         case 0xB6 :\r
663                                 fputs("MODPUB   ",output_fp);\r
664                                 WriteRecInfo();\r
665                                 fputs("\r\n", output_fp);\r
666                                 DumpRecord();\r
667                                 break;\r
668         default:\r
669                         UnknownRType(RType);\r
670                         fputs("\r\n", output_fp);\r
671                 DumpRecord();\r
672                                 break;\r
673         }\r
674   RType = fgetc(input_fp);\r
675   if (RType == EOF) erc = 1;\r
676 \r
677   }\r
678 \r
679 }\r