/* Support routines for decoding "stabs" debugging information format.
- Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993
+ Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995
Free Software Foundation, Inc.
This file is part of GDB.
Avoid placing any object file format specific code in this file. */
#include "defs.h"
+#include <string.h>
#include "bfd.h"
#include "obstack.h"
#include "symtab.h"
#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};
/* Check for and handle cretinous stabs symbol name continuation! */
#define STABS_CONTINUE(pp) \
do { \
- if (**(pp) == '\\') *(pp) = next_symbol_text (); \
+ 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;
}
}
/* Check for and handle cretinous dbx symbol name continuation! */
- if ((*pp)[-1] == '\\')
+ if ((*pp)[-1] == '\\' || (*pp)[-1] == '?')
{
*pp = next_symbol_text ();
}
case '9':
case '(':
- (*pp)--;
- if (read_type_number (pp, xtypenums) != 0)
- return error_type (pp);
-
- 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);
- else
- {
- struct type *xtype = *dbx_lookup_type (xtypenums);
-
- /* This can happen if we had '-' followed by a garbage character,
- for example. */
- if (xtype == NULL)
- return error_type (pp);
+ {
+ char *pp_saved;
- /* The type is being defined to another type. So we copy the type.
- This loses if we copy a C++ class and so we lose track of how
- the names are mangled (but g++ doesn't output stabs like this
- now anyway). */
+ (*pp)--;
+ pp_saved = *pp;
- type = alloc_type (objfile);
- memcpy (type, xtype, sizeof (struct type));
+ /* Peek ahead at the number to detect void. */
+ if (read_type_number (pp, xtypenums) != 0)
+ return error_type (pp);
- /* The idea behind clearing the names is that the only purpose
- for defining a type to another type is so that the name of
- one can be different. So we probably don't need to worry much
- about the case where the compiler doesn't give a name to the
- new type. */
- TYPE_NAME (type) = NULL;
- TYPE_TAG_NAME (type) = NULL;
- }
- if (typenums[0] != -1)
- *dbx_lookup_type (typenums) = type;
- break;
+ 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, 1, 0, NULL, objfile);
+ else
+ {
+ struct type *xtype;
+
+ /* Go back to the number and have read_type get it. This means
+ that we can deal with something like t(1,2)=(3,4)=... which
+ the Lucid compiler uses. */
+ *pp = pp_saved;
+ xtype = read_type (pp, objfile);
+
+ /* The type is being defined to another type. So we copy the type.
+ This loses if we copy a C++ class and so we lose track of how
+ the names are mangled (but g++ doesn't output stabs like this
+ now anyway). */
+
+ type = alloc_type (objfile);
+ memcpy (type, xtype, sizeof (struct type));
+
+ /* The idea behind clearing the names is that the only purpose
+ for defining a type to another type is so that the name of
+ one can be different. So we probably don't need to worry much
+ about the case where the compiler doesn't give a name to the
+ new type. */
+ TYPE_NAME (type) = NULL;
+ TYPE_TAG_NAME (type) = NULL;
+ }
+ if (typenums[0] != -1)
+ *dbx_lookup_type (typenums) = type;
+ break;
+ }
/* In the following types, we must be sure to overwrite any existing
type that the typenums refer to, rather than allocating a new one
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++;
/* Now fill in the fields of the type-structure. */
- TYPE_LENGTH (type) = sizeof (int);
+ TYPE_LENGTH (type) = TARGET_INT_BIT / HOST_CHAR_BIT;
TYPE_CODE (type) = TYPE_CODE_ENUM;
TYPE_FLAGS (type) &= ~TYPE_FLAG_STUB;
TYPE_NFIELDS (type) = nsyms;
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;
break;
}
-#if 0
- /* This screws up perfectly good C programs with enums. FIXME. */
- /* Is this Modula-2's BOOLEAN type? Flag it as such if so. */
- if(TYPE_NFIELDS(type) == 2 &&
- ((STREQ(TYPE_FIELD_NAME(type,0),"TRUE") &&
- STREQ(TYPE_FIELD_NAME(type,1),"FALSE")) ||
- (STREQ(TYPE_FIELD_NAME(type,1),"TRUE") &&
- STREQ(TYPE_FIELD_NAME(type,0),"FALSE"))))
- TYPE_CODE(type) = TYPE_CODE_BOOL;
-#endif
-
return type;
}
type_bits = read_huge_number (pp, 0, &nbits);
if (nbits != 0)
return error_type (pp);
+ /* The type *should* end with a semicolon. If it are embedded
+ in a larger type the semicolon may be the only way to know where
+ the type ends. If this type is at the end of the stabstring we
+ can deal with the omitted semicolon (but we don't have to like
+ it). Don't bother to complain(), Sun's compiler omits the semicolon
+ for "void". */
+ 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() */