xref: /original-bsd/old/dbx/mappings.c (revision 0f89e6eb)
1 /*
2  * Copyright (c) 1983 Regents of the University of California.
3  * All rights reserved.  The Berkeley software License Agreement
4  * specifies the terms and conditions for redistribution.
5  */
6 
7 #ifndef lint
8 static char sccsid[] = "@(#)mappings.c	5.1 (Berkeley) 05/31/85";
9 #endif not lint
10 
11 static char rcsid[] = "$Header: mappings.c,v 1.4 84/12/26 10:40:25 linton Exp $";
12 
13 /*
14  * Source-to-object and vice versa mappings.
15  */
16 
17 #include "defs.h"
18 #include "mappings.h"
19 #include "symbols.h"
20 #include "source.h"
21 #include "object.h"
22 #include "machine.h"
23 
24 #ifndef public
25 #include "machine.h"
26 #include "source.h"
27 #include "symbols.h"
28 
29 typedef struct {
30     Address addr;
31     String filename;
32     Lineno lineindex;		/* index to first linetab entry */
33 } Filetab;
34 
35 typedef struct {
36     Lineno line;
37     Address addr;
38 } Linetab;
39 
40 Filetab *filetab;
41 Linetab *linetab;
42 
43 #define NOADDR ((Address) -1)	/* no address for line or procedure */
44 
45 #endif
46 
47 /*
48  * Get the source file name associated with a given address.
49  */
50 
51 public String srcfilename(addr)
52 Address addr;
53 {
54     register Address i, j, k;
55     Address a;
56     Filetab *ftp;
57     String s;
58 
59     s = nil;
60     if (nlhdr.nfiles != 0 and addr >= filetab[0].addr) {
61 	i = 0;
62 	j = nlhdr.nfiles - 1;
63 	while (i < j) {
64 	    k = (i + j) / 2;
65 	    ftp = &filetab[k];
66 	    a = ftp->addr;
67 	    if (a == addr) {
68 		s = ftp->filename;
69 		break;
70 	    } else if (addr > a) {
71 		i = k + 1;
72 	    } else {
73 		j = k - 1;
74 	    }
75 	}
76 	if (s == nil) {
77 	    if (addr >= filetab[i].addr) {
78 		s = filetab[i].filename;
79 	    } else {
80 		s = filetab[i-1].filename;
81 	    }
82 	}
83     }
84     return s;
85 }
86 
87 /*
88  * Find the line associated with the given address.
89  * If the second parameter is true, then the address must match
90  * a source line exactly.  Otherwise the nearest source line
91  * below the given address is returned.
92  *
93  * Return the index of the line table entry or -1 if none suitable.
94  */
95 
96 private integer findline (addr, exact)
97 Address addr;
98 Boolean exact;
99 {
100     register Address i, j, k;
101     register Lineno r;
102     register Address a;
103 
104     if (nlhdr.nlines == 0 or addr < linetab[0].addr) {
105 	r = -1;
106     } else {
107 	i = 0;
108 	j = nlhdr.nlines - 1;
109 	if (addr == linetab[i].addr) {
110 	    r = i;
111 	} else if (addr == linetab[j].addr) {
112 	    r = j;
113 	} else if (addr > linetab[j].addr) {
114 	    r = exact ? -1 : j;
115 	} else {
116 	    do {
117 		k = (i + j) div 2;
118 		a = linetab[k].addr;
119 	    if (a == addr) break;
120 		if (addr > a) {
121 		    i = k + 1;
122 		} else {
123 		    j = k - 1;
124 		}
125 	    } while (i <= j);
126 	    if (a == addr) {
127 		r = k;
128 	    } else if (exact) {
129 		r = -1;
130 	    } else if (addr > linetab[i].addr) {
131 		r = i;
132 	    } else {
133 		r = i - 1;
134 	    }
135 	}
136     }
137     return r;
138 }
139 
140 /*
141  * Lookup the source line number nearest (from below) to an address.
142  *
143  * It is possible (unfortunately) that the compiler will generate
144  * code before line number for a procedure.  Therefore we check
145  * to see that the found line is in the same procedure as the given address.
146  * If it isn't, then we walk forward until the first suitable line is found.
147  */
148 
149 public Lineno srcline(addr)
150 Address addr;
151 {
152     integer i;
153     Lineno r;
154     Symbol f1, f2;
155 
156     i = findline(addr, false);
157     if (i == -1) {
158 	r = 0;
159     } else {
160 	r = linetab[i].line;
161 	if (linetab[i].addr != addr) {
162 	    f1 = whatblock(addr);
163 	    if (nosource(f1)) {
164 		r = 0;
165 	    } else {
166 		f2 = whatblock(linetab[i].addr + 1);
167 		if (f1 != f2) {
168 		    do {
169 			++i;
170 		    } while (linetab[i].addr < addr and i < nlhdr.nlines);
171 		    r = linetab[i].line;
172 		}
173 	    }
174 	}
175     }
176     return r;
177 }
178 
179 /*
180  * Look for a line exactly corresponding to the given address.
181  */
182 
183 public Lineno linelookup(addr)
184 Address addr;
185 {
186     integer i;
187     Lineno r;
188 
189     i = findline(addr, true);
190     if (i == -1) {
191 	r = 0;
192     } else {
193 	r = linetab[i].line;
194     }
195     return r;
196 }
197 
198 /*
199  * Lookup the object address of a given line from the named file.
200  *
201  * Potentially all files in the file table need to be checked
202  * until the line is found since a particular file name may appear
203  * more than once in the file table (caused by includes).
204  */
205 
206 public Address objaddr(line, name)
207 Lineno line;
208 String name;
209 {
210     register Filetab *ftp;
211     register Lineno i, j;
212     Boolean foundfile;
213 
214     if (nlhdr.nlines == 0) {
215 	return NOADDR;
216     }
217     if (name == nil) {
218 	name = cursource;
219     }
220     foundfile = false;
221     for (ftp = &filetab[0]; ftp < &filetab[nlhdr.nfiles]; ftp++) {
222 	if (streq(ftp->filename, name)) {
223 	    foundfile = true;
224 	    i = ftp->lineindex;
225 	    if (ftp == &filetab[nlhdr.nfiles-1]) {
226 		j = nlhdr.nlines;
227 	    } else {
228 		j = (ftp + 1)->lineindex;
229 	    }
230 	    while (i < j) {
231 		if (linetab[i].line == line) {
232 		    return linetab[i].addr;
233 		}
234 		i++;
235 	    }
236 	}
237     }
238     if (not foundfile) {
239 	error("source file \"%s\" not compiled with -g", name);
240     }
241     return NOADDR;
242 }
243 
244 /*
245  * Table for going from object addresses to the functions in which they belong.
246  */
247 
248 #define NFUNCS 500	/* initial size of function table */
249 
250 typedef struct {
251     Symbol func;
252     Address addr;
253 } AddrOfFunc;
254 
255 private AddrOfFunc *functab;
256 private int nfuncs = 0;
257 private int functablesize = 0;
258 
259 /*
260  * Insert a new function into the table.
261  */
262 
263 public newfunc(f, addr)
264 Symbol f;
265 Address addr;
266 {
267     register AddrOfFunc *af;
268     register int i;
269     AddrOfFunc *newfunctab;
270 
271     if (nfuncs >= functablesize) {
272 	if (functablesize == 0) {
273 	    functab = newarr(AddrOfFunc, NFUNCS);
274 	    functablesize = NFUNCS;
275 	} else {
276 	    functablesize *= 2;
277 	    newfunctab = newarr(AddrOfFunc, functablesize);
278 	    bcopy(functab, newfunctab, nfuncs * sizeof(AddrOfFunc));
279 	    dispose(functab);
280 	    functab = newfunctab;
281 	}
282     }
283     af = &functab[nfuncs];
284     af->func = f;
285     af->addr = addr;
286     ++nfuncs;
287 }
288 
289 /*
290  * Return the function that begins at the given address.
291  */
292 
293 public Symbol whatblock(addr)
294 Address addr;
295 {
296     register int i, j, k;
297     Address a;
298 
299     i = 0;
300     j = nfuncs - 1;
301     if (addr < functab[i].addr) {
302 	return program;
303     } else if (addr == functab[i].addr) {
304 	return functab[i].func;
305     } else if (addr >= functab[j].addr) {
306 	return functab[j].func;
307     }
308     while (i <= j) {
309 	k = (i + j) / 2;
310 	a = functab[k].addr;
311 	if (a == addr) {
312 	    return functab[k].func;
313 	} else if (addr > a) {
314 	    i = k+1;
315 	} else {
316 	    j = k-1;
317 	}
318     }
319     if (addr > functab[i].addr) {
320 	return functab[i].func;
321     } else {
322 	return functab[i-1].func;
323     }
324     /* NOTREACHED */
325 }
326 
327 /*
328  * Order the functab.
329  */
330 
331 private int cmpfunc(f1, f2)
332 AddrOfFunc *f1, *f2;
333 {
334     register Address a1, a2;
335 
336     a1 = (*f1).addr;
337     a2 = (*f2).addr;
338     return ( (a1 < a2) ? -1 : ( (a1 == a2) ? 0 : 1 ) );
339 }
340 
341 public ordfunctab()
342 {
343     qsort(functab, nfuncs, sizeof(AddrOfFunc), cmpfunc);
344 }
345 
346 /*
347  * Clear out the functab, used when re-reading the object information.
348  */
349 
350 public clrfunctab()
351 {
352     nfuncs = 0;
353 }
354 
355 public dumpfunctab()
356 {
357     int i;
358 
359     for (i = 0; i < nfuncs; i++) {
360 	psym(functab[i].func);
361     }
362 }
363