* Copyright (c) 1983 The Regents of the University of California.
* %sccs.include.redist.c%
static char sccsid
[] = "@(#)mappings.c 5.5 (Berkeley) %G%";
* Source-to-object and vice versa mappings.
Lineno lineindex
; /* index to first linetab entry */
#define NOADDR ((Address) -1) /* no address for line or procedure */
* Get the source file name associated with a given address.
public String
srcfilename(addr
)
register Address i
, j
, k
;
if (nlhdr
.nfiles
!= 0 and addr
>= filetab
[0].addr
) {
if (addr
>= filetab
[i
].addr
) {
s
= filetab
[i
-1].filename
;
* Find the line associated with the given address.
* If the second parameter is true, then the address must match
* a source line exactly. Otherwise the nearest source line
* below the given address is returned.
* Return the index of the line table entry or -1 if none suitable.
private integer
findline (addr
, exact
)
register Address i
, j
, k
;
if (nlhdr
.nlines
== 0 or addr
< linetab
[0].addr
) {
if (addr
== linetab
[i
].addr
) {
} else if (addr
== linetab
[j
].addr
) {
} else if (addr
> linetab
[j
].addr
) {
} else if (addr
> linetab
[i
].addr
) {
* Lookup the source line number nearest (from below) to an address.
* It is possible (unfortunately) that the compiler will generate
* code before line number for a procedure. Therefore we check
* to see that the found line is in the same procedure as the given address.
* If it isn't, then we walk forward until the first suitable line is found.
public Lineno
srcline (addr
)
i
= findline(addr
, false);
if (f1
== nil
or nosource(f1
)) {
if (r
!= 0 or a
>= CODESTART
+ objsize
) {
if (linetab
[i
].addr
!= addr
) {
f2
= whatblock(linetab
[i
].addr
+ 1);
} while (linetab
[i
].addr
< addr
and i
< nlhdr
.nlines
);
* Look for a line exactly corresponding to the given address.
public Lineno
linelookup(addr
)
i
= findline(addr
, true);
* Lookup the object address of a given line from the named file.
* Potentially all files in the file table need to be checked
* until the line is found since a particular file name may appear
* more than once in the file table (caused by includes).
public Address
objaddr(line
, name
)
for (ftp
= &filetab
[0]; ftp
< &filetab
[nlhdr
.nfiles
]; ftp
++) {
if (streq(ftp
->filename
, name
)) {
if (ftp
== &filetab
[nlhdr
.nfiles
-1]) {
j
= (ftp
+ 1)->lineindex
;
if (linetab
[i
].line
== line
) {
error("source file \"%s\" not compiled with -g", name
);
* Table for going from object addresses to the functions in which they belong.
#define NFUNCS 500 /* initial size of function table */
private AddrOfFunc
*functab
;
private int functablesize
= 0;
* Insert a new function into the table.
if (nfuncs
>= functablesize
) {
if (functablesize
== 0) {
functab
= newarr(AddrOfFunc
, NFUNCS
);
newfunctab
= newarr(AddrOfFunc
, functablesize
);
bcopy(functab
, newfunctab
, nfuncs
* sizeof(AddrOfFunc
));
* Return the function that begins at the given address.
public Symbol
whatblock(addr
)
if (addr
< functab
[i
].addr
) {
} else if (addr
== functab
[i
].addr
) {
} else if (addr
>= functab
[j
].addr
) {
if (addr
> functab
[i
].addr
) {
return functab
[i
-1].func
;
private int cmpfunc(f1
, f2
)
return ( (a1
< a2
) ? -1 : ( (a1
== a2
) ? 0 : 1 ) );
qsort(functab
, nfuncs
, sizeof(AddrOfFunc
), cmpfunc
);
* Clear out the functab, used when re-reading the object information.
for (i
= 0; i
< nfuncs
; i
++) {