home *** CD-ROM | disk | FTP | other *** search
- #define LANGUAGE_C 1
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <stdio.h>
- #include <filehdr.h>
- #include <syms.h>
- #include <ldfcn.h>
- #include "symtab.h"
-
- extern char *malloc();
- extern char *realloc();
- extern char *ldgetname();
-
- static int symcomp();
- static syment *findsym();
-
- int
- symtab_open(ldptr, adotout, symtabp)
- LDFILE *ldptr;
- char *adotout;
- symtab *symtabp;
- {
- struct stat statb;
- FILHDR filehdr;
- int symmax;
- syment *stbl;
- syment *sp;
- syment *nsp;
- SYMR sy;
- HDRR shdr;
- int i;
- int symcnt;
-
- symtabp->st_symcnt = 0;
- symtabp->st_tab = (syment *)0;
-
- if (stat(adotout, &statb) == -1)
- {
- couldnot("stat \"%s\"", adotout);
- return -1;
- }
-
- if (statb.st_size == 0)
- return 0;
-
- if (ldfhread(ldptr, &filehdr) != SUCCESS)
- {
- couldnot("read file header from file \"%s\"", adotout);
- return -1;
- }
-
- if (PSYMTAB(ldptr) == (pCHDRR)0)
- /*
- * No symbol table.
- */
- return 0;
-
- shdr = SYMHEADER(ldptr);
- symmax = shdr.isymMax + shdr.iextMax;
-
- if ((stbl = (syment *)malloc((unsigned)(symmax * sizeof(syment)))) == (syment *)0)
- {
- couldnot("allocate space for namelist of file \"%s\"", adotout);
- return -1;
- }
-
- for (i = 0, symcnt = 0, sp = stbl; i < symmax; i++)
- {
- if (ldtbread(ldptr, i, &sy) == FAILURE)
- {
- couldnot("read indexed symbol tabel entry from file \"%s\"", adotout);
- return -1;
- }
-
- if
- (
- sy.st != stGlobal
- &&
- sy.st != stStatic
- &&
- sy.st != stProc
- &&
- sy.st != stStaticProc
- )
- continue;
-
- sp->n_value = sy.value;
- sp->n_scnum = sy.sc;
- sp->n_name = ldgetname(ldptr, &sy);
- sp->n_proc = (struct procent *)0;
-
- symcnt++;
- sp++;
- }
-
- /*
- * Sort by address.
- */
- qsort(stbl, symcnt, sizeof(*sp), symcomp);
-
- /*
- * Remove duplicates.
- */
- for (sp = nsp = stbl; sp < &stbl[symcnt]; sp++)
- {
- *nsp++ = *sp;
- while (sp[1].n_value == sp[0].n_value)
- sp++;
- }
-
- /*
- * Compact the table.
- */
- symcnt = nsp - stbl;
- if ((stbl = (syment *)realloc((char *)stbl, (unsigned int)(symcnt * sizeof(syment)))) == (syment *)0)
- {
- couldnot("reallocate symbol table space for file \"%s\"", adotout);
- return -1;
- }
-
- /*
- * Pass back the results.
- */
- symtabp->st_symcnt = symcnt;
- symtabp->st_tab = stbl;
-
- return 0;
- }
-
- int
- symtab_close(symtabp)
- symtab *symtabp;
- {
- if (symtabp->st_tab != (syment *)0)
- {
- (void)free((char *)(symtabp->st_tab));
- symtabp->st_tab = (syment *)0;
- }
-
- symtabp->st_symcnt = 0;
-
- return 0;
- }
-
- char *
- symtab_text_address(symtabp, address)
- symtab *symtabp;
- unsigned long address;
- {
- static char buf[512];
- syment *sp;
-
- if ((sp = findsym(symtabp, address)) == (syment *)0)
- sprintf(&buf[0], "0x%06x", address);
- else
- sprintf(&buf[0], "%s+0x%02x", sp->n_name, address - sp->n_value);
-
- return &buf[0];
- }
-
- static
- int
- symcomp(a, b)
- syment *a;
- syment *b;
- {
- return a->n_value - b->n_value;
- }
-
- static
- syment *
- findsym(symtabp, addr)
- symtab *symtabp;
- unsigned long addr;
- {
- int low;
- int high;
- int i;
- syment *tab;
-
- if (symtabp == (symtab *)0 || (tab = symtabp->st_tab) == (syment *)0)
- return (syment *)0;
-
- low = 0;
- high = symtabp->st_symcnt;
-
- while (high - low > 1)
- {
- i = (low + high) / 2;
-
- if (tab[i].n_value <= addr)
- low = i;
- else
- high = i;
- }
-
- return &tab[low];
- }
-