home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 2 / 2870 / syms.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-02-28  |  6.0 KB  |  311 lines

  1. /*
  2.  * Copyright 1991, John F. Haugh II
  3.  * An unpublished work.
  4.  * All rights reserved.
  5.  *
  6.  * Permission is granted to copy and create derivative works for any
  7.  * non-commercial purpose, provided this copyright notice is preserved
  8.  * in all copies of source code, or included in human readable form
  9.  * and conspicuously displayed on all copies of object code or
  10.  * distribution media.
  11.  */
  12.  
  13. #ifndef    lint
  14. static    char    sccsid[] = "@(#)syms.c    2.1    07:15:42    2/27/91";
  15. #endif
  16.  
  17. #include <sys/types.h>
  18. #include <sys/a.out.h>
  19. #include <sys/relsym.h>
  20. #include <stdio.h>
  21.  
  22. struct    xlist3 {
  23.     unsigned short    xl3_type;
  24.     unsigned short    xl3_seg;
  25.     unsigned long    xl3_value;
  26. };
  27.  
  28. struct    xlist    **symbols;
  29. int    nsymbols;
  30. int    maxsymbols;
  31.  
  32. extern    char    *strdup();
  33.  
  34. int
  35. initsyms (file)
  36. char    *file;
  37. {
  38.     FILE    *fp;
  39.     long    segsize;
  40.     long    pad;
  41.     struct    xexec    xexec;
  42.     struct    xext    xext;
  43.     struct    xseg    xseg;
  44.     struct    xlist    xlist;
  45.     char    buf[BUFSIZ];
  46.     char    *cp;
  47.  
  48.     if (! (fp = fopen (file, "r"))) {
  49.         perror (file);
  50.         return -1;
  51.     }
  52.     if (fread (&xexec, sizeof xexec, 1, fp) != 1) {
  53.         printf ("error reading xexec header\n");
  54.         return -1;
  55.     }
  56.     if (xexec.x_magic != X_MAGIC) {
  57.         printf ("not a valid x.out header\n");
  58.         return -1;
  59.     }
  60.     if (! (xexec.x_renv & XE_SEG)) {
  61.         printf ("not a segmented object\n");
  62.         return -1;
  63.     }
  64.     if (fread (&xext, sizeof xext, 1, fp) != 1) {
  65.         printf ("error reading xext record\n");
  66.         return -1;
  67.     }
  68.     if (fseek (fp, xext.xe_segpos, 0) == -1) {
  69.         printf ("error seeking to segment table\n");
  70.         return -1;
  71.     }
  72.     while (fread (&xseg, sizeof xseg, 1, fp) == 1 && xext.xe_segsize > 0) {
  73.         if (xseg.xs_type == XS_TSYMS)
  74.             break;
  75.  
  76.         xext.xe_segsize -= sizeof xseg;
  77.     }
  78.     if (xext.xe_segsize <= 0) {
  79.         printf ("error locating symbol table\n");
  80.         return -1;
  81.     }
  82.     if (fseek (fp, xseg.xs_filpos, 0) == -1) {
  83.         printf ("error seeking to symbol table\n");
  84.         return -1;
  85.     }
  86.     while (ftell (fp) < xseg.xs_filpos + xseg.xs_psize) {
  87.         if (nsymbols == maxsymbols) {
  88.             if (nsymbols == 0) {
  89.                 maxsymbols = 10;
  90.                 symbols = (struct xlist **)
  91.                     malloc (maxsymbols * sizeof *symbols);
  92.             } else {
  93.                 maxsymbols *= 2;
  94.                 symbols = (struct xlist **) realloc (symbols,
  95.                     maxsymbols * sizeof *symbols);
  96.             }
  97.         }
  98.         if (symbols == 0) {
  99.             printf ("error allocating memory for symbol table\n");
  100.             return -1;
  101.         }
  102.         fread (&xlist, sizeof (struct xlist3), 1, fp);
  103.         for (cp = buf;*cp++ = getc (fp);)
  104.             ;
  105.  
  106.         xlist.xl_name = strdup (buf);
  107.  
  108.         symbols[nsymbols] = (struct xlist *)
  109.                 malloc (sizeof (struct xlist));
  110.         *(symbols[nsymbols++]) = xlist;
  111.     }
  112.     fclose (fp);
  113.     return 0;
  114. }
  115.  
  116. long
  117. sym2addr (sym, type)
  118. char    *sym;
  119. int    type;
  120. {
  121.     int    i;
  122.     int    symbol_type;
  123.  
  124.     if (symbols == 0)
  125.         return -1;
  126.  
  127.     for (i = 0;i < nsymbols;i++) {
  128.         symbol_type = symbols[i]->xl_type & S_TYPE;
  129.  
  130.         if (type == 0 && strcmp (sym, symbols[i]->xl_name) == 0)
  131.             return symbols[i]->xl_value;
  132.  
  133.         if (type == symbol_type && ! strcmp (sym, symbols[i]->xl_name))
  134.             return symbols[i]->xl_value;
  135.     }
  136.     return -1;
  137. }
  138.  
  139. char *
  140. addr2sym (addr, diffp, type)
  141. long    addr;
  142. long    *diffp;
  143. int    type;
  144. {
  145.     int    guess = -1;
  146.     int    i;
  147.     int    symbol_type;
  148.  
  149.     if (symbols == 0)
  150.         return 0;
  151.  
  152.     for (i = 0;i < nsymbols;i++) {
  153.         symbol_type = symbols[i]->xl_type & S_TYPE;
  154.  
  155.         if (type == 0 && addr >= symbols[i]->xl_value &&
  156.             (guess == -1 ||
  157.              symbols[i]->xl_value > symbols[guess]->xl_value))
  158.             guess = i;
  159.  
  160.         if (type == symbol_type && addr >= symbols[i]->xl_value &&
  161.             (guess == -1 ||
  162.              symbols[i]->xl_value > symbols[guess]->xl_value))
  163.             guess = i;
  164.     }
  165.     if (guess == -1)
  166.         return 0;
  167.  
  168.     *diffp = addr - symbols[guess]->xl_value;
  169.     return symbols[guess]->xl_name;
  170. }
  171.  
  172. char *
  173. text2sym (addr, diffp)
  174. long    addr;
  175. long    *diffp;
  176. {
  177.     return addr2sym (addr, diffp, S_TEXT);
  178. }
  179.  
  180. char *
  181. data2sym (addr, diffp)
  182. long    addr;
  183. long    *diffp;
  184. {
  185.     char    *sym1, *sym2;
  186.     long    diff1, diff2;
  187.  
  188.     sym1 = addr2sym (addr, &diff1, S_DATA);
  189.     sym2 = addr2sym (addr, &diff2, S_BSS);
  190.  
  191.     if (sym1 && sym2) {
  192.         if (diff1 < diff2) {
  193.             *diffp = diff1;
  194.             return sym1;
  195.         } else {
  196.             *diffp = diff2;
  197.             return sym2;
  198.         }
  199.     }
  200.     if (sym1) {
  201.         *diffp = diff1;
  202.         return sym1;
  203.     } else if (sym2) {
  204.         *diffp = diff2;
  205.         return sym2;
  206.     } else
  207.         return 0;
  208. }
  209.  
  210. prtextaddr (cp)
  211. char    *cp;
  212. {
  213.     long    addr;
  214.     char    *sym;
  215.     long    diff;
  216.  
  217.     if (expr (&cp, &addr)) {
  218.         printf ("error in '%.15s'\n", cp);
  219.         return;
  220.     }
  221.     if (! (sym = text2sym (addr, &diff))) {
  222.         printf ("no text address for %d (%x)\n", addr, addr);
  223.         return;
  224.     }
  225.     if (diff != 0)
  226.         printf ("%d (%x) = %s+%d (%x)\n", addr, addr, sym, diff, diff);
  227.     else
  228.         printf ("%d (%x) = %s\n", addr, addr, sym);
  229. }
  230.  
  231. prdataaddr (cp)
  232. char    *cp;
  233. {
  234.     long    addr;
  235.     char    *sym;
  236.     long    diff;
  237.  
  238.     if (expr (&cp, &addr)) {
  239.         printf ("error in '%.15s'\n", cp);
  240.         return;
  241.     }
  242.     if (! (sym = data2sym (addr, &diff))) {
  243.         printf ("no data address for %d (%x)\n", addr, addr);
  244.         return;
  245.     }
  246.     if (diff != 0)
  247.         printf ("%d (%x) = %s+%d (%x)\n", addr, addr, sym, diff, diff);
  248.     else
  249.         printf ("%d (%x) = %s\n", addr, addr, sym);
  250. }
  251.  
  252. prsymbol (cp)
  253. char    *cp;
  254. {
  255.     char    buf[BUFSIZ];
  256.     long    addr;
  257.     int    type;
  258.     char    *sym;
  259.  
  260.     buf[0] = '_';
  261.     strcpy (buf + 1, cp);
  262.  
  263.     if ((addr = sym2addr (sym = buf + 1, type = S_TEXT)) == -1 &&
  264.         (addr = sym2addr (sym = buf, type = S_TEXT)) == -1 &&
  265.         (addr = sym2addr (sym = buf + 1, type = S_DATA)) == -1 &&
  266.         (addr = sym2addr (sym = buf, type = S_DATA)) == -1 &&
  267.         (addr = sym2addr (sym = buf + 1, type = S_BSS)) == -1 &&
  268.         (addr = sym2addr (sym = buf, type = S_BSS)) == -1) {
  269.         printf ("%s not found\n", cp);
  270.         return;
  271.     }
  272.     printf ("%s (%s) = %d (%x)\n", sym, type == S_TEXT ? "text":
  273.         (type == S_DATA ? "data":
  274.         (type == S_BSS ? "bss":"unknown")), addr, addr);
  275. }
  276.  
  277. #ifdef    TEST
  278. main (argc, argv)
  279. int    argc;
  280. char    **argv;
  281. {
  282.     int    i;
  283.     long    addr;
  284.     long    diff;
  285.     char    *sym;
  286.     char    buf[BUFSIZ];
  287.     char    *cp;
  288.  
  289.     if (initsyms (argv[1]))
  290.         exit (1);
  291.  
  292.     printf ("allocated %d slots for %d symbols\n", maxsymbols, nsymbols);
  293.  
  294.     while (gets (buf)) {
  295.         if (buf[0] >= '0' && buf[0] <= '9') {
  296.             cp = buf;
  297.             if (expr (&cp, &addr)) {
  298.                 printf ("error at '%.15s'\n", cp);
  299.                 continue;
  300.             }
  301.             sym = addr2sym (addr, &diff, 0);
  302.             printf ("name of %s (%x) is %s+%d\n",
  303.                 buf, addr, sym, diff);
  304.         } else {
  305.             addr = sym2addr (buf, 0);
  306.             printf ("address of %s is %d (%x)\n", buf, addr, addr);
  307.         }
  308.     }
  309. }
  310. #endif
  311.