home *** CD-ROM | disk | FTP | other *** search
/ Magazyn Exec 5 / CD_Magazyn_EXEC_nr_5.iso / Recent / dev / moni / HunkFunc.lha / HunkFunc / Source / HunkFunc.c next >
C/C++ Source or Header  |  2001-06-04  |  17KB  |  644 lines

  1. #define NAME     "HunkFunc"
  2. #define REVISION "13"
  3.  
  4. /* Programmheader
  5.  
  6.     Name:        HunkFunk
  7.     Author:        SDI
  8.     Distribution:    PD
  9.     Description:    object/binary file scanner
  10.     Compileropts:    -
  11.     Linkeropts:    -gsi -l amiga
  12.  
  13.  1.0   12.02.98 : made with help of Olaf 'Olsen' Barthel's HunkFunk
  14.  1.1   23.03.98 : now prints reloc infos
  15.  1.2   23.11.98 : added new overlay format
  16.  1.3   09.12.98 : added CHIP, FAST, ADVISORY to CODE/DATA/BSS hunks
  17.  1.4   28.12.98 : unknown hunk now prints 8 digits
  18.  1.5   30.08.99 : 4 new switches for command line, fixed lots of stuff
  19.  1.6   13.09.99 : better support for Overlay files
  20.  1.7   15.09.99 : changed overlay support, added SOVT keyword
  21.  1.8   27.09.99 : displays extra stuff message
  22.  1.9   03.11.99 : added number of EXT_REF's
  23.  1.10  13.11.99 : added H&P EHF stuff
  24.  1.11  29.11.99 : added CTRL_C to reloc print
  25.  1.12  26.06.00 : added abort for defective relocs, fixed overflow bugs
  26.  1.13  03.06.01 : added EXT_REF display
  27. */
  28.  
  29. #include <proto/dos.h>
  30. #include <proto/exec.h>
  31. #include <exec/memory.h>
  32. #include <dos/doshunks.h>
  33. #include "SDI_version.h"
  34. #define SDI_TO_ANSI
  35. #include "SDI_ASM_STD_protos.h"
  36.  
  37. /* CHIP, FAST and ADVISORY information is repeated in hunk itself. If
  38. the word is used normally, the information is in second longword (size).
  39. If it is preceeded by a '_', the information is in first longword (hunk
  40. type). */
  41.  
  42. #define PARAM "FILE/M/A,SREL=SHOWRELOC/S,SSYM=SHOWSYMBOL/S,SEXT=SHOWEXTERN/S,SOVT=SHOWOVERLAYTABLE/S,STATS/S"
  43.  
  44. /* Some simple macros. */
  45. #define ReadLong(Type)      Read(FileHandle, (Type), 4)
  46. #define ReadWord(Type)      Read(FileHandle, (Type), 2)
  47. #define ReadName(Longs)   Read(FileHandle, NameString, 4 * (Longs))
  48. #define SkipLong(Longs)   Seek(FileHandle, 4 * (Longs), OFFSET_CURRENT)
  49. #define SkipWord(Words)      Seek(FileHandle, 2* (Words), OFFSET_CURRENT)
  50. #define SkipByte(Bytes)      Seek(FileHandle, (Bytes), OFFSET_CURRENT)
  51. #define MakeName(Longs)   NameString[(Longs) * 4] = 0
  52. #define GetHunkName(Type) HunkNames[(Type)-HUNK_UNIT]
  53. #define CTRL_C          (SetSignal(0L,0L) & SIGBREAKF_CTRL_C)
  54.  
  55. STRPTR HunkNames[] = { /* access them with HunkNames[Type-HUNK_UNIT] */
  56. "HUNK_UNIT",    "HUNK_NAME",    "HUNK_CODE",    "HUNK_DATA",    "HUNK_BSS", 
  57. "HUNK_(ABS)RELOC32",    "HUNK_(REL)RELOC16",    "HUNK_(REL)RELOC8",    "HUNK_EXT",    "HUNK_SYMBOL",
  58. "HUNK_DEBUG",    "HUNK_END",    "HUNK_HEADER",    "",        "HUNK_OVERLAY",
  59. "HUNK_BREAK",    "HUNK_DREL32",    "HUNK_DREL16",    "HUNK_DREL8",    "HUNK_LIB",
  60. "HUNK_INDEX",    "HUNK_RELOC32SHORT",    "HUNK_RELRELOC32",    "HUNK_ABSRELOC16",
  61. "HUNK_DREL32EXE"
  62. };
  63.  
  64. #define HUNK_DREL32EXE    (HUNK_ABSRELOC16+1)
  65.  
  66. #define HUNK_PPC_CODE    0x4E9
  67. #define HUNK_RELRELOC26    0x4EC
  68. #define EXT_RELREF26    229
  69.  
  70. struct Args {
  71.   STRPTR * files;
  72.   ULONG    showreloc;
  73.   ULONG    showsymbol;
  74.   ULONG    showextern;
  75.   ULONG       showoverlaytable;
  76.   ULONG    stats;
  77. };
  78.  
  79. struct Stats {
  80.   ULONG Header;
  81.   ULONG Unit;
  82.   ULONG Lib;
  83.   ULONG Code;
  84.   ULONG Data;
  85.   ULONG BSS;
  86.   ULONG Debug;
  87.   ULONG Symbol;
  88.   ULONG Extern;
  89.   ULONG Reloc;
  90.   ULONG NumSymbol;
  91.   ULONG NumReloc;
  92.   ULONG NumExtern;
  93.   ULONG CodeSize;
  94.   ULONG DataSize;
  95.   ULONG BSSSize;
  96.   ULONG DebugSize;
  97.   ULONG PPCCode;
  98.   ULONG PPCCodeSize;
  99. };
  100.  
  101. struct DosLibrary *DOSBase = 0;
  102. struct ExecBase * SysBase  = 0;
  103.  
  104. STRPTR GetTabs(STRPTR);
  105. void ShowStats(struct Stats *);
  106. LONG ProcessFile(ULONG, ULONG, ULONG, ULONG, ULONG, struct Stats *);
  107.  
  108. ULONG start(void)
  109. {
  110.   ULONG ret = RETURN_FAIL;
  111.   struct DosLibrary *dosbase;
  112.   SysBase = (*((struct ExecBase **) 4));
  113.  
  114.   { /* test for WB and reply startup-message */
  115.     struct Process *task;
  116.     if(!(task = (struct Process *) FindTask(0))->pr_CLI)
  117.     {
  118.       WaitPort(&task->pr_MsgPort);
  119.       Forbid();
  120.       ReplyMsg(GetMsg(&task->pr_MsgPort));
  121.       return RETURN_FAIL;
  122.     }
  123.   }
  124.  
  125.   if((dosbase = (struct DosLibrary *) OpenLibrary("dos.library", 37)))
  126.   {
  127.     struct Args args;
  128.     struct RDArgs *rda;
  129.  
  130.     DOSBase = dosbase;
  131.  
  132.     memset(&args, 0, sizeof(struct Args));
  133.     if((rda = ReadArgs(PARAM, (LONG *) &args, 0)))
  134.     {
  135.       ret = 0;
  136.       while(*args.files)
  137.       {
  138.         ULONG err, fh;
  139.  
  140.         if((fh = Open(*args.files, MODE_OLDFILE)))
  141.         {
  142.       struct Stats stats;
  143.  
  144.           Printf("File '%s':\n", *args.files);
  145.           memset(&stats, 0, sizeof(struct Stats));
  146.           err = ProcessFile(fh, args.showreloc, args.showsymbol, args.showextern, args.showoverlaytable, &stats);
  147.           if(err == 2)
  148.             Printf("Unexpected end of file.\n");
  149.           if(args.stats)
  150.             ShowStats(&stats);
  151.           Close(fh);
  152.         }
  153.         else
  154.           PrintFault(IoErr(), *args.files);
  155.         if(CTRL_C)
  156.           SetIoErr(ERROR_BREAK);
  157.         ++args.files;
  158.       }
  159.     }
  160.     
  161.     if(ret)
  162.       PrintFault(IoErr(), 0);
  163.  
  164.     CloseLibrary((struct Library *) dosbase);
  165.   }
  166.   return ret;
  167. }
  168.  
  169. STRPTR GetTabs(STRPTR NameString)
  170. {
  171.   ULONG i = 0;
  172.  
  173.   while(*(NameString++) && i < 24)
  174.    ++i;
  175.   i >>= 3;
  176.   
  177.   return "\t\t\t"+i;
  178. }
  179.  
  180. void ShowStats(struct Stats *stats)
  181. {
  182.   Printf("STATISTICS:\nFile type\t");
  183.   if(stats->PPCCode)
  184.     Printf("PPC-WOS Objectfile");
  185.   else if(stats->Header)
  186.     Printf("Executable");
  187.   else if(stats->Lib)
  188.     Printf("New style link library");
  189.   else if(stats->Unit > 1)
  190.     Printf("Old style link library");
  191.   else
  192.     Printf("Objectfile");
  193.   Printf("\n");
  194.  
  195.   Printf("HUNK_CODE\t%6ld with total %6ld ($%06lx) Bytes\n", stats->Code, stats->CodeSize, stats->CodeSize);
  196.   if(stats->PPCCode)
  197.     Printf("HUNK_PPC_CODE\t%6ld with total %6ld ($%06lx) Bytes\n", stats->PPCCode, stats->PPCCodeSize, stats->PPCCodeSize);
  198.   Printf("HUNK_DATA\t%6ld with total %6ld ($%06lx) Bytes\n", stats->Data, stats->DataSize, stats->DataSize);
  199.   Printf("HUNK_BSS\t%6ld with total %6ld ($%06lx) Bytes\n", stats->BSS, stats->BSSSize, stats->BSSSize);
  200.   Printf("HUNK_DEBUG\t%6ld with total %6ld ($%06lx) Bytes\n", stats->Debug, stats->DebugSize, stats->DebugSize);
  201.   Printf("HUNK_EXT\t%6ld with total %6ld entr%s\n", stats->Extern, stats->NumExtern, stats->NumExtern == 1 ? "y" : "ies");
  202.   Printf("HUNK_RELOC\t%6ld with total %6ld entr%s\n", stats->Reloc, stats->NumReloc, stats->NumReloc == 1 ? "y" : "ies");
  203.   Printf("HUNK_SYMBOL\t%6ld with total %6ld entr%s\n", stats->Symbol, stats->NumSymbol, stats->NumSymbol == 1 ? "y" : "ies");
  204. }
  205.  
  206. /* return 0 on error */
  207. LONG ProcessFile(ULONG FileHandle, ULONG showreloc, ULONG showsymbol, ULONG showextern, ULONG showoverlaytable,
  208. struct Stats *stats)
  209. {
  210.   ULONG Type, Data, i;
  211.   UBYTE NameString[257];
  212.  
  213.   while(!CTRL_C)
  214.   {
  215.     if((i = ReadLong(&Type)) != 4)
  216.     {
  217.       if(i)
  218.         Printf("There %s %ld extra byte%s at end of file.\n", i == 1 ? "is" : "are", i, i == 1 ? "" : "s");
  219.       return 0;
  220.     }
  221.  
  222.     if(Type == HUNK_DREL32 && stats->Header)
  223.       Type = HUNK_DREL32EXE;
  224.  
  225.     /* Look which type it is. */
  226.     switch(Type & 0xFFFF)
  227.     {
  228.     case HUNK_UNIT:
  229.       ++stats->Unit;
  230.       ReadLong(&Data);
  231.       if(Data)
  232.         ReadName(Data);
  233.       MakeName(Data);
  234.       Printf("%s\t\"%s\"\n\n", GetHunkName(Type), NameString);
  235.       break;
  236.     case HUNK_NAME:
  237.       ReadLong(&Data);
  238.       if(Data)
  239.         ReadName(Data);
  240.       MakeName(Data);
  241.       Printf("%s\t\"%s\"\n", GetHunkName(Type), NameString);
  242.       break;
  243.     case HUNK_LIB:
  244.       ++stats->Lib;
  245.       ReadLong(&Data);
  246.       Printf("%s\t%6ld ($%06lx) Bytes\n\n", GetHunkName(Type), Data, Data);
  247.       break;
  248.     case HUNK_INDEX:
  249.       {
  250.         UWORD dat2;
  251.  
  252.         ReadLong(&Data);
  253.         Printf("%s\t%6ld ($%06lx) Bytes\n", GetHunkName(Type), Data, Data);
  254.         ReadWord(&dat2);
  255.         SkipByte((Data*4)-2);
  256.     Printf("  Textsize =\t%6ld Bytes\n\n", dat2);
  257.       }
  258.       break;
  259.     case HUNK_CODE: case HUNK_DATA: case HUNK_BSS:
  260.       ReadLong(&Data);
  261.       i = Data;
  262.       Data <<= 2;
  263.       Data &= 0x7FFFFFFF;
  264.       switch(Type&0xFFFF)
  265.       {
  266.       case HUNK_CODE: ++stats->Code; stats->CodeSize += Data; SkipByte(Data); break;
  267.       case HUNK_DATA: ++stats->Data; stats->DataSize += Data; SkipByte(Data); break;
  268.       case HUNK_BSS: ++stats->BSS; stats->BSSSize += Data; break;
  269.       }
  270.       Printf("%s\t%6ld ($%06lx) Bytes", GetHunkName(Type), Data, Data);
  271.       if(Type & HUNKF_CHIP)        Printf(" _CHIP");
  272.       if(Type & HUNKF_FAST)        Printf(" _FAST");
  273.       if(Type & HUNKF_ADVISORY)     Printf(" _ADVISORY");
  274.       if(i & HUNKF_CHIP)        Printf(" CHIP");
  275.       if(i & HUNKF_FAST)        Printf(" FAST");
  276.       if(i & HUNKF_ADVISORY)         Printf(" ADVISORY");
  277.       Printf("\n");
  278.       break;
  279.     case HUNK_PPC_CODE:
  280.       ReadLong(&Data);
  281.       i = Data;
  282.       Data <<= 2;
  283.       Data &= 0x7FFFFFFF;
  284.       ++stats->PPCCode; stats->PPCCodeSize += Data;
  285.       SkipByte(Data);
  286.       Printf("HUNK_PPC_CODE\t%6ld ($%06lx) Bytes", Data, Data);
  287.       if(Type & HUNKF_CHIP)        Printf(" _CHIP");
  288.       if(Type & HUNKF_FAST)        Printf(" _FAST");
  289.       if(Type & HUNKF_ADVISORY)     Printf(" _ADVISORY");
  290.       if(i & HUNKF_CHIP)        Printf(" CHIP");
  291.       if(i & HUNKF_FAST)        Printf(" FAST");
  292.       if(i & HUNKF_ADVISORY)         Printf(" ADVISORY");
  293.       Printf("\n");
  294.       break;
  295.     case HUNK_RELRELOC32: case HUNK_ABSRELOC16: case HUNK_RELRELOC26:
  296.     case HUNK_RELOC32: case HUNK_RELOC16: case HUNK_RELOC8:
  297.     case HUNK_DREL32: case HUNK_DREL16: case HUNK_DREL8:
  298.       if(Type == HUNK_RELRELOC26)
  299.         Printf("HUNK_RELRELOC26\n");
  300.       else
  301.         Printf("%s\n", GetHunkName(Type));
  302.       ++stats->Reloc;
  303.  
  304.       do
  305.       {
  306.     if(ReadLong(&Data) != 4)
  307.       return 2;
  308.     if(Data)
  309.     {
  310.       ULONG dat2 = 0, dat3;
  311.       ReadLong(&dat2);
  312.       stats->NumReloc += Data;
  313.       Printf("  Summary\t%6ld entr%s to hunk %ld%s\n", Data,
  314.       Data == 1 ? "y" : "ies", dat2, Data > 0xFFFF ? " (LoadSeg fails)" : "");
  315.       if(showreloc)
  316.       {
  317.         for(dat3 = Data; dat3 && !CTRL_C; --dat3)
  318.         {
  319.           if(ReadLong(&dat2) != 4)
  320.             return 2;
  321.           Printf("  Offset\t\t$%08lx\n", dat2);
  322.         }
  323.       }
  324.       else
  325.         SkipLong(Data);
  326.     }
  327.       } while(!CTRL_C && Data);
  328.       break;
  329.     case HUNK_RELOC32SHORT: case HUNK_DREL32EXE:
  330.       {
  331.         UWORD Data = 0;
  332.         ULONG nums = 0;
  333.         Printf("%s\n", GetHunkName(Type));
  334.         ++stats->Reloc;
  335.  
  336.         do
  337.         {
  338.       UWORD dat2 = 0;
  339.       ULONG dat3;
  340.       if(ReadWord(&Data) != 2)
  341.         return 2;
  342.       if(Data)
  343.       {
  344.             ReadWord(&dat2);
  345.             stats->NumReloc += Data;
  346.         Printf("  Summary\t%6ld entr%s to hunk %ld\n", Data,
  347.         Data == 1 ? "y" : "ies", dat2);
  348.         if(showreloc)
  349.         {
  350.           for(dat3 = Data; dat3 && !CTRL_C; --dat3)
  351.           {
  352.             if(ReadWord(&dat2) != 2)
  353.               return 2;
  354.             Printf("  Offset\t\t$%04lx\n", dat2);
  355.           }
  356.         }
  357.         else
  358.           SkipWord(Data);
  359.         nums += Data;
  360.       }
  361.         } while(!CTRL_C && Data);
  362.         if(!(nums & 1))
  363.           SkipWord(1);
  364.       }
  365.       break;
  366.     case HUNK_EXT:
  367.       Printf("HUNK_EXT\n");
  368.       ++stats->Extern;
  369.  
  370.       do
  371.       {
  372.     LONG i;
  373.  
  374.         ReadLong(&Data);
  375.         if(!Data)
  376.       break;
  377.     ++stats->NumExtern;
  378.     if(showextern)
  379.     {
  380.           switch((Data >> 24) & 0xFF)
  381.       {
  382.       case EXT_DEF:       Printf("  EXT_DEF"); break;
  383.       case EXT_ABS:       Printf("  EXT_ABS"); break;
  384.       case EXT_RES:       Printf("  EXT_RES"); break;
  385.       case EXT_REF32:     Printf("  EXT_REF32"); break;
  386.       case EXT_COMMON:    Printf("  EXT_COMMON"); break;
  387.       case EXT_REF16:     Printf("  EXT_REF16"); break;
  388.       case EXT_REF8:      Printf("  EXT_REF8"); break;
  389.       case EXT_DEXT32:    Printf("  EXT_DEXT32"); break;
  390.       case EXT_DEXT16:    Printf("  EXT_DEXT16"); break;
  391.       case EXT_DEXT8:     Printf("  EXT_DEXT8"); break;
  392.       case EXT_RELREF32:  Printf("  EXT_RELREF32"); break;
  393.       case EXT_RELREF26:  Printf("  EXT_RELREF26"); break;
  394.       case EXT_RELCOMMON: Printf("  EXT_RELCOMMON"); break;
  395.       default: Printf("  EXT_??? ($%02x)\n",(Data >> 24) & 0xFF);
  396.         break;
  397.           }
  398.         }
  399.  
  400.     /* Is it followed by a symbol name? */
  401.  
  402.     if(Data & 0xFFFFFF)
  403.     {
  404.       ReadName(Data & 0xFFFFFF);
  405.       MakeName(Data & 0xFFFFFF);
  406.       if(showextern)
  407.             Printf("\t%s", NameString);
  408.         }
  409.  
  410.     /* Remember extension type. */
  411.         i = (Data >> 24) & 0xFF;
  412.  
  413.     /* Display value of symbol. */
  414.         if(i == EXT_DEF || i == EXT_ABS || i == EXT_RES)
  415.         {
  416.       if(!(Data & 0xFFFFFF) && showextern)
  417.         Printf("\t???");
  418.  
  419.       ReadLong(&Data);
  420.       if(showextern)
  421.         Printf("%s= $%08lx", GetTabs(NameString), Data);
  422.     }
  423.  
  424.     /* Skip relocation information. */
  425.         if(i == EXT_REF32 || i == EXT_REF16 || i == EXT_REF8 ||
  426.         i == EXT_DEXT32 || i == EXT_DEXT16 || i == EXT_DEXT8 ||
  427.         i == EXT_RELREF32 || i == EXT_RELREF26)
  428.     {
  429.       ReadLong(&Data);
  430.       if(showextern)
  431.       {
  432.         ULONG d;
  433.  
  434.         if(Data > 1)
  435.         {
  436.           Printf("%s= %ld entries", GetTabs(NameString), Data);
  437.           while(Data--)
  438.           {
  439.             ReadLong(&d);
  440.             Printf("\n\t\t%s= $%08lx", GetTabs(""), d);
  441.           }
  442.         }
  443.         else
  444.         {
  445.           ReadLong(&d);
  446.           Printf("%s= $%08lx (1 entry)", GetTabs(NameString), d);
  447.         }
  448.       }
  449.       else
  450.         SkipLong(Data);
  451.     }
  452.  
  453.     /* Display size of common block. */
  454.         if(i == EXT_COMMON || i == EXT_RELCOMMON)
  455.     {
  456.       ReadLong(&Data);
  457.  
  458.       if(showextern)
  459.         Printf("\tSize = %ld Bytes", Data << 2);
  460.       ReadLong(&Data);
  461.       SkipLong(Data);
  462.     }
  463.     if(showextern)
  464.           Printf("\n");
  465.       } while(!CTRL_C);
  466.       break;
  467.     case HUNK_SYMBOL:
  468.       Printf("HUNK_SYMBOL\n");
  469.       ++stats->Symbol;
  470.  
  471.       do
  472.       {
  473.     ReadLong(&Data);
  474.  
  475.     if(!Data)
  476.       break;
  477.  
  478.     ++stats->NumSymbol;
  479.     /* Display name. */
  480.         ReadName(Data & 0xFFFFFF);
  481.         MakeName(Data & 0xFFFFFF);
  482.  
  483.     if(showsymbol)
  484.           Printf("  Symbol\t%s", NameString);
  485.  
  486.     /* Display value. */
  487.         ReadLong(&Data);
  488.  
  489.     if(showsymbol)
  490.       Printf("%s= $%08lx\n", GetTabs(NameString), Data);
  491.       } while(!CTRL_C);
  492.       break;
  493.     case HUNK_DEBUG:
  494.       ++stats->Debug;
  495.       ReadLong(&Data);
  496.       SkipLong(Data);
  497.       Data <<= 2;
  498.       stats->DebugSize += Data;
  499.       Printf("HUNK_DEBUG\t%6ld ($%06lx) Bytes\n", Data, Data);
  500.       break;
  501.     case HUNK_END:
  502.       Printf("HUNK_END\n\n");
  503.       break;
  504.     case HUNK_HEADER:
  505.       Printf("HUNK_HEADER\n");
  506.  
  507.       ++stats->Header;
  508.  
  509.       do
  510.       {
  511.         ULONG data2;
  512.  
  513.     if(ReadLong(&Data) != 4)
  514.       return 2;
  515.  
  516.     /* Display names of resident libraries. */
  517.         if(!Data)
  518.           break;
  519.  
  520.     if((data2 = Data) > 64)
  521.       data2 = 64;
  522.     Data -= data2;
  523.  
  524.     if(ReadName(data2) != 4*data2)
  525.       return 2;
  526.     if(Data && SkipLong(Data) < 0)
  527.       return 2;
  528.     MakeName(data2);
  529.  
  530.     Printf("  Name =\t%s\n", NameString);
  531.       } while(!CTRL_C);
  532.  
  533.       if(!CTRL_C)
  534.       {
  535.         LONG i,From,To;
  536.  
  537.         ReadLong(&Data);
  538.  
  539.     Printf("  Numhunks =\t%6ld (", Data);
  540.         ReadLong(&From);
  541.         Printf("%ld to ", From);
  542.         ReadLong(&To);
  543.         Printf("%ld)\n",To);
  544.  
  545.         /* Display hunk lengths/types. */
  546.         for(i = 0; !CTRL_C && i < To - From + 1; ++i)
  547.         {
  548.       ReadLong(&Data);
  549.           Printf("  Hunk %03ld =\t%6ld ($%06lx) Bytes", i,
  550.           (Data & 0x3FFFFFFF) << 2, (Data & 0x3FFFFFFF) << 2);
  551.  
  552.       if((Data & HUNKF_CHIP) && (Data & HUNKF_FAST))
  553.       {    /* extended type */
  554.         ULONG t;
  555.         ReadLong(&t);
  556.         Printf(" MEMTYPE($%08lx)", t);
  557.       }
  558.       else
  559.       {
  560.             if(Data & HUNKF_CHIP)    Printf(" CHIP");
  561.             if(Data & HUNKF_FAST)    Printf(" FAST");
  562.           }
  563.           if(Data & HUNKF_ADVISORY)    Printf(" ADVISORY");
  564.  
  565.       Printf("\n");
  566.         }
  567.         Printf("\n");
  568.       }
  569.       break;
  570.     case HUNK_OVERLAY:
  571.       {
  572.         LONG TabSize, Data, Data2 = 0;
  573.         ULONG *ovt = 0;
  574.         Printf("HUNK_OVERLAY\n");
  575.         ReadLong(&TabSize);
  576.  
  577.     Printf("  TableSize\t%6ld ($%06lx) Bytes\n", TabSize*4, TabSize*4);
  578.  
  579.     if(TabSize)
  580.     {
  581.       ReadLong(&Data2);
  582.       if(showoverlaytable && (ovt = (ULONG *) AllocVec(TabSize*4, MEMF_ANY)))
  583.         Read(FileHandle, ovt, TabSize*4);
  584.       else
  585.         SkipLong(TabSize);
  586.     }
  587.     ReadLong(&Data);
  588.     if(!TabSize && Data == HUNK_BREAK)
  589.     {
  590.       Data = Seek(FileHandle, 0, OFFSET_END);
  591.       Data = Seek(FileHandle, 0, OFFSET_END) - Data;
  592.       Printf("HUNK_BREAK\n\nLeft Space\t%6ld ($%06lx) Bytes\n", Data, Data);
  593.     }
  594.     else if(TabSize && Data >= HUNK_UNIT && Data <= HUNK_ABSRELOC16)
  595.     {
  596.       Seek(FileHandle, -4, OFFSET_CURRENT);
  597.       Printf("  Levels\t%6ld\n", Data2-2);
  598.       Printf("  Entries\t%6ld\n", (TabSize-Data2+1) >> 3);
  599.     }
  600.     else
  601.     {
  602.       Data = Seek(FileHandle, 0, OFFSET_END);
  603.       Data = Seek(FileHandle, 0, OFFSET_END) - Data;
  604.       Printf("  DataSize\t%6ld ($%06lx) Bytes\n", Data+8, Data+8);
  605.       if(ovt)
  606.       {
  607.         for(Data = TabSize-1; Data; --Data)
  608.           ovt[Data] = ovt[Data-1];
  609.         ovt[0] = Data2;
  610.       }
  611.     }
  612.     if(ovt)
  613.     {
  614.       Data2 = 0;
  615.       while(Data2 < TabSize)
  616.       {
  617.         Printf("  Data $%04lx\t", Data2*4);
  618.         for(Data = 0; Data < 4; ++Data)
  619.         {
  620.           if(Data2 < TabSize)
  621.           {
  622.             Printf("%08lx%s", ovt[Data2], Data2 < TabSize-1 ? " " : "");
  623.             ++Data2;
  624.           }
  625.         }
  626.         Printf("\n");
  627.       }
  628.       FreeVec(ovt);
  629.     }
  630.     Printf("\n");
  631.       }
  632.       break;
  633.     case HUNK_BREAK:
  634.       Printf("HUNK_BREAK\n\n");
  635.       break;
  636.     default:
  637.       Printf("HUNK_??? ($%08lx) - Aborting!\n\n", Type);
  638.       return 1;
  639.     }
  640.   }
  641.  
  642.   return 0;
  643. }
  644.