modified traceback to deal with "inline" functions, i.e. blocks
[unix-history] / usr / src / old / dbx / object.c
index 83fbe39..3bff241 100644 (file)
@@ -1,6 +1,6 @@
 /* Copyright (c) 1982 Regents of the University of California */
 
 /* Copyright (c) 1982 Regents of the University of California */
 
-static char sccsid[] = "@(#)@(#)object.c 1.1 %G%";
+static char sccsid[] = "@(#)object.c 1.10 %G%";
 
 /*
  * Object code interface, mainly for extraction of symbolic information.
 
 /*
  * Object code interface, mainly for extraction of symbolic information.
@@ -38,10 +38,12 @@ private Language curlang;
 private Symbol curmodule;
 private Symbol curparam;
 private Boolean warned;
 private Symbol curmodule;
 private Symbol curparam;
 private Boolean warned;
+private Symbol curcomm;
+private Symbol commchain;
+private Boolean strip_ = false;
 
 private Filetab *filep;
 
 private Filetab *filep;
-private Linetab *linep;
-private Address curfaddr;
+private Linetab *linep, *prevlinep;
 
 #define curfilename() (filep-1)->filename
 
 
 #define curfilename() (filep-1)->filename
 
@@ -64,6 +66,11 @@ private Integer curlevel;
 }
 
 #define exitblock() { \
 }
 
 #define exitblock() { \
+    if (curblock->class == FUNC or curblock->class == PROC) { \
+       if (prevlinep != linep) { \
+           curblock->symvalue.funcv.src = true; \
+       } \
+    } \
     --curlevel; \
     curblock = blkstack[curlevel]; \
 }
     --curlevel; \
     curblock = blkstack[curlevel]; \
 }
@@ -156,9 +163,21 @@ Fileid f;
        index = np->n_un.n_strx;
        if (index != 0) {
            name = &stringtab[index - 4];
        index = np->n_un.n_strx;
        if (index != 0) {
            name = &stringtab[index - 4];
+           /*
+             *  if the program contains any .f files a trailing _ is stripped
+                    *  from the name on the assumption it was added by the compiler.
+            *  This only affects names that follow the sdb N_SO entry with
+             *  the .f name. 
+             */
+            if(strip_ && *name != '\0' ) {
+                 register char *p, *q;
+                 for(p=name,q=(name+1); *q != '\0'; p=q++);
+                 if (*p == '_')  *p = '\0';
+            }
+
        } else {
            name = nil;
        } else {
            name = nil;
-       }
+       } 
        /*
         * assumptions:
         *      not an N_STAB   ==> name != nil
        /*
         * assumptions:
         *      not an N_STAB   ==> name != nil
@@ -166,6 +185,7 @@ Fileid f;
         *      name[0] != '_'  ==> filename or invisible
         *
         * The "-lg" signals the beginning of global loader symbols.
         *      name[0] != '_'  ==> filename or invisible
         *
         * The "-lg" signals the beginning of global loader symbols.
+         *
         */
        if ((np->n_type&N_STAB) != 0) {
            enter_nl(name, np);
         */
        if ((np->n_type&N_STAB) != 0) {
            enter_nl(name, np);
@@ -178,12 +198,12 @@ Fileid f;
                }
            }
            enterline(0, (linep-1)->addr + 1);
                }
            }
            enterline(0, (linep-1)->addr + 1);
-       } else if (name[0] == '_') {
-           if (afterlg) {
+       } else if (afterlg) {
+           if (name[0] == '_') {
                check_global(&name[1], np);
                check_global(&name[1], np);
-           } else if (curblock->name != nil) {
-               check_local(&name[1], np);
            }
            }
+       } else if (name[0] == '_') {
+           check_local(&name[1], np);
        } else if ((np->n_type&N_TEXT) == N_TEXT) {
            check_filename(name);
        }
        } else if ((np->n_type&N_TEXT) == N_TEXT) {
            check_filename(name);
        }
@@ -210,14 +230,15 @@ private initsyms()
     }
     program = insert(identname(progname, true));
     program->class = PROG;
     }
     program = insert(identname(progname, true));
     program->class = PROG;
-    newfunc(program);
+    program->symvalue.funcv.beginaddr = 0;
     findbeginning(program);
     findbeginning(program);
