home *** CD-ROM | disk | FTP | other *** search
/ ftp.ee.pdx.edu / 2014.02.ftp.ee.pdx.edu.tar / ftp.ee.pdx.edu / pub / users / Harry / Blitz / version-1-0 / BlitzSrc / dumpObj.c < prev    next >
C/C++ Source or Header  |  2006-09-25  |  13KB  |  522 lines

  1. /* Program to dump a BLITZ ".o" or "a.out" file
  2. **
  3. ** Copyright 2000-2006, Harry H. Porter III
  4. **
  5. ** This file may be freely copied, modified and compiled, on the sole
  6. ** condition that if you modify it...
  7. **   (1) Your name and the date of modification is added to this comment
  8. **       under "Modifications by", and
  9. **   (2) Your name and the date of modification is added to the printHelp()
  10. **       routine under "Modifications by".
  11. **
  12. ** Original Author:
  13. **   11/12/00 - Harry H. Porter III
  14. **
  15. ** Modifcations by:
  16. **   03/15/06 - Harry H. Porter III
  17. **
  18. */
  19.  
  20. #include <stdlib.h>
  21. #include <stdio.h>
  22. #include <stdarg.h>
  23. #include <string.h>
  24.  
  25.  
  26.  
  27. /*****  Global variables *****/
  28.  
  29. char * commandInFileName = NULL; /* The input filename, if provided */
  30. FILE * inputFile;                /* The input file */
  31. int textSize;
  32. int dataSize;
  33. int bssSize;
  34. int textAddr;
  35. int dataAddr;
  36. int bssAddr;
  37. int count;
  38. int row [16];
  39. int size;
  40. int symbolNum;
  41. int locationToUpdate;
  42. int value;
  43. int relativeTo;
  44. int len;
  45.  
  46.  
  47.  
  48. /* Function prototypes */
  49.  
  50. void processCommandLine (int argc, char ** argv);
  51. void printHelp ();
  52. int readInteger ();
  53. int readByte ();
  54. void printSegment (int startingAddr);
  55. void readline ();
  56. int getNext ();
  57. void putlong (int i);
  58. void printline ();
  59. void putbyt (int c);
  60. void fatalError (char * msg);
  61.  
  62.  
  63.  
  64. /* main()
  65. **
  66. ** Read and print .o file.
  67. */
  68. main (int argc, char ** argv) {
  69.     int i, lineNumber;
  70.     int magic;
  71.     int sawEntryLabel;
  72.     processCommandLine (argc, argv);
  73.     printf ("=====  HEADER INFO  =====\n\n");
  74.     magic = readInteger ();
  75.     if (magic == 0x424C5A6F) {
  76.       printf ("magic number = BLZo (This is a '.o' file.)\n");
  77.     } else if (magic == 0x424C5A78) {
  78.       printf ("magic number = BLZx (This is an 'a.out' file.)\n");
  79.     } else {
  80.       fatalError ("Magic number is not 'BLZo' or 'BLZx'");
  81.     }
  82.     if (magic == 0x424C5A78) {   /* if we have an a.out file... */
  83.       textSize = readInteger ();
  84.       dataSize = readInteger ();
  85.       bssSize = readInteger ();
  86.       printf (".text size = %08x (%d)\n", textSize, textSize);
  87.       printf (".data size = %08x (%d)\n", dataSize, dataSize);
  88.       printf (".bss size =  %08x (%d)\n", bssSize, bssSize);
  89.       textAddr = readInteger ();
  90.       dataAddr = readInteger ();
  91.       bssAddr = readInteger ();
  92.       printf (".text load addr = %08x (%d)\n", textAddr, textAddr);
  93.       printf (".data load addr = %08x (%d)\n", dataAddr, dataAddr);
  94.       printf (".bss load addr =  %08x (%d)\n", bssAddr, bssAddr);
  95.       magic = readInteger ();
  96.       if (magic != 0x2a2a2a2a) {
  97.         fatalError ("Invalid file format - missing \"****\" separator");
  98.       }
  99.       printf ("\n=====  TEXT SEGMENT  =====\n\n");
  100.       count = textSize;
  101.       printSegment (textAddr);
  102.       magic = readInteger ();
  103.       if (magic != 0x2a2a2a2a) {
  104.         fatalError ("Invalid file format - missing \"****\" separator");
  105.       }
  106.       printf ("\n=====  DATA SEGMENT  =====\n\n");
  107.       count = dataSize;
  108.       printSegment (dataAddr);
  109.       magic = readInteger ();
  110.       if (magic != 0x2a2a2a2a) {
  111.         fatalError ("Invalid file format - missing \"****\" separator");
  112.       }
  113.       printf ("\n=====  LABEL INFORMATION  =====\n\n");
  114.       printf ("Value   (in decimal)  Label\n");
  115.       printf ("====================  ==================\n");
  116.       while (1) {
  117.         len = readInteger ();
  118.         if (len <= 0) break;
  119.         value = readInteger ();
  120.         printf ("%08x%12d  ", value, value);
  121.         for (; len>0; len--) {
  122.           i = readByte ();
  123.           printf ("%c", i);
  124.         }
  125.         printf ("\n");
  126.       }
  127.   
  128.       magic = readInteger ();
  129.       if (magic != 0x2a2a2a2a) {
  130.         fatalError ("Invalid file format - missing \"****\" separator");
  131.       }
  132.   
  133.     } else {   /* if we have an .o file... */
  134.       sawEntryLabel = readInteger ();
  135.       if (sawEntryLabel == 1) {
  136.         printf (".text contains _entry = TRUE\n");
  137.       } else if (sawEntryLabel == 0) {
  138.         printf (".text contains _entry = FALSE\n");
  139.       } else {
  140.         fatalError ("sawEntryLabel has invalid value");
  141.       }
  142.       textSize = readInteger ();
  143.       dataSize = readInteger ();
  144.       bssSize = readInteger ();
  145.       printf (".text size = %08x (%d)\n", textSize, textSize);
  146.       printf (".data size = %08x (%d)\n", dataSize, dataSize);
  147.       printf (".bss size =  %08x (%d)\n", bssSize, bssSize);
  148.       printf ("\n=====  TEXT SEGMENT  =====\n\n");
  149.       count = textSize;
  150.       printSegment (0);
  151.       magic = readInteger ();
  152.       if (magic != 0x2a2a2a2a) {
  153.         fatalError ("Invalid file format - missing \"****\" separator");
  154.       }
  155.       printf ("\n=====  DATA SEGMENT  =====\n\n");
  156.       count = dataSize;
  157.       printSegment (0);
  158.   
  159.       magic = readInteger ();
  160.       if (magic != 0x2a2a2a2a) {
  161.         fatalError ("Invalid file format - missing \"****\" separator");
  162.       }
  163.   
  164.       printf ("\n=====  SYMBOL TABLE  =====\n\n");
  165.       printf ("Number  Value     Relative to   Symbol\n");
  166.       printf ("======  ========  ===========   ======\n");
  167.       while (1) {
  168.         symbolNum = readInteger ();
  169.         if (symbolNum == 0) break;
  170.         value = readInteger ();
  171.         relativeTo = readInteger ();
  172.         len = readInteger ();
  173.         printf ("%d\t%08x\t%d\t", symbolNum, value, relativeTo);
  174.         for (; len>0; len--) {
  175.           i = readByte ();
  176.           printf ("%c", i);
  177.         }
  178.         printf ("\n");
  179.       }
  180.   
  181.       magic = readInteger ();
  182.       if (magic != 0x2a2a2a2a) {
  183.         fatalError ("Invalid file format - missing \"****\" separator");
  184.       }
  185.   
  186.       printf ("\n=====  RELOCATION INFO  =====\n\n");
  187.       printf ("Type    Locatn-to-modify New-val  Rel-to Src-Line\n");
  188.       printf ("======= ================ ======== ====== ========\n");
  189.       while (1) {
  190.         i = readInteger ();
  191.         if (i == 0) {
  192.           break;
  193.         } else if (i == 1) {
  194.           printf ("8-bit\t");
  195.         } else if (i == 2) {
  196.           printf ("16-bit\t");
  197.         } else if (i == 3) {
  198.           printf ("24-bit\t");
  199.         } else if (i == 4) {
  200.           printf ("32-bit\t");
  201.         } else if (i == 5) {
  202.           printf ("set-hi\t");
  203.         } else if (i == 6) {
  204.           printf ("set-lo\t");
  205.         } else if (i == 7) {
  206.           printf ("ldaddr\t");
  207.         } else {
  208.           fatalError ("Invalid relocation record code");
  209.         }
  210.         value = readInteger ();
  211.         printf ("%08x ", value);
  212.         i = readInteger ();
  213.         if (i == 1) {
  214.           printf (".text\t");
  215.         } else if (i == 2) {
  216.           printf (".data\t");
  217.         } else {
  218.           printf ("*****\t");
  219.         }
  220.         value = readInteger ();
  221.         printf (" %08x ", value);
  222.         value = readInteger ();
  223.         printf ("%4d   ", value);
  224.         lineNumber = readInteger ();
  225.         printf ("%6d  \n", lineNumber);
  226.       }
  227.       magic = readInteger ();
  228.       if (magic != 0x2a2a2a2a) {
  229.         fatalError ("Invalid file format - missing \"****\" separator");
  230.       }
  231.   
  232.       printf ("\n=====  ADDRESS LABELS  =====\n\n");
  233.       printf ("Segment Offset    Label\n");
  234.       printf ("======= ========  =====\n");
  235.       while (1) {
  236.         i = readInteger ();
  237.         if (i == 0) break;
  238.         if (i == 1) printf (".text\t");
  239.         if (i == 2) printf (".data\t");
  240.         if (i == 3) printf (".bss\t");
  241.         value = readInteger ();
  242.         len = readInteger ();
  243.         printf ("%08x  ", value);
  244.         for (; len>0; len--) {
  245.           i = readByte ();
  246.           printf ("%c", i);
  247.         }
  248.         printf ("\n");
  249.       }
  250.   
  251.       magic = readInteger ();
  252.       if (magic != 0x2a2a2a2a) {
  253.         fatalError ("Invalid file format - missing \"****\" separator");
  254.       }
  255.     }
  256. }
  257.  
  258.  
  259.  
  260. /* processCommandLine (argc, argv)
  261. **
  262. ** This routine processes the command line options.
  263. */
  264. void processCommandLine (int argc, char ** argv) {
  265.   int argCount;
  266.   int len;
  267.   for (argc--, argv++; argc > 0; argc -= argCount, argv += argCount) {
  268.     argCount = 1;
  269.     /* Scan the -h option */
  270.     if (!strcmp (*argv, "-h")) {
  271.       printHelp ();
  272.       exit (1);
  273.     /* Scan an input file name */
  274.     } else if ((*argv)[0] != '-') {
  275.       if (commandInFileName == NULL) {
  276.         commandInFileName = *argv;
  277.       } else {
  278.         fprintf (stderr,
  279.           "dumpObj: Invalid command line;  Multiple input files;  Use -h for help display\n");
  280.         exit (1);
  281.       }
  282.     } else {
  283.       fprintf (stderr,
  284.         "dumpObj: Invalid command line option (%s);  Use -h for help display\n",
  285.         *argv);
  286.       exit (1);
  287.     }
  288.   }
  289.  
  290.   /* Open the input (.o) file */
  291.   if (commandInFileName == NULL) {
  292.     inputFile = stdin;
  293.   } else {
  294.     inputFile = fopen (commandInFileName, "r");
  295.     if (inputFile == NULL) {
  296.       fprintf (stderr,
  297.           "dumpObj: Input file \"%s\" could not be opened\n", commandInFileName);
  298.       exit (1);
  299.     }
  300.   }
  301. }
  302.  
  303.  
  304.  
  305. /* printHelp ()
  306. **
  307. ** This routine prints some documentation.  It is invoked whenever
  308. ** the -h option is used on the command line.
  309. */
  310. void printHelp () {
  311.   printf (
  312. "================================================\n"
  313. "=====                                      =====\n"
  314. "=====  The BLITZ Object File Dump Program  =====\n"
  315. "=====                                      =====\n"
  316. "================================================\n"
  317. "\n"
  318. "Copyright 2000-2006, Harry H. Porter III\n"
  319. "========================================\n"
  320. "  Original Author:\n"
  321. "    11/12/00 - Harry H. Porter III\n"
  322. "  Modifcations by:\n"
  323. "    03/15/06 - Harry H. Porter III\n"
  324. "\n"
  325. "Overview\n"
  326. "========\n"
  327. "  This program prints out a BLITZ \".o\" or \"a.out\" file in human-readable\n"
  328. "  form.  This program does some (very limited) error checking on the file.\n"
  329. "\n"
  330. "Command Line Options\n"
  331. "====================\n"
  332. "  Command line options may be given in any order.\n"
  333. "    -h\n"
  334. "      Print this info.  The input source is ignored.\n"
  335. "    filename\n"
  336. "      The input source will come from this file.  (This file should be a\n"
  337. "      \".o\" or \"a.out\" file.)  If an input file is not named on the command\n"
  338. "      line, the source must come from stdin.  Only one input source is allowed.\n");
  339. }
  340.  
  341.  
  342.  
  343. /* readInteger ()
  344. **
  345. ** Read and return an integer.
  346. */
  347. int readInteger () {
  348.   int i, numBytesRead;
  349.   numBytesRead = fread (&i, 4, 1, inputFile);
  350.   if (numBytesRead != 1) {
  351.     fatalError ("Problem reading from input file");
  352.   }
  353.   return i;
  354. }
  355.  
  356.  
  357.  
  358. /* readByte ()
  359. **
  360. ** Read 1 byte and return an integer.
  361. */
  362. int readByte () {
  363.   int i, numBytesRead;
  364.   char c;
  365.   numBytesRead = fread (&c, 1, 1, inputFile);
  366.   if (numBytesRead != 1) {
  367.     fatalError ("Problem reading from input file");
  368.   }
  369.   i = c;
  370.   return i;
  371. }
  372.  
  373.  
  374.  
  375. /* printSegment (startingAddr)
  376. **
  377. ** This routine reads raw bytes from the input file and prints them
  378. ** out in a formatted way like this:
  379. **
  380. ** 00002000: 0000 0000 0000 0000 0000 0000 0000 0000   ................
  381. ** 00002010: 6162 6364 6566 6768 3400 0000 696A 6B6C   abcdefgh4...ijkl
  382. ** 00002020: 6D6E 6F70 7172 7374 7576 7778 797A 0000   mnopqrstuvwxyz..
  383. **
  384. ** It is passed the starting address; in this example it was 0x0000200.
  385. */
  386. void printSegment (int startingAddr) {
  387.    int addr;
  388.  
  389.    /* Each execution of this loop prints a single output line. */
  390.    addr = startingAddr;
  391.    readline ();
  392.    while (size > 0) {
  393.      putlong (addr);
  394.      printf (":  ");
  395.      printline ();
  396.      addr = addr + 16;
  397.      readline ();
  398.    }
  399.  
  400. }
  401.  
  402.  
  403.  
  404. /* readline ()
  405. **
  406. ** This routine reads in the next 16 bytes from the file and
  407. ** places them in the array named 'row', setting 'size' to
  408. ** be the number of bytes read in.  Size will be less than
  409. ** 16 if EOF was encountered, and may possibly be 0.
  410. */
  411. void readline () {
  412.   int c;
  413.   size = 0;
  414.   c = getNext ();
  415.   while (c != -999) {
  416.     row [size] = c;
  417.     size = size + 1;
  418.     if (size >= 16) break;
  419.     c = getNext ();
  420.   }
  421. }
  422.  
  423.  
  424.  
  425. /* getNext ()
  426. **
  427. ** Read next char, decrementing count.  Return it, or -999 if count <= 0.
  428. */
  429. int getNext () {
  430.   if (count <= 0) return -999;
  431.   count--;
  432.   return readByte();
  433. }
  434.  
  435.  
  436.  
  437. /* putlong ()
  438. **
  439. ** This routine is passed an integer, which it displays as 8 hex digits.
  440. */
  441. void putlong (int i) {
  442.   putbyt ((i>>24) & 0x000000ff);
  443.   putbyt ((i>>16) & 0x000000ff);
  444.   putbyt ((i>>8) & 0x000000ff);
  445.   putbyt ((i>>0) & 0x000000ff);
  446. }
  447.  
  448.  
  449.  
  450. /* printline ()
  451. **
  452. ** This routine prints the current 'row'.
  453. */
  454. void printline () {
  455.   int i, c;
  456.   if (size > 0) {
  457.     i = 0;
  458.     while (i<16) {
  459.       if (i < size) {
  460.         putbyt (row[i]);
  461.       } else {
  462.         printf ("  ");
  463.       }
  464.       i++;
  465.       if ((i%2) == 0) {
  466.         putchar (' ');
  467.       }
  468.       if ((i%4) == 0) {
  469.         putchar (' ');
  470.       }
  471.     }
  472.     printf ("  ");
  473.     for (i=0; i<size; i++) {
  474.       c = row[i];
  475.       if ((c>=' ') && (c <= '~')) {
  476.         putchar (c);
  477.       } else {
  478.         putchar ('.');
  479.       }
  480.     }
  481.     printf ("\n");
  482.   }
  483. }
  484.  
  485.  
  486.  
  487. /* putbyt ()
  488. **
  489. ** This routine is passed a byte (i.e., an integer -128..255) which
  490. ** it displays as 2 hex characters.  If passed a number out of that
  491. ** range, it outputs nothing.
  492. */
  493. void putbyt (int c) {
  494.   int i;
  495.   if (c<0) c = c + 256;
  496.   if ((c >= 0) && (c <= 255)) {
  497.     i = (c & 0x000000f0) >> 4;
  498.     if (i < 10) {
  499.       putchar ('0' + i);
  500.     } else {
  501.       putchar ('A' + i - 10);
  502.     }
  503.     i = (c & 0x0000000f) >> 0;
  504.     if (i < 10) {
  505.       putchar ('0' + i);
  506.     } else {
  507.       putchar ('A' + i - 10);
  508.     }
  509.   }
  510. }
  511.  
  512.  
  513.  
  514. /* fatalError (msg)
  515. **
  516. ** Print this message and abort.
  517. */
  518. void fatalError (char * msg) {
  519.   printf ("\n*****  ERROR: %s  *****\n", msg);
  520.   exit (1);
  521. }
  522.