/* Support routines for decoding "stabs" debugging information format.
- Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994
+ Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995
Free Software Foundation, Inc.
This file is part of GDB.
#include "symfile.h"
#include "objfiles.h"
#include "aout/stab_gnu.h" /* We always use GNU stabs, not native */
+#include "libaout.h"
+#include "aout/aout64.h"
+#include "gdb-stabs.h"
#include "buildsym.h"
#include "complaints.h"
#include "demangle.h"
struct complaint rs6000_builtin_complaint =
{"Unknown builtin type %d", 0, 0};
+struct complaint unresolved_sym_chain_complaint =
+ {"%s: `%s' from global_sym_chain unresolved", 0, 0};
+
struct complaint stabs_general_complaint =
{"%s", 0, 0};
if (**(pp) == '\\' || (**(pp) == '?' && (*(pp))[1] == '\0')) \
*(pp) = next_symbol_text (); \
} while (0)
-
\f
+/* FIXME: These probably should be our own types (like rs6000_builtin_type
+ has its own types) rather than builtin_type_*. */
+static struct type **os9k_type_vector[] = {
+ 0,
+ &builtin_type_int,
+ &builtin_type_char,
+ &builtin_type_long,
+ &builtin_type_short,
+ &builtin_type_unsigned_char,
+ &builtin_type_unsigned_short,
+ &builtin_type_unsigned_long,
+ &builtin_type_unsigned_int,
+ &builtin_type_float,
+ &builtin_type_double,
+ &builtin_type_void,
+ &builtin_type_long_double
+};
+
+static void os9k_init_type_vector PARAMS ((struct type **));
+
+static void
+os9k_init_type_vector(tv)
+ struct type **tv;
+{
+ int i;
+ for (i=0; i<sizeof(os9k_type_vector)/sizeof(struct type **); i++)
+ tv[i] = (os9k_type_vector[i] == 0 ? 0 : *(os9k_type_vector[i]));
+}
+
/* Look up a dbx type-number pair. Return the address of the slot
where the type for that number-pair is stored.
The number-pair is in TYPENUMS.
(type_vector_length * sizeof (struct type *)));
memset (&type_vector[old_len], 0,
(type_vector_length - old_len) * sizeof (struct type *));
+
+ if (os9k_stabs)
+ /* Deal with OS9000 fundamental types. */
+ os9k_init_type_vector (type_vector);
}
return (&type_vector[index]);
}
sym = find_symbol_in_list (symbols, name, pp-name);
if (!sym)
{
+ /* FIXME-maybe: it would be nice if we noticed whether
+ the variable was defined *anywhere*, not just whether
+ it is defined in this compilation unit. But neither
+ xlc or GCC seem to need such a definition, and until
+ we do psymtabs (so that the minimal symbols from all
+ compilation units are available now), I'm not sure
+ how to get the information. */
+
/* On xcoff, if a global is defined and never referenced,
ld will remove it from the executable. There is then
a N_GSYM stab for it, but no regular (C_EXT) symbol. */
static char *type_synonym_name;
#if !defined (REG_STRUCT_HAS_ADDR)
-#define REG_STRUCT_HAS_ADDR(gcc_p) 0
+#define REG_STRUCT_HAS_ADDR(gcc_p,type) 0
#endif
/* ARGSUSED */
obstack_alloc (&objfile -> symbol_obstack, sizeof (struct symbol));
memset (sym, 0, sizeof (struct symbol));
+ switch (type & N_TYPE)
+ {
+ case N_TEXT:
+ SYMBOL_SECTION(sym) = SECT_OFF_TEXT;
+ break;
+ case N_DATA:
+ SYMBOL_SECTION(sym) = SECT_OFF_DATA;
+ break;
+ case N_BSS:
+ SYMBOL_SECTION(sym) = SECT_OFF_BSS;
+ break;
+ }
+
if (processing_gcc_compilation)
{
/* GCC 2.x puts the line number in desc. SunOS apparently puts in the
/* This was an anonymous type that was never fixed up. */
goto normal;
+#ifdef STATIC_TRANSFORM_NAME
+ case 'X':
+ /* SunPRO (3.0 at least) static variable encoding. */
+ goto normal;
+#endif
+
default:
complain (&unrecognized_cplus_name_complaint, string);
goto normal; /* Do *something* with it */
We need to convert this to the function-returning-type-X type
in GDB. E.g. "int" is converted to "function returning int". */
if (TYPE_CODE (SYMBOL_TYPE (sym)) != TYPE_CODE_FUNC)
- {
-#if 0
- /* This code doesn't work -- it needs to realloc and can't. */
- /* Attempt to set up to record a function prototype... */
- struct type *new = alloc_type (objfile);
-
- /* Generate a template for the type of this function. The
- types of the arguments will be added as we read the symbol
- table. */
- *new = *lookup_function_type (SYMBOL_TYPE(sym));
- SYMBOL_TYPE(sym) = new;
- TYPE_OBJFILE (new) = objfile;
- in_function_type = new;
-#else
- SYMBOL_TYPE (sym) = lookup_function_type (SYMBOL_TYPE (sym));
-#endif
- }
+ SYMBOL_TYPE (sym) = lookup_function_type (SYMBOL_TYPE (sym));
/* fall into process_prototype_types */
process_prototype_types:
/* This case is faked by a conditional above,
when there is no code letter in the dbx data.
Dbx data never actually contains 'l'. */
+ case 's':
case 'l':
SYMBOL_TYPE (sym) = read_type (&p, objfile);
SYMBOL_CLASS (sym) = LOC_LOCAL;
SYMBOL_CLASS (sym) = DBX_PARM_SYMBOL_CLASS (type);
SYMBOL_VALUE (sym) = valu;
SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
-#if 0
- /* This doesn't work yet. */
- add_param_to_type (&in_function_type, sym);
-#endif
add_symbol_to_list (sym, &local_symbols);
-#if TARGET_BYTE_ORDER == LITTLE_ENDIAN
- /* On little-endian machines, this crud is never necessary, and,
- if the extra bytes contain garbage, is harmful. */
- break;
-#else /* Big endian. */
+ if (TARGET_BYTE_ORDER != BIG_ENDIAN)
+ {
+ /* On little-endian machines, this crud is never necessary,
+ and, if the extra bytes contain garbage, is harmful. */
+ break;
+ }
+
/* If it's gcc-compiled, if it says `short', believe it. */
if (processing_gcc_compilation || BELIEVE_PCC_PROMOTION)
break;
#endif /* no BELIEVE_PCC_PROMOTION_TYPE. */
}
#endif /* !BELIEVE_PCC_PROMOTION. */
-#endif /* Big endian. */
case 'P':
/* acc seems to use P to delare the prototypes of functions that
/* Sun cc uses a pair of symbols, one 'p' and one 'r' with the same
name to represent an argument passed in a register.
GCC uses 'P' for the same case. So if we find such a symbol pair
- we combine it into one 'P' symbol.
+ we combine it into one 'P' symbol. For Sun cc we need to do this
+ regardless of REG_STRUCT_HAS_ADDR, because the compiler puts out
+ the 'p' symbol even if it never saves the argument onto the stack.
- But we only do this in the REG_STRUCT_HAS_ADDR case, so that
+ On most machines, we want to preserve both symbols, so that
we can still get information about what is going on with the
stack (VAX for computing args_printed, using stack slots instead
of saved registers in backtraces, etc.).
if (local_symbols
&& local_symbols->nsyms > 0
- && REG_STRUCT_HAS_ADDR (processing_gcc_compilation)
+#ifndef USE_REGISTER_NOT_ARG
+ && REG_STRUCT_HAS_ADDR (processing_gcc_compilation,
+ SYMBOL_TYPE (sym))
&& (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_STRUCT
- || TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_UNION))
+ || TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_UNION)
+#endif
+ )
{
struct symbol *prev_sym;
prev_sym = local_symbols->symbol[local_symbols->nsyms - 1];
- if (SYMBOL_CLASS (prev_sym) == LOC_ARG
+ if ((SYMBOL_CLASS (prev_sym) == LOC_REF_ARG
+ || SYMBOL_CLASS (prev_sym) == LOC_ARG)
&& STREQ (SYMBOL_NAME (prev_sym), SYMBOL_NAME(sym)))
{
SYMBOL_CLASS (prev_sym) = LOC_REGPARM;
SYMBOL_TYPE (sym) = read_type (&p, objfile);
SYMBOL_CLASS (sym) = LOC_STATIC;
SYMBOL_VALUE_ADDRESS (sym) = valu;
+#ifdef STATIC_TRANSFORM_NAME
+ if (SYMBOL_NAME (sym)[0] == '$')
+ {
+ struct minimal_symbol *msym;
+ msym = lookup_minimal_symbol (SYMBOL_NAME (sym), NULL, objfile);
+ if (msym != NULL)
+ {
+ SYMBOL_NAME (sym) = STATIC_TRANSFORM_NAME (SYMBOL_NAME (sym));
+ SYMBOL_VALUE_ADDRESS (sym) = SYMBOL_VALUE_ADDRESS (msym);
+ }
+ }
+#endif
SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
add_symbol_to_list (sym, &file_symbols);
break;
if (TYPE_NAME (SYMBOL_TYPE (sym)) == NULL)
{
- if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_PTR
+ /* gcc-2.6 or later (when using -fvtable-thunks)
+ emits a unique named type for a vtable entry.
+ Some gdb code depends on that specific name. */
+ extern const char vtbl_ptr_name[];
+
+ if ((TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_PTR
+ && strcmp (SYMBOL_NAME (sym), vtbl_ptr_name))
|| TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_FUNC)
{
/* If we are giving a name to a type such as "pointer to
SYMBOL_TYPE (sym) = read_type (&p, objfile);
SYMBOL_CLASS (sym) = LOC_STATIC;
SYMBOL_VALUE_ADDRESS (sym) = valu;
+#ifdef STATIC_TRANSFORM_NAME
+ if (SYMBOL_NAME (sym)[0] == '$')
+ {
+ struct minimal_symbol *msym;
+ msym = lookup_minimal_symbol (SYMBOL_NAME (sym), NULL, objfile);
+ if (msym != NULL)
+ {
+ SYMBOL_NAME (sym) = STATIC_TRANSFORM_NAME (SYMBOL_NAME (sym));
+ SYMBOL_VALUE_ADDRESS (sym) = SYMBOL_VALUE_ADDRESS (msym);
+ }
+ }
+#endif
SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
- add_symbol_to_list (sym, &local_symbols);
+ if (os9k_stabs)
+ add_symbol_to_list (sym, &global_symbols);
+ else
+ add_symbol_to_list (sym, &local_symbols);
break;
case 'v':
add_symbol_to_list (sym, &local_symbols);
break;
+ case 'a':
+ /* Reference parameter which is in a register. */
+ SYMBOL_TYPE (sym) = read_type (&p, objfile);
+ SYMBOL_CLASS (sym) = LOC_REGPARM_ADDR;
+ SYMBOL_VALUE (sym) = STAB_REG_TO_REGNUM (valu);
+ if (SYMBOL_VALUE (sym) >= NUM_REGS)
+ {
+ complain (®_value_complaint, SYMBOL_SOURCE_NAME (sym));
+ SYMBOL_VALUE (sym) = SP_REGNUM; /* Known safe, though useless */
+ }
+ SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+ add_symbol_to_list (sym, &local_symbols);
+ break;
+
case 'X':
/* This is used by Sun FORTRAN for "function result value".
Sun claims ("dbx and dbxtool interfaces", 2nd ed)
to LOC_REGPARM_ADDR for structures and unions. */
if (SYMBOL_CLASS (sym) == LOC_REGPARM
- && REG_STRUCT_HAS_ADDR (processing_gcc_compilation)
+ && REG_STRUCT_HAS_ADDR (processing_gcc_compilation,
+ SYMBOL_TYPE (sym))
&& ((TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_STRUCT)
|| (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_UNION)))
SYMBOL_CLASS (sym) = LOC_REGPARM_ADDR;
+ /* Likewise for converting LOC_ARG to LOC_REF_ARG (for the 7th and
+ subsequent arguments on the sparc, for example). */
+ if (SYMBOL_CLASS (sym) == LOC_ARG
+ && REG_STRUCT_HAS_ADDR (processing_gcc_compilation,
+ SYMBOL_TYPE (sym))
+ && ((TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_STRUCT)
+ || (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_UNION)))
+ SYMBOL_CLASS (sym) = LOC_REF_ARG;
+
return sym;
}
if (typenums[0] == xtypenums[0] && typenums[1] == xtypenums[1])
/* It's being defined as itself. That means it is "void". */
- type = init_type (TYPE_CODE_VOID, 0, 0, NULL, objfile);
+ type = init_type (TYPE_CODE_VOID, 1, 0, NULL, objfile);
else
{
struct type *xtype;
break;
case 'f': /* Function returning another type */
+ if (os9k_stabs && **pp == '(')
+ {
+ /* Function prototype; parse it.
+ We must conditionalize this on os9k_stabs because otherwise
+ it could be confused with a Sun-style (1,3) typenumber
+ (I think). */
+ struct type *t;
+ ++*pp;
+ while (**pp != ')')
+ {
+ t = read_type(pp, objfile);
+ if (**pp == ',') ++*pp;
+ }
+ }
type1 = read_type (pp, objfile);
type = make_function_type (type1, dbx_lookup_type (typenums));
break;
- case 'k': /* Const qualifier on some type (Sun) */
+ case 'k': /* Const qualifier on some type (Sun) */
+ case 'c': /* Const qualifier on some type (OS9000) */
+ /* Because 'c' means other things to AIX and 'k' is perfectly good,
+ only accept 'c' in the os9k_stabs case. */
+ if (type_descriptor == 'c' && !os9k_stabs)
+ return error_type (pp);
type = read_type (pp, objfile);
/* FIXME! For now, we ignore const and volatile qualifiers. */
break;
- case 'B': /* Volatile qual on some type (Sun) */
+ case 'B': /* Volatile qual on some type (Sun) */
+ case 'i': /* Volatile qual on some type (OS9000) */
+ /* Because 'i' means other things to AIX and 'B' is perfectly good,
+ only accept 'i' in the os9k_stabs case. */
+ if (type_descriptor == 'i' && !os9k_stabs)
+ return error_type (pp);
type = read_type (pp, objfile);
/* FIXME! For now, we ignore const and volatile qualifiers. */
break;
*dbx_lookup_type (typenums) = type;
break;
- case 'b': /* Sun ACC builtin int type */
- type = read_sun_builtin_type (pp, typenums, objfile);
- if (typenums[0] != -1)
- *dbx_lookup_type (typenums) = type;
+ case 'b':
+ if (os9k_stabs)
+ /* Const and volatile qualified type. */
+ type = read_type (pp, objfile);
+ else
+ {
+ /* Sun ACC builtin int type */
+ type = read_sun_builtin_type (pp, typenums, objfile);
+ if (typenums[0] != -1)
+ *dbx_lookup_type (typenums) = type;
+ }
break;
case 'R': /* Sun ACC builtin float type */
/* Size specified in a type attribute overrides any other size. */
if (type_size != -1)
- TYPE_LENGTH (type) = type_size / TARGET_CHAR_BIT;
+ TYPE_LENGTH (type) = (type_size + TARGET_CHAR_BIT - 1) / TARGET_CHAR_BIT;
return type;
}
int typenum;
{
/* We recognize types numbered from -NUMBER_RECOGNIZED to -1. */
-#define NUMBER_RECOGNIZED 30
+#define NUMBER_RECOGNIZED 34
/* This includes an empty slot for type number -0. */
static struct type *negative_types[NUMBER_RECOGNIZED + 1];
struct type *rettype = NULL;
"unsigned long", NULL);
break;
case 11:
- rettype = init_type (TYPE_CODE_VOID, 0, 0, "void", NULL);
+ rettype = init_type (TYPE_CODE_VOID, 1, 0, "void", NULL);
break;
case 12:
/* IEEE single precision (32 bit). */
case 30:
rettype = init_type (TYPE_CODE_CHAR, 2, 0, "wchar", NULL);
break;
+ case 31:
+ rettype = init_type (TYPE_CODE_INT, 8, 0, "long long", NULL);
+ break;
+ case 32:
+ rettype = init_type (TYPE_CODE_INT, 8, TYPE_FLAG_UNSIGNED,
+ "unsigned long long", NULL);
+ break;
+ case 33:
+ rettype = init_type (TYPE_CODE_INT, 8, TYPE_FLAG_UNSIGNED,
+ "logical*8", NULL);
+ break;
+ case 34:
+ rettype = init_type (TYPE_CODE_INT, 8, 0, "integer*8", NULL);
+ break;
}
negative_types[-typenum] = rettype;
return rettype;
while (**pp != ';')
{
+ if (os9k_stabs && **pp == ',') break;
STABS_CONTINUE (pp);
/* Get space to record the next field's data. */
new = (struct nextfield *) xmalloc (sizeof (struct nextfield));
{
register int n;
- for (n = 0; n < TYPE_N_BASECLASSES (type); n++)
- {
- if (TYPE_CODE (TYPE_BASECLASS (type, n)) == TYPE_CODE_UNDEF)
- {
- /* @@ Memory leak on objfile -> type_obstack? */
- return 0;
- }
- TYPE_NFN_FIELDS_TOTAL (type) +=
- TYPE_NFN_FIELDS_TOTAL (TYPE_BASECLASS (type, n));
- }
-
for (n = TYPE_NFN_FIELDS (type);
fip -> fnlist != NULL;
fip -> fnlist = fip -> fnlist -> next)
int nbits;
/* Format of an array type:
- "ar<index type>;lower;upper;<array_contents_type>". Put code in
- to handle this.
+ "ar<index type>;lower;upper;<array_contents_type>".
+ OS9000: "arlower,upper;<array_contents_type>".
Fortran adjustable arrays use Adigits or Tdigits for lower or upper;
for these, produce a type like float[][]. */
- index_type = read_type (pp, objfile);
- if (**pp != ';')
- /* Improper format of array type decl. */
- return error_type (pp);
- ++*pp;
+ if (os9k_stabs)
+ index_type = builtin_type_int;
+ else
+ {
+ index_type = read_type (pp, objfile);
+ if (**pp != ';')
+ /* Improper format of array type decl. */
+ return error_type (pp);
+ ++*pp;
+ }
if (!(**pp >= '0' && **pp <= '9') && **pp != '-')
{
(*pp)++;
adjustable = 1;
}
- lower = read_huge_number (pp, ';', &nbits);
+ lower = read_huge_number (pp, os9k_stabs ? ',' : ';', &nbits);
if (nbits != 0)
return error_type (pp);
/* If we have an array whose element type is not yet known, but whose
bounds *are* known, record it to be adjusted at the end of the file. */
- /* FIXME: Why check for zero length rather than TYPE_FLAG_STUB? I think
- the two have the same effect except that the latter is cleaner and the
- former would be wrong for types which really are zero-length (if we
- have any). */
- if (TYPE_LENGTH (element_type) == 0 && !adjustable)
+ if ((TYPE_FLAGS (element_type) & TYPE_FLAG_STUB) && !adjustable)
{
TYPE_FLAGS (type) |= TYPE_FLAG_TARGET_STUB;
add_undefined_type (type);
struct pending **symlist;
struct pending *osyms, *syms;
int o_nsyms;
+ int nbits;
#if 0
/* FIXME! The stabs produced by Sun CC merrily define things that ought
osyms = *symlist;
o_nsyms = osyms ? osyms->nsyms : 0;
+ if (os9k_stabs)
+ {
+ /* Size. Perhaps this does not have to be conditionalized on
+ os9k_stabs (assuming the name of an enum constant can't start
+ with a digit). */
+ read_huge_number (pp, 0, &nbits);
+ if (nbits != 0)
+ return error_type (pp);
+ }
+
/* Read the value-names and their values.
The input syntax is NAME:VALUE,NAME:VALUE, and so on.
A semicolon or comma instead of a NAME means the end. */
while (**pp && **pp != ';' && **pp != ',')
{
- int nbits;
STABS_CONTINUE (pp);
p = *pp;
while (*p != ':') p++;
that in something like "enum {FOO, LAST_THING=FOO}" we print
FOO, not LAST_THING. */
- for (syms = *symlist, n = 0; syms; syms = syms->next)
+ for (syms = *symlist, n = nsyms - 1; ; syms = syms->next)
{
- int j = 0;
- if (syms == osyms)
- j = o_nsyms;
- for (; j < syms->nsyms; j++,n++)
+ int last = syms == osyms ? o_nsyms : 0;
+ int j = syms->nsyms;
+ for (; --j >= last; --n)
{
struct symbol *xsym = syms->symbol[j];
SYMBOL_TYPE (xsym) = type;
if (**pp == ';')
++(*pp);
- return init_type (type_bits == 0 ? TYPE_CODE_VOID : TYPE_CODE_INT,
- type_bits / TARGET_CHAR_BIT,
- signed_type ? 0 : TYPE_FLAG_UNSIGNED, (char *)NULL,
- objfile);
+ if (type_bits == 0)
+ return init_type (TYPE_CODE_VOID, 1,
+ signed_type ? 0 : TYPE_FLAG_UNSIGNED, (char *)NULL,
+ objfile);
+ else
+ return init_type (TYPE_CODE_INT,
+ type_bits / TARGET_CHAR_BIT,
+ signed_type ? 0 : TYPE_FLAG_UNSIGNED, (char *)NULL,
+ objfile);
}
static struct type *
p++;
}
- upper_limit = LONG_MAX / radix;
+ if (os9k_stabs)
+ upper_limit = ULONG_MAX / radix;
+ else
+ upper_limit = LONG_MAX / radix;
+
while ((c = *p++) >= '0' && c < ('0' + radix))
{
if (n <= upper_limit)
int typenums[2];
struct objfile *objfile;
{
+ char *orig_pp = *pp;
int rangenums[2];
long n2, n3;
int n2bits, n3bits;
int self_subrange;
struct type *result_type;
- struct type *index_type;
+ struct type *index_type = NULL;
/* First comes a type we are a subrange of.
In C it is usually 0, 1 or the type being defined. */
- /* FIXME: according to stabs.texinfo and AIX doc, this can be a type-id
- not just a type number. */
if (read_type_number (pp, rangenums) != 0)
return error_type (pp);
self_subrange = (rangenums[0] == typenums[0] &&
rangenums[1] == typenums[1]);
+ if (**pp == '=')
+ {
+ *pp = orig_pp;
+ index_type = read_type (pp, objfile);
+ }
+
/* A semicolon should now follow; skip it. */
if (**pp == ';')
(*pp)++;
if (n2bits == -1 || n3bits == -1)
return error_type (pp);
-
+
+ if (index_type)
+ goto handle_true_range;
+
/* If limits are huge, must be large integral type. */
if (n2bits != 0 || n3bits != 0)
{
/* A type defined as a subrange of itself, with bounds both 0, is void. */
if (self_subrange && n2 == 0 && n3 == 0)
- return init_type (TYPE_CODE_VOID, 0, 0, NULL, objfile);
+ return init_type (TYPE_CODE_VOID, 1, 0, NULL, objfile);
/* If n3 is zero and n2 is not, we want a floating type,
and n2 is the width in bytes.
/* We have a real range type on our hands. Allocate space and
return a real pointer. */
+ handle_true_range:
/* At this point I don't have the faintest idea how to deal with
a self_subrange type; I'm going to assume that this is used
for (j = common_block_i; j < common_block->nsyms; j++)
add_symbol_to_list (common_block->symbol[j], &new);
- SYMBOL_NAMESPACE (sym) = (enum namespace)((long) new);
+ SYMBOL_TYPE (sym) = (struct type *) new;
/* Should we be putting local_symbols back to what it was?
Does it matter? */
struct symbol *sym;
int valu;
{
- struct pending *next = (struct pending *) SYMBOL_NAMESPACE (sym);
+ struct pending *next = (struct pending *) SYMBOL_TYPE (sym);
for ( ; next; next = next->next)
{
register int j;
/* Scan through all of the global symbols defined in the object file,
assigning values to the debugging symbols that need to be assigned
- to. Get these symbols from the minimal symbol table. */
+ to. Get these symbols from the minimal symbol table.
+ Return 1 if there might still be unresolved debugging symbols, else 0. */
-void
-scan_file_globals (objfile)
+static int scan_file_globals_1 PARAMS ((struct objfile *));
+
+static int
+scan_file_globals_1 (objfile)
struct objfile *objfile;
{
int hash;
struct minimal_symbol *msymbol;
struct symbol *sym, *prev;
+ /* Avoid expensive loop through all minimal symbols if there are
+ no unresolved symbols. */
+ for (hash = 0; hash < HASHSIZE; hash++)
+ {
+ if (global_sym_chain[hash])
+ break;
+ }
+ if (hash >= HASHSIZE)
+ return 0;
+
if (objfile->msymbols == 0) /* Beware the null file. */
- return;
+ return 1;
for (msymbol = objfile -> msymbols; SYMBOL_NAME (msymbol) != NULL; msymbol++)
{
QUIT;
+ /* Skip static symbols. */
+ switch (MSYMBOL_TYPE (msymbol))
+ {
+ case mst_file_text:
+ case mst_file_data:
+ case mst_file_bss:
+ continue;
+ default:
+ break;
+ }
+
prev = NULL;
/* Get the hash index and check all the symbols
{
SYMBOL_VALUE_ADDRESS (sym) = SYMBOL_VALUE_ADDRESS (msymbol);
}
+
+ SYMBOL_SECTION (sym) = SYMBOL_SECTION (msymbol);
if (prev)
{
}
}
}
+ return 1;
+}
+
+/* Assign values to global debugging symbols.
+ Search the passed objfile first, then try the runtime common symbols.
+ Complain about any remaining unresolved symbols and remove them
+ from the chain. */
+
+void
+scan_file_globals (objfile)
+ struct objfile *objfile;
+{
+ int hash;
+ struct symbol *sym, *prev;
+
+ if (scan_file_globals_1 (objfile) == 0)
+ return;
+ if (rt_common_objfile && scan_file_globals_1 (rt_common_objfile) == 0)
+ return;
+
+ for (hash = 0; hash < HASHSIZE; hash++)
+ {
+ sym = global_sym_chain[hash];
+ while (sym)
+ {
+ complain (&unresolved_sym_chain_complaint,
+ objfile->name, SYMBOL_NAME (sym));
+
+ /* Change the symbol address from the misleading chain value
+ to address zero. */
+ prev = sym;
+ sym = SYMBOL_VALUE_CHAIN (sym);
+ SYMBOL_VALUE_ADDRESS (prev) = 0;
+ }
+ }
+ memset (global_sym_chain, 0, sizeof (global_sym_chain));
}
/* Initialize anything that needs initializing when starting to read
/* FIXME: If common_block_name is not already NULL, we should complain(). */
common_block_name = NULL;
+
+ os9k_stabs = 0;
}
/* Call after end_symtab() */