home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 109 / EnigmaAmiga109CD.iso / software / sviluppo / hunkreader / src / hunkreader.c < prev    next >
C/C++ Source or Header  |  1999-12-27  |  26KB  |  1,024 lines

  1.  
  2. /*
  3.  * [!BGN - MACHINE GENERATED - DO NOT EDIT THIS HEADER]
  4.  *
  5.  * Program   : HunkReader (Executable/Object file hunk viewer)
  6.  * Version   : 1.6
  7.  * File      : Work:Source/!WIP/HunkReader/HunkReader.c
  8.  * Author    : Andrew Bell
  9.  * Copyright : Copyright © 1999 Andrew Bell, All rights reserved.
  10.  * Created   : Saturday 15-Nov-97 08:30:00
  11.  * Modified  : Tuesday 16-Nov-99 22:37:06
  12.  * Comment   : 
  13.  *
  14.  * (Generated with StampSource 1.4 by Andrew Bell)
  15.  *
  16.  * [!END - MACHINE GENERATED - DO NOT EDIT THIS HEADER]
  17.  *
  18.  */
  19.  
  20. /* Created: Sat/15/Nov/1997 */
  21.  
  22. #define MONTH "December"
  23. #define YEAR  "1997-99"
  24. #define EMAIL "andrew.ab2000@bigfoot.com"
  25. #define WWW   "http://www.homeusers.prestel.co.uk/ab2000"
  26.  
  27. /* Maybe one day I'll make this code totally portable. */
  28.  
  29. /* Includes */
  30.  
  31. #include <HunkReader_rev.h>
  32.  
  33. #include <exec/types.h>
  34. #include <exec/execbase.h>
  35. #include <exec/memory.h>
  36.  
  37. #include <dos/dos.h>
  38. #include <dos/dosextens.h>
  39. #include <dos/doshunks.h>
  40. #include <dos/stdio.h>
  41.  
  42. #include <clib/exec_protos.h>
  43. #include <clib/dos_protos.h>
  44. #include <pragma/exec_lib.h>
  45. #include <pragma/dos_lib.h>
  46.  
  47. #pragma header
  48.  
  49. /* Defines */
  50.  
  51. #define MASK ( HUNKF_ADVISORY | HUNKF_CHIP | HUNKF_FAST )
  52.  
  53. #define TEMPLATE "FILE/A,DSYM/S,DREL/S,DEXT/S,STATS/S"
  54.  
  55. enum
  56. {
  57.   ARG_FILE = 0,     /* Incoming file */
  58.   ARG_DSYM,         /* Display symbol tables */
  59.   ARG_DREL,         /* Display reloc tables */
  60.   ARG_DEXT,         /* Display ext hunks */
  61.   ARG_STATS,        /* Display stats */
  62.   ARG_AMT           /* Array size */
  63. };
  64.  
  65. /* Prototypes */
  66.  
  67. void DoErr( void );
  68. void DumpHunks( BPTR );
  69. ULONG MoveForward( BPTR, LONG );
  70. BOOL TestAbort( void );
  71. void BuildFlagString( ULONG, UBYTE *);
  72. LONG MyRead( BPTR FH, APTR Buf, ULONG Length);
  73. UBYTE *Plural( ULONG, UBYTE *, UBYTE *);
  74.  
  75. void DoHUNK_EXT( BPTR FH );
  76. void DoUNKNOWN( BPTR FH );
  77. void DoHUNK_HEADER( BPTR FH );
  78. void DoHUNK_CODE( BPTR FH );
  79. void DoHUNK_DATA( BPTR FH );
  80. void DoHUNK_BSS( BPTR FH );
  81. void DoHUNK_END( BPTR FH );
  82. void DoHUNK_OVERLAY( BPTR FH);
  83. void DoHUNK_BREAK( BPTR FH );
  84. void DoHUNK_DEBUG( BPTR FH );
  85. void DoHUNK_SYMBOL( BPTR FH );
  86. void DoHUNK_RELOC32( BPTR FH );
  87. void DoHUNK_DREL32( BPTR FH );
  88. void DoHUNK_RELOC32SHORT( BPTR FH );
  89. void DoHUNK_DREL32( BPTR FH );
  90. void DoHUNK_UNIT( BPTR FH );
  91. void DoHUNK_NAME( BPTR FH );
  92. void DoHUNK_EXT( BPTR FH );
  93.  
  94. /* We let the startup code/linker deal with these */
  95.  
  96. extern struct ExecBase *SysBase;
  97. extern struct Library *DOSBase;
  98.  
  99.  
  100. /* Varables and data */
  101.  
  102. static UBYTE VerTag[] = VERSTAG;
  103.  
  104. ULONG aa[ARG_AMT];
  105. ULONG stream[99];
  106. UBYTE TempBuffer[256+4];
  107.  
  108. /***********************************************************************/
  109.  
  110. ULONG main( void )
  111. {
  112.   struct RDArgs *ArgInfo;
  113.  
  114.   if (SysBase->LibNode.lib_Version < 37)
  115.   {
  116.     #define BADOSTXT "Sorry, this program requires at least OS 37+\n"
  117.     
  118.     if (DOSBase) Write(Output(), BADOSTXT, sizeof(BADOSTXT) );
  119.     return RETURN_FAIL;
  120.   }
  121.   
  122.   if (ArgInfo = (struct RDArgs *) ReadArgs(TEMPLATE, (LONG *) &aa, NULL))
  123.   {
  124.     BPTR InLock;
  125.  
  126.     Printf(VERS " (" DATE "),\n"
  127.           "Copyright © " YEAR " Andrew Bell, All rights reserved.\n"
  128.           "email: " EMAIL "\n"
  129.           "  web: " WWW "\n");
  130.  
  131.     if (InLock = Lock( (UBYTE *) aa[ARG_FILE], SHARED_LOCK))
  132.     {
  133.       struct FileInfoBlock *FIB;
  134.  
  135.       if (FIB = (struct FileInfoBlock *) AllocDosObject(DOS_FIB, NULL))
  136.       {
  137.         if (Examine(InLock, FIB))
  138.         {
  139.           if (FIB->fib_DirEntryType < 0)
  140.           {
  141.             if (FIB->fib_Size)
  142.             {
  143.               BPTR InHandle;
  144.  
  145.               Printf("\nViewing %s's hunks structure, length %lu bytes.\n\n",
  146.                 &FIB->fib_FileName, FIB->fib_Size);
  147.  
  148.               if (InHandle = Open( (UBYTE *) aa[ARG_FILE], MODE_OLDFILE))
  149.               {
  150.                 if (SysBase->LibNode.lib_Version >= 40)
  151.                 {
  152.                   SetVBuf(InHandle, NULL, BUF_FULL, (64*1024));
  153.                 }
  154.                 
  155.                 DumpHunks(InHandle);
  156.                 Close(InHandle);
  157.  
  158.               }   /* Open */
  159.               else DoErr();
  160.  
  161.             }   /* NULL length check */
  162.             else Printf("Subject file is empty!\n");
  163.  
  164.           }   /* File/dir check */
  165.           else Printf("I need a file, not a directory!\n");
  166.  
  167.         }   /* Examine() */
  168.         else DoErr();
  169.  
  170.         FreeDosObject(DOS_FIB, FIB);
  171.  
  172.       } /* AllocDosObject() */
  173.       else DoErr();
  174.  
  175.       UnLock(InLock);
  176.  
  177.     } /* Lock() */
  178.     else DoErr();
  179.  
  180.     FreeArgs(ArgInfo);
  181.  
  182.   } /* ReadArgs() */
  183.   else DoErr();
  184.  
  185.   return RETURN_OK;
  186.  
  187. } /* _main() */
  188.  
  189. /***********************************************************************/
  190.  
  191. void DoErr( void )
  192. {
  193.   PrintFault(IoErr(), "Error ");
  194. }
  195.  
  196. /***********************************************************************/
  197.  
  198. /* Global variables */
  199.  
  200. BOOL Flag_EOF    = FALSE; /* Will equal TRUE if EOF (All OK) */
  201. BOOL Flag_UEOF   = FALSE; /* Will equal TRUE if unexpected EOF  */
  202. BOOL Flag_Error  = FALSE; /* Will equal TRUE if error happened */
  203. BOOL Flag_BadId  = FALSE; /* Unknown hunk pop up it's ugly head */
  204. BOOL Flag_Break  = FALSE; /* Will equal TRUE if Ctrl+C is hit */
  205. BOOL Flag_NotSup = FALSE; /* Hunk type is not supported */
  206.  
  207. BOOL FFlag_Exe   = FALSE; /* Will equal TRUE if HUNK_HEADER was encontered */
  208. BOOL FFlag_Obj   = FALSE; /* Will equal TRUE if HUNK_UNIT was encontered */
  209.  
  210. ULONG HunkOrgId  = NULL;  /* Unaltered ID, contains length + bits */
  211. ULONG HunkId     = NULL;  /* Altered ID, contains length only */
  212. ULONG HunkFlags  = NULL;  /* Altered ID, contains bits only */
  213. ULONG HunkOffset = NULL;
  214. ULONG HunkCnt    = NULL;
  215.  
  216. /* Zero all of these */
  217.  
  218. ULONG Cnt_Header       = 0; /* */
  219. ULONG Cnt_Code         = 0; /* */
  220. ULONG Cnt_Data         = 0; /* */
  221. ULONG Cnt_BSS          = 0; /* */
  222. ULONG Cnt_End          = 0; /* */
  223. ULONG Cnt_Overlay      = 0; /* */
  224. ULONG Cnt_Break        = 0; /* */
  225. ULONG Cnt_Symbol       = 0; /* */
  226. ULONG Cnt_SymbolEnt    = 0; /* */
  227. ULONG Cnt_Debug        = 0; /* */
  228. ULONG Cnt_Reloc32      = 0; /* */
  229. ULONG Cnt_Reloc32Ent   = 0; /* Number of entries */
  230. ULONG Cnt_Reloc32Short = 0; /* */
  231. ULONG Cnt_Reloc32SEnt  = 0; /* Number of entries */
  232. ULONG Cnt_DRel32       = 0; /* */
  233. ULONG Cnt_DRel32Ent    = 0; /* */
  234.  
  235. ULONG Cnt_HunksChip    = 0; /* */
  236. ULONG Cnt_HunksFast    = 0; /* */
  237. ULONG Cnt_HunksPub     = 0; /* */
  238. ULONG Cnt_HunksAdv     = 0; /* */
  239.  
  240. ULONG TOTALAlloc = 0;
  241.  
  242. void DumpHunks( BPTR FH )
  243. {
  244.   LONG ReadResult;
  245.  
  246.   do
  247.   {
  248.     HunkOffset = Seek(FH, 0, OFFSET_CURRENT);
  249.  
  250.     if (HunkOffset == -1)
  251.     {
  252.       Flag_Error = TRUE; break;
  253.     }
  254.  
  255.     if ((ReadResult = Read(FH, &HunkOrgId, 4)) == -1)
  256.     {
  257.       Flag_Error = TRUE; break;
  258.     }
  259.  
  260.     if (ReadResult == NULL)
  261.     {
  262.       Flag_EOF=TRUE; break;
  263.     }
  264.  
  265.     HunkId = HunkOrgId;
  266.  
  267.     HunkFlags = HunkId & MASK;  /* extract flag bits from id */
  268.     HunkId &= ~MASK;        /* remove flag bits from id */
  269.  
  270.     switch(HunkId)
  271.     {
  272.       case HUNK_HEADER: DoHUNK_HEADER(FH); break;
  273.       case HUNK_CODE: DoHUNK_CODE(FH); break;
  274.       case HUNK_DATA: DoHUNK_DATA(FH); break;
  275.       case HUNK_BSS: DoHUNK_BSS(FH); break;
  276.       case HUNK_END: DoHUNK_END(FH); break;
  277.       case HUNK_RELOC32: DoHUNK_RELOC32(FH); break;
  278.       case HUNK_RELOC32SHORT: DoHUNK_RELOC32SHORT(FH); break;
  279.       case HUNK_DREL32: DoHUNK_DREL32(FH); break;
  280.  
  281.       case HUNK_OVERLAY: DoHUNK_OVERLAY(FH); break;
  282.       case HUNK_BREAK: DoHUNK_BREAK(FH); break;
  283.       case HUNK_DEBUG: DoHUNK_DEBUG(FH); break;
  284.       case HUNK_SYMBOL: DoHUNK_SYMBOL(FH); break;
  285.  
  286.       case HUNK_UNIT: DoHUNK_UNIT(FH); break;
  287.       case HUNK_NAME: DoHUNK_NAME(FH); break;
  288.       case HUNK_EXT: DoHUNK_EXT(FH); break;
  289.  
  290.       default: DoUNKNOWN(FH); break;
  291.     }
  292.  
  293.   TestAbort();
  294.  
  295.   }
  296.   while(    (Flag_EOF == FALSE)
  297.       &&  (Flag_UEOF == FALSE)
  298.       &&  (Flag_Error == FALSE)
  299.       &&  (Flag_BadId == FALSE)
  300.       &&  (Flag_Break == FALSE)
  301.       &&  (Flag_NotSup == FALSE) );
  302.  
  303.   Printf("\n");
  304.  
  305.   if (Flag_EOF)
  306.   {
  307.     Printf("\t\tEnd of file\n\n");
  308.  
  309.     if (aa[ARG_STATS])
  310.     {
  311.       /* This test does not show all hunks! */
  312.  
  313.       Printf("    Object Type: %s\n"
  314.           "      Amt Hunks: %lu\n"
  315.           "    Hunk_Header: %lu\n"
  316.           "      Hunk_Code: %lu\n"
  317.           "      Hunk_Data: %lu\n"
  318.           "       Hunk_BSS: %lu\n"
  319.           "       Hunk_End: %lu\n"
  320.           "   Hunk_Overlay: %lu\n"
  321.           "     Hunk_Break: %lu\n"
  322.           "    Hunk_Symbol: %lu (total entries: %lu)\n"
  323.           "     Hunk_Debug: %lu\n"
  324.           "   Hunk_Reloc32: %lu (total entries: %lu, %lu bytes)\n"
  325.           " Hunk_Reloc32Sh: %lu (total entries: %lu, %lu bytes)\n"
  326.           "    Hunk_DRel32: %lu (total entries: %lu, %lu bytes)\n"
  327.  
  328.           "   Hunks > Chip: %lu\n"
  329.           "   Hunks > Fast: %lu\n"
  330.           " Hunks > Public: %lu\n"
  331.           " Advisory Hunks: %lu\n"
  332.           "\n"
  333.           " Amount of memory required to load program, approx: %lu (exe only)\n"
  334.           "\n",
  335.         
  336.       (ULONG) (FFlag_Exe ? "Command file" : "Linkable object file"),
  337.       HunkCnt,
  338.  
  339.       Cnt_Header,
  340.       Cnt_Code,
  341.       Cnt_Data,
  342.       Cnt_BSS,
  343.       Cnt_End,
  344.       Cnt_Overlay,
  345.       Cnt_Break,
  346.       Cnt_Symbol,
  347.       Cnt_SymbolEnt,
  348.       Cnt_Debug,
  349.  
  350.       Cnt_Reloc32,
  351.       Cnt_Reloc32Ent,
  352.       Cnt_Reloc32Ent << 2,
  353.  
  354.       Cnt_Reloc32Short,
  355.       Cnt_Reloc32SEnt,
  356.       Cnt_Reloc32SEnt << 2, /* Use real bytes here */
  357.  
  358.       Cnt_DRel32,
  359.       Cnt_DRel32Ent,
  360.       Cnt_DRel32Ent << 2,
  361.  
  362.       Cnt_HunksChip,
  363.       Cnt_HunksFast,
  364.       Cnt_HunksPub,
  365.       Cnt_HunksAdv,
  366.       TOTALAlloc );
  367.     }
  368.  
  369.   }
  370.   else if (Flag_UEOF)
  371.     Printf("\t\tUnexpected end of file, bad file structure!\n\n");
  372.   else if (Flag_Error)
  373.     DoErr();
  374.   else if (Flag_BadId)
  375.     Printf("\t\tEncountered an unknown hunk type!\n");
  376.   else if (Flag_NotSup)
  377.     Printf("\t\tEncountered an unsupported hunk type!\n");
  378. }
  379.  
  380. /***********************************************************************/
  381.  
  382. void DoHUNK_HEADER( BPTR FH )
  383. {
  384.   ULONG HunkATInfo[4];    /* Hunk Allocation Table Info */
  385.   ULONG HunkASize;
  386.   ULONG HunkCnt;
  387.   ULONG HunkRange;
  388.   ULONG AllocFlags;
  389.  
  390.   Cnt_Header++;
  391.  
  392.   FFlag_Exe = TRUE;
  393.  
  394.   Printf("\n\tOffset: 0x%08lx - 0x%08lx - HUNK_HEADER\n",
  395.     HunkOffset, HunkOrgId);
  396.  
  397.   if (MyRead(FH, &HunkATInfo, 4*4)) return; /* Read 4 LONGs */
  398.  
  399.   Printf("\t\tAmt of hunks in alloc table: %lu (%lu to %lu)\n",
  400.     HunkATInfo[1], /* Amt  */
  401.     HunkATInfo[2], /* Rng1 */
  402.     HunkATInfo[3]  /* Rng2 */ );
  403.  
  404.   HunkRange=(HunkATInfo[3]-HunkATInfo[2])+1; /* (Rng2-Rng1) + 1 */
  405.  
  406.   for (HunkCnt = 0; HunkCnt < HunkRange ; HunkCnt++)
  407.   {
  408.     if (MyRead(FH, &HunkASize, 4)) return;
  409.  
  410.     AllocFlags = HunkASize & MASK;    /* Keep alloc flags */
  411.  
  412.     BuildFlagString(HunkASize, TempBuffer);
  413.  
  414.     if (AllocFlags & HUNKF_ADVISORY) Cnt_HunksAdv++;
  415.     else if (AllocFlags & HUNKF_FAST) Cnt_HunksFast++;
  416.     else if (AllocFlags & HUNKF_CHIP) Cnt_HunksChip++;
  417.     else Cnt_HunksPub++;
  418.  
  419.     HunkASize &= ~MASK; /* remove flags */
  420.  
  421.     TOTALAlloc += (HunkASize << 2);
  422.  
  423.     Printf("\t\tHunk %3lu, length %9lu %s\n",
  424.       HunkCnt, HunkASize * 4, &TempBuffer );
  425.  
  426.     if (TestAbort()) return;
  427.   }
  428. }
  429.  
  430. /***********************************************************************/
  431.  
  432. void DoHUNK_CODE( BPTR FH )
  433. {
  434.   ULONG HunkLength;
  435.  
  436.   Cnt_Code++;
  437.  
  438.   Printf("Hnk #%lu\tOffset: 0x%08lx - 0x%08lx - HUNK_CODE\n",
  439.     HunkCnt++, HunkOffset, HunkOrgId );
  440.  
  441.   if (MyRead(FH, &HunkLength, 4)) return;
  442.   
  443.   HunkLength *= 4;
  444.  
  445.   BuildFlagString(HunkOrgId, TempBuffer);
  446.  
  447.   Printf("\t\tRead length - %lu %s\n",
  448.     HunkLength, (ULONG)TempBuffer );
  449.  
  450.   if (MoveForward(FH, HunkLength)) return;
  451. }
  452.  
  453. /***********************************************************************/
  454.  
  455. void DoHUNK_DATA( BPTR FH )
  456. {
  457.   ULONG HunkLength;
  458.  
  459.   Cnt_Data++;
  460.  
  461.   Printf("Hnk #%lu\tOffset: 0x%08lx - 0x%08lx - HUNK_DATA\n",
  462.     HunkCnt++, HunkOffset, HunkOrgId, &stream);
  463.  
  464.   if (MyRead(FH, &HunkLength, 4)) return; HunkLength *= 4;
  465.  
  466.   BuildFlagString(HunkOrgId, TempBuffer);
  467.  
  468.   Printf("\t\tRead length - %lu %s\n",
  469.     HunkLength, TempBuffer );
  470.  
  471.   if (MoveForward(FH, HunkLength)) return;
  472. }
  473.  
  474. /***********************************************************************/
  475.  
  476. void DoHUNK_BSS( BPTR FH )
  477. {
  478.   ULONG HunkLength;
  479.  
  480.   Cnt_BSS++;
  481.  
  482.   Printf("Hnk #%lu\tOffset: 0x%08lx - 0x%08lx - HUNK_BSS\n",
  483.     HunkCnt++, HunkOffset, HunkOrgId );
  484.  
  485.   if (MyRead(FH, &HunkLength, 4)) return; HunkLength*=4;
  486.  
  487.   BuildFlagString(HunkOrgId, TempBuffer);
  488.  
  489.   Printf("\t\tAllocation length - %lu %s\n",
  490.     HunkLength, TempBuffer );
  491. }
  492.  
  493. /***********************************************************************/
  494.  
  495. void DoHUNK_END( BPTR FH )
  496. {
  497.   Cnt_End++;
  498.  
  499.   Printf("\tOffset: 0x%08lx - 0x%08lx - HUNK_END\n",
  500.     HunkOffset, HunkOrgId );
  501. }
  502.  
  503. /***********************************************************************/
  504.  
  505. void DoHUNK_OVERLAY( BPTR FH )
  506. {
  507.   ULONG HunkLength;
  508.  
  509.   Cnt_Overlay++;
  510.  
  511.   Printf("Hnk #%lu\tOffset: 0x%08lx - 0x%08lx - HUNK_OVERLAY\n",
  512.     HunkCnt++, HunkOffset, HunkOrgId );
  513.  
  514.   if (MyRead(FH, &HunkLength, 4)) return; HunkLength*=4;
  515.  
  516.   BuildFlagString(HunkOrgId, TempBuffer);
  517.  
  518.   Printf("\t\tLength - %lu %s\n",
  519.     HunkLength, TempBuffer );
  520.  
  521.   if (MoveForward(FH, HunkLength+4)) return;
  522. }
  523.  
  524. /***********************************************************************/
  525.  
  526. void DoHUNK_BREAK( BPTR FH )
  527. {
  528.   Cnt_Break++;
  529.  
  530.   Printf("\tOffset: 0x%08lx - 0x%08lx - HUNK_BREAK\n",
  531.     HunkOffset, HunkOrgId );
  532. }
  533.  
  534. /***********************************************************************/
  535.  
  536. void DoHUNK_DEBUG( BPTR FH )
  537. {
  538.   ULONG HunkLength;
  539.  
  540.   Cnt_Debug++;
  541.  
  542.   Printf("\tOffset: 0x%08lx - 0x%08lx - HUNK_DEBUG\n",
  543.     HunkOffset, HunkOrgId, &stream);
  544.  
  545.   if (MyRead(FH, &HunkLength, 4)) return; HunkLength *= 4;
  546.  
  547.   BuildFlagString(HunkOrgId, TempBuffer);
  548.  
  549.   Printf("\t\tLength - %lu\n", HunkLength, TempBuffer );
  550.  
  551.   if (MoveForward(FH, HunkLength)) return;
  552. }
  553.  
  554. /***********************************************************************/
  555. /* Length, <........>, Offset */
  556.  
  557. /* TODO: Merge this hunk with HUNK_EXT, because both are identical */
  558.  
  559. void DoHUNK_SYMBOL( BPTR FH )
  560. {
  561.   APTR SymBuf;
  562.   ULONG SymCnt,SymLen,SymOffset;
  563.   ULONG R1,R2;
  564.  
  565.   Cnt_Symbol++;
  566.  
  567.   Printf("\tOffset: 0x%08lx - 0x%08lx - HUNK_SYMBOL\n",
  568.     HunkOffset, HunkOrgId );
  569.  
  570.   for(SymCnt = 0;;)
  571.   {
  572.     if (MyRead(FH, &SymLen, 4)) return;
  573.     if (SymLen == NULL) break;
  574.  
  575.     if (aa[ARG_DSYM])
  576.     {
  577.       if (SymBuf = (APTR)AllocVec( (SymLen + 1) * 4, MEMF_CLEAR))
  578.       {
  579.         R1 = MyRead(FH, SymBuf, SymLen*4);      /* Read symbol */
  580.         R2 = MyRead(FH, &SymOffset, 4);       /* Read offset */
  581.  
  582.         Printf( "\t\t[%-30.30s] at 0x%08lx (%lu)\n",
  583.           SymBuf, SymOffset, SymOffset );
  584.  
  585.         FreeVec(SymBuf);
  586.  
  587.         if (R1 || R2) return;
  588.       }
  589.       else
  590.         if (MoveForward(FH, (SymLen+1)*4)) return;  /* Skip symbol + offset */
  591.     }
  592.     else
  593.       if (MoveForward(FH, (SymLen+1)*4)) return;  /* Skip symbol + offset */
  594.  
  595.     if (TestAbort()) return;
  596.  
  597.     SymCnt++;
  598.   }
  599.  
  600.   Printf("\t\tContains %lu symbol entr%s\n",
  601.     SymCnt, Plural( SymCnt, "y", "ies" ));
  602.  
  603.   Cnt_SymbolEnt += SymCnt;
  604. }
  605.  
  606. /***********************************************************************/
  607. /* Amount, Hunk, <........> */
  608.  
  609. void DoHUNK_RELOC32( BPTR FH )
  610. {
  611.   ULONG RelocAmt,RelocHunk;
  612.   Cnt_Reloc32++;
  613.  
  614.   Printf("\tOffset: 0x%08lx - 0x%08lx - HUNK_RELOC32\n",
  615.     HunkOffset, HunkOrgId );
  616.  
  617.   for(;;)
  618.   {
  619.     if (MyRead(FH, &RelocAmt, 4)) return;
  620.     if (RelocAmt == NULL) break;          /* End of table? */
  621.     if (MyRead(FH, &RelocHunk, 4)) return;
  622.  
  623.     Cnt_Reloc32Ent+=RelocAmt;
  624.  
  625.     Printf("\t\t%lu reference%s to hunk #%lu\n",
  626.           RelocAmt, Plural(RelocAmt, "", "s"), RelocHunk );
  627.  
  628.     if (aa[ARG_DREL])
  629.     {
  630.       while (RelocAmt--)
  631.       {
  632.         ULONG Rel32;
  633.         
  634.         if (MyRead(FH, &Rel32, 4)) return;
  635.  
  636.         Printf("\t\tRelocate offset 0x%08lx using hunk base #%lu\n",
  637.           Rel32, RelocHunk );
  638.  
  639.         if (TestAbort()) return;
  640.       }
  641.     }
  642.     else if (MoveForward(FH, RelocAmt*4)) return;
  643.   }
  644. }
  645.  
  646. /***********************************************************************/
  647.  
  648. void DoHUNK_DREL32( BPTR FH )
  649. {
  650.   UWORD RelocAmt, RelocHunk, RelocEntry;
  651.   ULONG POF;
  652.  
  653.   Printf("\tOffset: 0x%08lx - 0x%08lx - HUNK_DREL32\n",
  654.     HunkOffset, HunkOrgId );
  655.  
  656.   Cnt_DRel32++;
  657.  
  658.   for(;;)
  659.   {   
  660.     if (MyRead(FH, &RelocAmt, 2)) return;
  661.     if (RelocAmt == NULL) break;        /* End of table? */
  662.     if (MyRead(FH, &RelocHunk, 2)) return;
  663.  
  664.     Cnt_DRel32Ent += RelocAmt;
  665.  
  666.     Printf("\t\t%lu reference%s to hunk #%lu\n",
  667.       (ULONG) RelocAmt,
  668.       Plural(RelocAmt, "", "s"),
  669.       (ULONG) RelocHunk );
  670.  
  671.     stream[1] = RelocHunk;
  672.  
  673.     if (aa[ARG_DREL])
  674.     {
  675.       while (RelocAmt--)
  676.       {
  677.         if (MyRead(FH, &RelocEntry, 2)) return;
  678.  
  679.         Printf("\t\tRelocate offset 0x%04lx using hunk base #%lu\n",
  680.           (ULONG) RelocEntry, (ULONG) RelocHunk );
  681.  
  682.         if (TestAbort()) return;
  683.       }
  684.     }
  685.     else if (MoveForward(FH, RelocAmt*2)) return;
  686.   }
  687.  
  688.   POF = Seek(FH, 0, OFFSET_CURRENT);
  689.  
  690.   /* If we are not on a LONG boundary then align... */
  691.  
  692.   if ((POF >> 2) << 2 != POF)
  693.     if (MoveForward(FH, 2)) return;   /* Alignment fix */
  694.  
  695. }
  696.  
  697. /***********************************************************************/
  698.  
  699. void DoHUNK_RELOC32SHORT( BPTR FH )
  700. {
  701.   UWORD RelocAmt,RelocHunk;
  702.   UWORD RelocEntry;
  703.   ULONG POF;
  704.  
  705.   Cnt_Reloc32Short++;
  706.  
  707.   Printf("\tOffset: 0x%08lx - 0x%08lx - HUNK_RELOC32SHORT\n",
  708.     (ULONG) HunkOffset, (ULONG) HunkOrgId );
  709.  
  710.   for(;;)
  711.   {
  712.     if (MyRead(FH, &RelocAmt, 2)) return;
  713.     if (RelocAmt == NULL) break;        /* End of table? */
  714.     if (MyRead(FH, &RelocHunk, 2)) return;
  715.  
  716.     Cnt_Reloc32SEnt += RelocAmt;
  717.  
  718.     Printf("\t\t%lu reference%s to hunk #%lu\n",
  719.       (ULONG)RelocAmt,
  720.       Plural(RelocAmt, "", "s"),
  721.       (ULONG)RelocHunk );
  722.  
  723.     stream[1] = RelocHunk;
  724.  
  725.     if (aa[ARG_DREL])
  726.     {
  727.       while (RelocAmt--)
  728.       {
  729.         if (MyRead(FH, &RelocEntry, 2)) return;
  730.  
  731.         Printf("\t\tRelocate offset 0x%04lx using hunk base #%lu\n",
  732.           (ULONG) RelocEntry, (ULONG) RelocHunk );
  733.  
  734.         if (TestAbort()) return;
  735.       }
  736.     }
  737.     else if (MoveForward(FH, RelocAmt * 2)) return;
  738.   }
  739.  
  740.   POF = Seek(FH, 0, OFFSET_CURRENT);
  741.  
  742.   /* If we are not on a LONG boundary then align... */
  743.  
  744.   if ((POF >> 2) << 2 != POF)
  745.     if (MoveForward(FH, 2)) return;   /* Alignment fix */
  746. }
  747.  
  748. /***********************************************************************/
  749.  
  750. void DoHUNK_UNIT( BPTR FH )
  751. {
  752.   ULONG NameLen;
  753.   APTR NameBuf;
  754.  
  755.   FFlag_Obj = TRUE;
  756.  
  757.   Printf("\tOffset: 0x%08lx - 0x%08lx - HUNK_UNIT\n",
  758.     HunkOffset, HunkOrgId );
  759.  
  760.   if (MyRead(FH, &NameLen, 4)) return;    /* Get length of name */
  761.  
  762.   if ( NameBuf = (APTR) AllocVec( (NameLen + 1) * 4, MEMF_CLEAR) )
  763.   {
  764.     if (MyRead(FH, NameBuf, NameLen*4)) return;
  765.     Printf("\t\tUnit name: %.40s\n", NameBuf);
  766.     FreeVec(NameBuf);
  767.   }
  768.   else if (MoveForward(FH, NameLen*4)) return;
  769. }
  770.  
  771. /***********************************************************************/
  772.  
  773. void DoHUNK_NAME( BPTR FH )
  774. {
  775.   ULONG NameLen;
  776.   APTR NameBuf;
  777.  
  778.   Printf("\tOffset: 0x%08lx - 0x%08lx - HUNK_NAME\n",
  779.     HunkOffset, HunkOrgId );
  780.  
  781.   if (MyRead(FH, &NameLen, 4)) return;    /* Get length of name */
  782.  
  783.   if (NameBuf = (APTR) AllocVec((NameLen+1)*4, MEMF_CLEAR))
  784.   {
  785.     if (MyRead(FH, NameBuf, NameLen*4)) return;
  786.  
  787.     Printf("\t\tHunk name: %.40s\n", NameBuf);
  788.  
  789.     FreeVec(NameBuf);
  790.   }
  791.   else if (MoveForward(FH, NameLen*4)) return;
  792. }
  793.  
  794. /***********************************************************************/
  795.  
  796. #define EXT_NEWCOMMON 4  /* 5? */
  797.  
  798. void DoHUNK_EXT( BPTR FH )
  799. {
  800.   APTR  ExtTypeStr;
  801.   UBYTE ExtType;
  802.   UWORD ExtLen;
  803.   ULONG ExtOffset;
  804.   ULONG RefCnt;
  805.   ULONG ComSize;
  806.   APTR  ExtSymBuf;
  807.  
  808.   ULONG R1,R2,R3;   /* Results, Used for IO error checking */
  809.  
  810.   Printf("\tOffset: 0x%08lx - 0x%08lx - HUNK_EXT\n",
  811.     HunkOffset, HunkOrgId );
  812.  
  813.   for (;;)
  814.   {
  815.     R1 = MyRead(FH, &ExtType, 1);   /* Read ext type */
  816.     R2 = MoveForward(FH, 1);      /* Alignment fix */
  817.     R3 = MyRead(FH, &ExtLen, 2);    /* Read ext length */
  818.  
  819.     if (R1 || R2 || R3) return;
  820.  
  821.     if (ExtLen == NULL) break;  /* End of ext hunk? */
  822.  
  823.     switch(ExtType)
  824.     {
  825.       case EXT_SYMB: ExtTypeStr = "EXT_SYMB"; goto XDEF;
  826.       case EXT_DEF:  ExtTypeStr = "EXT_DEF";  goto XDEF;
  827.       case EXT_ABS:  ExtTypeStr = "EXT_ABS";  goto XDEF;
  828.       case EXT_RES:  ExtTypeStr = "EXT_RES";
  829.  
  830.         XDEF:   /* sym def, XDEF */
  831.  
  832.         if (ExtSymBuf = (APTR)AllocVec((ExtLen+2)*4, MEMF_CLEAR))
  833.         {
  834.           R1 = MyRead(FH, ExtSymBuf, (ExtLen*4));   /* Read ext symbol */
  835.           R2 = MyRead(FH, &ExtOffset, 4);       /* Read common size */
  836.  
  837.           if (aa[ARG_DEXT])
  838.           {
  839.             Printf("\t\t%-14.14s [%-30.30s] = 0x%08lx\n",         
  840.               (ULONG) ExtTypeStr, (ULONG) ExtSymBuf, ExtOffset );
  841.           }
  842.           FreeVec(ExtSymBuf);
  843.           if (R1 || R2) return;
  844.         }
  845.         else
  846.         {
  847.           R1 = MyRead(FH, &ExtOffset, 4); /* Read common size */
  848.           R2 = MoveForward(FH, ExtLen*4); /* Skip ext symbol */
  849.           if (R1 || R2) return;
  850.         }
  851.         break;
  852.  
  853.       case EXT_COMMON: ExtTypeStr = "EXT_COMMON";
  854.         COMMONREF:  /* common ref */
  855.  
  856.         if (ExtSymBuf = (APTR) AllocVec((ExtLen+2)*4, MEMF_CLEAR))
  857.         {
  858.           R1 = MyRead(FH, ExtSymBuf ,(ExtLen*4)+4);   /* Read ext symbol to buffer */
  859.           R2 = MyRead(FH, &ComSize, 4);         /* Read common size */
  860.           R3 = MyRead(FH, &RefCnt, 4);            /* Read ref count */
  861.           R3 = MoveForward(FH, RefCnt*4);         /* Skip reference entries */
  862.  
  863.           if (aa[ARG_DEXT]) /* Does use want to see ext info? */
  864.           {
  865.             Printf("\t\t%-14.14s [%-30.30s] cs: %lu ref%s: %lu\n",
  866.               (ULONG) ExtTypeStr,
  867.               (ULONG) ExtSymBuf,
  868.               (ULONG) Plural(RefCnt, "", "s"),
  869.               ComSize,
  870.               RefCnt ); /* Check text bounds */
  871.           }
  872.           FreeVec(ExtSymBuf);
  873.           if (R1 || R2 || R3) return;
  874.         }
  875.         else  /* If unable to alloc sym buf then Seek() */
  876.         {
  877.           R1 = MoveForward(FH, (ExtLen*4)+8); /* Skip symbol + common size*/
  878.           R2 = MoveForward(FH, 4);        /* Skip ref count */
  879.           R3 = MoveForward(FH, RefCnt*4);   /* Skip refs */
  880.           if (R1 || R2 || R3) return;
  881.         }
  882.         break;
  883.  
  884.       case EXT_REF32:     ExtTypeStr = "EXT_REF32";     goto XREF;
  885.       case EXT_REF16:     ExtTypeStr = "EXT_REF16";     goto XREF;
  886.       case EXT_REF8:      ExtTypeStr = "EXT_REF8";      goto XREF;
  887.       case EXT_DEXT32:    ExtTypeStr = "EXT_DEXT32";    goto XREF;
  888.       case EXT_DEXT16:    ExtTypeStr = "EXT_DEXT16";    goto XREF;
  889.       case EXT_DEXT8:     ExtTypeStr = "EXT_DEXT8";     goto XREF;
  890.       case EXT_RELREF32:  ExtTypeStr = "EXT_RELREF32";  goto XREF;
  891.       case EXT_RELCOMMON: ExtTypeStr = "EXT_RELCOMMON"; goto XREF;
  892.       case EXT_ABSREF16:  ExtTypeStr = "EXT_ABSREF16";  goto XREF;
  893.       case EXT_ABSREF8:   ExtTypeStr = "EXT_ABSREF8"; 
  894.  
  895.         XREF: /* sym ref, XREF */
  896.  
  897.         if (ExtSymBuf = (APTR) AllocVec((ExtLen*4)+4, MEMF_CLEAR))
  898.         {
  899.           R1 = MyRead(FH, ExtSymBuf, ExtLen*4); /* Read symbol */
  900.           R2 = MyRead(FH, &RefCnt, 4);        /* Read ref count */
  901.           R3 = MoveForward(FH, RefCnt*4);     /* Skip references */
  902.  
  903.           if (aa[ARG_DEXT])
  904.           {
  905.             Printf("\t\t%-14.14s [%-30.30s] ref%s: %lu\n",
  906.               (ULONG) ExtTypeStr,
  907.               (ULONG) ExtSymBuf,
  908.               (ULONG) Plural(RefCnt, "", "s"),
  909.               RefCnt ); /* Check text bounds */
  910.           }
  911.           FreeVec(ExtSymBuf);
  912.           
  913.           if (R1 || R2 || R3) return;
  914.         }
  915.         else
  916.         {
  917.           R1 = MoveForward(FH, ExtLen*4);   /* Skip symbol */
  918.           R2 = MyRead(FH, &RefCnt, 4);      /* Get ref count */
  919.           R3 = MoveForward(FH, RefCnt*4);   /* Skip references */
  920.           if (R1 || R2 || R3) return;
  921.         }
  922.         break;
  923.     }
  924.     if (TestAbort()) break;
  925.   }
  926.  
  927. }
  928.  
  929. /***********************************************************************/
  930.  
  931. void DoUNKNOWN( BPTR FH )
  932. {
  933.   Printf("\tOffset: 0x%08lx - 0x%08lx - Unknown hunk!!!\n",
  934.     HunkOffset, HunkOrgId );
  935.     
  936.   Flag_BadId = TRUE;
  937. }
  938.  
  939. /***********************************************************************/
  940.  
  941. ULONG MoveForward( BPTR FH, LONG Length)
  942. {
  943.   LONG Result = Seek(FH, Length, OFFSET_CURRENT);
  944.  
  945.   if (Result == -1)
  946.   {
  947.     Flag_Error = TRUE;
  948.     return(-1);
  949.   }
  950.   else
  951.     return(NULL);
  952. }
  953.  
  954. /***********************************************************************/
  955.  
  956. BOOL TestAbort( void )
  957. {
  958.   if (CheckSignal(SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C)
  959.   {
  960.     Printf("\n***Break:\n\n");
  961.     Flag_Break = TRUE;
  962.     return(TRUE);
  963.   }
  964.   else
  965.     return(FALSE);
  966. }
  967.  
  968. /***********************************************************************/
  969.  
  970. void BuildFlagString( ULONG Flags, UBYTE *Buf)
  971. {
  972.   /* move.b d0,(a3)+ \n rts */
  973.   
  974.   static UWORD putChProc[] = { 0x16c0, 0x4e75 };
  975.  
  976.   stream[0] = (ULONG)"";
  977.   stream[1] = (ULONG)"";
  978.   stream[2] = (ULONG)"";
  979.  
  980.   Flags &= MASK;        /* remove unwanted size */
  981.  
  982.   if (Flags & HUNKF_CHIP)
  983.     stream[0] = (ULONG)"[Load to Chip] ";
  984.   if (Flags & HUNKF_FAST)
  985.     stream[1] = (ULONG)"[Load to Fast] ";
  986.   if (Flags & HUNKF_ADVISORY)
  987.     stream[2] = (ULONG)"[Advisory]";
  988.  
  989.  
  990.  
  991.   RawDoFmt("%s%s%s", &stream, (void *) &putChProc, Buf);
  992. }
  993.  
  994. /***********************************************************************/
  995.  
  996. LONG MyRead( BPTR FH, APTR Buf, ULONG Length)
  997. {
  998.   LONG Result;
  999.   
  1000.   if (!Length) return 0;  /* If user passes NULL, then return */
  1001.  
  1002.   Result = FRead(FH, Buf, Length, 1);
  1003.  
  1004.   if (Result != 1)
  1005.   {
  1006.     Flag_UEOF = TRUE;
  1007.     return -1;  /* Not OK */
  1008.   }
  1009.   else
  1010.   {
  1011.     return 0;   /* OK */
  1012.   }
  1013. }
  1014.  
  1015. /***********************************************************************/
  1016.  
  1017. UBYTE *Plural( ULONG Val, UBYTE *One, UBYTE *Many)
  1018. {
  1019.   if (Val == 1) return(One); else return(Many);
  1020. }
  1021.  
  1022.  
  1023.  
  1024.