home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume25 / trash / part01 / syms.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-03-22  |  3.1 KB  |  199 lines

  1. #define    LANGUAGE_C    1
  2. #include        <sys/types.h>
  3. #include        <sys/stat.h>
  4. #include        <stdio.h>
  5. #include        <filehdr.h>
  6. #include        <syms.h>
  7. #include        <ldfcn.h>
  8. #include        "symtab.h"
  9.  
  10. extern char        *malloc();
  11. extern char        *realloc();
  12. extern char        *ldgetname();
  13.  
  14. static int        symcomp();
  15. static syment        *findsym();
  16.  
  17. int
  18. symtab_open(ldptr, adotout, symtabp)
  19. LDFILE    *ldptr;
  20. char    *adotout;
  21. symtab    *symtabp;
  22. {
  23.     struct stat    statb;
  24.     FILHDR        filehdr;
  25.     int        symmax;
  26.     syment        *stbl;
  27.     syment        *sp;
  28.     syment        *nsp;
  29.     SYMR        sy;
  30.     HDRR        shdr;
  31.     int        i;
  32.     int        symcnt;
  33.  
  34.     symtabp->st_symcnt = 0;
  35.     symtabp->st_tab = (syment *)0;
  36.  
  37.     if (stat(adotout, &statb) == -1)
  38.     {
  39.         couldnot("stat \"%s\"", adotout);
  40.         return -1;
  41.     }
  42.  
  43.     if (statb.st_size == 0)
  44.         return 0;
  45.  
  46.     if (ldfhread(ldptr, &filehdr) != SUCCESS)
  47.     {
  48.         couldnot("read file header from file \"%s\"", adotout);
  49.         return -1;
  50.     }
  51.  
  52.     if (PSYMTAB(ldptr) == (pCHDRR)0)
  53.         /*
  54.          * No symbol table.
  55.          */
  56.         return 0;
  57.  
  58.     shdr = SYMHEADER(ldptr);
  59.     symmax = shdr.isymMax + shdr.iextMax;
  60.  
  61.     if ((stbl = (syment *)malloc((unsigned)(symmax * sizeof(syment)))) == (syment *)0)
  62.     {
  63.         couldnot("allocate space for namelist of file \"%s\"", adotout);
  64.         return -1;
  65.     }
  66.  
  67.     for (i = 0, symcnt = 0, sp = stbl; i < symmax; i++)
  68.     {
  69.         if (ldtbread(ldptr, i, &sy) == FAILURE)
  70.         {
  71.             couldnot("read indexed symbol tabel entry from file \"%s\"", adotout);
  72.             return -1;
  73.         }
  74.  
  75.         if
  76.         (
  77.             sy.st != stGlobal
  78.             &&
  79.             sy.st != stStatic
  80.             &&
  81.             sy.st != stProc
  82.             &&
  83.             sy.st != stStaticProc
  84.         )
  85.             continue;
  86.  
  87.         sp->n_value = sy.value;
  88.         sp->n_scnum = sy.sc;
  89.         sp->n_name = ldgetname(ldptr, &sy);
  90.         sp->n_proc = (struct procent *)0;
  91.  
  92.         symcnt++;
  93.         sp++;
  94.     }
  95.  
  96.     /*
  97.      * Sort by address.
  98.      */
  99.     qsort(stbl, symcnt, sizeof(*sp), symcomp);
  100.  
  101.     /*
  102.      * Remove duplicates.
  103.      */
  104.     for (sp = nsp = stbl; sp < &stbl[symcnt]; sp++)
  105.     {
  106.         *nsp++ = *sp;
  107.         while (sp[1].n_value == sp[0].n_value)
  108.             sp++;
  109.     }
  110.  
  111.     /*
  112.      * Compact the table.
  113.      */
  114.     symcnt = nsp - stbl;
  115.     if ((stbl = (syment *)realloc((char *)stbl, (unsigned int)(symcnt * sizeof(syment)))) == (syment *)0)
  116.     {
  117.         couldnot("reallocate symbol table space for file \"%s\"", adotout);
  118.         return -1;
  119.     }
  120.  
  121.     /*
  122.      * Pass back the results.
  123.      */
  124.     symtabp->st_symcnt = symcnt;
  125.     symtabp->st_tab = stbl;
  126.  
  127.     return 0;
  128. }
  129.  
  130. int
  131. symtab_close(symtabp)
  132. symtab    *symtabp;
  133. {
  134.     if (symtabp->st_tab != (syment *)0)
  135.     {
  136.         (void)free((char *)(symtabp->st_tab));
  137.         symtabp->st_tab = (syment *)0;
  138.     }
  139.  
  140.     symtabp->st_symcnt = 0;
  141.  
  142.     return 0;
  143. }
  144.  
  145. char    *
  146. symtab_text_address(symtabp, address)
  147. symtab        *symtabp;
  148. unsigned long    address;
  149. {
  150.     static char    buf[512];
  151.     syment        *sp;
  152.  
  153.     if ((sp = findsym(symtabp, address)) == (syment *)0)
  154.         sprintf(&buf[0], "0x%06x", address);
  155.     else
  156.         sprintf(&buf[0], "%s+0x%02x", sp->n_name, address - sp->n_value);
  157.  
  158.     return &buf[0];
  159. }
  160.  
  161. static
  162. int
  163. symcomp(a, b)
  164. syment    *a;
  165. syment    *b;
  166. {
  167.     return a->n_value - b->n_value;
  168. }
  169.  
  170. static
  171. syment    *
  172. findsym(symtabp, addr)
  173. symtab        *symtabp;
  174. unsigned long    addr;
  175. {
  176.     int    low;
  177.     int    high;
  178.     int    i;
  179.     syment    *tab;
  180.  
  181.     if (symtabp == (symtab *)0 || (tab = symtabp->st_tab) == (syment *)0)
  182.         return (syment *)0;
  183.  
  184.     low = 0;
  185.     high = symtabp->st_symcnt;
  186.  
  187.     while (high - low > 1)
  188.     {
  189.         i = (low + high) / 2;
  190.  
  191.         if (tab[i].n_value <= addr)
  192.             low = i;
  193.         else
  194.             high = i;
  195.     }
  196.  
  197.     return &tab[low];
  198. }
  199.