1*21611Sdist /* 2*21611Sdist * Copyright (c) 1983 Regents of the University of California. 3*21611Sdist * All rights reserved. The Berkeley software License Agreement 4*21611Sdist * specifies the terms and conditions for redistribution. 5*21611Sdist */ 69671Slinton 7*21611Sdist #ifndef lint 8*21611Sdist static char sccsid[] = "@(#)mappings.c 5.1 (Berkeley) 05/31/85"; 9*21611Sdist #endif not lint 109671Slinton 1118224Slinton static char rcsid[] = "$Header: mappings.c,v 1.4 84/12/26 10:40:25 linton Exp $"; 1218224Slinton 139671Slinton /* 149671Slinton * Source-to-object and vice versa mappings. 159671Slinton */ 169671Slinton 179671Slinton #include "defs.h" 189671Slinton #include "mappings.h" 199671Slinton #include "symbols.h" 209671Slinton #include "source.h" 219671Slinton #include "object.h" 229671Slinton #include "machine.h" 239671Slinton 249671Slinton #ifndef public 259671Slinton #include "machine.h" 269671Slinton #include "source.h" 279671Slinton #include "symbols.h" 289671Slinton 299671Slinton typedef struct { 309671Slinton Address addr; 319671Slinton String filename; 329671Slinton Lineno lineindex; /* index to first linetab entry */ 339671Slinton } Filetab; 349671Slinton 359671Slinton typedef struct { 369671Slinton Lineno line; 379671Slinton Address addr; 389671Slinton } Linetab; 399671Slinton 409671Slinton Filetab *filetab; 419671Slinton Linetab *linetab; 429671Slinton 439671Slinton #define NOADDR ((Address) -1) /* no address for line or procedure */ 449671Slinton 459671Slinton #endif 469671Slinton 479671Slinton /* 489671Slinton * Get the source file name associated with a given address. 499671Slinton */ 509671Slinton 519671Slinton public String srcfilename(addr) 529671Slinton Address addr; 539671Slinton { 549671Slinton register Address i, j, k; 559671Slinton Address a; 569671Slinton Filetab *ftp; 579671Slinton String s; 589671Slinton 599671Slinton s = nil; 609671Slinton if (nlhdr.nfiles != 0 and addr >= filetab[0].addr) { 619671Slinton i = 0; 629671Slinton j = nlhdr.nfiles - 1; 639671Slinton while (i < j) { 649671Slinton k = (i + j) / 2; 659671Slinton ftp = &filetab[k]; 669671Slinton a = ftp->addr; 679671Slinton if (a == addr) { 689671Slinton s = ftp->filename; 699671Slinton break; 709671Slinton } else if (addr > a) { 719671Slinton i = k + 1; 729671Slinton } else { 739671Slinton j = k - 1; 749671Slinton } 759671Slinton } 769671Slinton if (s == nil) { 779671Slinton if (addr >= filetab[i].addr) { 789671Slinton s = filetab[i].filename; 799671Slinton } else { 809671Slinton s = filetab[i-1].filename; 819671Slinton } 829671Slinton } 839671Slinton } 849671Slinton return s; 859671Slinton } 869671Slinton 879671Slinton /* 889671Slinton * Find the line associated with the given address. 899671Slinton * If the second parameter is true, then the address must match 909671Slinton * a source line exactly. Otherwise the nearest source line 9118224Slinton * below the given address is returned. 9218224Slinton * 9318224Slinton * Return the index of the line table entry or -1 if none suitable. 949671Slinton */ 959671Slinton 9618224Slinton private integer findline (addr, exact) 979671Slinton Address addr; 989671Slinton Boolean exact; 999671Slinton { 1009671Slinton register Address i, j, k; 1019671Slinton register Lineno r; 1029671Slinton register Address a; 1039671Slinton 1049671Slinton if (nlhdr.nlines == 0 or addr < linetab[0].addr) { 10518224Slinton r = -1; 1069671Slinton } else { 1079671Slinton i = 0; 1089671Slinton j = nlhdr.nlines - 1; 1099671Slinton if (addr == linetab[i].addr) { 11018224Slinton r = i; 1119671Slinton } else if (addr == linetab[j].addr) { 11218224Slinton r = j; 1139671Slinton } else if (addr > linetab[j].addr) { 11418224Slinton r = exact ? -1 : j; 1159671Slinton } else { 1169671Slinton do { 1179671Slinton k = (i + j) div 2; 1189671Slinton a = linetab[k].addr; 1199671Slinton if (a == addr) break; 1209671Slinton if (addr > a) { 1219671Slinton i = k + 1; 1229671Slinton } else { 1239671Slinton j = k - 1; 1249671Slinton } 1259671Slinton } while (i <= j); 1269671Slinton if (a == addr) { 12718224Slinton r = k; 1289671Slinton } else if (exact) { 12918224Slinton r = -1; 1309671Slinton } else if (addr > linetab[i].addr) { 13118224Slinton r = i; 1329671Slinton } else { 13318224Slinton r = i - 1; 1349671Slinton } 1359671Slinton } 1369671Slinton } 1379671Slinton return r; 1389671Slinton } 1399671Slinton 1409671Slinton /* 14118224Slinton * Lookup the source line number nearest (from below) to an address. 14218224Slinton * 14318224Slinton * It is possible (unfortunately) that the compiler will generate 14418224Slinton * code before line number for a procedure. Therefore we check 14518224Slinton * to see that the found line is in the same procedure as the given address. 14618224Slinton * If it isn't, then we walk forward until the first suitable line is found. 1479671Slinton */ 1489671Slinton 1499671Slinton public Lineno srcline(addr) 1509671Slinton Address addr; 1519671Slinton { 15218224Slinton integer i; 15318224Slinton Lineno r; 15418224Slinton Symbol f1, f2; 15518224Slinton 15618224Slinton i = findline(addr, false); 15718224Slinton if (i == -1) { 15818224Slinton r = 0; 15918224Slinton } else { 16018224Slinton r = linetab[i].line; 16118224Slinton if (linetab[i].addr != addr) { 16218224Slinton f1 = whatblock(addr); 16318224Slinton if (nosource(f1)) { 16418224Slinton r = 0; 16518224Slinton } else { 16618224Slinton f2 = whatblock(linetab[i].addr + 1); 16718224Slinton if (f1 != f2) { 16818224Slinton do { 16918224Slinton ++i; 17018224Slinton } while (linetab[i].addr < addr and i < nlhdr.nlines); 17118224Slinton r = linetab[i].line; 17218224Slinton } 17318224Slinton } 17418224Slinton } 17518224Slinton } 17618224Slinton return r; 1779671Slinton } 1789671Slinton 1799671Slinton /* 1809671Slinton * Look for a line exactly corresponding to the given address. 1819671Slinton */ 1829671Slinton 1839671Slinton public Lineno linelookup(addr) 1849671Slinton Address addr; 1859671Slinton { 18618224Slinton integer i; 18718224Slinton Lineno r; 18818224Slinton 18918224Slinton i = findline(addr, true); 19018224Slinton if (i == -1) { 19118224Slinton r = 0; 19218224Slinton } else { 19318224Slinton r = linetab[i].line; 19418224Slinton } 19518224Slinton return r; 1969671Slinton } 1979671Slinton 1989671Slinton /* 1999671Slinton * Lookup the object address of a given line from the named file. 2009671Slinton * 2019671Slinton * Potentially all files in the file table need to be checked 2029671Slinton * until the line is found since a particular file name may appear 2039671Slinton * more than once in the file table (caused by includes). 2049671Slinton */ 2059671Slinton 2069671Slinton public Address objaddr(line, name) 2079671Slinton Lineno line; 2089671Slinton String name; 2099671Slinton { 2109671Slinton register Filetab *ftp; 2119671Slinton register Lineno i, j; 2129671Slinton Boolean foundfile; 2139671Slinton 2149671Slinton if (nlhdr.nlines == 0) { 2159671Slinton return NOADDR; 2169671Slinton } 2179671Slinton if (name == nil) { 2189671Slinton name = cursource; 2199671Slinton } 2209671Slinton foundfile = false; 2219671Slinton for (ftp = &filetab[0]; ftp < &filetab[nlhdr.nfiles]; ftp++) { 2229671Slinton if (streq(ftp->filename, name)) { 2239671Slinton foundfile = true; 2249671Slinton i = ftp->lineindex; 2259671Slinton if (ftp == &filetab[nlhdr.nfiles-1]) { 2269671Slinton j = nlhdr.nlines; 2279671Slinton } else { 2289671Slinton j = (ftp + 1)->lineindex; 2299671Slinton } 2309671Slinton while (i < j) { 2319671Slinton if (linetab[i].line == line) { 2329671Slinton return linetab[i].addr; 2339671Slinton } 2349671Slinton i++; 2359671Slinton } 2369671Slinton } 2379671Slinton } 2389671Slinton if (not foundfile) { 23918224Slinton error("source file \"%s\" not compiled with -g", name); 2409671Slinton } 2419671Slinton return NOADDR; 2429671Slinton } 2439671Slinton 2449671Slinton /* 2459671Slinton * Table for going from object addresses to the functions in which they belong. 2469671Slinton */ 2479671Slinton 24818224Slinton #define NFUNCS 500 /* initial size of function table */ 2499671Slinton 25014439Slinton typedef struct { 25114439Slinton Symbol func; 25214439Slinton Address addr; 25314439Slinton } AddrOfFunc; 25414439Slinton 25518224Slinton private AddrOfFunc *functab; 25618224Slinton private int nfuncs = 0; 25718224Slinton private int functablesize = 0; 2589671Slinton 2599671Slinton /* 2609671Slinton * Insert a new function into the table. 2619671Slinton */ 2629671Slinton 26314439Slinton public newfunc(f, addr) 2649671Slinton Symbol f; 26514439Slinton Address addr; 2669671Slinton { 26714439Slinton register AddrOfFunc *af; 26818224Slinton register int i; 26918224Slinton AddrOfFunc *newfunctab; 27014439Slinton 27118224Slinton if (nfuncs >= functablesize) { 27218224Slinton if (functablesize == 0) { 27318224Slinton functab = newarr(AddrOfFunc, NFUNCS); 27418224Slinton functablesize = NFUNCS; 27518224Slinton } else { 27618224Slinton functablesize *= 2; 27718224Slinton newfunctab = newarr(AddrOfFunc, functablesize); 27818224Slinton bcopy(functab, newfunctab, nfuncs * sizeof(AddrOfFunc)); 27918224Slinton dispose(functab); 28018224Slinton functab = newfunctab; 28118224Slinton } 2829671Slinton } 28314439Slinton af = &functab[nfuncs]; 28414439Slinton af->func = f; 28514439Slinton af->addr = addr; 2869671Slinton ++nfuncs; 2879671Slinton } 2889671Slinton 2899671Slinton /* 2909671Slinton * Return the function that begins at the given address. 2919671Slinton */ 2929671Slinton 2939671Slinton public Symbol whatblock(addr) 2949671Slinton Address addr; 2959671Slinton { 2969671Slinton register int i, j, k; 2979671Slinton Address a; 2989671Slinton 2999671Slinton i = 0; 3009671Slinton j = nfuncs - 1; 30114439Slinton if (addr < functab[i].addr) { 3029671Slinton return program; 30314439Slinton } else if (addr == functab[i].addr) { 30414439Slinton return functab[i].func; 30514439Slinton } else if (addr >= functab[j].addr) { 30614439Slinton return functab[j].func; 3079671Slinton } 3089671Slinton while (i <= j) { 3099671Slinton k = (i + j) / 2; 31014439Slinton a = functab[k].addr; 3119671Slinton if (a == addr) { 31214439Slinton return functab[k].func; 3139671Slinton } else if (addr > a) { 3149671Slinton i = k+1; 3159671Slinton } else { 3169671Slinton j = k-1; 3179671Slinton } 3189671Slinton } 31914439Slinton if (addr > functab[i].addr) { 32014439Slinton return functab[i].func; 3219671Slinton } else { 32214439Slinton return functab[i-1].func; 3239671Slinton } 3249671Slinton /* NOTREACHED */ 3259671Slinton } 3269671Slinton 3279671Slinton /* 3289671Slinton * Order the functab. 3299671Slinton */ 3309671Slinton 3319671Slinton private int cmpfunc(f1, f2) 33214439Slinton AddrOfFunc *f1, *f2; 3339671Slinton { 3349671Slinton register Address a1, a2; 3359671Slinton 33614439Slinton a1 = (*f1).addr; 33714439Slinton a2 = (*f2).addr; 3389671Slinton return ( (a1 < a2) ? -1 : ( (a1 == a2) ? 0 : 1 ) ); 3399671Slinton } 3409671Slinton 3419671Slinton public ordfunctab() 3429671Slinton { 34314439Slinton qsort(functab, nfuncs, sizeof(AddrOfFunc), cmpfunc); 3449671Slinton } 3459671Slinton 3469671Slinton /* 3479671Slinton * Clear out the functab, used when re-reading the object information. 3489671Slinton */ 3499671Slinton 3509671Slinton public clrfunctab() 3519671Slinton { 3529671Slinton nfuncs = 0; 3539671Slinton } 35412541Scsvaf 35512541Scsvaf public dumpfunctab() 35612541Scsvaf { 35714439Slinton int i; 35812541Scsvaf 35914439Slinton for (i = 0; i < nfuncs; i++) { 36014439Slinton psym(functab[i].func); 36114439Slinton } 36212541Scsvaf } 363