add vdioctl
[unix-history] / usr / src / old / dbx / mappings.c
CommitLineData
2a24676e
DF
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 */
abf043f1 6
2a24676e 7#ifndef lint
5fa7a784 8static char sccsid[] = "@(#)mappings.c 5.2 (Berkeley) %G%";
2a24676e 9#endif not lint
0022c355
ML
10
11static char rcsid[] = "$Header: mappings.c,v 1.4 84/12/26 10:40:25 linton Exp $";
abf043f1
ML
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
29typedef struct {
30 Address addr;
31 String filename;
32 Lineno lineindex; /* index to first linetab entry */
33} Filetab;
34
35typedef struct {
36 Lineno line;
37 Address addr;
38} Linetab;
39
40Filetab *filetab;
41Linetab *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
51public String srcfilename(addr)
52Address 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
0022c355
ML
91 * below the given address is returned.
92 *
93 * Return the index of the line table entry or -1 if none suitable.
abf043f1
ML
94 */
95
0022c355 96private integer findline (addr, exact)
abf043f1
ML
97Address addr;
98Boolean exact;
99{
100 register Address i, j, k;
101 register Lineno r;
102 register Address a;
103
5fa7a784 104 if (nlhdr.nlines == 0) {
0022c355 105 r = -1;
5fa7a784
DS
106 } else if (addr < linetab[0].addr) {
107 r = exact ? -1 : 0;
abf043f1
ML
108 } else {
109 i = 0;
110 j = nlhdr.nlines - 1;
111 if (addr == linetab[i].addr) {
0022c355 112 r = i;
abf043f1 113 } else if (addr == linetab[j].addr) {
0022c355 114 r = j;
abf043f1 115 } else if (addr > linetab[j].addr) {
0022c355 116 r = exact ? -1 : j;
abf043f1
ML
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) {
0022c355 129 r = k;
abf043f1 130 } else if (exact) {
0022c355 131 r = -1;
abf043f1 132 } else if (addr > linetab[i].addr) {
0022c355 133 r = i;
abf043f1 134 } else {
0022c355 135 r = i - 1;
abf043f1
ML
136 }
137 }
138 }
139 return r;
140}
141
142/*
0022c355
ML
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.
abf043f1
ML
149 */
150
151public Lineno srcline(addr)
152Address addr;
153{
0022c355
ML
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;
abf043f1
ML
179}
180
181/*
182 * Look for a line exactly corresponding to the given address.
183 */
184
185public Lineno linelookup(addr)
186Address addr;
187{
0022c355
ML
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;
abf043f1
ML
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
208public Address objaddr(line, name)
209Lineno line;
210String 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) {
0022c355 241 error("source file \"%s\" not compiled with -g", name);
abf043f1
ML
242 }
243 return NOADDR;
244}
245
246/*
247 * Table for going from object addresses to the functions in which they belong.
248 */
249
0022c355 250#define NFUNCS 500 /* initial size of function table */
abf043f1 251
d4345abe
ML
252typedef struct {
253 Symbol func;
254 Address addr;
255} AddrOfFunc;
256
0022c355
ML
257private AddrOfFunc *functab;
258private int nfuncs = 0;
259private int functablesize = 0;
abf043f1
ML
260
261/*
262 * Insert a new function into the table.
abf043f1
ML
263 */
264
d4345abe 265public newfunc(f, addr)
abf043f1 266Symbol f;
d4345abe 267Address addr;
abf043f1 268{
d4345abe 269 register AddrOfFunc *af;
0022c355
ML
270 register int i;
271 AddrOfFunc *newfunctab;
d4345abe 272
0022c355
ML
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 }
abf043f1 284 }
d4345abe
ML
285 af = &functab[nfuncs];
286 af->func = f;
287 af->addr = addr;
abf043f1
ML
288 ++nfuncs;
289}
290
291/*
292 * Return the function that begins at the given address.
293 */
294
295public Symbol whatblock(addr)
296Address addr;
297{
298 register int i, j, k;
299 Address a;
300
301 i = 0;
302 j = nfuncs - 1;
d4345abe 303 if (addr < functab[i].addr) {
abf043f1 304 return program;
d4345abe
ML
305 } else if (addr == functab[i].addr) {
306 return functab[i].func;
307 } else if (addr >= functab[j].addr) {
308 return functab[j].func;
abf043f1
ML
309 }
310 while (i <= j) {
311 k = (i + j) / 2;
d4345abe 312 a = functab[k].addr;
abf043f1 313 if (a == addr) {
d4345abe 314 return functab[k].func;
abf043f1
ML
315 } else if (addr > a) {
316 i = k+1;
317 } else {
318 j = k-1;
319 }
320 }
d4345abe
ML
321 if (addr > functab[i].addr) {
322 return functab[i].func;
abf043f1 323 } else {
d4345abe 324 return functab[i-1].func;
abf043f1
ML
325 }
326 /* NOTREACHED */
327}
328
329/*
330 * Order the functab.
331 */
332
333private int cmpfunc(f1, f2)
d4345abe 334AddrOfFunc *f1, *f2;
abf043f1
ML
335{
336 register Address a1, a2;
337
d4345abe
ML
338 a1 = (*f1).addr;
339 a2 = (*f2).addr;
abf043f1
ML
340 return ( (a1 < a2) ? -1 : ( (a1 == a2) ? 0 : 1 ) );
341}
342
343public ordfunctab()
344{
d4345abe 345 qsort(functab, nfuncs, sizeof(AddrOfFunc), cmpfunc);
abf043f1
ML
346}
347
348/*
349 * Clear out the functab, used when re-reading the object information.
350 */
351
352public clrfunctab()
353{
354 nfuncs = 0;
355}
e3de3d54
AF
356
357public dumpfunctab()
358{
d4345abe
ML
359 int i;
360
361 for (i = 0; i < nfuncs; i++) {
362 psym(functab[i].func);
363 }
e3de3d54 364}