+    newfunc(program);
     enterblock(program);
     curmodule = program;
     t_boolean = maketype("$boolean", 0L, 1L);
     t_int = maketype("$integer", 0x80000000L, 0x7fffffffL);
     t_char = maketype("$char", 0L, 127L);
     enterblock(program);
     curmodule = program;
     t_boolean = maketype("$boolean", 0L, 1L);
     t_int = maketype("$integer", 0x80000000L, 0x7fffffffL);
     t_char = maketype("$char", 0L, 127L);
-    t_real = maketype("$real", 4L, 0L);
+    t_real = maketype("$real", 8L, 0L);
     t_nil = maketype("$nil", 0L, 0L);
 }
 
     t_nil = maketype("$nil", 0L, 0L);
 }
 
@@ -244,8 +265,7 @@ register struct nlist *np;
 {
     register Symbol s;
     String mname, suffix;
 {
     register Symbol s;
     String mname, suffix;
-    register Name n;
-    register Symbol *tt;
+    register Name n, nn;
 
     s = nil;
     if (name == nil) {
 
     s = nil;
     if (name == nil) {
@@ -254,6 +274,33 @@ register struct nlist *np;
        n = identname(name, true);
     }
     switch (np->n_type) {
        n = identname(name, true);
     }
     switch (np->n_type) {
+
+    /*
+     * Build a symbol for the common; all GSYMS that follow will be chained;
+     * the head of this list is kept in common.offset, the tail in common.chain
+     */
+       case N_BCOMM:
+           if (curcomm) {
+               curcomm->symvalue.common.chain = commchain;
+           }
+           curcomm = lookup(n);
+           if (curcomm == nil) {
+               curcomm = insert(n);
+               curcomm->class = COMMON;
+               curcomm->block = curblock;
+               curcomm->level = program->level;
+               curcomm->symvalue.common.chain = nil;
+           }
+           commchain = curcomm->symvalue.common.chain;
+           break;
+
+       case N_ECOMM:
+           if (curcomm) {
+               curcomm->symvalue.common.chain = commchain;
+               curcomm = nil;
+           }
+           break;
+                                  
        case N_LBRAC:
            s = symbol_alloc();
            s->class = PROC;
        case N_LBRAC:
            s = symbol_alloc();
            s->class = PROC;
@@ -284,6 +331,9 @@ register struct nlist *np;
            }
            suffix = rindex(mname, '.');
            curlang = findlanguage(suffix);
            }
            suffix = rindex(mname, '.');
            curlang = findlanguage(suffix);
+           if(curlang == findlanguage(".f")) {
+                            strip_ = true;
+            } 
            if (suffix != nil) {
                *suffix = '\0';
            }
            if (suffix != nil) {
                *suffix = '\0';
            }
@@ -293,9 +343,16 @@ register struct nlist *np;
                    exitblock();
                }
            }
                    exitblock();
                }
            }
-           s = insert(identname(mname, true));
+           nn = identname(mname, true);
+           if (curmodule == nil or curmodule->name != nn) {
+               s = insert(nn);
+               s->class = MODULE;
+               s->symvalue.funcv.beginaddr = 0;
+               findbeginning(s);
+           } else {
+               s = curmodule;
+           }
            s->language = curlang;
            s->language = curlang;
-           s->class = MODULE;
            enterblock(s);
            curmodule = s;
            if (program->language == nil) {
            enterblock(s);
            curmodule = s;
            if (program->language == nil) {
@@ -303,9 +360,7 @@ register struct nlist *np;
            }
            warned = false;
            enterfile(ident(n), (Address) np->n_value);
            }
            warned = false;
            enterfile(ident(n), (Address) np->n_value);
-           for (tt = &typetable[0]; tt < &typetable[NTYPES]; tt++) {
-               *tt = nil;
-           }
+           bzero(typetable, sizeof(typetable));
            break;
 
        /*
            break;
 
        /*
@@ -345,12 +400,18 @@ register struct nlist *np;
        case N_PC:
            break;
 
        case N_PC:
            break;
 
+       case N_LENG:
        default:
        default:
+           /*
+            * Should complain out this, obviously the wrong symbol format.
+            *
            if (name != nil) {
                printf("%s, ", name);
            }
            printf("ntype %2x, desc %x, value %x\n",
                np->n_type, np->n_desc, np->n_value);
            if (name != nil) {
                printf("%s, ", name);
            }
            printf("ntype %2x, desc %x, value %x\n",
                np->n_type, np->n_desc, np->n_value);
+            *
+            */
            break;
     }
 }
            break;
     }
 }
