aboutsummaryrefslogtreecommitdiff
path: root/gdb/dbxread.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/dbxread.c')
-rw-r--r--gdb/dbxread.c230
1 files changed, 193 insertions, 37 deletions
diff --git a/gdb/dbxread.c b/gdb/dbxread.c
index cbb4e0c..9c9f2bf 100644
--- a/gdb/dbxread.c
+++ b/gdb/dbxread.c
@@ -1936,6 +1936,8 @@ read_dbx_symtab (desc, stringtab, stringtab_size, nlistlen, inclink,
profile_types[i] = 0;
#endif
+ stringtab_global = stringtab;
+
pst = (struct partial_symtab *) 0;
includes_allocated = 30;
@@ -2270,9 +2272,7 @@ read_dbx_symtab (desc, stringtab, stringtab_size, nlistlen, inclink,
p = (char *) index (namestring, ':');
- /* Skip if there is no : or if the thing following the : is
- not a letter (which indicates declaration of a local
- variable, which we aren't interested in). */
+ /* Skip if there is no :. */
if (!p) continue;
switch (p[1])
@@ -2281,11 +2281,75 @@ read_dbx_symtab (desc, stringtab, stringtab_size, nlistlen, inclink,
ADD_PSYMBOL_TO_LIST (namestring, p - namestring,
STRUCT_NAMESPACE, LOC_TYPEDEF,
static_psymbols, bufp->n_value);
- continue;
+ goto check_enum;
case 't':
ADD_PSYMBOL_TO_LIST (namestring, p - namestring,
VAR_NAMESPACE, LOC_TYPEDEF,
static_psymbols, bufp->n_value);
+ check_enum:
+ /* If this is an enumerated type, we need to
+ add all the enum constants to the partial symbol
+ table. This does not cover enums without names, e.g.
+ "enum {a, b} c;" in C, but fortunately those are
+ rare. There is no way for GDB to find those from the
+ enum type without spending too much time on it. Thus
+ to solve this problem, the compiler needs to put out separate
+ constant symbols ('c' N_LSYMS) for enum constants in
+ enums without names. */
+
+ /* We are looking for something of the form
+ <name> ":" ("t" | "T") [<number> "="] "e"
+ {<constant> ":" <value> ","} ";". */
+
+ /* Skip over the colon and the 't' or 'T'. */
+ p += 2;
+ /* This type may be given a number. Skip over it. */
+ while ((*p >= '0' && *p <= '9')
+ || *p == '=')
+ p++;
+
+ if (*p++ == 'e')
+ {
+ /* We have found an enumerated type. */
+ /* According to comments in read_enum_type
+ a comma could end it instead of a semicolon.
+ I don't know where that happens.
+ Accept either. */
+ while (*p && *p != ';' && *p != ',')
+ {
+ char *q;
+
+ /* Check for and handle cretinous dbx symbol name
+ continuation! */
+ if (*p == '\\')
+ p = next_symbol_text ();
+
+ /* Point to the character after the name
+ of the enum constant. */
+ for (q = p; *q && *q != ':'; q++)
+ ;
+ /* Note that the value doesn't matter for
+ enum constants in psymtabs, just in symtabs. */
+ ADD_PSYMBOL_TO_LIST (p, q - p,
+ VAR_NAMESPACE, LOC_CONST,
+ static_psymbols, 0);
+ /* Point past the name. */
+ p = q;
+ /* Skip over the value. */
+ while (*p && *p != ',')
+ p++;
+ /* Advance past the comma. */
+ if (*p)
+ p++;
+ }
+ }
+
+ continue;
+ case 'c':
+ /* Constant, e.g. from "const" in Pascal. */
+ ADD_PSYMBOL_TO_LIST (namestring, p - namestring,
+ VAR_NAMESPACE, LOC_CONST,
+ static_psymbols, bufp->n_value);
continue;
default:
#ifdef PROFILE_TYPES
@@ -2293,10 +2357,18 @@ read_dbx_symtab (desc, stringtab, stringtab_size, nlistlen, inclink,
printf ("Funny...LSYM with a letter that isn't a type\n");
autovars++;
#endif
+ /* Skip if the thing following the : is
+ not a letter (which indicates declaration of a local
+ variable, which we aren't interested in). */
continue;
}
case N_FUN:
+#if 0
+ /* This special-casing of N_FUN is just wrong; N_FUN
+ does not mean "function"; it means "text segment".
+ So N_FUN can go with 'V', etc. as well as 'f' or 'F'. */
+
SET_NAMESTRING();
p = (char *) index (namestring, ':');
@@ -2314,7 +2386,7 @@ read_dbx_symtab (desc, stringtab, stringtab_size, nlistlen, inclink,
static_psymbols, bufp->n_value);
continue;
-
+#endif /* 0 */
case N_GSYM: /* Global (extern) variable; can be
data or bss (sigh). */
case N_STSYM: /* Data seg var -- static */
@@ -2369,17 +2441,36 @@ read_dbx_symtab (desc, stringtab, stringtab_size, nlistlen, inclink,
global_psymbols, bufp->n_value);
continue;
- /* I don't think the default case should happen. A breakpoint
- here to check would probably be good. */
- default:
+ case 'f':
+ ADD_PSYMBOL_TO_LIST (namestring, p - namestring,
+ VAR_NAMESPACE, LOC_BLOCK,
+ static_psymbols, bufp->n_value);
+ continue;
+
/* Two things show up here (hopefully); static symbols of
local scope (static used inside braces) or extensions
of structure symbols. We can ignore both. */
- if (p[1] != 'V' && p[1] != '('
- && (p[1] < '0' || p[1] > '9'))
- fatal ("Internal error: Unexpected debugging symbol type '%c' at symnum %d.\n",
- p[1], symnum);
+ case 'V':
+ case '(':
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ /* Global functions are ignored here. I'm not
+ sure what psymtab they go into (or just the misc
+ function vector). */
+ case 'F':
continue;
+
+ default:
+ fatal ("Internal error: Unexpected debugging symbol type '%c' at symnum %d.\n",
+ p[1], symnum);
}
#ifdef N_BINCL
@@ -3657,6 +3748,32 @@ add_file_command (arg_string)
fflush (stdout);
}
+/* Read a number by which a type is referred to in dbx data,
+ or perhaps read a pair (FILENUM, TYPENUM) in parentheses.
+ Just a single number N is equivalent to (0,N).
+ Return the two numbers by storing them in the vector TYPENUMS.
+ TYPENUMS will then be used as an argument to dbx_lookup_type. */
+
+static void
+read_type_number (pp, typenums)
+ register char **pp;
+ register int *typenums;
+{
+ if (**pp == '(')
+ {
+ (*pp)++;
+ typenums[0] = read_number (pp, ',');
+ typenums[1] = read_number (pp, ')');
+ }
+ else
+ {
+ typenums[0] = 0;
+ typenums[1] = read_number (pp, 0);
+ }
+}
+
+
+
static struct symbol *
define_symbol (value, string, desc)
int value;
@@ -3696,7 +3813,10 @@ define_symbol (value, string, desc)
/* c is a special case, not followed by a type-number.
SYMBOL:c=iVALUE for an integer constant symbol.
- SYMBOL:c=rVALUE for a floating constant symbol. */
+ SYMBOL:c=rVALUE for a floating constant symbol.
+ SYMBOL:c=eTYPE,INTVALUE for an enum constant symbol.
+ e.g. "b:c=e6,0" for "const b = blob1"
+ (where type 6 is defined by "blobs:t6=eblob1:0,blob2:1,;"). */
if (deftype == 'c')
{
if (*p++ != '=')
@@ -3722,6 +3842,22 @@ define_symbol (value, string, desc)
SYMBOL_CLASS (sym) = LOC_CONST;
}
break;
+ case 'e':
+ /* SYMBOL:c=eTYPE,INTVALUE for an enum constant symbol.
+ e.g. "b:c=e6,0" for "const b = blob1"
+ (where type 6 is defined by "blobs:t6=eblob1:0,blob2:1,;"). */
+ {
+ int typenums[2];
+
+ read_type_number (&p, typenums);
+ if (*p++ != ',')
+ error ("Invalid symbol data: no comma in enum const symbol");
+
+ SYMBOL_TYPE (sym) = *dbx_lookup_type (typenums);
+ SYMBOL_VALUE (sym) = atoi (p);
+ SYMBOL_CLASS (sym) = LOC_CONST;
+ }
+ break;
default:
error ("Invalid symbol data at symtab pos %d.", symnum);
}
@@ -3796,9 +3932,40 @@ define_symbol (value, string, desc)
SYMBOL_VALUE (sym) = value;
SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
add_symbol_to_list (sym, &local_symbols);
+
/* If it's compiled, if it says `short', believe it. */
if (processing_gcc_compilation || BELIEVE_PCC_PROMOTION)
break;
+
+#if defined(BELIEVE_PCC_PROMOTION_TYPE)
+ /* This macro is defined on machines (e.g. sparc) where
+ we should believe the type of a PCC 'short' argument,
+ but shouldn't believe the address (the address is
+ the address of the corresponding int). Note that
+ this is only different from the BELIEVE_PCC_PROMOTION
+ case on big-endian machines.
+
+ My guess is that this correction, as opposed to changing
+ the parameter to an 'int' (as done below, for PCC
+ on most machines), is the right thing to do
+ on all machines, but I don't want to risk breaking
+ something that already works. On most PCC machines,
+ the sparc problem doesn't come up because the calling
+ function has to zero the top bytes (not knowing whether
+ the called function wants an int or a short), so there
+ is no practical difference between an int and a short
+ (except perhaps what happens when the GDB user types
+ "print short_arg = 0x10000;"). */
+ if (SYMBOL_TYPE (sym) == builtin_type_char
+ || SYMBOL_TYPE (sym) == builtin_type_unsigned_char)
+ SYMBOL_VALUE (sym) += 3;
+ if (SYMBOL_TYPE (sym) == builtin_type_short
+ || SYMBOL_TYPE (sym) == builtin_type_unsigned_short)
+ SYMBOL_VALUE (sym) += 2;
+ break;
+
+#else /* no BELIEVE_PCC_PROMOTION_TYPE. */
+
/* If PCC says a parameter is a short or a char,
it is really an int. */
if (SYMBOL_TYPE (sym) == builtin_type_char
@@ -3809,6 +3976,8 @@ define_symbol (value, string, desc)
SYMBOL_TYPE (sym) = builtin_type_unsigned_int;
break;
+#endif /* no BELIEVE_PCC_PROMOTION_TYPE. */
+
case 'P':
SYMBOL_CLASS (sym) = LOC_REGPARM;
SYMBOL_VALUE (sym) = STAB_REG_TO_REGNUM (value);
@@ -3960,30 +4129,6 @@ cleanup_undefined_types ()
-/* Read a number by which a type is referred to in dbx data,
- or perhaps read a pair (FILENUM, TYPENUM) in parentheses.
- Just a single number N is equivalent to (0,N).
- Return the two numbers by storing them in the vector TYPENUMS.
- TYPENUMS will then be used as an argument to dbx_lookup_type. */
-
-static void
-read_type_number (pp, typenums)
- register char **pp;
- register int *typenums;
-{
- if (**pp == '(')
- {
- (*pp)++;
- typenums[0] = read_number (pp, ',');
- typenums[1] = read_number (pp, ')');
- }
- else
- {
- typenums[0] = 0;
- typenums[1] = read_number (pp, 0);
- }
-}
-
/* Read a dbx type reference or definition;
return the type that is meant.
This can be just a number, in which case it references
@@ -4508,6 +4653,16 @@ read_struct_type (pp, type)
list->field.bitpos = read_number (pp, ',');
list->field.bitsize = read_number (pp, ';');
+#if 0
+ /* This is wrong because this is identical to the symbols
+ produced for GCC 0-size arrays. For example:
+ typedef union {
+ int num;
+ char str[0];
+ } foo;
+ The code which dumped core in such circumstances should be
+ fixed not to dump core. */
+
/* g++ -g0 can put out bitpos & bitsize zero for a static
field. This does not give us any way of getting its
class, so we can't know its name. But we can just
@@ -4536,6 +4691,7 @@ Therefore GDB will not know about your class variables.\n\
list = list->next;
}
else
+#endif /* 0 */
{
/* Detect an unpacked field and mark it as such.
dbx gives a bit size for all fields.