19671Slinton /* Copyright (c) 1982 Regents of the University of California */ 29671Slinton 3*14439Slinton static char sccsid[] = "@(#)mappings.c 1.4 08/10/83"; 49671Slinton 59671Slinton /* 69671Slinton * Source-to-object and vice versa mappings. 79671Slinton */ 89671Slinton 99671Slinton #include "defs.h" 109671Slinton #include "mappings.h" 119671Slinton #include "symbols.h" 129671Slinton #include "source.h" 139671Slinton #include "object.h" 149671Slinton #include "machine.h" 159671Slinton 169671Slinton #ifndef public 179671Slinton #include "machine.h" 189671Slinton #include "source.h" 199671Slinton #include "symbols.h" 209671Slinton 219671Slinton typedef struct { 229671Slinton Address addr; 239671Slinton String filename; 249671Slinton Lineno lineindex; /* index to first linetab entry */ 259671Slinton } Filetab; 269671Slinton 279671Slinton typedef struct { 289671Slinton Lineno line; 299671Slinton Address addr; 309671Slinton } Linetab; 319671Slinton 329671Slinton Filetab *filetab; 339671Slinton Linetab *linetab; 349671Slinton 359671Slinton #define NOADDR ((Address) -1) /* no address for line or procedure */ 369671Slinton 379671Slinton #endif 389671Slinton 399671Slinton /* 409671Slinton * Get the source file name associated with a given address. 419671Slinton */ 429671Slinton 439671Slinton public String srcfilename(addr) 449671Slinton Address addr; 459671Slinton { 469671Slinton register Address i, j, k; 479671Slinton Address a; 489671Slinton Filetab *ftp; 499671Slinton String s; 509671Slinton 519671Slinton s = nil; 529671Slinton if (nlhdr.nfiles != 0 and addr >= filetab[0].addr) { 539671Slinton i = 0; 549671Slinton j = nlhdr.nfiles - 1; 559671Slinton while (i < j) { 569671Slinton k = (i + j) / 2; 579671Slinton ftp = &filetab[k]; 589671Slinton a = ftp->addr; 599671Slinton if (a == addr) { 609671Slinton s = ftp->filename; 619671Slinton break; 629671Slinton } else if (addr > a) { 639671Slinton i = k + 1; 649671Slinton } else { 659671Slinton j = k - 1; 669671Slinton } 679671Slinton } 689671Slinton if (s == nil) { 699671Slinton if (addr >= filetab[i].addr) { 709671Slinton s = filetab[i].filename; 719671Slinton } else { 729671Slinton s = filetab[i-1].filename; 739671Slinton } 749671Slinton } 759671Slinton } 769671Slinton return s; 779671Slinton } 789671Slinton 799671Slinton /* 809671Slinton * Find the line associated with the given address. 819671Slinton * If the second parameter is true, then the address must match 829671Slinton * a source line exactly. Otherwise the nearest source line 839671Slinton * below the given address is returned. In any case, if no suitable 849671Slinton * line exists, 0 is returned. 859671Slinton */ 869671Slinton 879671Slinton private Lineno findline(addr, exact) 889671Slinton Address addr; 899671Slinton Boolean exact; 909671Slinton { 919671Slinton register Address i, j, k; 929671Slinton register Lineno r; 939671Slinton register Address a; 949671Slinton 959671Slinton if (nlhdr.nlines == 0 or addr < linetab[0].addr) { 969671Slinton r = 0; 979671Slinton } else { 989671Slinton i = 0; 999671Slinton j = nlhdr.nlines - 1; 1009671Slinton if (addr == linetab[i].addr) { 1019671Slinton r = linetab[i].line; 1029671Slinton } else if (addr == linetab[j].addr) { 1039671Slinton r = linetab[j].line; 1049671Slinton } else if (addr > linetab[j].addr) { 1059671Slinton r = exact ? 0 : linetab[j].line; 1069671Slinton } else { 1079671Slinton do { 1089671Slinton k = (i + j) div 2; 1099671Slinton a = linetab[k].addr; 1109671Slinton if (a == addr) break; 1119671Slinton if (addr > a) { 1129671Slinton i = k + 1; 1139671Slinton } else { 1149671Slinton j = k - 1; 1159671Slinton } 1169671Slinton } while (i <= j); 1179671Slinton if (a == addr) { 1189671Slinton r = linetab[k].line; 1199671Slinton } else if (exact) { 1209671Slinton r = 0; 1219671Slinton } else if (addr > linetab[i].addr) { 1229671Slinton r = linetab[i].line; 1239671Slinton } else { 1249671Slinton r = linetab[i-1].line; 1259671Slinton } 1269671Slinton } 1279671Slinton } 1289671Slinton return r; 1299671Slinton } 1309671Slinton 1319671Slinton /* 1329671Slinton * Lookup the source line number nearest from below to an address. 1339671Slinton */ 1349671Slinton 1359671Slinton public Lineno srcline(addr) 1369671Slinton Address addr; 1379671Slinton { 1389671Slinton return findline(addr, false); 1399671Slinton } 1409671Slinton 1419671Slinton /* 1429671Slinton * Look for a line exactly corresponding to the given address. 1439671Slinton */ 1449671Slinton 1459671Slinton public Lineno linelookup(addr) 1469671Slinton Address addr; 1479671Slinton { 1489671Slinton return findline(addr, true); 1499671Slinton } 1509671Slinton 1519671Slinton /* 1529671Slinton * Lookup the object address of a given line from the named file. 1539671Slinton * 1549671Slinton * Potentially all files in the file table need to be checked 1559671Slinton * until the line is found since a particular file name may appear 1569671Slinton * more than once in the file table (caused by includes). 1579671Slinton */ 1589671Slinton 1599671Slinton public Address objaddr(line, name) 1609671Slinton Lineno line; 1619671Slinton String name; 1629671Slinton { 1639671Slinton register Filetab *ftp; 1649671Slinton register Lineno i, j; 1659671Slinton Boolean foundfile; 1669671Slinton 1679671Slinton if (nlhdr.nlines == 0) { 1689671Slinton return NOADDR; 1699671Slinton } 1709671Slinton if (name == nil) { 1719671Slinton name = cursource; 1729671Slinton } 1739671Slinton foundfile = false; 1749671Slinton for (ftp = &filetab[0]; ftp < &filetab[nlhdr.nfiles]; ftp++) { 1759671Slinton if (streq(ftp->filename, name)) { 1769671Slinton foundfile = true; 1779671Slinton i = ftp->lineindex; 1789671Slinton if (ftp == &filetab[nlhdr.nfiles-1]) { 1799671Slinton j = nlhdr.nlines; 1809671Slinton } else { 1819671Slinton j = (ftp + 1)->lineindex; 1829671Slinton } 1839671Slinton while (i < j) { 1849671Slinton if (linetab[i].line == line) { 1859671Slinton return linetab[i].addr; 1869671Slinton } 1879671Slinton i++; 1889671Slinton } 1899671Slinton } 1909671Slinton } 1919671Slinton if (not foundfile) { 1929671Slinton error("unknown source file \"%s\"", name); 1939671Slinton } 1949671Slinton return NOADDR; 1959671Slinton } 1969671Slinton 1979671Slinton /* 1989671Slinton * Table for going from object addresses to the functions in which they belong. 1999671Slinton */ 2009671Slinton 2019671Slinton #define MAXNFUNCS 1001 /* maximum number of functions allowed */ 2029671Slinton 203*14439Slinton typedef struct { 204*14439Slinton Symbol func; 205*14439Slinton Address addr; 206*14439Slinton } AddrOfFunc; 207*14439Slinton 208*14439Slinton private AddrOfFunc functab[MAXNFUNCS]; 2099671Slinton private int nfuncs; 2109671Slinton 2119671Slinton /* 2129671Slinton * Insert a new function into the table. 2139671Slinton * The table is ordered by object address. 2149671Slinton */ 2159671Slinton 216*14439Slinton public newfunc(f, addr) 2179671Slinton Symbol f; 218*14439Slinton Address addr; 2199671Slinton { 220*14439Slinton register AddrOfFunc *af; 221*14439Slinton 2229671Slinton if (nfuncs >= MAXNFUNCS) { 2239671Slinton panic("too many procedures/functions"); 2249671Slinton } 225*14439Slinton af = &functab[nfuncs]; 226*14439Slinton af->func = f; 227*14439Slinton af->addr = addr; 2289671Slinton ++nfuncs; 2299671Slinton } 2309671Slinton 2319671Slinton /* 2329671Slinton * Return the function that begins at the given address. 2339671Slinton */ 2349671Slinton 2359671Slinton public Symbol whatblock(addr) 2369671Slinton Address addr; 2379671Slinton { 2389671Slinton register int i, j, k; 2399671Slinton Address a; 2409671Slinton 2419671Slinton i = 0; 2429671Slinton j = nfuncs - 1; 243*14439Slinton if (addr < functab[i].addr) { 2449671Slinton return program; 245*14439Slinton } else if (addr == functab[i].addr) { 246*14439Slinton return functab[i].func; 247*14439Slinton } else if (addr >= functab[j].addr) { 248*14439Slinton return functab[j].func; 2499671Slinton } 2509671Slinton while (i <= j) { 2519671Slinton k = (i + j) / 2; 252*14439Slinton a = functab[k].addr; 2539671Slinton if (a == addr) { 254*14439Slinton return functab[k].func; 2559671Slinton } else if (addr > a) { 2569671Slinton i = k+1; 2579671Slinton } else { 2589671Slinton j = k-1; 2599671Slinton } 2609671Slinton } 261*14439Slinton if (addr > functab[i].addr) { 262*14439Slinton return functab[i].func; 2639671Slinton } else { 264*14439Slinton return functab[i-1].func; 2659671Slinton } 2669671Slinton /* NOTREACHED */ 2679671Slinton } 2689671Slinton 2699671Slinton /* 2709671Slinton * Order the functab. 2719671Slinton */ 2729671Slinton 2739671Slinton private int cmpfunc(f1, f2) 274*14439Slinton AddrOfFunc *f1, *f2; 2759671Slinton { 2769671Slinton register Address a1, a2; 2779671Slinton 278*14439Slinton a1 = (*f1).addr; 279*14439Slinton a2 = (*f2).addr; 2809671Slinton return ( (a1 < a2) ? -1 : ( (a1 == a2) ? 0 : 1 ) ); 2819671Slinton } 2829671Slinton 2839671Slinton public ordfunctab() 2849671Slinton { 285*14439Slinton qsort(functab, nfuncs, sizeof(AddrOfFunc), cmpfunc); 2869671Slinton } 2879671Slinton 2889671Slinton /* 2899671Slinton * Clear out the functab, used when re-reading the object information. 2909671Slinton */ 2919671Slinton 2929671Slinton public clrfunctab() 2939671Slinton { 2949671Slinton nfuncs = 0; 2959671Slinton } 29612541Scsvaf 29712541Scsvaf public dumpfunctab() 29812541Scsvaf { 299*14439Slinton int i; 30012541Scsvaf 301*14439Slinton for (i = 0; i < nfuncs; i++) { 302*14439Slinton psym(functab[i].func); 303*14439Slinton } 30412541Scsvaf } 305