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