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