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.2 (Berkeley) 2/19/86";
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) {
105: r = -1;
106: } else if (addr < linetab[0].addr) {
107: r = exact ? -1 : 0;
108: } else {
109: i = 0;
110: j = nlhdr.nlines - 1;
111: if (addr == linetab[i].addr) {
112: r = i;
113: } else if (addr == linetab[j].addr) {
114: r = j;
115: } else if (addr > linetab[j].addr) {
116: r = exact ? -1 : j;
117: } else {
118: do {
119: k = (i + j) div 2;
120: a = linetab[k].addr;
121: if (a == addr) break;
122: if (addr > a) {
123: i = k + 1;
124: } else {
125: j = k - 1;
126: }
127: } while (i <= j);
128: if (a == addr) {
129: r = k;
130: } else if (exact) {
131: r = -1;
132: } else if (addr > linetab[i].addr) {
133: r = i;
134: } else {
135: r = i - 1;
136: }
137: }
138: }
139: return r;
140: }
141:
142: /*
143: * Lookup the source line number nearest (from below) to an address.
144: *
145: * It is possible (unfortunately) that the compiler will generate
146: * code before line number for a procedure. Therefore we check
147: * to see that the found line is in the same procedure as the given address.
148: * If it isn't, then we walk forward until the first suitable line is found.
149: */
150:
151: public Lineno srcline(addr)
152: Address addr;
153: {
154: integer i;
155: Lineno r;
156: Symbol f1, f2;
157:
158: i = findline(addr, false);
159: if (i == -1) {
160: r = 0;
161: } else {
162: r = linetab[i].line;
163: if (linetab[i].addr != addr) {
164: f1 = whatblock(addr);
165: if (nosource(f1)) {
166: r = 0;
167: } else {
168: f2 = whatblock(linetab[i].addr + 1);
169: if (f1 != f2) {
170: do {
171: ++i;
172: } while (linetab[i].addr < addr and i < nlhdr.nlines);
173: r = linetab[i].line;
174: }
175: }
176: }
177: }
178: return r;
179: }
180:
181: /*
182: * Look for a line exactly corresponding to the given address.
183: */
184:
185: public Lineno linelookup(addr)
186: Address addr;
187: {
188: integer i;
189: Lineno r;
190:
191: i = findline(addr, true);
192: if (i == -1) {
193: r = 0;
194: } else {
195: r = linetab[i].line;
196: }
197: return r;
198: }
199:
200: /*
201: * Lookup the object address of a given line from the named file.
202: *
203: * Potentially all files in the file table need to be checked
204: * until the line is found since a particular file name may appear
205: * more than once in the file table (caused by includes).
206: */
207:
208: public Address objaddr(line, name)
209: Lineno line;
210: String name;
211: {
212: register Filetab *ftp;
213: register Lineno i, j;
214: Boolean foundfile;
215:
216: if (nlhdr.nlines == 0) {
217: return NOADDR;
218: }
219: if (name == nil) {
220: name = cursource;
221: }
222: foundfile = false;
223: for (ftp = &filetab[0]; ftp < &filetab[nlhdr.nfiles]; ftp++) {
224: if (streq(ftp->filename, name)) {
225: foundfile = true;
226: i = ftp->lineindex;
227: if (ftp == &filetab[nlhdr.nfiles-1]) {
228: j = nlhdr.nlines;
229: } else {
230: j = (ftp + 1)->lineindex;
231: }
232: while (i < j) {
233: if (linetab[i].line == line) {
234: return linetab[i].addr;
235: }
236: i++;
237: }
238: }
239: }
240: if (not foundfile) {
241: error("source file \"%s\" not compiled with -g", name);
242: }
243: return NOADDR;
244: }
245:
246: /*
247: * Table for going from object addresses to the functions in which they belong.
248: */
249:
250: #define NFUNCS 500 /* initial size of function table */
251:
252: typedef struct {
253: Symbol func;
254: Address addr;
255: } AddrOfFunc;
256:
257: private AddrOfFunc *functab;
258: private int nfuncs = 0;
259: private int functablesize = 0;
260:
261: /*
262: * Insert a new function into the table.
263: */
264:
265: public newfunc(f, addr)
266: Symbol f;
267: Address addr;
268: {
269: register AddrOfFunc *af;
270: register int i;
271: AddrOfFunc *newfunctab;
272:
273: if (nfuncs >= functablesize) {
274: if (functablesize == 0) {
275: functab = newarr(AddrOfFunc, NFUNCS);
276: functablesize = NFUNCS;
277: } else {
278: functablesize *= 2;
279: newfunctab = newarr(AddrOfFunc, functablesize);
280: bcopy(functab, newfunctab, nfuncs * sizeof(AddrOfFunc));
281: dispose(functab);
282: functab = newfunctab;
283: }
284: }
285: af = &functab[nfuncs];
286: af->func = f;
287: af->addr = addr;
288: ++nfuncs;
289: }
290:
291: /*
292: * Return the function that begins at the given address.
293: */
294:
295: public Symbol whatblock(addr)
296: Address addr;
297: {
298: register int i, j, k;
299: Address a;
300:
301: i = 0;
302: j = nfuncs - 1;
303: if (addr < functab[i].addr) {
304: return program;
305: } else if (addr == functab[i].addr) {
306: return functab[i].func;
307: } else if (addr >= functab[j].addr) {
308: return functab[j].func;
309: }
310: while (i <= j) {
311: k = (i + j) / 2;
312: a = functab[k].addr;
313: if (a == addr) {
314: return functab[k].func;
315: } else if (addr > a) {
316: i = k+1;
317: } else {
318: j = k-1;
319: }
320: }
321: if (addr > functab[i].addr) {
322: return functab[i].func;
323: } else {
324: return functab[i-1].func;
325: }
326: /* NOTREACHED */
327: }
328:
329: /*
330: * Order the functab.
331: */
332:
333: private int cmpfunc(f1, f2)
334: AddrOfFunc *f1, *f2;
335: {
336: register Address a1, a2;
337:
338: a1 = (*f1).addr;
339: a2 = (*f2).addr;
340: return ( (a1 < a2) ? -1 : ( (a1 == a2) ? 0 : 1 ) );
341: }
342:
343: public ordfunctab()
344: {
345: qsort(functab, nfuncs, sizeof(AddrOfFunc), cmpfunc);
346: }
347:
348: /*
349: * Clear out the functab, used when re-reading the object information.
350: */
351:
352: public clrfunctab()
353: {
354: nfuncs = 0;
355: }
356:
357: public dumpfunctab()
358: {
359: int i;
360:
361: for (i = 0; i < nfuncs; i++) {
362: psym(functab[i].func);
363: }
364: }
Defined functions
Defined variables
rcsid
defined in line
11;
never used
sccsid
defined in line
8;
never used
Defined macros