xref: /csrg-svn/old/dbx/mappings.c (revision 14439)
19671Slinton /* Copyright (c) 1982 Regents of the University of California */
29671Slinton 
3*14439Slinton static char sccsid[] = "@(#)mappings.c 1.4 08/10/83";
49671Slinton 
59671Slinton /*
69671Slinton  * Source-to-object and vice versa mappings.
79671Slinton  */
89671Slinton 
99671Slinton #include "defs.h"
109671Slinton #include "mappings.h"
119671Slinton #include "symbols.h"
129671Slinton #include "source.h"
139671Slinton #include "object.h"
149671Slinton #include "machine.h"
159671Slinton 
169671Slinton #ifndef public
179671Slinton #include "machine.h"
189671Slinton #include "source.h"
199671Slinton #include "symbols.h"
209671Slinton 
219671Slinton typedef struct {
229671Slinton     Address addr;
239671Slinton     String filename;
249671Slinton     Lineno lineindex;		/* index to first linetab entry */
259671Slinton } Filetab;
269671Slinton 
279671Slinton typedef struct {
289671Slinton     Lineno line;
299671Slinton     Address addr;
309671Slinton } Linetab;
319671Slinton 
329671Slinton Filetab *filetab;
339671Slinton Linetab *linetab;
349671Slinton 
359671Slinton #define NOADDR ((Address) -1)	/* no address for line or procedure */
369671Slinton 
379671Slinton #endif
389671Slinton 
399671Slinton /*
409671Slinton  * Get the source file name associated with a given address.
419671Slinton  */
429671Slinton 
439671Slinton public String srcfilename(addr)
449671Slinton Address addr;
459671Slinton {
469671Slinton     register Address i, j, k;
479671Slinton     Address a;
489671Slinton     Filetab *ftp;
499671Slinton     String s;
509671Slinton 
519671Slinton     s = nil;
529671Slinton     if (nlhdr.nfiles != 0 and addr >= filetab[0].addr) {
539671Slinton 	i = 0;
549671Slinton 	j = nlhdr.nfiles - 1;
559671Slinton 	while (i < j) {
569671Slinton 	    k = (i + j) / 2;
579671Slinton 	    ftp = &filetab[k];
589671Slinton 	    a = ftp->addr;
599671Slinton 	    if (a == addr) {
609671Slinton 		s = ftp->filename;
619671Slinton 		break;
629671Slinton 	    } else if (addr > a) {
639671Slinton 		i = k + 1;
649671Slinton 	    } else {
659671Slinton 		j = k - 1;
669671Slinton 	    }
679671Slinton 	}
689671Slinton 	if (s == nil) {
699671Slinton 	    if (addr >= filetab[i].addr) {
709671Slinton 		s = filetab[i].filename;
719671Slinton 	    } else {
729671Slinton 		s = filetab[i-1].filename;
739671Slinton 	    }
749671Slinton 	}
759671Slinton     }
769671Slinton     return s;
779671Slinton }
789671Slinton 
799671Slinton /*
809671Slinton  * Find the line associated with the given address.
819671Slinton  * If the second parameter is true, then the address must match
829671Slinton  * a source line exactly.  Otherwise the nearest source line
839671Slinton  * below the given address is returned.  In any case, if no suitable
849671Slinton  * line exists, 0 is returned.
859671Slinton  */
869671Slinton 
879671Slinton private Lineno findline(addr, exact)
889671Slinton Address addr;
899671Slinton Boolean exact;
909671Slinton {
919671Slinton     register Address i, j, k;
929671Slinton     register Lineno r;
939671Slinton     register Address a;
949671Slinton 
959671Slinton     if (nlhdr.nlines == 0 or addr < linetab[0].addr) {
969671Slinton 	r = 0;
979671Slinton     } else {
989671Slinton 	i = 0;
999671Slinton 	j = nlhdr.nlines - 1;
1009671Slinton 	if (addr == linetab[i].addr) {
1019671Slinton 	    r = linetab[i].line;
1029671Slinton 	} else if (addr == linetab[j].addr) {
1039671Slinton 	    r = linetab[j].line;
1049671Slinton 	} else if (addr > linetab[j].addr) {
1059671Slinton 	    r = exact ? 0 : linetab[j].line;
1069671Slinton 	} else {
1079671Slinton 	    do {
1089671Slinton 		k = (i + j) div 2;
1099671Slinton 		a = linetab[k].addr;
1109671Slinton 	    if (a == addr) break;
1119671Slinton 		if (addr > a) {
1129671Slinton 		    i = k + 1;
1139671Slinton 		} else {
1149671Slinton 		    j = k - 1;
1159671Slinton 		}
1169671Slinton 	    } while (i <= j);
1179671Slinton 	    if (a == addr) {
1189671Slinton 		r = linetab[k].line;
1199671Slinton 	    } else if (exact) {
1209671Slinton 		r = 0;
1219671Slinton 	    } else if (addr > linetab[i].addr) {
1229671Slinton 		r = linetab[i].line;
1239671Slinton 	    } else {
1249671Slinton 		r = linetab[i-1].line;
1259671Slinton 	    }
1269671Slinton 	}
1279671Slinton     }
1289671Slinton     return r;
1299671Slinton }
1309671Slinton 
1319671Slinton /*
1329671Slinton  * Lookup the source line number nearest from below to an address.
1339671Slinton  */
1349671Slinton 
1359671Slinton public Lineno srcline(addr)
1369671Slinton Address addr;
1379671Slinton {
1389671Slinton     return findline(addr, false);
1399671Slinton }
1409671Slinton 
1419671Slinton /*
1429671Slinton  * Look for a line exactly corresponding to the given address.
1439671Slinton  */
1449671Slinton 
1459671Slinton public Lineno linelookup(addr)
1469671Slinton Address addr;
1479671Slinton {
1489671Slinton     return findline(addr, true);
1499671Slinton }
1509671Slinton 
1519671Slinton /*
1529671Slinton  * Lookup the object address of a given line from the named file.
1539671Slinton  *
1549671Slinton  * Potentially all files in the file table need to be checked
1559671Slinton  * until the line is found since a particular file name may appear
1569671Slinton  * more than once in the file table (caused by includes).
1579671Slinton  */
1589671Slinton 
1599671Slinton public Address objaddr(line, name)
1609671Slinton Lineno line;
1619671Slinton String name;
1629671Slinton {
1639671Slinton     register Filetab *ftp;
1649671Slinton     register Lineno i, j;
1659671Slinton     Boolean foundfile;
1669671Slinton 
1679671Slinton     if (nlhdr.nlines == 0) {
1689671Slinton 	return NOADDR;
1699671Slinton     }
1709671Slinton     if (name == nil) {
1719671Slinton 	name = cursource;
1729671Slinton     }
1739671Slinton     foundfile = false;
1749671Slinton     for (ftp = &filetab[0]; ftp < &filetab[nlhdr.nfiles]; ftp++) {
1759671Slinton 	if (streq(ftp->filename, name)) {
1769671Slinton 	    foundfile = true;
1779671Slinton 	    i = ftp->lineindex;
1789671Slinton 	    if (ftp == &filetab[nlhdr.nfiles-1]) {
1799671Slinton 		j = nlhdr.nlines;
1809671Slinton 	    } else {
1819671Slinton 		j = (ftp + 1)->lineindex;
1829671Slinton 	    }
1839671Slinton 	    while (i < j) {
1849671Slinton 		if (linetab[i].line == line) {
1859671Slinton 		    return linetab[i].addr;
1869671Slinton 		}
1879671Slinton 		i++;
1889671Slinton 	    }
1899671Slinton 	}
1909671Slinton     }
1919671Slinton     if (not foundfile) {
1929671Slinton 	error("unknown source file \"%s\"", name);
1939671Slinton     }
1949671Slinton     return NOADDR;
1959671Slinton }
1969671Slinton 
1979671Slinton /*
1989671Slinton  * Table for going from object addresses to the functions in which they belong.
1999671Slinton  */
2009671Slinton 
2019671Slinton #define MAXNFUNCS 1001      /* maximum number of functions allowed */
2029671Slinton 
203*14439Slinton typedef struct {
204*14439Slinton     Symbol func;
205*14439Slinton     Address addr;
206*14439Slinton } AddrOfFunc;
207*14439Slinton 
208*14439Slinton private AddrOfFunc functab[MAXNFUNCS];
2099671Slinton private int nfuncs;
2109671Slinton 
2119671Slinton /*
2129671Slinton  * Insert a new function into the table.
2139671Slinton  * The table is ordered by object address.
2149671Slinton  */
2159671Slinton 
216*14439Slinton public newfunc(f, addr)
2179671Slinton Symbol f;
218*14439Slinton Address addr;
2199671Slinton {
220*14439Slinton     register AddrOfFunc *af;
221*14439Slinton 
2229671Slinton     if (nfuncs >= MAXNFUNCS) {
2239671Slinton 	panic("too many procedures/functions");
2249671Slinton     }
225*14439Slinton     af = &functab[nfuncs];
226*14439Slinton     af->func = f;
227*14439Slinton     af->addr = addr;
2289671Slinton     ++nfuncs;
2299671Slinton }
2309671Slinton 
2319671Slinton /*
2329671Slinton  * Return the function that begins at the given address.
2339671Slinton  */
2349671Slinton 
2359671Slinton public Symbol whatblock(addr)
2369671Slinton Address addr;
2379671Slinton {
2389671Slinton     register int i, j, k;
2399671Slinton     Address a;
2409671Slinton 
2419671Slinton     i = 0;
2429671Slinton     j = nfuncs - 1;
243*14439Slinton     if (addr < functab[i].addr) {
2449671Slinton 	return program;
245*14439Slinton     } else if (addr == functab[i].addr) {
246*14439Slinton 	return functab[i].func;
247*14439Slinton     } else if (addr >= functab[j].addr) {
248*14439Slinton 	return functab[j].func;
2499671Slinton     }
2509671Slinton     while (i <= j) {
2519671Slinton 	k = (i + j) / 2;
252*14439Slinton 	a = functab[k].addr;
2539671Slinton 	if (a == addr) {
254*14439Slinton 	    return functab[k].func;
2559671Slinton 	} else if (addr > a) {
2569671Slinton 	    i = k+1;
2579671Slinton 	} else {
2589671Slinton 	    j = k-1;
2599671Slinton 	}
2609671Slinton     }
261*14439Slinton     if (addr > functab[i].addr) {
262*14439Slinton 	return functab[i].func;
2639671Slinton     } else {
264*14439Slinton 	return functab[i-1].func;
2659671Slinton     }
2669671Slinton     /* NOTREACHED */
2679671Slinton }
2689671Slinton 
2699671Slinton /*
2709671Slinton  * Order the functab.
2719671Slinton  */
2729671Slinton 
2739671Slinton private int cmpfunc(f1, f2)
274*14439Slinton AddrOfFunc *f1, *f2;
2759671Slinton {
2769671Slinton     register Address a1, a2;
2779671Slinton 
278*14439Slinton     a1 = (*f1).addr;
279*14439Slinton     a2 = (*f2).addr;
2809671Slinton     return ( (a1 < a2) ? -1 : ( (a1 == a2) ? 0 : 1 ) );
2819671Slinton }
2829671Slinton 
2839671Slinton public ordfunctab()
2849671Slinton {
285*14439Slinton     qsort(functab, nfuncs, sizeof(AddrOfFunc), cmpfunc);
2869671Slinton }
2879671Slinton 
2889671Slinton /*
2899671Slinton  * Clear out the functab, used when re-reading the object information.
2909671Slinton  */
2919671Slinton 
2929671Slinton public clrfunctab()
2939671Slinton {
2949671Slinton     nfuncs = 0;
2959671Slinton }
29612541Scsvaf 
29712541Scsvaf public dumpfunctab()
29812541Scsvaf {
299*14439Slinton     int i;
30012541Scsvaf 
301*14439Slinton     for (i = 0; i < nfuncs; i++) {
302*14439Slinton 	psym(functab[i].func);
303*14439Slinton     }
30412541Scsvaf }
305