home *** CD-ROM | disk | FTP | other *** search
/ APDL Public Domain 1 / APDL_PD1A.iso / program / dde / aofutils / c / Analyse
Encoding:
Text File  |  1992-05-14  |  21.5 KB  |  913 lines

  1. /* > Analyse */
  2.  
  3. /* Released to Public Domain by David McQuillan */
  4.  
  5. /* cc -DANALYSE  -> object code analyser                     */
  6. /*                  analyse AOF_file                         */
  7. /* cc -DRETAIN   -> utility to retain only a list of globals */
  8. /*                  retain AOF_file names_file               */
  9. /* cc -DSUPPRESS -> utility to suppress a list of globals    */
  10. /*                  suppress AOF_file names_file             */
  11. /* names_file is a space comma or newline separated list of  */
  12. /* names which are global in the object file.                */
  13. /* The object file is overwritten by Retain and Suppress     */
  14.  
  15.  
  16. #include <setjmp.h>
  17. #include <signal.h>
  18. #include <stdio.h>
  19. #include <stdlib.h>
  20. #include <string.h>
  21. #include <kernel.h>
  22.  
  23.  
  24. typedef unsigned char bool;
  25.  
  26. #define FALSE 0
  27. #define TRUE 1
  28.  
  29. typedef struct
  30. {
  31.     jmp_buf js;
  32. } jmp_struct;
  33.  
  34. static jmp_struct err_jmp;
  35.  
  36.  
  37. /* Format of a chunk file header - first few bytes of a chunk file */
  38.  
  39. typedef struct chunk_file_header_entry
  40. {
  41.     unsigned ChunkIDPrefix;
  42.     unsigned ChunkIDType;
  43.     unsigned FileOffset;
  44.     unsigned Size;
  45. } chunk_file_header_entrys;
  46.  
  47. typedef struct chunk_file_header
  48. {
  49.     unsigned ChunkField;
  50.     unsigned maxChunks;
  51.     unsigned numChunks;
  52.     struct chunk_file_header_entry entry[1];
  53. } chunk_file_headers;
  54.  
  55. #define ChunkFileID      (0xC3CBC6C5)
  56. #define ChunkID_LIB      (0x5F42494C)   /* (unsigned)('LIB_') */
  57. #define ChunkID_OFL      (0x5F4C464F)   /* (unsigned)('OFL_') */
  58. #define ChunkID_OBJ      (0x5F4A424F)   /* (unsigned)('OBJ_') */
  59. #define ChunkID_LIB_DIRY (0x59524944)   /* (unsigned)('DIRY') */
  60. #define ChunkID_LIB_TIME (0x454D4954)   /* (unsigned)('TIME') */
  61. #define ChunkID_LIB_VRSN (0x4E535256)   /* (unsigned)('VRSN') */
  62. #define ChunkID_LIB_DATA (0x41544144)   /* (unsigned)('DATA') */
  63. #define ChunkID_OFL_SYMT (0x544D5953)   /* (unsigned)('SYMT') */
  64. #define ChunkID_OFL_TIME (0x454D4954)   /* (unsigned)('TIME') */
  65. #define ChunkID_OBJ_HEAD (0x44414548)   /* (unsigned)('HEAD') */
  66. #define ChunkID_OBJ_AREA (0x41455241)   /* (unsigned)('AREA') */
  67. #define ChunkID_OBJ_IDFN (0x4E464449)   /* (unsigned)('IDFN') */
  68. #define ChunkID_OBJ_SYMT (0x544D5953)   /* (unsigned)('SYMT') */
  69. #define ChunkID_OBJ_STRT (0x54525453)   /* (unsigned)('STRT') */
  70.  
  71. #define ChunkFile_HdrSize(hdr_ptr) \
  72.         (sizeof (struct chunk_file_header) + \
  73.         ((hdr_ptr)->maxChunks - 1) * sizeof (struct chunk_file_header_entry))
  74.  
  75. typedef struct lib_diry_entry
  76. {
  77.     unsigned ChunkIndex;
  78.     unsigned EntryLength;
  79.     unsigned DataLength;
  80.     char LibData[1];
  81. } lib_diry_entrys;
  82.  
  83. #define Lib_DataName(ptr) (char *)((ptr)->LibData)
  84. #define Lib_DataTime(ptr) ((struct lib_TimeStamp *)((ptr)->LibData + \
  85.                           ( (strlen((ptr)->LibData)+4) & ~0x03 ) ) )
  86.  
  87. typedef struct lib_TimeStamp
  88. {
  89.     char t[8];
  90. } lib_TimeStamps;
  91.  
  92. typedef struct ofl_symt_entry
  93. {
  94.     unsigned ChunkIndex;
  95.     unsigned EntryLength;
  96.     unsigned DataLength;
  97.     char Name[1];
  98. } ofl_symt_entrys;
  99.  
  100. typedef struct obj_file_header_entry
  101. {
  102.     unsigned AreaName;
  103.     unsigned Attributes;
  104.     unsigned AreaSize;
  105.     unsigned numRelocations;
  106.     unsigned unused;
  107. } obj_file_header_entrys;
  108.  
  109. typedef struct obj_file_header
  110. {
  111.     unsigned Type;
  112.     unsigned Version;
  113.     unsigned numAreas;
  114.     unsigned numSymbols;
  115.     unsigned EntryArea;
  116.     unsigned EntryOffset;
  117.     struct obj_file_header_entry entry[1];
  118. } obj_file_headers;
  119.  
  120. #define ObjFileType (0xC5E2D080)
  121.  
  122. typedef struct obj_symt_entry
  123. {
  124.     unsigned Name;
  125.     unsigned Attributes;
  126.     unsigned Value;
  127.     unsigned AreaName;
  128. } obj_symt_entrys;
  129.  
  130.  
  131. /*
  132.  *  interrupt
  133.  */
  134.  
  135. static void interrupt(int type)
  136. {
  137.     switch (type)
  138.     {
  139.         case SIGINT:
  140.         printf("\nEscape pressed\n");
  141.         break;
  142.     default:
  143.         printf("\nSignal type %d\n", type);
  144.     }
  145.     longjmp(err_jmp.js, 1);
  146. }
  147.  
  148.  
  149. /*
  150.  *  Load a file into store
  151.  *  *len is initialised with extra to add.
  152.  */
  153.  
  154. static void *LoadFile(char *name, unsigned *len)
  155. {
  156.     _kernel_osfile_block o_b;
  157.     void *adr;
  158.     int ret;
  159.  
  160.     ret = _kernel_osfile(5, name, &o_b);
  161.  
  162.     if (ret == 0)
  163.     {
  164.         fprintf(stderr, "File %s does not exist\n", name);
  165.         return NULL;
  166.     }
  167.     else if (ret == 2)
  168.     {
  169.         fprintf(stderr, "File %s is a directory\n", name);
  170.         return NULL;
  171.     }
  172.  
  173.     /* Load the file  */
  174.  
  175.     *len += o_b.start;
  176.  
  177.     adr = malloc(*len);
  178.  
  179.     o_b.load = (int) adr;
  180.     o_b.exec = 0;
  181.  
  182.     _kernel_osfile(255, name, &o_b);
  183.  
  184.     return adr;
  185. }
  186.  
  187.  
  188. /*
  189.  *  Save file from store
  190.  */
  191.  
  192. static void SaveFile(char *name, void *adr, int len, int type)
  193. {
  194.     _kernel_osfile_block o_b;
  195.     int ret;
  196.  
  197.     /* Save the file  */
  198.  
  199.     o_b.load = type;
  200.     o_b.exec = 0;
  201.     o_b.start = (int) adr;
  202.     o_b.end = o_b.start + len;
  203.  
  204.     ret = _kernel_osfile(10, name, &o_b);
  205.  
  206.     if (ret < 0)
  207.     {
  208.         fprintf(stderr, "Error code %d when saving file %s\n", ret, name);
  209.         exit(EXIT_FAILURE);
  210.     }
  211.  
  212.     return;
  213. }
  214.  
  215.  
  216. /*
  217.  *  dump
  218.  */
  219.  
  220. static void dump(unsigned adr_start, unsigned adr_end)
  221. {
  222.     char line[80];
  223.  
  224.     sprintf(line, "memory %X %X", adr_start, adr_end);
  225. #ifdef ANALYSE
  226.     system(line);
  227. #endif
  228. }
  229.  
  230. /*
  231.  * converts the calendar time pointed to by timer to local time in the form
  232.  * of a string. It is equivalent to asctime(sys_localtime(timer));
  233.  */
  234.  
  235. static char *lib_ctime(lib_TimeStamps * timer)
  236. {
  237.     _kernel_swi_regs r;
  238.     char t[5];
  239.     static char p[30];
  240.  
  241.     t[0] = timer->t[6];
  242.     t[1] = timer->t[7];
  243.     t[2] = timer->t[0];
  244.     t[3] = timer->t[1];
  245.     t[4] = timer->t[2];
  246.  
  247.     r.r[0] = (int) t;
  248.     r.r[1] = (int) p;
  249.     r.r[2] = 30;
  250.     r.r[3] = (int) "%w3 %m3 %dy %24:%mi:%se %ce%yr";
  251.  
  252.     _kernel_swi(0xC1, &r, &r);
  253.  
  254.     return p;
  255. }
  256.  
  257.  
  258. /*
  259.  *  chunk pointers
  260.  */
  261.  
  262. static chunk_file_headers *hdr_area;
  263. static unsigned hdr_maxc;
  264. static unsigned lib_diry;
  265. static unsigned lib_diry_size;
  266. static unsigned ofl_symt;
  267. static unsigned ofl_symt_size;
  268. static unsigned obj_vrsn;
  269. static unsigned obj_head;
  270. static unsigned obj_area;
  271. static unsigned obj_symt;
  272. static unsigned obj_symt_size;
  273. static unsigned obj_strt;
  274. static unsigned entry_area;
  275. static unsigned entry_disp;
  276.  
  277.  
  278. /*
  279.  *  Retained or Suppressed Names
  280.  */
  281.  
  282. static char *names[1000];
  283. static int names_cnt;
  284.  
  285. static int compare_pnames(const void *ps1, const void *ps2)
  286. {
  287.     return strcmp(*(char **)ps1, *(char **)ps2);
  288. }
  289.  
  290.  
  291. /*
  292.  *  print_file_header
  293.  */
  294.  
  295. static bool print_file_head(unsigned area, bool setup)
  296. {
  297.     chunk_file_headers *hdr = (chunk_file_headers *) area;
  298.     unsigned maxc;
  299.     unsigned chunk;
  300.  
  301. #ifdef ANALYSE
  302.     printf("\n");
  303.  
  304.     printf("Chunk File check %08X\n", hdr->ChunkField);
  305. #endif
  306.  
  307.     if (hdr->ChunkField != ChunkFileID)
  308.     {
  309.         printf("Start not 0x%08X\n", ChunkFileID);
  310.         return FALSE;
  311.     }
  312.  
  313.     maxc = hdr->maxChunks;
  314.  
  315.     if (setup)
  316.     {
  317.         hdr_area = hdr;
  318.         hdr_maxc = maxc;
  319.     }
  320.  
  321. #ifdef ANALYSE
  322.     printf("Max chunks %d, Num chunks %d\n\n", maxc, hdr->numChunks);
  323. #endif
  324.  
  325.     for (chunk = 0; chunk < maxc; ++chunk)
  326.     {
  327.         chunk_file_header_entrys *entry = &hdr->entry[chunk];
  328.         unsigned Prefix, Type, Offset, Size;
  329.  
  330.         Prefix = entry->ChunkIDPrefix;
  331.         Type = entry->ChunkIDType;
  332.         Offset = entry->FileOffset;
  333.         Size = entry->Size;
  334.  
  335.         if (Offset != 0)
  336.         {
  337.             unsigned ao = area + Offset;
  338.  
  339. #ifdef ANALYSE
  340.             printf("%.8s %8X %8X\n", &entry->ChunkIDPrefix, Offset, Size);
  341. #endif
  342.  
  343.             if (!setup)
  344.             {
  345.                 /* don't set up static ponters  */
  346.             }
  347.             else if (Prefix == ChunkID_LIB)
  348.             {
  349.                 if (Type == ChunkID_LIB_DIRY)
  350.                 {
  351.                     lib_diry = ao;
  352.                     lib_diry_size = Size;
  353.                 }
  354.             }
  355.             else if (Prefix == ChunkID_OFL)
  356.             {
  357.                 if (Type == ChunkID_OFL_SYMT)
  358.                 {
  359.                     ofl_symt = ao;
  360.                     ofl_symt_size = Size;
  361.                 }
  362.             }
  363.             else if (Prefix == ChunkID_OBJ)
  364.             {
  365.                 switch (Type)
  366.                 {
  367.                 case ChunkID_OBJ_HEAD:
  368.                     {
  369.                         obj_file_headers *obj = (obj_file_headers *) ao;
  370.  
  371.                         entry_area = obj->EntryArea-1;
  372.                         entry_disp = obj->EntryOffset;
  373.  
  374.                         obj_head = ao;
  375.                     }
  376.                     break;
  377.                 case ChunkID_OBJ_AREA:
  378.                     obj_area = ao;
  379.                     break;
  380.                 case ChunkID_OBJ_SYMT:
  381.                     obj_symt = ao;
  382.                     obj_symt_size = Size;
  383.                     break;
  384.                 case ChunkID_OBJ_STRT:
  385.                     obj_strt = ao;
  386.                     break;
  387.                 default:
  388.                     break;
  389.                 }
  390.             }
  391.         }
  392.     }
  393.     return TRUE;
  394. }
  395.  
  396.  
  397. /*
  398.  *  print_lib_diry
  399.  */
  400.  
  401. static void print_lib_diry(unsigned ao, unsigned size, int chunk)
  402. {
  403.     unsigned aend = ao + size;
  404.  
  405. #ifdef ANALYSE
  406.     printf("\n");
  407. #endif
  408.  
  409.     while (ao < aend)
  410.     {
  411.         lib_diry_entrys *p = (lib_diry_entrys *) ao;
  412.  
  413.         if (p->ChunkIndex != 0 && (chunk < 0 || chunk == p->ChunkIndex))
  414.         {
  415. #ifdef ANALYSE
  416.             printf("%s %8X  %s\n", lib_ctime(Lib_DataTime(p)),
  417.                    p->ChunkIndex, Lib_DataName(p));
  418. #endif
  419.         }
  420.  
  421.         ao += p->EntryLength;
  422.     }
  423. }
  424.  
  425.  
  426. /*
  427.  *  print_ofl_symt
  428.  */
  429.  
  430. static void print_ofl_symt(unsigned ao, unsigned size, int chunk)
  431. {
  432.     unsigned aend = ao + size;
  433.  
  434. #ifdef ANALYSE
  435.     printf("\n");
  436. #endif
  437.  
  438.     while (ao < aend)
  439.     {
  440.         ofl_symt_entrys *p = (ofl_symt_entrys *) ao;
  441.  
  442.         if (chunk < 0 || chunk == p->ChunkIndex)
  443.         {
  444. #ifdef ANALYSE
  445.             printf("%6X  %s\n", p->ChunkIndex, p->Name);
  446. #endif
  447.         }
  448.  
  449.         ao += p->EntryLength;
  450.     }
  451. }
  452.  
  453.  
  454. /*
  455.  *  print_obj_symt
  456.  */
  457.  
  458. static void print_obj_symt(unsigned ao, unsigned Size, int req_area)
  459. {
  460.     obj_file_headers *obj = (obj_file_headers *) obj_head;
  461.     unsigned numSymbols = Size / sizeof(obj_symt_entrys);
  462.     obj_symt_entrys *symt = (obj_symt_entrys *) ao;
  463.     unsigned symbol;
  464.     bool any_done = FALSE;
  465.  
  466.     if (req_area == entry_area || req_area == -1)
  467.     {
  468. #ifdef ANALYSE
  469.         printf("\n");
  470.         if (entry_area == -1)
  471.             printf("No entry point\n");
  472.         else
  473.             printf("Entry: %8X %6X  %s\n", entry_disp, entry_area,
  474.                 (char *)(obj_strt + obj->entry[entry_area].AreaName));
  475. #endif
  476.     }
  477.  
  478.     for (symbol = 0; symbol < numSymbols; ++symbol)
  479.     {
  480.         obj_symt_entrys *entry = &symt[symbol];
  481.         unsigned Attr = entry->Attributes;
  482.         unsigned area = 0;
  483.         char *areaz = "";
  484.         bool do_print = (req_area < 0);
  485.  
  486.         if ((Attr & 4) == 0 && (Attr & 1) == 1)
  487.         {
  488.             int i;
  489.             int start_i = 0;
  490.             int end_i = obj->numAreas - 1;
  491.  
  492.             if (!do_print)
  493.                 end_i = start_i = req_area;
  494.  
  495.             for (i = start_i; i <= end_i; ++i)
  496.             {
  497.                 if (entry->AreaName == obj->entry[i].AreaName)
  498.                 {
  499.                     area = i;
  500.                     areaz = (char *) (obj_strt + entry->AreaName);
  501.                     do_print = TRUE;
  502.                 }
  503.             }
  504.         }
  505.  
  506.         if (do_print)
  507.         {
  508.             if (!any_done)
  509.             {
  510. #ifdef ANALYSE
  511.                 printf("\n");
  512. #endif
  513.                 any_done = TRUE;
  514.             }
  515.  
  516. #ifdef ANALYSE
  517.             printf("%2X %c%c%c%c%c%c %8X %8X %6X  %-16.16s %6X  %s\n",
  518.                    Attr, "x.XG"[Attr & 3], ".A"[(Attr >> 2) & 1], ".c"[(Attr >> 3) & 1],
  519.                    ".W"[(Attr >> 4) & 1], ".S"[(Attr >> 5) & 1], ".C"[(Attr >> 6) & 1],
  520.                    entry->Value, entry->AreaName, area, areaz, symbol,
  521.                    (char *) (obj_strt + entry->Name));
  522. #endif
  523.  
  524. #ifdef RETAIN
  525.             if ((Attr & 3) == 3)
  526.             {
  527.                 const char *entry_name = (char *) (obj_strt + entry->Name);
  528.  
  529.                 if (bsearch(&entry_name, names, names_cnt, 4,
  530.                         &compare_pnames) == NULL)
  531.                     entry->Attributes ^= 2;  /* 3 -> 1 */
  532.             }
  533. #endif
  534.  
  535. #ifdef SUPPRESS
  536.             if ((Attr & 3) == 3)
  537.             {
  538.                 const char *entry_name = (char *) (obj_strt + entry->Name);
  539.  
  540.                 if (! bsearch(&entry_name, names, names_cnt, 4,
  541.                         &compare_pnames) == NULL)
  542.                     entry->Attributes ^= 2;  /* 3 -> 1 */
  543.             }
  544. #endif
  545.         }
  546.         ao += sizeof(obj_symt_entrys);
  547.     }
  548. }
  549.  
  550.  
  551. /*
  552.  *  print_obj_area
  553.  */
  554.  
  555. static void print_obj_area(obj_file_headers * obj, unsigned ao)
  556. {
  557.     obj_symt_entrys *symt = (obj_symt_entrys *) obj_symt;
  558.     int area;
  559.  
  560. #ifdef ANALYSE
  561.     if (ao == 0)
  562.         printf("\n");
  563. #endif
  564.  
  565.     for (area = 0; area < obj->numAreas; ++area)
  566.     {
  567.         obj_file_header_entrys *entry = &obj->entry[area];
  568.         unsigned Attributes = entry->Attributes;
  569.  
  570. #ifdef ANALYSE
  571.         if (ao != 0)
  572.             printf("\nAREA %6X\n\n", area);
  573.  
  574.         printf("%8X %c%c%c%c%c%c %8X %8X %8X %6X  %s\n",
  575.                Attributes,
  576.                (Attributes & 0x0200 ? 'C' : 'D'),
  577.                (Attributes & 0x0400 ? 'c' : '.'),
  578.                (Attributes & 0x0800 ? 'R' : '.'),
  579.                (Attributes & 0x1000 ? 'N' : '.'),
  580.                (Attributes & 0x2000 ? 'R' : 'W'),
  581.                (Attributes & 0x8000 ? 'd' : '.'),
  582.                entry->AreaSize,
  583.                entry->numRelocations,
  584.                entry->unused,
  585.                area,
  586.                (char *) (obj_strt + entry->AreaName));
  587. #endif
  588.  
  589.         if (ao != 0)
  590.             print_obj_symt(obj_symt, obj_symt_size, area);
  591.  
  592.         if (ao != 0 && (Attributes & 0x1800) == 0)
  593.         {
  594.             char *namez;
  595.             int j;
  596.  
  597.             dump(ao, ao + entry->AreaSize);
  598.             ao = (ao + entry->AreaSize + 3) & -4;
  599.  
  600. #ifdef ANALYSE
  601.             if (entry->numRelocations != 0)
  602.                 printf("\nRelocations\n\n");
  603. #endif
  604.  
  605.             for (j = 0; j < entry->numRelocations; ++j)
  606.             {
  607.                 unsigned Offset = *(int *) ao;
  608.                 unsigned Action = *(int *) (ao + 4);
  609.                 unsigned Type, Additive, Reloc, Field, SID;
  610.  
  611.                 if (Action & 0x80000000)
  612.                 {
  613.                     Type = 2;
  614.                     Field = (Action >> 24) & 3;
  615.                     Reloc = (Action >> 26) & 1;
  616.                     Additive = (Action >> 27) & 1;
  617.                     SID = Action & 0xFFFFFF;
  618.                 }
  619.                 else
  620.                 {
  621.                     Type = 1;
  622.                     Field = (Action >> 16) & 3;
  623.                     Reloc = (Action >> 18) & 1;
  624.                     Additive = (Action >> 19) & 1;
  625.                     SID = Action & 0xFFFF;
  626.                 }
  627.  
  628.                 if (Type == 1 && Reloc == 0 && Additive == 0)
  629.                     namez = "";
  630.                 else if (Type == 2 && Additive == 0)
  631.                 {
  632.                     namez = (char *) (obj_strt + obj->entry[SID].AreaName);
  633.                 }
  634.                 else
  635.                 {
  636.                     namez = (char *) (obj_strt + symt[SID].Name);
  637.                 }
  638.  
  639. #ifdef ANALYSE
  640.                 printf("%8X %8X T%1X %c%c%c %6X  %s\n",
  641.                        Offset, Action,
  642.                        Type, "BH.x"[Field], "AP"[Reloc], ".S"[Additive],
  643.                        SID, namez);
  644. #endif
  645.                 ao += 8;
  646.             }
  647.         }
  648.     }
  649. }
  650.  
  651.  
  652. /*
  653.  *  main
  654.  */
  655.  
  656. extern int main(int argn, char *argv[])
  657. {
  658.     char *infile, *namesfile;
  659.     unsigned area, len;
  660.     unsigned namesarea, nameslen;
  661.     unsigned chunk;
  662.  
  663.     /* Initialisation  */
  664.  
  665.     if (setjmp(err_jmp.js))
  666.     {
  667.         exit(0);
  668.     }
  669.     signal(SIGINT, *interrupt);
  670.  
  671.     lib_diry = 0;
  672.     lib_diry_size = 0;
  673.     ofl_symt = 0;
  674.     ofl_symt_size = 0;
  675.     obj_vrsn = 150;
  676.     obj_head = 0;
  677.     obj_area = 0;
  678.     obj_symt = 0;
  679.     obj_symt_size = 0;
  680.     obj_strt = 0;
  681.  
  682. #ifdef ANALYSE
  683.     if (argn < 2 || argn > 2)
  684.     {
  685.         printf("Syntax is *analyse objfile\n");
  686.         exit(0);
  687.     }
  688. #endif
  689.  
  690. #ifdef RETAIN
  691.     if (argn < 3 || argn > 3)
  692.     {
  693.         printf("Syntax is *retain objfile namesfile\n");
  694.         exit(0);
  695.     }
  696. #endif
  697.  
  698. #ifdef SUPPRESS
  699.     if (argn < 3 || argn > 3)
  700.     {
  701.         printf("Syntax is *suppress objfile namesfile\n");
  702.         exit(0);
  703.     }
  704. #endif
  705.  
  706.     infile = argv[1];
  707.  
  708.     len = 0;
  709.     area = (unsigned) LoadFile(infile, &len);
  710.     if (area == NULL)
  711.     {
  712.         fprintf(stderr, "File %s not loaded\n", infile);
  713.         exit(0);
  714.     }
  715.  
  716. #if defined(RETAIN) || defined(SUPPRESS)
  717.  
  718.     namesfile = argv[2];
  719.  
  720.     nameslen = 1;
  721.     namesarea = (unsigned) LoadFile(namesfile, &nameslen);
  722.     if (namesarea == NULL)
  723.     {
  724.         fprintf(stderr, "File %s not loaded\n", namesfile);
  725.         exit(0);
  726.     }
  727.     *(char *)(namesarea+nameslen-1) = 0;
  728.  
  729.     {
  730.         char *name;
  731.  
  732.         names_cnt = 0;
  733.         name = strtok((char *)namesarea, ", \n\t");
  734.         while (name != NULL)
  735.         {
  736.             names[names_cnt++] = name;
  737.             name = strtok(NULL, " \n\t");
  738.         }
  739.     }
  740.  
  741.     qsort(names, names_cnt, 4, compare_pnames);
  742.  
  743. #endif
  744.  
  745. #ifdef ANALYSE
  746.     printf("\nFile %s\n", infile);
  747. #endif
  748.  
  749.     if (!print_file_head(area, TRUE))
  750.         exit(0);
  751.  
  752.     for (chunk = 0; chunk < hdr_maxc; ++chunk)
  753.     {
  754.         chunk_file_header_entrys *entry = &hdr_area->entry[chunk];
  755.         unsigned Prefix, Type, Offset, Size;
  756.  
  757.         Prefix = entry->ChunkIDPrefix;
  758.         Type = entry->ChunkIDType;
  759.         Offset = entry->FileOffset;
  760.         Size = entry->Size;
  761.  
  762.         if (Offset != 0)
  763.         {
  764.             unsigned ao0, ao, aend;
  765.             char *namez;
  766.  
  767. #ifdef ANALYSE
  768.             printf("\n%.8s %8X %8X\n", &entry->ChunkIDPrefix, Offset, Size);
  769. #endif
  770.  
  771.             ao = area + Offset;
  772.             aend = ao + Size;
  773.  
  774.             switch (Prefix)
  775.             {
  776.             case ChunkID_LIB:
  777.                 switch (Type)
  778.                 {
  779.                 case ChunkID_LIB_TIME:
  780. #ifdef ANALYSE
  781.                     printf("\nTime %s\n", lib_ctime((lib_TimeStamps *) ao));
  782. #endif
  783.                     break;
  784.                 case ChunkID_LIB_VRSN:
  785. #ifdef ANALYSE
  786.                     printf("\nVersion %d\n", *(int *) ao);
  787. #endif
  788.                     break;
  789.                 case ChunkID_LIB_DIRY:
  790.                     print_lib_diry(ao, Size, -1);
  791.                     break;
  792.                 case ChunkID_LIB_DATA:
  793.                     {
  794.                         print_lib_diry(lib_diry, lib_diry_size, chunk);
  795.  
  796.                         if (ofl_symt_size != 0)
  797.                         {
  798. #ifdef ANALYSE
  799.                             printf("\nEntries\n");
  800. #endif
  801.                             print_ofl_symt(ofl_symt, ofl_symt_size, chunk);
  802.                         }
  803.  
  804. #ifdef ANALYSE
  805.                         printf("\n");
  806. #endif
  807.                         print_file_head(ao, FALSE);
  808.                     }
  809.                     break;
  810.                 default:
  811.                     dump(ao, aend);
  812.                 }
  813.                 break;
  814.  
  815.             case ChunkID_OFL:
  816.                 switch (Type)
  817.                 {
  818.                 case ChunkID_OFL_TIME:
  819. #ifdef ANALYSE
  820.                     printf("\nTime %s\n", lib_ctime((lib_TimeStamps *) ao));
  821. #endif
  822.                     break;
  823.                 case ChunkID_OFL_SYMT:
  824.                     print_ofl_symt(ao, Size, -1);
  825.                     break;
  826.                 default:
  827.                     dump(ao, aend);
  828.                 }
  829.                 break;
  830.  
  831.             case ChunkID_OBJ:
  832.                 switch (Type)
  833.                 {
  834.                 case ChunkID_OBJ_HEAD:
  835.                     {
  836.                         obj_file_headers *obj = (obj_file_headers *) ao;
  837.  
  838. #ifdef ANALYSE
  839.                         printf("\nObject file type %08X\n", obj->Type);
  840.                         if (obj->Type != ObjFileType)
  841.                             printf(" !=  0x%08X\n", ObjFileType);
  842.                         printf("Version Number   %d\n", obj->Version);
  843.                         printf("Number of areas  %d\n", obj->numAreas);
  844.                         printf("No. of symbols   %d\n", obj->numSymbols);
  845.                         printf("Entry address info. %8X %8X\n",
  846.                                obj->EntryArea, obj->EntryOffset);
  847. #endif
  848.  
  849.                         obj_vrsn = obj->Version;
  850.                         print_obj_area(obj, 0);
  851.                     }
  852.                     break;
  853.                 case ChunkID_OBJ_AREA:
  854.                     {
  855.                         obj_file_headers *obj = (obj_file_headers *) obj_head;
  856.  
  857.                         print_obj_area(obj, ao);
  858.                     }
  859.                     break;
  860.                 case ChunkID_OBJ_IDFN:
  861. #ifdef ANALYSE
  862.                     printf("\n%s\n", (char *) ao);
  863. #endif
  864.                     break;
  865.                 case ChunkID_OBJ_SYMT:
  866.                     print_obj_symt(ao, Size, -1);
  867.                     break;
  868.                 case ChunkID_OBJ_STRT:
  869.                     printf("\n");
  870.                     ao0 = ao;
  871.                     if (obj_vrsn >= 150)
  872.                     {
  873. #ifdef ANALYSE
  874.                         printf("Length Strings  0x%X\n\n", *(int *) ao);
  875. #endif
  876.                         ao += 4;
  877.                     }
  878.                     while (ao < aend)
  879.                     {
  880.                         if (*(char *) ao == 0)
  881.                             ++ao;
  882.                         else
  883.                         {
  884.                             namez = (char *) ao;
  885. #ifdef ANALYSE
  886.                             printf("%8X  %s\n", ao - ao0, namez);
  887. #endif
  888.                             ao += strlen(namez) + 1;
  889.                         }
  890.                     }
  891.                     break;
  892.                 default:
  893.                     dump(ao, aend);
  894.                 }
  895.                 break;
  896.  
  897.             default:
  898.                 dump(ao, aend);
  899.             }
  900.         }
  901.     }
  902.  
  903. #if defined(RETAIN) || defined(SUPPRESS)
  904.  
  905.     /*  Produce output file  */
  906.  
  907.     SaveFile(infile, (void *)area, len, 0xffd);
  908.  
  909. #endif
  910.  
  911.     return 0;
  912. }
  913.