home *** CD-ROM | disk | FTP | other *** search
/ APDL Public Domain 1 / APDL_PD1A.iso / program / dde / decaof / c / decode next >
Encoding:
Text File  |  1992-11-20  |  9.6 KB  |  406 lines

  1. /*
  2.  * decode an AOF file
  3.  *
  4.  * Andy Duplain, BT Customer Systems, Brighton, UK.  duplain@btcs.bt.co.uk
  5.  */
  6.  
  7. #include <stdio.h>
  8. #ifdef BSD42
  9. #include <strings.h>
  10. #else
  11. #include <string.h>
  12. #endif
  13. #include "decaof.h"
  14. #include "cproto.h"
  15. #include "io.h"
  16. #include "main.h"
  17. #include "misc.h"
  18. #include "error.h"
  19.  
  20. static struct chunkhdr *hdr;
  21. static struct chunkent *ents, *ent;
  22. static struct aofhdr *aofhdr;
  23. static struct areahdr *areahdrs;
  24. static struct symbol *symboltab;
  25. static char *stringtab;
  26. static long area_offset;
  27. static Word symboltab_size;
  28.  
  29. static char *cptr;
  30.  
  31. static void print_area P__((FILE *ifp, struct areahdr *areahdr, Word offset, Word reloff));
  32. static char *string P__((Word offset));
  33. static char *symname P__((Word offset));
  34. static char *areaname P__((Word offset));
  35.  
  36. int
  37. decode()
  38. {
  39.     register i;
  40.     Word offset, reloff;
  41.     FILE *ifp;
  42.     char *filename;
  43.  
  44.     while (nfiles--) {
  45.         filename = *files++;
  46.         ifp = fopen(filename, R_OPENMODE);
  47.         if (!ifp) {
  48.             error("unable to open file \"%s\"", filename);
  49.             continue;
  50.         };
  51.  
  52.         hdr = NULL;
  53.         ents = NULL;
  54.         aofhdr = NULL;
  55.         areahdrs = NULL;
  56.         stringtab = NULL;
  57.         symboltab = NULL;
  58.  
  59.         /* read chunk header */
  60.         hdr = read_chunkhdr(ifp);
  61.         if (!hdr) {
  62.             error("reading file \"%s\"", filename);
  63.             goto next_file;
  64.         }
  65.         if (hdr->chunkfileid != 0xc3cbc6c5) {
  66.             error("file \"%s\" is not a chunk file", filename);
  67.             goto next_file;
  68.         }
  69.  
  70.         /* read chunk entries in */
  71.         ents = read_chunkents(ifp, hdr);
  72.         if (!ents) {
  73.             error("reading chunk entries for file \"%s\"", filename);
  74.             goto next_file;
  75.         }
  76.  
  77.         printf("** File:\n%s\n", filename);
  78.  
  79.         /* read string table */
  80.         ent = find_ent(hdr, ents, "OBJ_STRT");
  81.         if (ent) {
  82.             stringtab = read_stringtab(ifp, ent);
  83.             if (!stringtab) {
  84.                 error("reading string table for file \"%s\"", filename);
  85.                 goto next_file;
  86.             }
  87.         } else
  88.             puts("\n** no string table");
  89.  
  90.         /* read and print identification string */
  91.         ent = find_ent(hdr, ents, "OBJ_IDFN");
  92.         if (ent) {
  93.             char *idstr;
  94.             idstr = read_ident(ifp, ent);
  95.             if (!idstr) {
  96.                 error("reading identification for file \"%s\"", filename);
  97.                 goto next_file;
  98.             }
  99.             printf("\n** Identification:\n%s\n", idstr);
  100.             free_chunk_memory(idstr);    /* not needed */
  101.         } else
  102.             puts("\n** no identification chunk");
  103.  
  104.         /* find file offset of OBJ_AREA (for later use) */
  105.         ent = find_ent(hdr, ents, "OBJ_AREA");
  106.         area_offset = ent->offset;
  107.  
  108.         /* read-in AOF header */
  109.         ent = find_ent(hdr, ents, "OBJ_HEAD");
  110.         if (ent) {
  111.             aofhdr = read_aofhdr(ifp, ent);
  112.             if (!aofhdr) {
  113.                 error("reading AOF header for file \"%s\"", filename);
  114.                 goto next_file;
  115.             }
  116.             puts("\n** AOF Header:");
  117.             if (aofhdr->filetype == 0xc5e2d080)
  118.                 cptr = "Relocatable object format";
  119.             else if (aofhdr->filetype == 0xc5e2d081)
  120.                 cptr = "AOF image type 1";
  121.             else if (aofhdr->filetype == 0xc5e2d083)
  122.                 cptr = "AOF image type 2";
  123.             else if (aofhdr->filetype == 0xc5e2d087)
  124.                 cptr = "AOF image type 3";
  125.             else
  126.                 cptr = "unknown image type";
  127.             puts(cptr);
  128.  
  129.             printf("version %ld\n", aofhdr->version);
  130.             i = aofhdr->numareas;
  131.             printf("%ld area%s\n", i, i == 1 ? "" : "s");
  132.             i = aofhdr->numsyms;
  133.             printf("%ld symbol%s\n", i, i == 1 ? "" : "s");
  134.  
  135.             /* read in the symbol table, if any */
  136.             if (aofhdr->numsyms) {
  137.                 ent = find_ent(hdr, ents, "OBJ_SYMT");
  138.                 if (ent) {
  139.                     symboltab = read_symboltab(ifp, ent, aofhdr->numsyms);
  140.                     if (!symboltab) {
  141.                         error("reading symbol table for file \"%s\"", filename);
  142.                         goto next_file;
  143.                     }                    
  144.                     symboltab_size = ent->size;
  145.                 }
  146.             }
  147.  
  148.             /* decode each of the areas */
  149.             areahdrs = (struct areahdr *)(aofhdr + sizeof(struct aofhdr));
  150.             offset = reloff = 0;
  151.             for (i = 0; i < aofhdr->numareas; i++) {
  152.                 Byte flags = (areahdrs[i].flags >> 8) & 0xff;
  153.  
  154.                 if (!(flags & AT_NOINIT))
  155.                     reloff = offset + areahdrs[i].size;
  156.                 print_area(ifp, &areahdrs[i], offset, reloff);
  157.                 if (!(flags & AT_NOINIT))
  158.                     offset = reloff + (areahdrs[i].numrelocs * sizeof(struct reloc));
  159.             }
  160.         } else
  161.             puts("\n** no AOF header");
  162.  
  163.         if (symtab && aofhdr->numsyms) {
  164.             puts("\n** Symbol table:");
  165.             for (i = 0; i < aofhdr->numsyms; i++) {
  166.                 Byte flags;
  167.                 printf("%-16s ", string(symboltab[i].name));
  168.                 flags = symboltab[i].flags & 0xff;
  169.                 switch (flags & 0x3) {
  170.                     case 0x01:
  171.                         fputs("local ", stdout);
  172.                         break;
  173.                     case 0x02:
  174.                         fputs("extern ",
  175.                             stdout);
  176.                         break;
  177.                     case 0x03:
  178.                         fputs("global ", stdout);
  179.                         break;
  180.                     default:
  181.                         fputs("unknown-type ", stdout);
  182.                         break;
  183.                 }                
  184.                 if (flags & (1<<2) && flags & (1<<0))
  185.                     fputs("constant ", stdout);
  186.                 if (flags & (1<<3) && !(flags & (1<<0)))
  187.                     fputs("case-insensitive ", stdout);
  188.                 if (flags & (1<<4) && (flags & 0x03 == 0x02))
  189.                     fputs("weak ", stdout);
  190.                 if (flags & (1<<5) && (flags & 0x03 == 0x03))
  191.                     fputs("strong ", stdout);
  192.                 if (flags & (1<<6) && (flags & 0x03 == 0x02))
  193.                     fputs("common ", stdout);
  194.                 if (flags & (1<<0) || flags & (1<<6)) {
  195.                     if (flags & (1<<2))
  196.                         printf("= 0x%08lx", symboltab[i].value);
  197.                     else
  198.                         printf("at \"%s\" + 0x%06lx", string(symboltab[i].areaname), symboltab[i].value);
  199.                 }
  200.                 putchar('\n');
  201.             }
  202.         }
  203.  
  204.         if (strtab && *(Word *)stringtab) {
  205.             puts("\n** String table:");
  206.             offset = 4;
  207.             while (cptr = string(offset)) {
  208.                 printf("%06lx: %s\n", offset, cptr);
  209.                 offset += strlen(cptr) + 1;
  210.             }
  211.         }
  212.  
  213. next_file:
  214.         free_chunk_memory((char *)aofhdr);
  215.         free_chunk_memory((char *)symboltab);
  216.         free_chunk_memory((char *)stringtab);
  217.         free_chunk_memory((char *)ents);
  218.         fclose(ifp);
  219.     }
  220.  
  221.     return (0);
  222. }
  223.  
  224. /*
  225.  * print each AOF area...
  226.  */
  227. static void
  228. print_area(ifp, areahdr, offset, reloff)
  229.     FILE *ifp;
  230.     struct areahdr *areahdr;
  231.     Word offset, reloff;
  232. {
  233.     Byte flags = (areahdr->flags >> 8) & 0xff;
  234.  
  235.     printf("\n** Area \"%s\" ", string(areahdr->name));
  236.     if (flags & AT_DEBUG)
  237.         fputs("debug ", stdout);
  238.     else {
  239.         if (flags & AT_CODE)
  240.             fputs("code ", stdout);
  241.         else
  242.             fputs("data ", stdout);
  243.     }
  244.     if (flags & AT_COMMDEF)
  245.         fputs("commdef ", stdout);
  246.     if (flags & AT_READONLY)
  247.         fputs("readonly ", stdout);
  248.     if (flags & AT_NOINIT)
  249.         fputs("noinit ", stdout);
  250.     printf("\nsize %ld byte%s, %ld relocation%s\n", areahdr->size, areahdr->size == 1 ? "" : "s", areahdr->numrelocs, areahdr->numrelocs == 1 ? "" : "s");
  251.  
  252.     if (area_contents) {
  253.         register cols = 0, size = areahdr->size;
  254.         register Word area_off;
  255.  
  256.         fseek(ifp, area_offset + offset, 0);
  257.         fputs("contents:\n000000: ", stdout);
  258.         area_off = 0;
  259.         while (area_off < size) {
  260.             printf("%l08x", read_word(ifp));
  261.             area_off += 4;
  262.             if (++cols == 8) {
  263.                 printf("\n%06lx: ", area_off);
  264.                 cols = 0;
  265.             } else
  266.                 putchar(' ');
  267.         }
  268.         if (cols)
  269.             putchar('\n');
  270.     }
  271.  
  272.     if (reloc_dir && areahdr->numrelocs) {
  273.         register struct reloc *reloc;
  274.         register Word numrelocs;
  275.  
  276.         fseek(ifp, area_offset + reloff, 0);
  277.         puts("relocations:");
  278.         for (numrelocs = areahdr->numrelocs; numrelocs; numrelocs--) {
  279.             enum {unknown, type1, type2} rtype;
  280.             int shift;
  281.  
  282.             reloc = read_reloc(ifp);
  283.             if (!reloc) {
  284.                 error("reading relocation directive");
  285.                 return;
  286.             }
  287.  
  288.             if ((reloc->flags & 0xfff00000) == 0x00000000)
  289.                 rtype = type1;
  290.             else if ((reloc->flags & 0xf0000000) == 0x80000000)
  291.                 rtype = type2;
  292.             else {
  293.                 puts("** unknown relocation type");
  294.                 continue;
  295.             }
  296.  
  297.             switch ((reloc->flags >> (rtype == type1 ? 16 : 24)) & 0x03) {
  298.             case 0x00:
  299.                 cptr = "byte at";
  300.                 break;
  301.             case 0x01:
  302.                 cptr = "halfword at";
  303.                 break;
  304.             case 0x02:
  305.                 cptr = "word at";
  306.                 break;
  307.             case 0x03:
  308.                 cptr = "unknown-field-type at";
  309.                 break;
  310.             }
  311.             printf("%s 0x%06lx ", cptr, reloc->offset);
  312.  
  313.             if (rtype == type1) {
  314.                 fputs("type-1 ", stdout);
  315.                 switch ((reloc->flags >> 18) & 0x03) {
  316.                 case 0x01:
  317.                 case 0x03:
  318.                     /* pc-relative (always symbol) */
  319.                     printf("pc-relative to symbol \"%s\"", symname(reloc->flags & 0xffff));
  320.                     break;
  321.                 case 0x02:
  322.                     /* additive symbol */
  323.                     printf("displaced by symbol \"%s\"", symname(reloc->flags & 0xffff));
  324.                     break;
  325.                 case 0x00:
  326.                     /* additive internal */
  327.                     fputs("displaced by this area", stdout);
  328.                     break;
  329.                 }
  330.             } else if (rtype == type2) {
  331.                 fputs("type-2 ", stdout);
  332.                 switch ((reloc->flags >> 26) & 0x03) {
  333.                 case 0x00:
  334.                     /* additive internal */
  335.                     printf("displaced by area \"%s\"", areaname(reloc->flags & 0xffffff));
  336.                     break;
  337.                 case 0x01:
  338.                     /* pc-relative internal */
  339.                     printf("pc-relative to area \"%s\"", areaname(reloc->flags & 0xffffff));
  340.                     break;
  341.  
  342.                 case 0x02:
  343.                     /* additive symbol */
  344.                     printf("displaced by symbol \"%s\"", symname(reloc->flags & 0xffffff));
  345.                     break;
  346.  
  347.                 case 0x03:
  348.                     /* pc-relative symbol */
  349.                     printf("pc-relative to symbol \"%s\"", symname(reloc->flags & 0xffffff));
  350.                     break;
  351.                 }
  352.             } else
  353.                 fputs("type-unknown", stdout);
  354.             putchar('\n');
  355.         }
  356.     }
  357. }
  358.  
  359. /*
  360.  * return a pointer to a string in the string table
  361.  */
  362. static char *
  363. string(offset)
  364.     Word offset;
  365. {
  366.     if (!stringtab || offset < 4 || offset >= *(Word *)stringtab)
  367.         return (NULL);
  368.     return ((char *)(stringtab + offset));
  369. }
  370.  
  371. /*
  372.  * return a pointer to a symbol name in the symbol table
  373.  */
  374. static char *
  375. symname(offset)
  376.     Word offset;
  377. {
  378.     register struct symbol *sym;
  379.  
  380.     if (!symboltab || offset > symboltab_size)
  381.         return (NULL);
  382.     sym = (struct symbol *)(symboltab + offset);
  383.     return (string(sym->name));
  384. }
  385.  
  386. /*
  387.  * return a pointer to an area name, given the area's offset
  388.  * into the OBJ_AREA.
  389.  */
  390. static char *
  391. areaname(offset)
  392.     Word offset;
  393. {
  394.     register Word aoff;
  395.     register i;
  396.  
  397.     if (!aofhdr || !areahdrs)
  398.         return (NULL);
  399.     for (i = 0, aoff = 0; i < aofhdr->numareas; i++)
  400.         if (aoff == offset)
  401.             return (string(areahdrs[i].name));
  402.         else if (!(areahdrs[i].flags & AT_NOINIT))
  403.             aoff += areahdrs[i].size + (sizeof(struct reloc) * areahdrs[i].numrelocs);
  404.     return (NULL);
  405. }
  406.