xref: /csrg-svn/old/dbx/mappings.c (revision 9671)
1*9671Slinton /* Copyright (c) 1982 Regents of the University of California */
2*9671Slinton 
3*9671Slinton static char sccsid[] = "@(#)@(#)mappings.c 1.1 12/15/82";
4*9671Slinton 
5*9671Slinton /*
6*9671Slinton  * Source-to-object and vice versa mappings.
7*9671Slinton  */
8*9671Slinton 
9*9671Slinton #include "defs.h"
10*9671Slinton #include "mappings.h"
11*9671Slinton #include "symbols.h"
12*9671Slinton #include "source.h"
13*9671Slinton #include "object.h"
14*9671Slinton #include "machine.h"
15*9671Slinton 
16*9671Slinton #ifndef public
17*9671Slinton #include "machine.h"
18*9671Slinton #include "source.h"
19*9671Slinton #include "symbols.h"
20*9671Slinton 
21*9671Slinton typedef struct {
22*9671Slinton     Address addr;
23*9671Slinton     String filename;
24*9671Slinton     Lineno lineindex;		/* index to first linetab entry */
25*9671Slinton } Filetab;
26*9671Slinton 
27*9671Slinton typedef struct {
28*9671Slinton     Lineno line;
29*9671Slinton     Address addr;
30*9671Slinton } Linetab;
31*9671Slinton 
32*9671Slinton Filetab *filetab;
33*9671Slinton Linetab *linetab;
34*9671Slinton 
35*9671Slinton #define NOADDR ((Address) -1)	/* no address for line or procedure */
36*9671Slinton 
37*9671Slinton #endif
38*9671Slinton 
39*9671Slinton /*
40*9671Slinton  * Get the source file name associated with a given address.
41*9671Slinton  */
42*9671Slinton 
43*9671Slinton public String srcfilename(addr)
44*9671Slinton Address addr;
45*9671Slinton {
46*9671Slinton     register Address i, j, k;
47*9671Slinton     Address a;
48*9671Slinton     Filetab *ftp;
49*9671Slinton     String s;
50*9671Slinton 
51*9671Slinton     s = nil;
52*9671Slinton     if (nlhdr.nfiles != 0 and addr >= filetab[0].addr) {
53*9671Slinton 	i = 0;
54*9671Slinton 	j = nlhdr.nfiles - 1;
55*9671Slinton 	while (i < j) {
56*9671Slinton 	    k = (i + j) / 2;
57*9671Slinton 	    ftp = &filetab[k];
58*9671Slinton 	    a = ftp->addr;
59*9671Slinton 	    if (a == addr) {
60*9671Slinton 		s = ftp->filename;
61*9671Slinton 		break;
62*9671Slinton 	    } else if (addr > a) {
63*9671Slinton 		i = k + 1;
64*9671Slinton 	    } else {
65*9671Slinton 		j = k - 1;
66*9671Slinton 	    }
67*9671Slinton 	}
68*9671Slinton 	if (s == nil) {
69*9671Slinton 	    if (addr >= filetab[i].addr) {
70*9671Slinton 		s = filetab[i].filename;
71*9671Slinton 	    } else {
72*9671Slinton 		s = filetab[i-1].filename;
73*9671Slinton 	    }
74*9671Slinton 	}
75*9671Slinton     }
76*9671Slinton     return s;
77*9671Slinton }
78*9671Slinton 
79*9671Slinton /*
80*9671Slinton  * Find the line associated with the given address.
81*9671Slinton  * If the second parameter is true, then the address must match
82*9671Slinton  * a source line exactly.  Otherwise the nearest source line
83*9671Slinton  * below the given address is returned.  In any case, if no suitable
84*9671Slinton  * line exists, 0 is returned.
85*9671Slinton  */
86*9671Slinton 
87*9671Slinton private Lineno findline(addr, exact)
88*9671Slinton Address addr;
89*9671Slinton Boolean exact;
90*9671Slinton {
91*9671Slinton     register Address i, j, k;
92*9671Slinton     register Lineno r;
93*9671Slinton     register Address a;
94*9671Slinton 
95*9671Slinton     if (nlhdr.nlines == 0 or addr < linetab[0].addr) {
96*9671Slinton 	r = 0;
97*9671Slinton     } else {
98*9671Slinton 	i = 0;
99*9671Slinton 	j = nlhdr.nlines - 1;
100*9671Slinton 	if (addr == linetab[i].addr) {
101*9671Slinton 	    r = linetab[i].line;
102*9671Slinton 	} else if (addr == linetab[j].addr) {
103*9671Slinton 	    r = linetab[j].line;
104*9671Slinton 	} else if (addr > linetab[j].addr) {
105*9671Slinton 	    r = exact ? 0 : linetab[j].line;
106*9671Slinton 	} else {
107*9671Slinton 	    do {
108*9671Slinton 		k = (i + j) div 2;
109*9671Slinton 		a = linetab[k].addr;
110*9671Slinton 	    if (a == addr) break;
111*9671Slinton 		if (addr > a) {
112*9671Slinton 		    i = k + 1;
113*9671Slinton 		} else {
114*9671Slinton 		    j = k - 1;
115*9671Slinton 		}
116*9671Slinton 	    } while (i <= j);
117*9671Slinton 	    if (a == addr) {
118*9671Slinton 		r = linetab[k].line;
119*9671Slinton 	    } else if (exact) {
120*9671Slinton 		r = 0;
121*9671Slinton 	    } else if (addr > linetab[i].addr) {
122*9671Slinton 		r = linetab[i].line;
123*9671Slinton 	    } else {
124*9671Slinton 		r = linetab[i-1].line;
125*9671Slinton 	    }
126*9671Slinton 	}
127*9671Slinton     }
128*9671Slinton     return r;
129*9671Slinton }
130*9671Slinton 
131*9671Slinton /*
132*9671Slinton  * Lookup the source line number nearest from below to an address.
133*9671Slinton  */
134*9671Slinton 
135*9671Slinton public Lineno srcline(addr)
136*9671Slinton Address addr;
137*9671Slinton {
138*9671Slinton     return findline(addr, false);
139*9671Slinton }
140*9671Slinton 
141*9671Slinton /*
142*9671Slinton  * Look for a line exactly corresponding to the given address.
143*9671Slinton  */
144*9671Slinton 
145*9671Slinton public Lineno linelookup(addr)
146*9671Slinton Address addr;
147*9671Slinton {
148*9671Slinton     return findline(addr, true);
149*9671Slinton }
150*9671Slinton 
151*9671Slinton /*
152*9671Slinton  * Lookup the object address of a given line from the named file.
153*9671Slinton  *
154*9671Slinton  * Potentially all files in the file table need to be checked
155*9671Slinton  * until the line is found since a particular file name may appear
156*9671Slinton  * more than once in the file table (caused by includes).
157*9671Slinton  */
158*9671Slinton 
159*9671Slinton public Address objaddr(line, name)
160*9671Slinton Lineno line;
161*9671Slinton String name;
162*9671Slinton {
163*9671Slinton     register Filetab *ftp;
164*9671Slinton     register Lineno i, j;
165*9671Slinton     Boolean foundfile;
166*9671Slinton 
167*9671Slinton     if (nlhdr.nlines == 0) {
168*9671Slinton 	return NOADDR;
169*9671Slinton     }
170*9671Slinton     if (name == nil) {
171*9671Slinton 	name = cursource;
172*9671Slinton     }
173*9671Slinton     foundfile = false;
174*9671Slinton     for (ftp = &filetab[0]; ftp < &filetab[nlhdr.nfiles]; ftp++) {
175*9671Slinton 	if (streq(ftp->filename, name)) {
176*9671Slinton 	    foundfile = true;
177*9671Slinton 	    i = ftp->lineindex;
178*9671Slinton 	    if (ftp == &filetab[nlhdr.nfiles-1]) {
179*9671Slinton 		j = nlhdr.nlines;
180*9671Slinton 	    } else {
181*9671Slinton 		j = (ftp + 1)->lineindex;
182*9671Slinton 	    }
183*9671Slinton 	    while (i < j) {
184*9671Slinton 		if (linetab[i].line == line) {
185*9671Slinton 		    return linetab[i].addr;
186*9671Slinton 		}
187*9671Slinton 		i++;
188*9671Slinton 	    }
189*9671Slinton 	}
190*9671Slinton     }
191*9671Slinton     if (not foundfile) {
192*9671Slinton 	error("unknown source file \"%s\"", name);
193*9671Slinton     }
194*9671Slinton     return NOADDR;
195*9671Slinton }
196*9671Slinton 
197*9671Slinton /*
198*9671Slinton  * Table for going from object addresses to the functions in which they belong.
199*9671Slinton  */
200*9671Slinton 
201*9671Slinton #define MAXNFUNCS 1001      /* maximum number of functions allowed */
202*9671Slinton 
203*9671Slinton private Symbol functab[MAXNFUNCS];
204*9671Slinton private int nfuncs;
205*9671Slinton 
206*9671Slinton /*
207*9671Slinton  * Insert a new function into the table.
208*9671Slinton  * The table is ordered by object address.
209*9671Slinton  */
210*9671Slinton 
211*9671Slinton public newfunc(f)
212*9671Slinton Symbol f;
213*9671Slinton {
214*9671Slinton     if (nfuncs >= MAXNFUNCS) {
215*9671Slinton 	panic("too many procedures/functions");
216*9671Slinton     }
217*9671Slinton     functab[nfuncs] = f;
218*9671Slinton     ++nfuncs;
219*9671Slinton }
220*9671Slinton 
221*9671Slinton /*
222*9671Slinton  * Return the function that begins at the given address.
223*9671Slinton  */
224*9671Slinton 
225*9671Slinton public Symbol whatblock(addr)
226*9671Slinton Address addr;
227*9671Slinton {
228*9671Slinton     register int i, j, k;
229*9671Slinton     Address a;
230*9671Slinton 
231*9671Slinton     i = 0;
232*9671Slinton     j = nfuncs - 1;
233*9671Slinton     if (addr < codeloc(functab[i])) {
234*9671Slinton 	return program;
235*9671Slinton     } else if (addr == codeloc(functab[i])) {
236*9671Slinton 	return functab[i];
237*9671Slinton     } else if (addr >= codeloc(functab[j])) {
238*9671Slinton 	return functab[j];
239*9671Slinton     }
240*9671Slinton     while (i <= j) {
241*9671Slinton 	k = (i + j) / 2;
242*9671Slinton 	a = codeloc(functab[k]);
243*9671Slinton 	if (a == addr) {
244*9671Slinton 	    return functab[k];
245*9671Slinton 	} else if (addr > a) {
246*9671Slinton 	    i = k+1;
247*9671Slinton 	} else {
248*9671Slinton 	    j = k-1;
249*9671Slinton 	}
250*9671Slinton     }
251*9671Slinton     if (addr > codeloc(functab[i])) {
252*9671Slinton 	return functab[i];
253*9671Slinton     } else {
254*9671Slinton 	return functab[i-1];
255*9671Slinton     }
256*9671Slinton     /* NOTREACHED */
257*9671Slinton }
258*9671Slinton 
259*9671Slinton /*
260*9671Slinton  * Order the functab.
261*9671Slinton  */
262*9671Slinton 
263*9671Slinton private int cmpfunc(f1, f2)
264*9671Slinton Symbol *f1, *f2;
265*9671Slinton {
266*9671Slinton     register Address a1, a2;
267*9671Slinton 
268*9671Slinton     a1 = codeloc(*f1);
269*9671Slinton     a2 = codeloc(*f2);
270*9671Slinton     return ( (a1 < a2) ? -1 : ( (a1 == a2) ? 0 : 1 ) );
271*9671Slinton }
272*9671Slinton 
273*9671Slinton public ordfunctab()
274*9671Slinton {
275*9671Slinton     qsort(functab, nfuncs, sizeof(Symbol), cmpfunc);
276*9671Slinton }
277*9671Slinton 
278*9671Slinton /*
279*9671Slinton  * Clear out the functab, used when re-reading the object information.
280*9671Slinton  */
281*9671Slinton 
282*9671Slinton public clrfunctab()
283*9671Slinton {
284*9671Slinton     nfuncs = 0;
285*9671Slinton }
286