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