@@ -365,7 +426,7 @@ String name;
 register struct nlist *np;
 {
     register Name n;
 register struct nlist *np;
 {
     register Name n;
-    register Symbol t;
+    register Symbol t, u;
 
     if (not streq(name, "end")) {
        n = identname(name, true);
 
     if (not streq(name, "end")) {
        n = identname(name, true);
@@ -380,27 +441,57 @@ register struct nlist *np;
                t->type = t_int;
                t->block = curblock;
                t->level = program->level;
                t->type = t_int;
                t->block = curblock;
                t->level = program->level;
+               t->symvalue.funcv.src = false;
            }
            t->symvalue.funcv.beginaddr = np->n_value;
            newfunc(t);
            findbeginning(t);
            }
            t->symvalue.funcv.beginaddr = np->n_value;
            newfunc(t);
            findbeginning(t);
-       } else {
+       } else if ((np->n_type&N_TYPE) == N_BSS) {
            find(t, n) where
            find(t, n) where
-               t->class == VAR and t->level == program->level
+               t->class == COMMON
            endfind(t);
            endfind(t);
-           if (t == nil) {
-               t = insert(n);
-               t->language = findlanguage(".s");
-               t->class = VAR;
-               t->type = t_int;
-               t->block = curblock;
-               t->level = program->level;
+           if (t != nil) {
+               u = (Symbol) t->symvalue.common.offset;
+               while (u != nil) {
+                   u->symvalue.offset = u->symvalue.common.offset+np->n_value;
+                   u = u->symvalue.common.chain;
+               }
+            } else {
+               check_var(np, n);
            }
            }
-           t->symvalue.offset = np->n_value;
+        } else {
+           check_var(np, n);
        }
     }
 }
 
        }
     }
 }
 
+/*
+ * Check to see if a namelist entry refers to a variable.
+ * If not, create a variable for the entry.  In any case,
+ * set the offset of the variable according to the value field
+ * in the entry.
+ */
+
+private check_var(np, n)
+struct nlist *np;
+register Name n;
+{
+    register Symbol t;
+
+    find(t, n) where
+       t->class == VAR and t->level == program->level
+    endfind(t);
+    if (t == nil) {
+       t = insert(n);
+       t->language = findlanguage(".s");
+       t->class = VAR;
+       t->type = t_int;
+       t->level = program->level;
+    }
+    t->block = curblock;
+    t->symvalue.offset = np->n_value;
+}
+
 /*
  * Check to see if a local _name is known in the current scope.
  * If not then enter it.
 /*
  * Check to see if a local _name is known in the current scope.
  * If not then enter it.
@@ -424,6 +515,7 @@ register struct nlist *np;
        t->level = cur->level;
        if ((np->n_type&N_TYPE) == N_TEXT) {
            t->class = FUNC;
        t->level = cur->level;
        if ((np->n_type&N_TYPE) == N_TEXT) {
            t->class = FUNC;
+           t->symvalue.funcv.src = false;
            t->symvalue.funcv.beginaddr = np->n_value;
            newfunc(t);
            findbeginning(t);
            t->symvalue.funcv.beginaddr = np->n_value;
            newfunc(t);
            findbeginning(t);
@@ -457,6 +549,8 @@ String name;
        s = insert(identname(&mname[i+1], true));
        s->language = findlanguage(".s");
        s->class = MODULE;
        s = insert(identname(&mname[i+1], true));
        s->language = findlanguage(".s");
        s->class = MODULE;
+       s->symvalue.funcv.beginaddr = 0;
+       findbeginning(s);
        if (curblock->class != PROG) {
            exitblock();
            if (curblock->class != PROG) {
        if (curblock->class != PROG) {
            exitblock();
            if (curblock->class != PROG) {
@@ -544,11 +638,13 @@ struct nlist *np;
            /*
             * A hack for C typedefs that don't create new types,
             * e.g. typedef unsigned int Hashvalue;
            /*
             * A hack for C typedefs that don't create new types,
             * e.g. typedef unsigned int Hashvalue;
+            *  or  typedef struct blah BLAH;
             */
            if (*curchar == '\0') {
                s->type = typetable[i];
                if (s->type == nil) {
             */
            if (*curchar == '\0') {
                s->type = typetable[i];
                if (s->type == nil) {
-                   panic("nil type for %d", i);
+                   s->type = symbol_alloc();
+                   typetable[i] = s->type;
                }
                knowtype = true;
            } else {
                }
                knowtype = true;
            } else {
@@ -589,6 +685,7 @@ struct nlist *np;
            }
            curparam = s;
            if (isnew) {
            }
            curparam = s;
            if (isnew) {
+               s->symvalue.funcv.src = false;
                s->symvalue.funcv.beginaddr = np->n_value;
                newfunc(s);
                findbeginning(s);
                s->symvalue.funcv.beginaddr = np->n_value;
                newfunc(s);
                findbeginning(s);
@@ -604,8 +701,23 @@ struct nlist *np;
            s->block = curmodule;
            break;
 
            s->block = curmodule;
            break;
 
+/*
+ *  keep global BSS variables chained so can resolve when get the start
+ *  of common; keep the list in order so f77 can display all vars in a COMMON
+*/
        case 'V':       /* own variable */
            s->level = 2;
        case 'V':       /* own variable */
            s->level = 2;
+           if (curcomm) {
+             if (commchain != nil) {
+                 commchain->symvalue.common.chain = s;
+             }                   
+             else {
+                 curcomm->symvalue.common.offset = (int) s;
+             }                   
+              commchain = s;
+              s->symvalue.common.offset = np->n_value;
+              s->symvalue.common.chain = nil;
+           }
            break;
 
        case 'r':       /* register variable */
            break;
 
        case 'r':       /* register variable */
@@ -695,14 +807,63 @@ Symbol type;
        }
        t->language = curlang;
        t->level = b;
        }
        t->language = curlang;
        t->level = b;
