BSD 4_4 release
[unix-history] / usr / src / old / dbx / mappings.c
index ebc402e..fefc5ee 100644 (file)
@@ -1,6 +1,39 @@
-/* Copyright (c) 1982 Regents of the University of California */
+/*
+ * Copyright (c) 1983 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
 
 
-static char sccsid[] = "@(#)mappings.c 1.4 %G%";
+#ifndef lint
+static char sccsid[] = "@(#)mappings.c 5.5 (Berkeley) 6/1/90";
+#endif /* not lint */
 
 /*
  * Source-to-object and vice versa mappings.
 
 /*
  * Source-to-object and vice versa mappings.
@@ -80,11 +113,12 @@ Address addr;
  * 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
  * 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.  In any case, if no suitable
- * line exists, 0 is returned.
+ * below the given address is returned.
+ *
+ * Return the index of the line table entry or -1 if none suitable.
  */
 
  */
 
-private Lineno findline(addr, exact)
+private integer findline (addr, exact)
 Address addr;
 Boolean exact;
 {
 Address addr;
 Boolean exact;
 {
@@ -93,16 +127,16 @@ Boolean exact;
     register Address a;
 
     if (nlhdr.nlines == 0 or addr < linetab[0].addr) {
     register Address a;
 
     if (nlhdr.nlines == 0 or addr < linetab[0].addr) {
-       r = 0;
+       r = -1;
     } else {
        i = 0;
        j = nlhdr.nlines - 1;
        if (addr == linetab[i].addr) {
     } else {
        i = 0;
        j = nlhdr.nlines - 1;
        if (addr == linetab[i].addr) {
-           r = linetab[i].line;
+           r = i;
        } else if (addr == linetab[j].addr) {
        } else if (addr == linetab[j].addr) {
-           r = linetab[j].line;
+           r = j;
        } else if (addr > linetab[j].addr) {
        } else if (addr > linetab[j].addr) {
-           r = exact ? 0 : linetab[j].line;
+           r = exact ? -1 : j;
        } else {
            do {
                k = (i + j) div 2;
        } else {
            do {
                k = (i + j) div 2;
@@ -115,13 +149,13 @@ Boolean exact;
                }
            } while (i <= j);
            if (a == addr) {
                }
            } while (i <= j);
            if (a == addr) {
-               r = linetab[k].line;
+               r = k;
            } else if (exact) {
            } else if (exact) {
-               r = 0;
+               r = -1;
            } else if (addr > linetab[i].addr) {
            } else if (addr > linetab[i].addr) {
-               r = linetab[i].line;
+               r = i;
            } else {
            } else {
-               r = linetab[i-1].line;
+               r = i - 1;
            }
        }
     }
            }
        }
     }
@@ -129,13 +163,54 @@ Boolean exact;
 }
 
 /*
 }
 
 /*
- * Lookup the source line number nearest from below to an address.
+ * 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)
+public Lineno srcline (addr)
 Address addr;
 {
 Address addr;
 {
-    return findline(addr, false);
+    Lineno i, r;
+    Symbol f1, f2;
+    Address a;
+
+    i = findline(addr, false);
+    if (i == -1) {
+       f1 = whatblock(addr);
+       if (f1 == nil or nosource(f1)) {
+           r = 0;
+       } else {
+           a = codeloc(f1);
+           for (;;) {
+               r = linelookup(a);
+               if (r != 0 or a >= CODESTART + objsize) {
+                   break;
+               }
+               ++a;
+           }
+       }
+    } else {
+       r = linetab[i].line;
+       if (linetab[i].addr != addr) {
+           f1 = whatblock(addr);
+           if (nosource(f1)) {
+               r = 0;
+           } else {
+               f2 = whatblock(linetab[i].addr + 1);
+               if (f1 != f2) {
+                   do {
+                       ++i;
+                   } while (linetab[i].addr < addr and i < nlhdr.nlines);
+                   r = linetab[i].line;
+               }
+           }
+       }
+    }
+    return r;
 }
 
 /*
 }
 
 /*
@@ -145,7 +220,16 @@ Address addr;
 public Lineno linelookup(addr)
 Address addr;
 {
 public Lineno linelookup(addr)
 Address addr;
 {
-    return findline(addr, true);
+    integer i;
+    Lineno r;
+
+    i = findline(addr, true);
+    if (i == -1) {
+       r = 0;
+    } else {
+       r = linetab[i].line;
+    }
+    return r;
 }
 
 /*
 }
 
 /*
@@ -189,7 +273,7 @@ String name;
        }
     }
     if (not foundfile) {
        }
     }
     if (not foundfile) {
-       error("unknown source file \"%s\"", name);
+       error("source file \"%s\" not compiled with -g", name);
     }
     return NOADDR;
 }
     }
     return NOADDR;
 }
@@ -198,19 +282,19 @@ String name;
  * Table for going from object addresses to the functions in which they belong.
  */
 
  * Table for going from object addresses to the functions in which they belong.
  */
 
-#define MAXNFUNCS 1001      /* maximum number of functions allowed */
+#define NFUNCS 500     /* initial size of function table */
 
 typedef struct {
     Symbol func;
     Address addr;
 } AddrOfFunc;
 
 
 typedef struct {
     Symbol func;
     Address addr;
 } AddrOfFunc;
 
-private AddrOfFunc functab[MAXNFUNCS];
-private int nfuncs;
+private AddrOfFunc *functab;
+private int nfuncs = 0;
+private int functablesize = 0;
 
 /*
  * Insert a new function into the table.
 
 /*
  * Insert a new function into the table.
- * The table is ordered by object address.
  */
 
 public newfunc(f, addr)
  */
 
 public newfunc(f, addr)
@@ -218,9 +302,20 @@ Symbol f;
 Address addr;
 {
     register AddrOfFunc *af;
 Address addr;
 {
     register AddrOfFunc *af;
+    register int i;
+    AddrOfFunc *newfunctab;
 
 
-    if (nfuncs >= MAXNFUNCS) {
-       panic("too many procedures/functions");
+    if (nfuncs >= functablesize) {
+       if (functablesize == 0) {
+           functab = newarr(AddrOfFunc, NFUNCS);
+           functablesize = NFUNCS;
+       } else {
+           functablesize *= 2;
+           newfunctab = newarr(AddrOfFunc, functablesize);
+           bcopy(functab, newfunctab, nfuncs * sizeof(AddrOfFunc));
+           dispose(functab);
+           functab = newfunctab;
+       }
     }
     af = &functab[nfuncs];
     af->func = f;
     }
     af = &functab[nfuncs];
     af->func = f;