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