+       t->block = curblock;
        class = *curchar++;
        switch (class) {
        class = *curchar++;
        switch (class) {
+
            case 'r':
                t->class = RANGE;
                t->type = constype(nil);
                skipchar(curchar, ';');
            case 'r':
                t->class = RANGE;
                t->type = constype(nil);
                skipchar(curchar, ';');
-               t->symvalue.rangev.lower = getint();
+                /* some letters indicate a dynamic bound, ie what follows
+                   is the offset from the fp which contains the bound; this will
+                   need a different encoding when pc a['A'..'Z'] is
+                   added; J is a special flag to handle fortran a(*) bounds
+                */
+               switch(*curchar) {
+                       case 'A':
+                               t->symvalue.rangev.lowertype = R_ARG;
+                               curchar++;
+                               break;
+
+                       case 'T':
+                               t->symvalue.rangev.lowertype = R_TEMP;
+                               curchar++;
+                               break;
+
+                       case 'J': 
+                               t->symvalue.rangev.lowertype = R_ADJUST;
+                               curchar++;
+                               break;
+
+                       default:
+                                t->symvalue.rangev.lowertype = R_CONST;
+                                break;
+
+               }
+               t->symvalue.rangev.lower = getint();
                skipchar(curchar, ';');
                skipchar(curchar, ';');
+               switch(*curchar) {
+                       case 'A':
+                               t->symvalue.rangev.uppertype = R_ARG;
+                               curchar++;
+                               break;
+
+                       case 'T':
+                               t->symvalue.rangev.uppertype = R_TEMP;
+                               curchar++;
+                               break;
+
+                       case 'J': 
+                               t->symvalue.rangev.uppertype = R_ADJUST;
+                               curchar++;
+                               break;
+
+                       default:
+                                t->symvalue.rangev.uppertype = R_CONST;
+                                break;
+
+               }
                t->symvalue.rangev.upper = getint();
                break;
 
                t->symvalue.rangev.upper = getint();
                break;
 
@@ -849,19 +1010,21 @@ Integer nf, nl;
 
 /*
  * Add a file to the file table.
 
 /*
  * Add a file to the file table.
+ *
+ * If the new address is the same as the previous file address
+ * this routine used to not enter the file, but this caused some
+ * problems so it has been removed.  It's not clear that this in
+ * turn may not also cause a problem.
  */
 
 private enterfile(filename, addr)
 String filename;
 Address addr;
 {
  */
 
 private enterfile(filename, addr)
 String filename;
 Address addr;
 {
-    if (addr != curfaddr) {
-       filep->addr = addr;
-       filep->filename = filename;
-       filep->lineindex = linep - linetab;
-       ++filep;
-       curfaddr = addr;
-    }
+    filep->addr = addr;
+    filep->filename = filename;
+    filep->lineindex = linep - linetab;
+    ++filep;
 }
 
 /*
 }
 
 /*