* serial.h (SERIAL_SET_TTY_STATE): Comment return value.
[deliverable/binutils-gdb.git] / gdb / symtab.c
index 47a85da3558b726a9d509d347e85da540accdbfe..3e751db5e693b612768846516456faa8f52dc806 100644 (file)
@@ -1,6 +1,6 @@
 /* Symbol table lookup for the GNU debugger, GDB.
-   Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992
-   Free Software Foundation, Inc.
+   Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994
+             Free Software Foundation, Inc.
 
 This file is part of GDB.
 
@@ -193,6 +193,10 @@ lookup_symtab (name)
   s = lookup_symtab_1 (name);
   if (s) return s;
 
+#if 0
+  /* This screws c-exp.y:yylex if there is both a type "tree" and a symtab
+     "tree.c".  */
+
   /* If name not found as specified, see if adding ".c" helps.  */
   /* Why is this?  Is it just a user convenience?  (If so, it's pretty
      questionable in the presence of C++, FORTRAN, etc.).  It's not in
@@ -203,6 +207,7 @@ lookup_symtab (name)
   strcat (copy, ".c");
   s = lookup_symtab_1 (copy);
   if (s) return s;
+#endif /* 0 */
 
   /* We didn't find anything; die.  */
   return 0;
@@ -420,6 +425,21 @@ find_pc_psymbol (psymtab, pc)
 
   best_pc = psymtab->textlow - 1;
 
+  /* Search the global symbols as well as the static symbols, so that
+     find_pc_partial_function doesn't use a minimal symbol and thus
+     cache a bad endaddr.  */
+  for (p = psymtab->objfile->global_psymbols.list + psymtab->globals_offset;
+       (p - (psymtab->objfile->global_psymbols.list + psymtab->globals_offset)
+       < psymtab->n_global_syms);
+       p++)
+    if (SYMBOL_NAMESPACE (p) == VAR_NAMESPACE
+       && SYMBOL_CLASS (p) == LOC_BLOCK
+       && pc >= SYMBOL_VALUE_ADDRESS (p)
+       && SYMBOL_VALUE_ADDRESS (p) > best_pc)
+      {
+       best_pc = SYMBOL_VALUE_ADDRESS (p);
+       best = p;
+      }
   for (p = psymtab->objfile->static_psymbols.list + psymtab->statics_offset;
        (p - (psymtab->objfile->static_psymbols.list + psymtab->statics_offset)
        < psymtab->n_static_syms);
@@ -449,6 +469,16 @@ find_pc_psymbol (psymtab, pc)
    BLOCK_FOUND is set to the block in which NAME is found (in the case of
    a field of `this', value_of_this sets BLOCK_FOUND to the proper value.) */
 
+/* This function has a bunch of loops in it and it would seem to be
+   attractive to put in some QUIT's (though I'm not really sure
+   whether it can run long enough to be really important).  But there
+   are a few calls for which it would appear to be bad news to quit
+   out of here: find_proc_desc in alpha-tdep.c and mips-tdep.c, and
+   nindy_frame_chain_valid in nindy-tdep.c.  (Note that there is C++
+   code below which can error(), but that probably doesn't affect
+   these calls since they are looking for a known variable and thus
+   can probably assume it will never hit the C++ code).  */
+
 struct symbol *
 lookup_symbol (name, block, namespace, is_a_field_of_this, symtab)
      const char *name;
@@ -1006,6 +1036,80 @@ find_pc_symtab (pc)
     }
   return (s);
 }
+\f
+/* Find the closest symbol value (of any sort -- function or variable)
+   for a given address value.  Slow but complete.  */
+
+struct symbol *
+find_addr_symbol (addr, symtabp, symaddrp)
+     CORE_ADDR addr;
+     struct symtab **symtabp;
+     CORE_ADDR *symaddrp;
+{
+  struct symtab *symtab, *best_symtab;
+  struct objfile *objfile;
+  register int bot, top;
+  register struct symbol *sym;
+  register CORE_ADDR sym_addr;
+  struct block *block;
+  int blocknum;
+
+  /* Info on best symbol seen so far */
+
+  register CORE_ADDR best_sym_addr = 0;
+  struct symbol *best_sym = 0;
+
+  /* FIXME -- we should pull in all the psymtabs, too!  */
+  ALL_SYMTABS (objfile, symtab)
+    {
+      /* Search the global and static blocks in this symtab for
+        the closest symbol-address to the desired address.  */
+
+      for (blocknum = GLOBAL_BLOCK; blocknum <= STATIC_BLOCK; blocknum++)
+       {
+         QUIT;
+         block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab), blocknum);
+         top = BLOCK_NSYMS (block);
+         for (bot = 0; bot < top; bot++)
+           {
+             sym = BLOCK_SYM (block, bot);
+             switch (SYMBOL_CLASS (sym))
+               {
+               case LOC_STATIC:        
+               case LOC_LABEL: 
+                 sym_addr = SYMBOL_VALUE_ADDRESS (sym);
+                 break;
+
+               case LOC_BLOCK:
+                 sym_addr = BLOCK_START (SYMBOL_BLOCK_VALUE (sym));
+                 break;
+
+               default:
+                 continue;
+               }
+
+               if (sym_addr <= addr)
+                 if (sym_addr > best_sym_addr)
+                   {
+                     /* Quit if we found an exact match.  */
+                     best_sym = sym;
+                     best_sym_addr = sym_addr;
+                     best_symtab = symtab;
+                     if (sym_addr == addr)
+                       goto done;
+                   }
+           }
+       }
+    }
+
+ done:
+  if (symtabp)
+    *symtabp = best_symtab;
+  if (symaddrp)
+    *symaddrp = best_sym_addr;
+  return best_sym;
+}
+
 
 /* Find the source file and line number for a given PC value.
    Return a structure containing a symtab pointer, a line number,
This page took 0.024574 seconds and 4 git commands to generate.