xref: /csrg-svn/old/dbx/mappings.c (revision 21611)
1*21611Sdist /*
2*21611Sdist  * Copyright (c) 1983 Regents of the University of California.
3*21611Sdist  * All rights reserved.  The Berkeley software License Agreement
4*21611Sdist  * specifies the terms and conditions for redistribution.
5*21611Sdist  */
69671Slinton 
7*21611Sdist #ifndef lint
8*21611Sdist static char sccsid[] = "@(#)mappings.c	5.1 (Berkeley) 05/31/85";
9*21611Sdist #endif not lint
109671Slinton 
1118224Slinton static char rcsid[] = "$Header: mappings.c,v 1.4 84/12/26 10:40:25 linton Exp $";
1218224Slinton 
139671Slinton /*
149671Slinton  * Source-to-object and vice versa mappings.
159671Slinton  */
169671Slinton 
179671Slinton #include "defs.h"
189671Slinton #include "mappings.h"
199671Slinton #include "symbols.h"
209671Slinton #include "source.h"
219671Slinton #include "object.h"
229671Slinton #include "machine.h"
239671Slinton 
249671Slinton #ifndef public
259671Slinton #include "machine.h"
269671Slinton #include "source.h"
279671Slinton #include "symbols.h"
289671Slinton 
299671Slinton typedef struct {
309671Slinton     Address addr;
319671Slinton     String filename;
329671Slinton     Lineno lineindex;		/* index to first linetab entry */
339671Slinton } Filetab;
349671Slinton 
359671Slinton typedef struct {
369671Slinton     Lineno line;
379671Slinton     Address addr;
389671Slinton } Linetab;
399671Slinton 
409671Slinton Filetab *filetab;
419671Slinton Linetab *linetab;
429671Slinton 
439671Slinton #define NOADDR ((Address) -1)	/* no address for line or procedure */
449671Slinton 
459671Slinton #endif
469671Slinton 
479671Slinton /*
489671Slinton  * Get the source file name associated with a given address.
499671Slinton  */
509671Slinton 
519671Slinton public String srcfilename(addr)
529671Slinton Address addr;
539671Slinton {
549671Slinton     register Address i, j, k;
559671Slinton     Address a;
569671Slinton     Filetab *ftp;
579671Slinton     String s;
589671Slinton 
599671Slinton     s = nil;
609671Slinton     if (nlhdr.nfiles != 0 and addr >= filetab[0].addr) {
619671Slinton 	i = 0;
629671Slinton 	j = nlhdr.nfiles - 1;
639671Slinton 	while (i < j) {
649671Slinton 	    k = (i + j) / 2;
659671Slinton 	    ftp = &filetab[k];
669671Slinton 	    a = ftp->addr;
679671Slinton 	    if (a == addr) {
689671Slinton 		s = ftp->filename;
699671Slinton 		break;
709671Slinton 	    } else if (addr > a) {
719671Slinton 		i = k + 1;
729671Slinton 	    } else {
739671Slinton 		j = k - 1;
749671Slinton 	    }
759671Slinton 	}
769671Slinton 	if (s == nil) {
779671Slinton 	    if (addr >= filetab[i].addr) {
789671Slinton 		s = filetab[i].filename;
799671Slinton 	    } else {
809671Slinton 		s = filetab[i-1].filename;
819671Slinton 	    }
829671Slinton 	}
839671Slinton     }
849671Slinton     return s;
859671Slinton }
869671Slinton 
879671Slinton /*
889671Slinton  * Find the line associated with the given address.
899671Slinton  * If the second parameter is true, then the address must match
909671Slinton  * a source line exactly.  Otherwise the nearest source line
9118224Slinton  * below the given address is returned.
9218224Slinton  *
9318224Slinton  * Return the index of the line table entry or -1 if none suitable.
949671Slinton  */
959671Slinton 
9618224Slinton private integer findline (addr, exact)
979671Slinton Address addr;
989671Slinton Boolean exact;
999671Slinton {
1009671Slinton     register Address i, j, k;
1019671Slinton     register Lineno r;
1029671Slinton     register Address a;
1039671Slinton 
1049671Slinton     if (nlhdr.nlines == 0 or addr < linetab[0].addr) {
10518224Slinton 	r = -1;
1069671Slinton     } else {
1079671Slinton 	i = 0;
1089671Slinton 	j = nlhdr.nlines - 1;
1099671Slinton 	if (addr == linetab[i].addr) {
11018224Slinton 	    r = i;
1119671Slinton 	} else if (addr == linetab[j].addr) {
11218224Slinton 	    r = j;
1139671Slinton 	} else if (addr > linetab[j].addr) {
11418224Slinton 	    r = exact ? -1 : j;
1159671Slinton 	} else {
1169671Slinton 	    do {
1179671Slinton 		k = (i + j) div 2;
1189671Slinton 		a = linetab[k].addr;
1199671Slinton 	    if (a == addr) break;
1209671Slinton 		if (addr > a) {
1219671Slinton 		    i = k + 1;
1229671Slinton 		} else {
1239671Slinton 		    j = k - 1;
1249671Slinton 		}
1259671Slinton 	    } while (i <= j);
1269671Slinton 	    if (a == addr) {
12718224Slinton 		r = k;
1289671Slinton 	    } else if (exact) {
12918224Slinton 		r = -1;
1309671Slinton 	    } else if (addr > linetab[i].addr) {
13118224Slinton 		r = i;
1329671Slinton 	    } else {
13318224Slinton 		r = i - 1;
1349671Slinton 	    }
1359671Slinton 	}
1369671Slinton     }
1379671Slinton     return r;
1389671Slinton }
1399671Slinton 
1409671Slinton /*
14118224Slinton  * Lookup the source line number nearest (from below) to an address.
14218224Slinton  *
14318224Slinton  * It is possible (unfortunately) that the compiler will generate
14418224Slinton  * code before line number for a procedure.  Therefore we check
14518224Slinton  * to see that the found line is in the same procedure as the given address.
14618224Slinton  * If it isn't, then we walk forward until the first suitable line is found.
1479671Slinton  */
1489671Slinton 
1499671Slinton public Lineno srcline(addr)
1509671Slinton Address addr;
1519671Slinton {
15218224Slinton     integer i;
15318224Slinton     Lineno r;
15418224Slinton     Symbol f1, f2;
15518224Slinton 
15618224Slinton     i = findline(addr, false);
15718224Slinton     if (i == -1) {
15818224Slinton 	r = 0;
15918224Slinton     } else {
16018224Slinton 	r = linetab[i].line;
16118224Slinton 	if (linetab[i].addr != addr) {
16218224Slinton 	    f1 = whatblock(addr);
16318224Slinton 	    if (nosource(f1)) {
16418224Slinton 		r = 0;
16518224Slinton 	    } else {
16618224Slinton 		f2 = whatblock(linetab[i].addr + 1);
16718224Slinton 		if (f1 != f2) {
16818224Slinton 		    do {
16918224Slinton 			++i;
17018224Slinton 		    } while (linetab[i].addr < addr and i < nlhdr.nlines);
17118224Slinton 		    r = linetab[i].line;
17218224Slinton 		}
17318224Slinton 	    }
17418224Slinton 	}
17518224Slinton     }
17618224Slinton     return r;
1779671Slinton }
1789671Slinton 
1799671Slinton /*
1809671Slinton  * Look for a line exactly corresponding to the given address.
1819671Slinton  */
1829671Slinton 
1839671Slinton public Lineno linelookup(addr)
1849671Slinton Address addr;
1859671Slinton {
18618224Slinton     integer i;
18718224Slinton     Lineno r;
18818224Slinton 
18918224Slinton     i = findline(addr, true);
19018224Slinton     if (i == -1) {
19118224Slinton 	r = 0;
19218224Slinton     } else {
19318224Slinton 	r = linetab[i].line;
19418224Slinton     }
19518224Slinton     return r;
1969671Slinton }
1979671Slinton 
1989671Slinton /*
1999671Slinton  * Lookup the object address of a given line from the named file.
2009671Slinton  *
2019671Slinton  * Potentially all files in the file table need to be checked
2029671Slinton  * until the line is found since a particular file name may appear
2039671Slinton  * more than once in the file table (caused by includes).
2049671Slinton  */
2059671Slinton 
2069671Slinton public Address objaddr(line, name)
2079671Slinton Lineno line;
2089671Slinton String name;
2099671Slinton {
2109671Slinton     register Filetab *ftp;
2119671Slinton     register Lineno i, j;
2129671Slinton     Boolean foundfile;
2139671Slinton 
2149671Slinton     if (nlhdr.nlines == 0) {
2159671Slinton 	return NOADDR;
2169671Slinton     }
2179671Slinton     if (name == nil) {
2189671Slinton 	name = cursource;
2199671Slinton     }
2209671Slinton     foundfile = false;
2219671Slinton     for (ftp = &filetab[0]; ftp < &filetab[nlhdr.nfiles]; ftp++) {
2229671Slinton 	if (streq(ftp->filename, name)) {
2239671Slinton 	    foundfile = true;
2249671Slinton 	    i = ftp->lineindex;
2259671Slinton 	    if (ftp == &filetab[nlhdr.nfiles-1]) {
2269671Slinton 		j = nlhdr.nlines;
2279671Slinton 	    } else {
2289671Slinton 		j = (ftp + 1)->lineindex;
2299671Slinton 	    }
2309671Slinton 	    while (i < j) {
2319671Slinton 		if (linetab[i].line == line) {
2329671Slinton 		    return linetab[i].addr;
2339671Slinton 		}
2349671Slinton 		i++;
2359671Slinton 	    }
2369671Slinton 	}
2379671Slinton     }
2389671Slinton     if (not foundfile) {
23918224Slinton 	error("source file \"%s\" not compiled with -g", name);
2409671Slinton     }
2419671Slinton     return NOADDR;
2429671Slinton }
2439671Slinton 
2449671Slinton /*
2459671Slinton  * Table for going from object addresses to the functions in which they belong.
2469671Slinton  */
2479671Slinton 
24818224Slinton #define NFUNCS 500	/* initial size of function table */
2499671Slinton 
25014439Slinton typedef struct {
25114439Slinton     Symbol func;
25214439Slinton     Address addr;
25314439Slinton } AddrOfFunc;
25414439Slinton 
25518224Slinton private AddrOfFunc *functab;
25618224Slinton private int nfuncs = 0;
25718224Slinton private int functablesize = 0;
2589671Slinton 
2599671Slinton /*
2609671Slinton  * Insert a new function into the table.
2619671Slinton  */
2629671Slinton 
26314439Slinton public newfunc(f, addr)
2649671Slinton Symbol f;
26514439Slinton Address addr;
2669671Slinton {
26714439Slinton     register AddrOfFunc *af;
26818224Slinton     register int i;
26918224Slinton     AddrOfFunc *newfunctab;
27014439Slinton 
27118224Slinton     if (nfuncs >= functablesize) {
27218224Slinton 	if (functablesize == 0) {
27318224Slinton 	    functab = newarr(AddrOfFunc, NFUNCS);
27418224Slinton 	    functablesize = NFUNCS;
27518224Slinton 	} else {
27618224Slinton 	    functablesize *= 2;
27718224Slinton 	    newfunctab = newarr(AddrOfFunc, functablesize);
27818224Slinton 	    bcopy(functab, newfunctab, nfuncs * sizeof(AddrOfFunc));
27918224Slinton 	    dispose(functab);
28018224Slinton 	    functab = newfunctab;
28118224Slinton 	}
2829671Slinton     }
28314439Slinton     af = &functab[nfuncs];
28414439Slinton     af->func = f;
28514439Slinton     af->addr = addr;
2869671Slinton     ++nfuncs;
2879671Slinton }
2889671Slinton 
2899671Slinton /*
2909671Slinton  * Return the function that begins at the given address.
2919671Slinton  */
2929671Slinton 
2939671Slinton public Symbol whatblock(addr)
2949671Slinton Address addr;
2959671Slinton {
2969671Slinton     register int i, j, k;
2979671Slinton     Address a;
2989671Slinton 
2999671Slinton     i = 0;
3009671Slinton     j = nfuncs - 1;
30114439Slinton     if (addr < functab[i].addr) {
3029671Slinton 	return program;
30314439Slinton     } else if (addr == functab[i].addr) {
30414439Slinton 	return functab[i].func;
30514439Slinton     } else if (addr >= functab[j].addr) {
30614439Slinton 	return functab[j].func;
3079671Slinton     }
3089671Slinton     while (i <= j) {
3099671Slinton 	k = (i + j) / 2;
31014439Slinton 	a = functab[k].addr;
3119671Slinton 	if (a == addr) {
31214439Slinton 	    return functab[k].func;
3139671Slinton 	} else if (addr > a) {
3149671Slinton 	    i = k+1;
3159671Slinton 	} else {
3169671Slinton 	    j = k-1;
3179671Slinton 	}
3189671Slinton     }
31914439Slinton     if (addr > functab[i].addr) {
32014439Slinton 	return functab[i].func;
3219671Slinton     } else {
32214439Slinton 	return functab[i-1].func;
3239671Slinton     }
3249671Slinton     /* NOTREACHED */
3259671Slinton }
3269671Slinton 
3279671Slinton /*
3289671Slinton  * Order the functab.
3299671Slinton  */
3309671Slinton 
3319671Slinton private int cmpfunc(f1, f2)
33214439Slinton AddrOfFunc *f1, *f2;
3339671Slinton {
3349671Slinton     register Address a1, a2;
3359671Slinton 
33614439Slinton     a1 = (*f1).addr;
33714439Slinton     a2 = (*f2).addr;
3389671Slinton     return ( (a1 < a2) ? -1 : ( (a1 == a2) ? 0 : 1 ) );
3399671Slinton }
3409671Slinton 
3419671Slinton public ordfunctab()
3429671Slinton {
34314439Slinton     qsort(functab, nfuncs, sizeof(AddrOfFunc), cmpfunc);
3449671Slinton }
3459671Slinton 
3469671Slinton /*
3479671Slinton  * Clear out the functab, used when re-reading the object information.
3489671Slinton  */
3499671Slinton 
3509671Slinton public clrfunctab()
3519671Slinton {
3529671Slinton     nfuncs = 0;
3539671Slinton }
35412541Scsvaf 
35512541Scsvaf public dumpfunctab()
35612541Scsvaf {
35714439Slinton     int i;
35812541Scsvaf 
35914439Slinton     for (i = 0; i < nfuncs; i++) {
36014439Slinton 	psym(functab[i].func);
36114439Slinton     }
36212541Scsvaf }
363