aboutsummaryrefslogtreecommitdiff
path: root/gdb/symtab.c
diff options
context:
space:
mode:
authorgdb-3.1 <gdb@fsf.org>1989-01-31 17:56:40 +0000
committerPedro Alves <palves@redhat.com>2012-06-03 15:36:31 +0100
commite91b87a36830d061ef87d67be5f309e4d4ed918f (patch)
tree3408ea913a9cccd51c9b7d0b3bc7d7897cac8a5b /gdb/symtab.c
parentbb7592f01006b09c846831a9fb9c306307ba34f6 (diff)
downloadgdb-e91b87a36830d061ef87d67be5f309e4d4ed918f.zip
gdb-e91b87a36830d061ef87d67be5f309e4d4ed918f.tar.gz
gdb-e91b87a36830d061ef87d67be5f309e4d4ed918f.tar.bz2
gdb-3.1
Diffstat (limited to 'gdb/symtab.c')
-rw-r--r--gdb/symtab.c592
1 files changed, 440 insertions, 152 deletions
diff --git a/gdb/symtab.c b/gdb/symtab.c
index 19fa494..5b36c71 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -19,17 +19,13 @@ anyone else from sharing it farther. Help stamp out software hoarding!
*/
#include "defs.h"
-#include "initialize.h"
#include "symtab.h"
#include "param.h"
#include <stdio.h>
#include <obstack.h>
+#include <assert.h>
-START_FILE
-
-static int find_line_common();
-static int lookup_misc_func();
/* Allocate an obstack to hold objects that should be freed
when we load a new symbol table.
@@ -40,6 +36,15 @@ struct obstack obstack1;
struct obstack *symbol_obstack = &obstack1;
+/* This obstack will be used for partial_symbol objects. It can
+ probably actually be the same as the symbol_obstack above, but I'd
+ like to keep them seperate for now. If I want to later, I'll
+ replace one with the other. */
+
+struct obstack obstack2;
+
+struct obstack *psymbol_obstack = &obstack2;
+
/* These variables point to the objects
representing the predefined C data types. */
@@ -48,20 +53,41 @@ struct type *builtin_type_char;
struct type *builtin_type_short;
struct type *builtin_type_int;
struct type *builtin_type_long;
+#ifdef LONG_LONG
+struct type *builtin_type_long_long;
+#endif
struct type *builtin_type_unsigned_char;
struct type *builtin_type_unsigned_short;
struct type *builtin_type_unsigned_int;
struct type *builtin_type_unsigned_long;
+#ifdef LONG_LONG
+struct type *builtin_type_unsigned_long_long;
+#endif
struct type *builtin_type_float;
struct type *builtin_type_double;
-/* Lookup the symbol table of a source file named NAME. */
+/* Block in which the most recently searched-for symbol was found.
+ Might be better to make this a parameter to lookup_symbol and
+ value_of_this. */
+struct block *block_found;
+
+/* Functions */
+static int find_line_common ();
+static int lookup_misc_func ();
+struct partial_symtab *lookup_partial_symtab ();
+struct symtab *psymtab_to_symtab ();
+static struct partial_symbol *lookup_partial_symbol ();
+
+/* Lookup the symbol table of a source file named NAME. If there
+ isn't any symtab for it, lookup the psymtab and read in the
+ symbtab. */
struct symtab *
lookup_symtab (name)
char *name;
{
register struct symtab *s;
+ register struct partial_symtab *ps;
register char *copy;
for (s = symtab_list; s; s = s->next)
@@ -77,6 +103,38 @@ lookup_symtab (name)
if (!strcmp (copy, s->filename))
return s;
+ ps = lookup_partial_symtab (name);
+ if (ps)
+ {
+ s = psymtab_to_symtab (ps);
+ return s;
+ }
+
+ return 0;
+}
+
+/* Lookup the partial symbol table of a source file named NAME. */
+
+struct partial_symtab *
+lookup_partial_symtab (name)
+char *name;
+{
+ register struct partial_symtab *s;
+ register char *copy;
+
+ for (s = partial_symtab_list; s; s = s->next)
+ if (!strcmp (name, s->filename))
+ return s;
+
+ /* If name not found as specified, see if adding ".c" helps. */
+
+ copy = (char *) alloca (strlen (name) + 3);
+ strcpy (copy, name);
+ strcat (copy, ".c");
+ for (s = partial_symtab_list; s; s = s->next)
+ if (!strcmp (copy, s->filename))
+ return s;
+
return 0;
}
@@ -90,7 +148,7 @@ lookup_typename (name, block, noerr)
struct block *block;
int noerr;
{
- register struct symbol *sym = lookup_symbol (name, block, VAR_NAMESPACE);
+ register struct symbol *sym = lookup_symbol (name, block, VAR_NAMESPACE, 0);
if (sym == 0 || SYMBOL_CLASS (sym) != LOC_TYPEDEF)
{
if (!strcmp (name, "int"))
@@ -138,11 +196,13 @@ lookup_struct (name, block)
char *name;
struct block *block;
{
- register struct symbol *sym = lookup_symbol (name, block, STRUCT_NAMESPACE);
+ register struct symbol *sym
+ = lookup_symbol (name, block, STRUCT_NAMESPACE, 0);
+
if (sym == 0)
error ("No struct type named %s.", name);
if (TYPE_CODE (SYMBOL_TYPE (sym)) != TYPE_CODE_STRUCT)
- error ("This context has union or enum %s, not a struct.", name);
+ error ("This context has class, union or enum %s, not a struct.", name);
return SYMBOL_TYPE (sym);
}
@@ -154,11 +214,13 @@ lookup_union (name, block)
char *name;
struct block *block;
{
- register struct symbol *sym = lookup_symbol (name, block, STRUCT_NAMESPACE);
+ register struct symbol *sym
+ = lookup_symbol (name, block, STRUCT_NAMESPACE, 0);
+
if (sym == 0)
error ("No union type named %s.", name);
if (TYPE_CODE (SYMBOL_TYPE (sym)) != TYPE_CODE_UNION)
- error ("This context has struct or enum %s, not a union.", name);
+ error ("This context has class, struct or enum %s, not a union.", name);
return SYMBOL_TYPE (sym);
}
@@ -170,11 +232,12 @@ lookup_enum (name, block)
char *name;
struct block *block;
{
- register struct symbol *sym = lookup_symbol (name, block, STRUCT_NAMESPACE);
+ register struct symbol *sym
+ = lookup_symbol (name, block, STRUCT_NAMESPACE, 0);
if (sym == 0)
error ("No enum type named %s.", name);
if (TYPE_CODE (SYMBOL_TYPE (sym)) != TYPE_CODE_ENUM)
- error ("This context has struct or union %s, not an enum.", name);
+ error ("This context has class, struct or union %s, not an enum.", name);
return SYMBOL_TYPE (sym);
}
@@ -238,14 +301,15 @@ lookup_reference_type (type)
return rtype;
}
+
/* Implement direct support for MEMBER_TYPE in GNU C++.
May need to construct such a type if this is the first use.
The TYPE is the type of the member. The DOMAIN is the type
of the aggregate that the member belongs to. */
struct type *
-lookup_member_type (domain, type)
- struct type *domain, *type;
+lookup_member_type (type, domain)
+ struct type *type, *domain;
{
register struct type *mtype = TYPE_MAIN_VARIANT (type);
struct type *main_type;
@@ -266,7 +330,8 @@ lookup_member_type (domain, type)
sizeof (struct type));
bzero (mtype, sizeof (struct type));
- if (main_type == 0) main_type = mtype;
+ if (main_type == 0)
+ main_type = mtype;
else
{
TYPE_NEXT_VARIANT (mtype) = TYPE_NEXT_VARIANT (main_type);
@@ -283,6 +348,16 @@ lookup_member_type (domain, type)
TYPE_LENGTH (mtype) = 1;
TYPE_CODE (mtype) = TYPE_CODE_MEMBER;
+#if 0
+ /* Now splice in the new member pointer type. */
+ if (main_type)
+ {
+ /* This type was not "smashed". */
+ TYPE_CHAIN (mtype) = TYPE_CHAIN (main_type);
+ TYPE_CHAIN (main_type) = mtype;
+ }
+#endif
+
return mtype;
}
@@ -352,9 +427,8 @@ lookup_basetype_type (type, offset, via_virtual, via_public)
May need to construct such a type if this is the first use. */
struct type *
-lookup_function_type (type, argtypes)
+lookup_function_type (type)
struct type *type;
- struct type **argtypes;
{
register struct type *ptype = TYPE_FUNCTION_TYPE (type);
if (ptype) return ptype;
@@ -466,17 +540,24 @@ static struct symbol *lookup_block_symbol ();
/* Find the definition for a specified symbol name NAME
in namespace NAMESPACE, visible from lexical block BLOCK.
- Returns the struct symbol pointer, or zero if no symbol is found. */
+ Returns the struct symbol pointer, or zero if no symbol is found.
+ C++: if IS_A_FIELD_OF_THIS is nonzero on entry, check to see if
+ NAME is a field of the current implied argument `this'. If so set
+ *IS_A_FIELD_OF_THIS to 1, otherwise set it to zero.
+ 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.) */
struct symbol *
-lookup_symbol_1 (name, block, namespace)
+lookup_symbol (name, block, namespace, is_a_field_of_this)
char *name;
register struct block *block;
enum namespace namespace;
+ int *is_a_field_of_this;
{
register int i, n;
register struct symbol *sym;
register struct symtab *s;
+ register struct partial_symtab *ps;
struct blockvector *bv;
/* Search specified block and its superiors. */
@@ -484,87 +565,147 @@ lookup_symbol_1 (name, block, namespace)
while (block != 0)
{
sym = lookup_block_symbol (block, name, namespace);
- if (sym) return sym;
+ if (sym)
+ {
+ block_found = block;
+ return sym;
+ }
block = BLOCK_SUPERBLOCK (block);
}
- return 0;
-}
-struct symbol *
-lookup_symbol_2 (name, block, namespace)
- char *name;
- register struct block *block; /* ignored as parameter */
- enum namespace namespace;
-{
- register int i, n;
- register struct symbol *sym;
- register struct symtab *s;
- struct blockvector *bv;
+ /* C++: If requested to do so by the caller,
+ check to see if NAME is a field of `this'. */
+ if (is_a_field_of_this)
+ {
+ int v = (int) value_of_this (0);
+
+ *is_a_field_of_this = 0;
+ if (v && check_field (v, name))
+ {
+ *is_a_field_of_this = 1;
+ return 0;
+ }
+ }
- /* Now search all symtabs' global blocks. */
+ /* Now search all global blocks. Do the symtab's first, then
+ check the psymtab's */
for (s = symtab_list; s; s = s->next)
{
bv = BLOCKVECTOR (s);
block = BLOCKVECTOR_BLOCK (bv, 0);
sym = lookup_block_symbol (block, name, namespace);
- if (sym) return sym;
+ if (sym)
+ {
+ block_found = block;
+ return sym;
+ }
}
- /* Now search all symtabs' per-file blocks.
- Not strictly correct, but more useful than an error. */
+ for (ps = partial_symtab_list; ps; ps = ps->next)
+ if (lookup_partial_symbol (ps, name, 1, namespace))
+ {
+ s = psymtab_to_symtab(ps);
+ bv = BLOCKVECTOR (s);
+ block = BLOCKVECTOR_BLOCK (bv, 0);
+ sym = lookup_block_symbol (block, name, namespace);
+ if (!sym)
+ fatal ("Internal: global symbol found in psymtab but not in symtab");
+ return sym;
+ }
+
+ /* Now search all per-file blocks.
+ Not strictly correct, but more useful than an error.
+ Do the symtabs first, then check the psymtabs */
for (s = symtab_list; s; s = s->next)
{
bv = BLOCKVECTOR (s);
block = BLOCKVECTOR_BLOCK (bv, 1);
sym = lookup_block_symbol (block, name, namespace);
- if (sym) return sym;
+ if (sym)
+ {
+ block_found = block;
+ return sym;
+ }
}
+
+ for (ps = partial_symtab_list; ps; ps = ps->next)
+ if (lookup_partial_symbol (ps, name, 0, namespace))
+ {
+ s = psymtab_to_symtab(ps);
+ bv = BLOCKVECTOR (s);
+ block = BLOCKVECTOR_BLOCK (bv, 1);
+ sym = lookup_block_symbol (block, name, namespace);
+ if (!sym)
+ fatal ("Internal: static symbol found in psymtab but not in symtab");
+ return sym;
+ }
+
return 0;
}
-struct symbol *
-lookup_symbol (name, block, namespace)
+/* Look, in partial_symtab PST, for symbol NAME. Check the global
+ symbols if GLOBAL, the static symbols if not */
+
+static struct partial_symbol *
+lookup_partial_symbol (pst, name, global, namespace)
+ struct partial_symtab *pst;
char *name;
- register struct block *block;
+ int global;
enum namespace namespace;
{
- register int i, n;
- register struct symbol *sym;
- register struct symtab *s;
- struct blockvector *bv;
+ struct partial_symbol *start, *psym;
+ int length = (global ? pst->n_global_syms : pst->n_static_syms);
- /* Search specified block and its superiors. */
+ start = (global ?
+ global_psymbols + pst->globals_offset :
+ static_psymbols + pst->statics_offset );
- while (block != 0)
+ if (!length)
+ return (struct partial_symbol *) 0;
+
+ if (global) /* This means we can use a binary */
+ /* search. */
{
- sym = lookup_block_symbol (block, name, namespace);
- if (sym) return sym;
- block = BLOCK_SUPERBLOCK (block);
- }
-
- /* Now search all symtabs' global blocks. */
+ struct partial_symbol *top, *bottom, *center;
+
+ /* Binary search. This search is guarranteed to end with center
+ pointing at the earliest partial symbol with the correct
+ name. At that point *all* partial symbols with that name
+ will be checked against the correct namespace. */
+ bottom = start;
+ top = start + length - 1;
+ while (top > bottom)
+ {
+ center = bottom + (top - bottom) / 2;
- for (s = symtab_list; s; s = s->next)
- {
- bv = BLOCKVECTOR (s);
- block = BLOCKVECTOR_BLOCK (bv, 0);
- sym = lookup_block_symbol (block, name, namespace);
- if (sym) return sym;
+ assert (center < top);
+
+ if (strcmp (SYMBOL_NAME (center), name) >= 0)
+ top = center;
+ else
+ bottom = center + 1;
+ }
+ assert (top == bottom);
+
+ while (!strcmp (SYMBOL_NAME (top), name))
+ {
+ if (SYMBOL_NAMESPACE (top) == namespace)
+ return top;
+ top ++;
+ }
}
-
- /* Now search all symtabs' per-file blocks.
- Not strictly correct, but more useful than an error. */
-
- for (s = symtab_list; s; s = s->next)
+ else
{
- bv = BLOCKVECTOR (s);
- block = BLOCKVECTOR_BLOCK (bv, 1);
- sym = lookup_block_symbol (block, name, namespace);
- if (sym) return sym;
+ /* Can't use a binary search */
+ for (psym = start; psym < start + length; psym++)
+ if (namespace == SYMBOL_NAMESPACE (psym)
+ && !strcmp (name, SYMBOL_NAME (psym)))
+ return psym;
}
- return 0;
+
+ return (struct partial_symbol *) 0;
}
/* Look for a symbol in block BLOCK. */
@@ -576,7 +717,7 @@ lookup_block_symbol (block, name, namespace)
enum namespace namespace;
{
register int bot, top, inc;
- register struct symbol *sym;
+ register struct symbol *sym, *parameter_sym;
top = BLOCK_NSYMS (block);
bot = 0;
@@ -631,8 +772,15 @@ lookup_block_symbol (block, name, namespace)
/* Here if block isn't sorted.
This loop is equivalent to the loop above,
- but hacked greatly for speed. */
+ but hacked greatly for speed.
+
+ Note that parameter symbols do not always show up last in the
+ list; this loop makes sure to take anything else other than
+ parameter symbols first; it only uses parameter symbols as a
+ last resort. Note that this only takes up extra computation
+ time on a match. */
+ parameter_sym = (struct symbol *) 0;
top = BLOCK_NSYMS (block);
inc = name[0];
while (bot < top)
@@ -641,10 +789,16 @@ lookup_block_symbol (block, name, namespace)
if (SYMBOL_NAME (sym)[0] == inc
&& !strcmp (SYMBOL_NAME (sym), name)
&& SYMBOL_NAMESPACE (sym) == namespace)
- return sym;
+ {
+ if (SYMBOL_CLASS (sym) == LOC_ARG ||
+ SYMBOL_CLASS (sym) == LOC_REGPARM)
+ parameter_sym = sym;
+ else
+ return sym;
+ }
bot++;
}
- return 0;
+ return parameter_sym; /* Will be 0 if not found. */
}
/* Return the symbol for the function which contains a specified
@@ -669,6 +823,7 @@ find_pc_symtab (pc)
register struct block *b;
struct blockvector *bv;
register struct symtab *s;
+ register struct partial_symtab *ps;
/* Search all symtabs for one whose file contains our pc */
@@ -681,6 +836,14 @@ find_pc_symtab (pc)
break;
}
+ if (!s)
+ for (ps = partial_symtab_list; ps; ps = ps->next)
+ if (pc >= ps->textlow && pc < ps->texthigh)
+ {
+ s = psymtab_to_symtab (ps);
+ break;
+ }
+
return s;
}
@@ -700,8 +863,8 @@ find_pc_line (pc, notcurrent)
struct symtab *s;
register struct linetable *l;
register int len;
- register int i, item;
- int line;
+ register int i;
+ register struct linetable_entry *item;
struct symtab_and_line value;
struct blockvector *bv;
@@ -745,6 +908,7 @@ find_pc_line (pc, notcurrent)
value.symtab = 0;
value.line = 0;
value.pc = pc;
+ value.end = 0;
return value;
}
@@ -763,26 +927,21 @@ find_pc_line (pc, notcurrent)
first_line = -1;
for (i = 0; i < len; i++)
{
- item = l->item[i];
- if (item < 0)
- line = - item - 1;
- else
+ item = &(l->item[i]);
+
+ if (first_line < 0)
{
- line++;
- if (first_line < 0)
- {
- first_line = line;
- first_pc = item;
- }
- /* Return the last line that did not start after PC. */
- if (pc >= item)
- {
- prev_line = line;
- prev_pc = item;
- }
- else
- break;
+ first_line = item->line;
+ first_pc = item->pc;
+ }
+ /* Return the last line that did not start after PC. */
+ if (pc >= item->pc)
+ {
+ prev_line = item->line;
+ prev_pc = item->pc;
}
+ else
+ break;
}
/* Is this file's best line closer than the best in the other files?
@@ -793,7 +952,7 @@ find_pc_line (pc, notcurrent)
best_line = prev_line;
best_symtab = s;
if (i < len)
- best_end = item;
+ best_end = item->pc;
else
best_end = 0;
}
@@ -843,7 +1002,7 @@ find_line_pc (symtab, line)
return 0;
l = LINETABLE (symtab);
index = find_line_common(l, line, &dummy);
- return index ? l->item[index] : 0;
+ return index ? l->item[index].pc : 0;
}
/* Find the range of pc values in a line.
@@ -871,7 +1030,7 @@ find_line_pc_range (symtab, thisline, startptr, endptr)
index = find_line_common (l, thisline, &exact_match);
if (index)
{
- *startptr = l->item[index];
+ *startptr = l->item[index].pc;
/* If we have not seen an entry for the specified line,
assume that means the specified line has zero bytes. */
if (!exact_match || index == l->nitems-1)
@@ -879,8 +1038,8 @@ find_line_pc_range (symtab, thisline, startptr, endptr)
else
/* Perhaps the following entry is for the following line.
It's worth a try. */
- if (l->item[index+1] > 0)
- *endptr = l->item[index+1];
+ if (l->item[index+1].line == thisline + 1)
+ *endptr = l->item[index+1].pc;
else
*endptr = find_line_pc (symtab, thisline+1);
return 1;
@@ -919,24 +1078,18 @@ find_line_common (l, lineno, exact_match)
len = l->nitems;
for (i = 0; i < len; i++)
{
- register int item = l->item[i];
+ register struct linetable_entry *item = &(l->item[i]);
- if (item < 0)
- nextline = - item - 1;
- else
+ if (item->line == lineno)
{
- nextline++;
- if (nextline == lineno)
- {
- *exact_match = 1;
- return i;
- }
+ *exact_match = 1;
+ return i;
+ }
- if (nextline > lineno && (best == 0 || nextline < best))
- {
- best = lineno;
- best_index = i;
- }
+ if (item->line > lineno && (best == 0 || item->line < best))
+ {
+ best = item->line;
+ best_index = i;
}
}
@@ -1008,7 +1161,7 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line)
struct symbol **sym_arr;
struct type *t, *field;
char **physnames;
-
+
/* Defaults have defaults. */
if (default_symtab == 0)
@@ -1043,6 +1196,7 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line)
if (p[0] == ':')
{
+
/* C++ */
if (p[1] ==':')
{
@@ -1058,7 +1212,7 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line)
while (*p == ' ' || *p == '\t') p++;
*argptr = p;
- sym_class = lookup_symbol (copy, 0, STRUCT_NAMESPACE);
+ sym_class = lookup_symbol (copy, 0, STRUCT_NAMESPACE, 0);
if (sym_class &&
(TYPE_CODE (SYMBOL_TYPE (sym_class)) == TYPE_CODE_STRUCT
@@ -1090,7 +1244,7 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line)
phys_name = TYPE_FN_FIELD_PHYSNAME (f, len);
physnames[i1] = (char *)alloca (strlen (phys_name) + 1);
strcpy (physnames[i1], phys_name);
- sym_arr[i1] = lookup_symbol (phys_name, SYMBOL_BLOCK_VALUE (sym_class), VAR_NAMESPACE);
+ sym_arr[i1] = lookup_symbol (phys_name, SYMBOL_BLOCK_VALUE (sym_class), VAR_NAMESPACE, 0);
if (sym_arr[i1]) i1++;
}
else while (t)
@@ -1098,7 +1252,7 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line)
class_name = TYPE_NAME (t);
while (*class_name++ != ' ');
- sym_class = lookup_symbol (class_name, 0, STRUCT_NAMESPACE);
+ sym_class = lookup_symbol (class_name, 0, STRUCT_NAMESPACE, 0);
for (method_counter = TYPE_NFN_FIELDS (SYMBOL_TYPE (sym_class)) - 1;
method_counter >= 0;
--method_counter)
@@ -1116,13 +1270,14 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line)
phys_name = TYPE_FN_FIELD_PHYSNAME (f, field_counter);
physnames[i1] = (char*) alloca (strlen (phys_name) + 1);
strcpy (physnames[i1], phys_name);
- sym_arr[i1] = lookup_symbol (phys_name, SYMBOL_BLOCK_VALUE (sym_class), VAR_NAMESPACE);
+ sym_arr[i1] = lookup_symbol (phys_name, SYMBOL_BLOCK_VALUE (sym_class), VAR_NAMESPACE, 0);
if (sym_arr[i1]) i1++;
}
}
if (TYPE_N_BASECLASSES (t))
t = TYPE_BASECLASS(t, 1);
- else break;
+ else
+ break;
}
if (i1 == 1)
@@ -1148,7 +1303,8 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line)
}
if (i1 > 0)
{
- return decode_line_2 (argptr, sym_arr, physnames, i1, funfirstline);
+ return decode_line_2 (argptr, sym_arr, physnames,
+ i1, funfirstline);
}
else
error ("that class does not have any method named %s",copy);
@@ -1158,6 +1314,7 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line)
}
/* end of C++ */
+
/* Extract the file name. */
p1 = p;
while (p != *argptr && p[-1] == ' ') --p;
@@ -1169,7 +1326,7 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line)
s = lookup_symtab (copy);
if (s == 0)
{
- if (symtab_list == 0)
+ if (symtab_list == 0 && partial_symtab_list == 0)
error ("No symbol table is loaded. Use the \"symbol-file\" command.");
error ("No source file named %s.", copy);
}
@@ -1195,6 +1352,20 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line)
/* We found a token consisting of all digits -- at least one digit. */
enum sign {none, plus, minus} sign = none;
+ /* This is where we need to make sure that we have good defaults.
+ We must guarrantee that this section of code is never executed
+ when we are called with just a function name, since
+ select_source_symtab calls us with such an argument */
+
+ if (s == 0 && default_symtab == 0)
+ {
+ if (symtab_list == 0 && partial_symtab_list == 0)
+ error ("No symbol table is loaded. Use the \"symbol-file\" command.");
+ select_source_symtab (symtab_list);
+ default_symtab = current_source_symtab;
+ default_line = current_source_line;
+ }
+
if (**argptr == '+')
sign = plus, (*argptr)++;
else if (**argptr == '-')
@@ -1244,7 +1415,7 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line)
If file specified, use that file's per-file block to start with. */
sym = lookup_symbol (copy, s ? BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), 1) : 0,
- VAR_NAMESPACE);
+ VAR_NAMESPACE, 0);
if (sym && SYMBOL_CLASS (sym) == LOC_BLOCK)
{
@@ -1253,7 +1424,12 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line)
if (funfirstline)
SKIP_PROLOGUE (pc);
value = find_pc_line (pc, 0);
+#ifdef convex
+ /* Convex: no need to suppress code on first line, if any */
+ value.pc = pc;
+#else
value.pc = (value.end && value.pc != pc) ? value.end : pc;
+#endif
values.sals = (struct symtab_and_line *)malloc (sizeof (struct symtab_and_line));
values.sals[0] = value;
values.nelts = 1;
@@ -1278,7 +1454,7 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line)
return values;
}
- if (symtab_list == 0)
+ if (symtab_list == 0 && partial_symtab_list == 0)
error ("No symbol table is loaded. Use the \"symbol-file\" command.");
error ("Function %s not defined.", copy);
}
@@ -1309,7 +1485,7 @@ decode_line_2 (argptr, sym_arr, physnames, nelts, funfirstline)
char *getenv();
struct symtabs_and_lines values, return_values;
register CORE_ADDR pc;
- char *args, *arg1, *read_line ();
+ char *args, *arg1, *gdb_read_line ();
int i;
char *prompt;
@@ -1342,7 +1518,7 @@ decode_line_2 (argptr, sym_arr, physnames, nelts, funfirstline)
printf("%s ",prompt);
fflush(stdout);
- args = read_line (0);
+ args = gdb_read_line (0, 0);
if (args == 0)
error_no_arg ("one or more choice numbers");
@@ -1395,7 +1571,7 @@ decode_line_2 (argptr, sym_arr, physnames, nelts, funfirstline)
/* Return the index of misc function named NAME. */
-static
+static int
lookup_misc_func (name)
register char *name;
{
@@ -1407,38 +1583,69 @@ lookup_misc_func (name)
return -1; /* not found */
}
+/*
+ * Slave routine for sources_info
+ */
+static int rows_output;
+
+static void
+output_source_filename (name, next)
+char *name;
+int next;
+{
+ static int column = 0;
+
+ if (column != 0 && column + strlen (name) >= 70)
+ {
+ printf ("\n");
+ column = 0;
+ if (++rows_output >= 21)
+ {
+ printf ("--Type Return to print more--");
+ fflush (stdout);
+ gdb_read_line (0, 0);
+ rows_output = 0;
+ }
+ }
+ else if (column != 0)
+ {
+ printf (" ");
+ column++;
+ }
+ printf ("%s", name);
+ column += strlen (name);
+ if (next)
+ {
+ printf (",");
+ column++;
+ }
+
+ if (!next) column = 0;
+}
+
static void
sources_info ()
{
register struct symtab *s;
+ register struct partial_symtab *ps;
register int column = 0;
- if (symtab_list == 0)
+ if (symtab_list == 0 && partial_symtab_list == 0)
{
printf ("No symbol table is loaded.\n");
return;
}
- printf ("Source files for which symbol table is known:\n");
+
+ printf ("Source files for which symbols have been read in:\n\n");
+ rows_output = 2;
for (s = symtab_list; s; s = s->next)
- {
- if (column != 0 && column + strlen (s->filename) >= 70)
- {
- printf ("\n");
- column = 0;
- }
- else if (column != 0)
- {
- printf (" ");
- column++;
- }
- printf ("%s", s->filename);
- column += strlen (s->filename);
- if (s->next)
- {
- printf (",");
- column++;
- }
- }
+ output_source_filename (s->filename, s->next);
+ printf ("\n\n");
+
+ printf ("Source files for which symbols will be read in on demand:\n\n");
+ rows_output += 2;
+ for (ps = partial_symtab_list; ps; ps = ps->next)
+ output_source_filename (ps->filename, ps->next);
printf ("\n");
}
@@ -1453,7 +1660,7 @@ sources_info ()
{ printf ("--Type Return to print more--"); \
print_count = 0; \
fflush (stdout); \
- read_line (); } }
+ gdb_read_line (0, 0); } }
static void sort_block_syms ();
@@ -1463,16 +1670,18 @@ list_symbols (regexp, class)
int class;
{
register struct symtab *s;
+ register struct partial_symtab *ps;
register struct blockvector *bv;
struct blockvector *prev_bv = 0;
register struct block *b;
register int i, j;
register struct symbol *sym;
+ struct partial_symbol *psym;
char *val;
- int found_in_file;
static char *classnames[]
= {"variable", "function", "type", "method"};
int print_count = 0;
+ int found_in_file = 0;
if (regexp)
if (val = (char *) re_comp (regexp))
@@ -1484,6 +1693,54 @@ list_symbols (regexp, class)
classnames[class],
regexp);
+ /* Search through the partial_symtab_list *first* for all symbols
+ matching the regexp. That way we don't have to reproduce all of
+ the machinery below. */
+ for (ps = partial_symtab_list; ps; ps = ps->next)
+ {
+ struct partial_symbol *bound, *gbound, *sbound;
+ int keep_going = 1;
+
+ gbound = global_psymbols + ps->globals_offset + ps->n_global_syms;
+ sbound = static_psymbols + ps->statics_offset + ps->n_static_syms;
+ bound = gbound;
+
+ /* Go through all of the symbols stored in a partial
+ symtab in one loop. */
+ psym = global_psymbols + ps->globals_offset;
+ while (keep_going)
+ {
+ if (psym >= bound)
+ {
+ if (bound == gbound && ps->n_static_syms != 0)
+ {
+ psym = static_psymbols + ps->statics_offset;
+ bound = sbound;
+ }
+ else
+ keep_going = 0;
+ }
+ else
+ {
+ QUIT;
+
+ /* If it would match (logic taken from loop below)
+ load the file and go on to the next one */
+ if ((regexp == 0 || re_exec (SYMBOL_NAME (psym)))
+ && ((class == 0 && SYMBOL_CLASS (psym) != LOC_TYPEDEF
+ && SYMBOL_CLASS (psym) != LOC_BLOCK)
+ || (class == 1 && SYMBOL_CLASS (psym) == LOC_BLOCK)
+ || (class == 2 && SYMBOL_CLASS (psym) == LOC_TYPEDEF)
+ || (class == 3 && SYMBOL_CLASS (psym) == LOC_BLOCK)))
+ {
+ psymtab_to_symtab(ps);
+ keep_going = 0;
+ }
+ }
+ psym++;
+ }
+ }
+
for (s = symtab_list; s; s = s->next)
{
found_in_file = 0;
@@ -1517,7 +1774,20 @@ list_symbols (regexp, class)
print_count += 2;
}
found_in_file = 1;
+#if 0
MORE;
+#else
+ {
+ print_count++;
+ if (print_count >= 21)
+ {
+ printf ("--Type Return to print more--");
+ print_count = 0;
+ fflush (stdout);
+ gdb_read_line (0, 0);
+ }
+ }
+#endif
if (class != 2 && i == 1)
printf ("static ");
if (class == 2
@@ -1633,8 +1903,20 @@ init_type (code, length, uns, name)
return type;
}
-static
-initialize ()
+/* Return Nonzero if block a is lexically nested within block b,
+ or if a and b have the same pc range.
+ Return zero otherwise. */
+int
+contained_in (a, b)
+ struct block *a, *b;
+{
+ if (!a || !b)
+ return 0;
+ return a->startaddr >= b->startaddr && a->endaddr <= b->endaddr;
+}
+
+void
+_initialize_symtab ()
{
add_info ("variables", variables_info,
"All global and static variable names, or those matching REGEXP.");
@@ -1651,6 +1933,7 @@ are listed.");
"Source files in the program.");
obstack_init (symbol_obstack);
+ obstack_init (psymbol_obstack);
builtin_type_void = init_type (TYPE_CODE_VOID, 0, 0, "void");
@@ -1666,6 +1949,11 @@ are listed.");
builtin_type_unsigned_short = init_type (TYPE_CODE_INT, sizeof (short), 1, "unsigned short");
builtin_type_unsigned_long = init_type (TYPE_CODE_INT, sizeof (long), 1, "unsigned long");
builtin_type_unsigned_int = init_type (TYPE_CODE_INT, sizeof (int), 1, "unsigned int");
+#ifdef LONG_LONG
+ builtin_type_long_long =
+ init_type (TYPE_CODE_INT, sizeof (long long), 0, "long long");
+ builtin_type_unsigned_long_long =
+ init_type (TYPE_CODE_INT, sizeof (long long), 1, "unsigned long long");
+#endif
}
-END_FILE