From 080868b4662cf9f1930714d09ad1d446dfd3a196 Mon Sep 17 00:00:00 2001 From: Peter Schauer Date: Sat, 26 Aug 1995 07:35:13 +0000 Subject: [PATCH] * mdebugread.c (parse_symbol): Handle sh.value of zero for enums. Determine signedness of enum type from enumerators. (parse_type): Handle btIndirect types, handle fBitfield for some non-member types. (upgrade_type): Use TYPE_FLAG_TARGET_STUB for arrays with unknown length. (cross_ref): Handle stIndirect forward reference to btTypedef. * stabsread.c (read_enum_type): Determine signedness of enum type from enumerators. * top.c (execute_command): Remove trailing whitespace from command arguments, except for `set' and `complete' commands. (validate_comname): Allow underscores in user defined command names. * values.c (modify_field): Change `Value does not fit in %d bits' error to a warning. Exclude sign extension bits of negative field values from fit check. --- gdb/ChangeLog | 22 ++++++++++ gdb/mdebugread.c | 105 +++++++++++++++++++++++++++++++++++++++++------ gdb/stabsread.c | 5 +++ gdb/top.c | 11 ++++- gdb/values.c | 16 ++++++-- 5 files changed, 142 insertions(+), 17 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 05889c08a06..e66fd844d11 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,25 @@ +Sat Aug 26 00:26:11 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) + + * mdebugread.c (parse_symbol): Handle sh.value of zero for enums. + Determine signedness of enum type from enumerators. + (parse_type): Handle btIndirect types, handle fBitfield for + some non-member types. + (upgrade_type): Use TYPE_FLAG_TARGET_STUB for arrays with + unknown length. + (cross_ref): Handle stIndirect forward reference to btTypedef. + + * stabsread.c (read_enum_type): Determine signedness of enum + type from enumerators. + + * top.c (execute_command): Remove trailing whitespace from + command arguments, except for `set' and `complete' commands. + (validate_comname): Allow underscores in user defined command + names. + + * values.c (modify_field): Change `Value does not fit in %d bits' + error to a warning. Exclude sign extension bits of negative field + values from fit check. + Fri Aug 25 11:31:29 1995 Michael Meissner * configure.in (powerpc*-*-eabisim*): Only link in the simulator diff --git a/gdb/mdebugread.c b/gdb/mdebugread.c index 33b447c0bda..4a1ca9a5365 100644 --- a/gdb/mdebugread.c +++ b/gdb/mdebugread.c @@ -202,6 +202,9 @@ static struct complaint unexpected_type_code_complaint = static struct complaint unable_to_cross_ref_complaint = {"unable to cross ref btTypedef for %s", 0, 0}; +static struct complaint bad_indirect_xref_complaint = +{"unable to cross ref btIndirect for %s", 0, 0}; + static struct complaint illegal_forward_tq0_complaint = {"illegal tq0 in forward typedef for %s", 0, 0}; @@ -1060,6 +1063,8 @@ parse_symbol (sh, ax, ext_sh, bigend, section_offsets) if (type_code == TYPE_CODE_ENUM) { + int unsigned_enum = 1; + /* This is a non-empty enum. */ /* DEC c89 has the number of enumerators in the sh.value field, @@ -1067,8 +1072,11 @@ parse_symbol (sh, ax, ext_sh, bigend, section_offsets) incompatibility quirk. This might do the wrong thing for an enum with one or two enumerators and gcc -gcoff -fshort-enums, but these cases - are hopefully rare enough. */ - if (TYPE_LENGTH (t) == TYPE_NFIELDS (t)) + are hopefully rare enough. + Alpha cc -migrate has a sh.value field of zero, we adjust + that too. */ + if (TYPE_LENGTH (t) == TYPE_NFIELDS (t) + || TYPE_LENGTH (t) == 0) TYPE_LENGTH (t) = TARGET_INT_BIT / HOST_CHAR_BIT; for (ext_tsym = ext_sh + external_sym_size; ; @@ -1096,12 +1104,16 @@ parse_symbol (sh, ax, ext_sh, bigend, section_offsets) SYMBOL_TYPE (enum_sym) = t; SYMBOL_NAMESPACE (enum_sym) = VAR_NAMESPACE; SYMBOL_VALUE (enum_sym) = tsym.value; + if (SYMBOL_VALUE (enum_sym) < 0) + unsigned_enum = 0; add_symbol (enum_sym, top_stack->cur_block); /* Skip the stMembers that we've handled. */ count++; f++; } + if (unsigned_enum) + TYPE_FLAGS (t) |= TYPE_FLAG_UNSIGNED; } /* make this the current type */ top_stack->cur_type = t; @@ -1481,6 +1493,11 @@ parse_type (fd, ax, aux_index, bs, bigend, sym_name) case btSet: type_code = TYPE_CODE_SET; break; + case btIndirect: + /* alpha cc -migrate uses this for typedefs. The true type will + be obtained by crossreferencing below. */ + type_code = TYPE_CODE_ERROR; + break; case btTypedef: /* alpha cc uses this for typedefs. The true type will be obtained by crossreferencing below. */ @@ -1497,17 +1514,59 @@ parse_type (fd, ax, aux_index, bs, bigend, sym_name) if (t->fBitfield) { + int width = AUX_GET_WIDTH (bigend, ax); + /* Inhibit core dumps with some cfront generated objects that corrupt the TIR. */ if (bs == (int *)NULL) { - complain (&bad_fbitfield_complaint, sym_name); - return mdebug_type_int; + /* Alpha cc -migrate encodes char and unsigned char types + as short and unsigned short types with a field width of 8. + Enum types also have a field width which we ignore for now. */ + if (t->bt == btShort && width == 8) + tp = mdebug_type_char; + else if (t->bt == btUShort && width == 8) + tp = mdebug_type_unsigned_char; + else if (t->bt == btEnum) + ; + else + complain (&bad_fbitfield_complaint, sym_name); } - *bs = AUX_GET_WIDTH (bigend, ax); + else + *bs = width; ax++; } + /* A btIndirect entry cross references to an aux entry containing + the type. */ + if (t->bt == btIndirect) + { + RNDXR rn[1]; + int rf; + FDR *xref_fh; + int xref_fd; + + (*debug_swap->swap_rndx_in) (bigend, &ax->a_rndx, rn); + ax++; + if (rn->rfd == 0xfff) + { + rf = AUX_GET_ISYM (bigend, ax); + ax++; + } + else + rf = rn->rfd; + + if (rf == -1) + { + complain (&bad_indirect_xref_complaint, sym_name); + return mdebug_type_int; + } + xref_fh = get_rfd (fd, rf); + xref_fd = xref_fh - debug_info->fdr; + tp = parse_type (xref_fd, debug_info->external_aux + xref_fh->iauxBase, + rn->index, (int *) NULL, xref_fh->fBigendian, sym_name); + } + /* All these types really point to some (common) MIPS type definition, and only the type-qualifiers fully identify them. We'll make the same effort at sharing. */ @@ -1575,10 +1634,8 @@ parse_type (fd, ax, aux_index, bs, bigend, sym_name) /* All these types really point to some (common) MIPS type definition, and only the type-qualifiers fully identify them. We'll make the same effort at sharing. - FIXME: btIndirect cannot happen here as it is handled by the - switch t->bt above. And we are not doing any guessing on range types. */ - if (t->bt == btIndirect || - t->bt == btRange) + FIXME: We are not doing any guessing on range types. */ + if (t->bt == btRange) { char *name; @@ -1763,6 +1820,13 @@ upgrade_type (fd, tpp, tq, ax, bigend, sym_name) ignore the erroneous bitsize from the auxiliary entry safely. dbx seems to ignore it too. */ + /* TYPE_FLAG_TARGET_STUB now takes care of the zero TYPE_LENGTH + problem. */ + if (TYPE_LENGTH (*tpp) == 0) + { + TYPE_FLAGS (t) |= TYPE_FLAG_TARGET_STUB; + } + *tpp = t; return 4 + off; @@ -3537,9 +3601,9 @@ cross_ref (fd, ax, tpp, type_code, pname, bigend, sym_name) For these the type will be void. This is a bad design decision as cross referencing across compilation units is impossible due to the missing name. - b) forward declarations of structs/unions/enums which are defined - later in this file or in another file in the same compilation - unit. Irix5 cc uses a stIndirect symbol for this. + b) forward declarations of structs/unions/enums/typedefs which + are defined later in this file or in another file in the same + compilation unit. Irix5 cc uses a stIndirect symbol for this. Simply cross reference those again to get the true type. The forward references are not entered in the pending list and in the symbol table. */ @@ -3568,6 +3632,23 @@ cross_ref (fd, ax, tpp, type_code, pname, bigend, sym_name) fh->fBigendian, sym_name); break; + case btTypedef: + /* Follow a forward typedef. This might recursively + call cross_ref till we get a non typedef'ed type. + FIXME: This is not correct behaviour, but gdb currently + cannot handle typedefs without type copying. Type + copying is impossible as we might have mutual forward + references between two files and the copied type would not + get filled in when we later parse its definition. */ + *tpp = parse_type (xref_fd, + debug_info->external_aux + fh->iauxBase, + sh.index, + (int *)NULL, + fh->fBigendian, + debug_info->ss + fh->issBase + sh.iss); + add_pending (fh, esh, *tpp); + break; + default: complain (&illegal_forward_bt_complaint, tir.bt, sym_name); *tpp = init_type (type_code, 0, 0, (char *) NULL, diff --git a/gdb/stabsread.c b/gdb/stabsread.c index 9c703e6eadc..167da0b57ad 100644 --- a/gdb/stabsread.c +++ b/gdb/stabsread.c @@ -3050,6 +3050,7 @@ read_enum_type (pp, type, objfile) struct pending *osyms, *syms; int o_nsyms; int nbits; + int unsigned_enum = 1; #if 0 /* FIXME! The stabs produced by Sun CC merrily define things that ought @@ -3107,6 +3108,8 @@ read_enum_type (pp, type, objfile) SYMBOL_CLASS (sym) = LOC_CONST; SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; SYMBOL_VALUE (sym) = n; + if (n < 0) + unsigned_enum = 0; add_symbol_to_list (sym, symlist); nsyms++; } @@ -3119,6 +3122,8 @@ read_enum_type (pp, type, objfile) TYPE_LENGTH (type) = TARGET_INT_BIT / HOST_CHAR_BIT; TYPE_CODE (type) = TYPE_CODE_ENUM; TYPE_FLAGS (type) &= ~TYPE_FLAG_STUB; + if (unsigned_enum) + TYPE_FLAGS (type) |= TYPE_FLAG_UNSIGNED; TYPE_NFIELDS (type) = nsyms; TYPE_FIELDS (type) = (struct field *) TYPE_ALLOC (type, sizeof (struct field) * nsyms); diff --git a/gdb/top.c b/gdb/top.c index 2d490a5bd07..20c18651a4d 100644 --- a/gdb/top.c +++ b/gdb/top.c @@ -1152,6 +1152,15 @@ execute_command (p, from_tty) /* Pass null arg rather than an empty one. */ arg = *p ? p : 0; + /* Clear off trailing whitespace, except for set and complete command. */ + if (arg && c->type != set_cmd && c->function.cfunc != complete_command) + { + p = arg + strlen (arg) - 1; + while (p >= arg && (*p == ' ' || *p == '\t')) + p--; + *(p + 1) = '\0'; + } + /* If this command has been hooked, run the hook first. */ if (c->hook) execute_user_command (c->hook, (char *)0); @@ -2574,7 +2583,7 @@ validate_comname (comname) p = comname; while (*p) { - if (!isalnum(*p) && *p != '-') + if (!isalnum(*p) && *p != '-' && *p != '_') error ("Junk in argument list: \"%s\"", p); p++; } diff --git a/gdb/values.c b/gdb/values.c index 53a411761d1..9a2301e0894 100644 --- a/gdb/values.c +++ b/gdb/values.c @@ -1,5 +1,5 @@ /* Low level packing and unpacking of values for GDB, the GNU Debugger. - Copyright 1986, 1987, 1989, 1991, 1993, 1994 + Copyright 1986, 1987, 1989, 1991, 1993, 1994, 1995 Free Software Foundation, Inc. This file is part of GDB. @@ -1288,14 +1288,22 @@ modify_field (addr, fieldval, bitpos, bitsize) { LONGEST oword; - /* Reject values too big to fit in the field in question, - otherwise adjoining fields may be corrupted. */ + /* If a negative fieldval fits in the field in question, chop + off the sign extension bits. */ + if (bitsize < (8 * sizeof (fieldval)) + && (~fieldval & ~((1 << (bitsize - 1)) - 1)) == 0) + fieldval = fieldval & ((1 << bitsize) - 1); + + /* Warn if value is too big to fit in the field in question. */ if (bitsize < (8 * sizeof (fieldval)) && 0 != (fieldval & ~((1<