From 2a5ec41d888f9f6004f237670e676ea5617f281e Mon Sep 17 00:00:00 2001 From: John Gilmore Date: Thu, 5 Dec 1991 11:56:20 +0000 Subject: [PATCH] Fix things pointed up by Fred Fish's test suite; see ChangeLog. --- gdb/ChangeLog | 29 +++++++ gdb/buildsym.c | 214 +++++++++++++++++++++++++++++++------------------ gdb/c-exp.y | 7 +- gdb/inflow.c | 122 ++++++++++++++++++---------- gdb/valops.c | 37 +++++---- gdb/valprint.c | 11 +-- 6 files changed, 278 insertions(+), 142 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index a1cabeb13da..18139592826 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,32 @@ +Thu Dec 5 03:34:21 1991 John Gilmore (gnu at cygnus.com) + + * inflow.c: Remember whether GDB has a terminal. Avoid switching + terminals back and forth if we don't have one. + + * c-exp.y (parse_number): Zero is not an unsigned int constant! + * dbxread.c (read_dbx_symtab): Enum type numbers can be in (1,2) form. + + Improve type parsing. + * buildsym.c (define_symbol, read_range_type): Add + long_kludge_name that passes the names of range types being + defined, down to where we must choose between 'int' and 'long' + variants. This fails on Sun C anyway since the compiler itself is + confused between int and long. + (read_array_type, cleanup_undefined_types): Correct the size of + array type whose element-type size isn't immediately known. + + Early preparation to blow away many builtin types, building them + on the fly as needed. Don't compare types to builtin types with + ==; examine the relevant fields instead. + * coffread.c (process_coff_symbol: C_ARG, C_REGPARM): Avoid ==. + * buildsym.c (define_symbol, case 'p'): Avoid ==. + * valops.c (value_arg_coerce): Avoid ==. Don't assume host and + target types are the same. + * valprint.c (val_print): I finally understand arrays, remove FIXME. + + * symmisc.c (printpsyms_command): Reduce redundancy, and put all + addresses in GDB itself into parens for easy cleanup and diffing. + Wed Dec 4 21:05:30 1991 Fred Fish (fnf at cygnus.com) * dwarfread (enum_type): Arrange for the order of enumeration diff --git a/gdb/buildsym.c b/gdb/buildsym.c index 86e726f858f..4f1fc24f313 100644 --- a/gdb/buildsym.c +++ b/gdb/buildsym.c @@ -1,5 +1,5 @@ /* Build symbol tables in GDB's internal format. - Copyright (C) 1986-1991 Free Software Foundation, Inc. + Copyright 1986, 1987, 1988, 1989, 1990, 1991 Free Software Foundation, Inc. This file is part of GDB. @@ -66,6 +66,14 @@ static const char vb_name[] = { '_','v','b',CPLUS_MARKER,'\0' }; #define BELIEVE_PCC_PROMOTION 0 #endif +/* During some calls to read_type (and thus to read_range_type), this + contains the name of the type being defined. Range types are only + used in C as basic types. We use the name to distinguish the otherwise + identical basic types "int" and "long" and their unsigned versions. + FIXME, this should disappear with better type management. */ + +static char *long_kludge_name; + /* Make a list of forward references which haven't been defined. */ static struct type **undef_types; static int undef_types_allocated, undef_types_length; @@ -1117,6 +1125,14 @@ define_symbol (valu, string, desc, type) strlen (SYMBOL_NAME (sym))); } + /* Here we save the name of the symbol for read_range_type, which + ends up reading in the basic types. In stabs, unfortunately there + is no distinction between "int" and "long" types except their + names. Until we work out a saner type policy (eliminating most + builtin types and using the names specified in the files), we + save away the name so that far away from here in read_range_type, + we can examine it to decide between "int" and "long". FIXME. */ + long_kludge_name = SYMBOL_NAME (sym); type_read = read_type (&p); if ((deftype == 'F' || deftype == 'f') @@ -1230,29 +1246,31 @@ define_symbol (valu, string, desc, type) up). I made this code adapt so that it will offset the symbol if it was pointing at an int-aligned location and not otherwise. This way you can use the same gdb for 4.0.x and - 4.1 systems. */ - - if (0 == SYMBOL_VALUE (sym) % sizeof (int)) - { - if (SYMBOL_TYPE (sym) == builtin_type_char - || SYMBOL_TYPE (sym) == builtin_type_unsigned_char) - SYMBOL_VALUE (sym) += 3; - else if (SYMBOL_TYPE (sym) == builtin_type_short - || SYMBOL_TYPE (sym) == builtin_type_unsigned_short) - SYMBOL_VALUE (sym) += 2; - } + 4.1 systems. + + If the parameter is shorter than an int, and is integral + (e.g. char, short, or unsigned equivalent), and is claimed to + be passed on an integer boundary, don't believe it! Offset the + parameter's address to the tail-end of that integer. */ + + if (TYPE_LENGTH (SYMBOL_TYPE (sym)) < TYPE_LENGTH (builtin_type_int) + && TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_INT + && 0 == SYMBOL_VALUE (sym) % TYPE_LENGTH (builtin_type_int)) { + SYMBOL_VALUE (sym) += TYPE_LENGTH (builtin_type_int) + - TYPE_LENGTH (SYMBOL_TYPE (sym)); + } 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 - || SYMBOL_TYPE (sym) == builtin_type_short) - SYMBOL_TYPE (sym) = builtin_type_int; - else if (SYMBOL_TYPE (sym) == builtin_type_unsigned_char - || SYMBOL_TYPE (sym) == builtin_type_unsigned_short) - SYMBOL_TYPE (sym) = builtin_type_unsigned_int; + if (TYPE_LENGTH (SYMBOL_TYPE (sym)) < TYPE_LENGTH (builtin_type_int) + && TYPE_CODE (SYMBOL_TYPE (sym) == TYPE_CODE_INT) { + SYMBOL_TYPE (sym) = TYPE_UNSIGNED (SYMBOL_TYPE (sym))? + builtin_type_unsigned_int: + builtin_type_int; + } break; #endif /* no BELIEVE_PCC_PROMOTION_TYPE. */ @@ -1386,45 +1404,86 @@ add_undefined_type (type) undef_types[undef_types_length++] = type; } -/* Add here something to go through each undefined type, see if it's - still undefined, and do a full lookup if so. */ +/* Go through each undefined type, see if it's still undefined, and fix it + up if possible. We have two kinds of undefined types: + + TYPE_CODE_ARRAY: Array whose target type wasn't defined yet. + Fix: update array length using the element bounds + and the target type's length. + TYPE_CODE_STRUCT, TYPE_CODE_UNION: Structure whose fields were not + yet defined at the time a pointer to it was made. + Fix: Do a full lookup on the struct/union tag. */ static void cleanup_undefined_types () { struct type **type; - for (type = undef_types; type < undef_types + undef_types_length; type++) - { - /* Reasonable test to see if it's been defined since. */ - if (TYPE_NFIELDS (*type) == 0) - { - struct pending *ppt; - int i; - /* Name of the type, without "struct" or "union" */ - char *typename = TYPE_NAME (*type); + for (type = undef_types; type < undef_types + undef_types_length; type++) { + switch (TYPE_CODE (*type)) { - if (!strncmp (typename, "struct ", 7)) - typename += 7; - if (!strncmp (typename, "union ", 6)) - typename += 6; + case TYPE_CODE_STRUCT: + case TYPE_CODE_UNION: + { + /* Reasonable test to see if it's been defined since. */ + if (TYPE_NFIELDS (*type) == 0) + { + struct pending *ppt; + int i; + /* Name of the type, without "struct" or "union" */ + char *typename = TYPE_NAME (*type); + + if (!strncmp (typename, "struct ", 7)) + typename += 7; + if (!strncmp (typename, "union ", 6)) + typename += 6; + + for (ppt = file_symbols; ppt; ppt = ppt->next) + for (i = 0; i < ppt->nsyms; i++) + { + struct symbol *sym = ppt->symbol[i]; + + if (SYMBOL_CLASS (sym) == LOC_TYPEDEF + && SYMBOL_NAMESPACE (sym) == STRUCT_NAMESPACE + && (TYPE_CODE (SYMBOL_TYPE (sym)) == + TYPE_CODE (*type)) + && !strcmp (SYMBOL_NAME (sym), typename)) + bcopy (SYMBOL_TYPE (sym), *type, sizeof (struct type)); + } + } + else + /* It has been defined; don't mark it as a stub. */ + TYPE_FLAGS (*type) &= ~TYPE_FLAG_STUB; + } + break; - for (ppt = file_symbols; ppt; ppt = ppt->next) - for (i = 0; i < ppt->nsyms; i++) - { - struct symbol *sym = ppt->symbol[i]; - - if (SYMBOL_CLASS (sym) == LOC_TYPEDEF - && SYMBOL_NAMESPACE (sym) == STRUCT_NAMESPACE - && (TYPE_CODE (SYMBOL_TYPE (sym)) == - TYPE_CODE (*type)) - && !strcmp (SYMBOL_NAME (sym), typename)) - bcopy (SYMBOL_TYPE (sym), *type, sizeof (struct type)); - } + case TYPE_CODE_ARRAY: + { + struct type *range_type; + int lower, upper; + + if (TYPE_LENGTH (*type) != 0) /* Better be unknown */ + goto badtype; + if (TYPE_NFIELDS (*type) != 1) + goto badtype; + range_type = TYPE_FIELD_TYPE (*type, 0); + if (TYPE_CODE (range_type) != TYPE_CODE_RANGE) + goto badtype; + + /* Now recompute the length of the array type, based on its + number of elements and the target type's length. */ + lower = TYPE_FIELD_BITPOS (range_type, 0); + upper = TYPE_FIELD_BITPOS (range_type, 1); + TYPE_LENGTH (*type) = (upper - lower + 1) + * TYPE_LENGTH (TYPE_TARGET_TYPE (*type)); } - else - /* It has been defined; don't mark it as a stub. */ - TYPE_FLAGS (*type) &= ~TYPE_FLAG_STUB; + break; + + default: + badtype: + error ("GDB internal error. cleanup_undefined_types with bad type."); + break; } + } undef_types_length = 0; } @@ -2579,6 +2638,11 @@ read_array_type (pp, type) sizeof (struct field)); TYPE_FIELD_TYPE (type, 0) = range_type; + /* 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. */ + if (TYPE_LENGTH (element_type) == 0 && !adjustable) + add_undefined_type (type); + return type; } @@ -2881,7 +2945,9 @@ read_range_type (pp, typenums) and they give no way to distinguish between double and single-complex! We don't have complex types, so we would lose on all fortran files! So return type `double' for all of those. It won't work right - for the complex values, but at least it makes the file loadable. */ + for the complex values, but at least it makes the file loadable. + + FIXME, we may be able to distinguish these by their names. FIXME. */ if (n3 == 0 && n2 > 0) { @@ -2894,11 +2960,15 @@ read_range_type (pp, typenums) else if (n2 == 0 && n3 == -1) { - /* FIXME -- this confuses host and target type sizes. */ - if (sizeof (int) == sizeof (long)) - return builtin_type_unsigned_int; - else + /* FIXME -- the only way to distinguish `unsigned int' from `unsigned + long' is to look at its name! */ + if ( + long_kludge_name && ((long_kludge_name[0] == 'u' /* unsigned */ && + long_kludge_name[9] == 'l' /* long */) + || (long_kludge_name[0] == 'l' /* long unsigned */))) return builtin_type_unsigned_long; + else + return builtin_type_unsigned_int; } /* Special case: char is defined (Who knows why) as a subrange of @@ -2908,6 +2978,8 @@ read_range_type (pp, typenums) /* Assumptions made here: Subrange of self is equivalent to subrange of int. FIXME: Host and target type-sizes assumed the same. */ + /* FIXME: This is the *only* place in GDB that depends on comparing + some type to a builtin type with ==. Fix it! */ else if (n2 == 0 && (self_subrange || *dbx_lookup_type (rangenums) == builtin_type_int)) @@ -2917,10 +2989,15 @@ read_range_type (pp, typenums) if (n3 == - sizeof (long long)) return builtin_type_unsigned_long_long; #endif + /* FIXME -- the only way to distinguish `unsigned int' from `unsigned + long' is to look at its name! */ + if (n3 == (unsigned long)~0L && + long_kludge_name && ((long_kludge_name[0] == 'u' /* unsigned */ && + long_kludge_name[9] == 'l' /* long */) + || (long_kludge_name[0] == 'l' /* long unsigned */))) + return builtin_type_unsigned_long; if (n3 == (unsigned int)~0L) return builtin_type_unsigned_int; - if (n3 == (unsigned long)~0L) - return builtin_type_unsigned_long; if (n3 == (unsigned short)~0L) return builtin_type_unsigned_short; if (n3 == (unsigned char)~0L) @@ -2933,10 +3010,13 @@ read_range_type (pp, typenums) else if (n2 == -n3 -1) { /* a signed type */ + /* FIXME -- the only way to distinguish `int' from `long' is to look + at its name! */ + if ((n3 == (1 << (8 * sizeof (long) - 1)) - 1) && + long_kludge_name && long_kludge_name[0] == 'l' /* long */) + return builtin_type_long; if (n3 == (1 << (8 * sizeof (int) - 1)) - 1) return builtin_type_int; - if (n3 == (1 << (8 * sizeof (long) - 1)) - 1) - return builtin_type_long; if (n3 == (1 << (8 * sizeof (short) - 1)) - 1) return builtin_type_short; if (n3 == (1 << (8 * sizeof (char) - 1)) - 1) @@ -2972,26 +3052,6 @@ read_range_type (pp, typenums) TYPE_FIELD_BITPOS (result_type, 0) = n2; TYPE_FIELD_BITPOS (result_type, 1) = n3; -#if 0 -/* Note that TYPE_LENGTH (result_type) is just overridden a few - statements down. What do we really need here? */ - /* We have to figure out how many bytes it takes to hold this - range type. I'm going to assume that anything that is pushing - the bounds of a long was taken care of above. */ - if (n2 >= MIN_OF_C_TYPE(char) && n3 <= MAX_OF_C_TYPE(char)) - TYPE_LENGTH (result_type) = 1; - else if (n2 >= MIN_OF_C_TYPE(short) && n3 <= MAX_OF_C_TYPE(short)) - TYPE_LENGTH (result_type) = sizeof (short); - else if (n2 >= MIN_OF_C_TYPE(int) && n3 <= MAX_OF_C_TYPE(int)) - TYPE_LENGTH (result_type) = sizeof (int); - else if (n2 >= MIN_OF_C_TYPE(long) && n3 <= MAX_OF_C_TYPE(long)) - TYPE_LENGTH (result_type) = sizeof (long); - else - /* Ranged type doesn't fit within known sizes. */ - /* FIXME -- use "long long" here. */ - return error_type (pp); -#endif - TYPE_LENGTH (result_type) = TYPE_LENGTH (TYPE_TARGET_TYPE (result_type)); return result_type; diff --git a/gdb/c-exp.y b/gdb/c-exp.y index 192ed47c1cf..7d4b1777ad3 100644 --- a/gdb/c-exp.y +++ b/gdb/c-exp.y @@ -977,10 +977,11 @@ parse_number (p, len, parsed_float, putithere) } if (i >= base) return ERROR; /* Invalid digit in this base */ - if(!unsigned_p && (prevn >= n)) + /* Portably test for overflow (only works for nonzero values, so make + a second check for zero). */ + if((prevn >= n) && n != 0) unsigned_p=1; /* Try something unsigned */ - /* Don't do the range check if n==i and i==0, since that special - case will give an overflow error. */ + /* If range checking enabled, portably test for unsigned overflow. */ if(RANGE_CHECK && n!=0) { if((unsigned_p && (unsigned)prevn >= (unsigned)n)) diff --git a/gdb/inflow.c b/gdb/inflow.c index 698cfb4f8be..0a66a4ccf9a 100644 --- a/gdb/inflow.c +++ b/gdb/inflow.c @@ -38,6 +38,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include +extern char *strerror(); /* strings corresponding to errno */ + extern struct target_ops child_ops; /* Nonzero if we are debugging an attached outside process @@ -48,6 +50,9 @@ int attach_flag; /* Record terminal status separately for debugger and inferior. */ +/* Does GDB have a terminal (on stdin)? */ +int gdb_has_a_terminal; + static TERMINAL sg_inferior; static TERMINAL sg_ours; @@ -82,15 +87,25 @@ static void (*sigint_ours) (); static void (*sigquit_ours) (); #endif /* TIOCGPGRP */ -/* Copy of inferior_io_terminal when inferior was last started. */ -static char *inferior_thisrun_terminal; +/* The name of the tty (from the `tty' command) that we gave to the inferior + when it was last started. */ -static void terminal_ours_1 (); +static char *inferior_thisrun_terminal; /* Nonzero if our terminal settings are in effect. Zero if the inferior's settings are in effect. */ + static int terminal_is_ours; +/* Macro for printing errors from ioctl operations */ + +#define OOPSY(what) \ + if (result == -1) \ + fprintf(stderr, "[%s failed in terminal_inferior: %s]\n", \ + what, strerror (errno)) + +static void terminal_ours_1 (); + /* Initialize the terminal settings we record for the inferior, before we actually run the inferior. */ @@ -125,24 +140,32 @@ terminal_init_inferior () void terminal_inferior () { - if (terminal_is_ours && inferior_thisrun_terminal == 0) + int result; + + if (gdb_has_a_terminal && terminal_is_ours && inferior_thisrun_terminal == 0) { - fcntl (0, F_SETFL, tflags_inferior); - fcntl (0, F_SETFL, tflags_inferior); - ioctl (0, TIOCSETN, &sg_inferior); + result = fcntl (0, F_SETFL, tflags_inferior); + result = fcntl (0, F_SETFL, tflags_inferior); + OOPSY ("fcntl F_SETFL"); + result = ioctl (0, TIOCSETN, &sg_inferior); + OOPSY ("ioctl TIOCSETN"); #if defined(TIOCGETC) && !defined(TIOCGETC_BROKEN) - ioctl (0, TIOCSETC, &tc_inferior); + result = ioctl (0, TIOCSETC, &tc_inferior); + OOPSY ("ioctl TIOCSETC"); #endif #if defined(TIOCGLTC) && !defined(TIOCGLTC_BROKEN) - ioctl (0, TIOCSLTC, <c_inferior); + result = ioctl (0, TIOCSLTC, <c_inferior); + OOPSY ("ioctl TIOCSLTC"); #endif #ifdef TIOCLGET - ioctl (0, TIOCLSET, &lmode_inferior); + result = ioctl (0, TIOCLSET, &lmode_inferior); + OOPSY ("ioctl TIOCLSET"); #endif #ifdef TIOCGPGRP - ioctl (0, TIOCSPGRP, &pgrp_inferior); + result = ioctl (0, TIOCSPGRP, &pgrp_inferior); + OOPSY ("ioctl TIOCSPGRP"); #else sigint_ours = (void (*) ()) signal (SIGINT, SIG_IGN); sigquit_ours = (void (*) ()) signal (SIGQUIT, SIG_IGN); @@ -179,17 +202,17 @@ static void terminal_ours_1 (output_only) int output_only; { + int result; #ifdef TIOCGPGRP /* Ignore this signal since it will happen when we try to set the pgrp. */ void (*osigttou) (); #endif /* TIOCGPGRP */ - /* The check for inferior_thisrun_terminal had been commented out - when the call to ioctl (TIOCNOTTY) was commented out. - Checking inferior_thisrun_terminal is necessary so that + /* Checking inferior_thisrun_terminal is necessary so that if GDB is running in the background, it won't block trying - to do the ioctl()'s below. */ - if (inferior_thisrun_terminal != 0) + to do the ioctl()'s below. Checking gdb_has_a_terminal + avoids attempting all the ioctl's when running in batch. */ + if (inferior_thisrun_terminal != 0 || gdb_has_a_terminal == 0) return; if (!terminal_is_ours) @@ -199,8 +222,8 @@ terminal_ours_1 (output_only) #ifdef TIOCGPGRP osigttou = (void (*) ()) signal (SIGTTOU, SIG_IGN); - ioctl (0, TIOCGPGRP, &pgrp_inferior); - ioctl (0, TIOCSPGRP, &pgrp_ours); + result = ioctl (0, TIOCGPGRP, &pgrp_inferior); + result = ioctl (0, TIOCSPGRP, &pgrp_ours); signal (SIGTTOU, osigttou); #else @@ -209,16 +232,16 @@ terminal_ours_1 (output_only) #endif /* TIOCGPGRP */ tflags_inferior = fcntl (0, F_GETFL, 0); - ioctl (0, TIOCGETP, &sg_inferior); + result = ioctl (0, TIOCGETP, &sg_inferior); #if defined(TIOCGETC) && !defined(TIOCGETC_BROKEN) - ioctl (0, TIOCGETC, &tc_inferior); + result = ioctl (0, TIOCGETC, &tc_inferior); #endif #if defined(TIOCGLTC) && !defined(TIOCGLTC_BROKEN) - ioctl (0, TIOCGLTC, <c_inferior); + result = ioctl (0, TIOCGLTC, <c_inferior); #endif #ifdef TIOCLGET - ioctl (0, TIOCLGET, &lmode_inferior); + result = ioctl (0, TIOCLGET, &lmode_inferior); #endif } @@ -232,18 +255,18 @@ terminal_ours_1 (output_only) sg_ours.sg_flags |= (RAW | CBREAK) & sg_inferior.sg_flags; #endif /* not HAVE_TERMIO */ - fcntl (0, F_SETFL, tflags_ours); - fcntl (0, F_SETFL, tflags_ours); - ioctl (0, TIOCSETN, &sg_ours); + result = fcntl (0, F_SETFL, tflags_ours); + result = fcntl (0, F_SETFL, tflags_ours); + result = ioctl (0, TIOCSETN, &sg_ours); #if defined(TIOCGETC) && !defined(TIOCGETC_BROKEN) - ioctl (0, TIOCSETC, &tc_ours); + result = ioctl (0, TIOCSETC, &tc_ours); #endif #if defined(TIOCGLTC) && !defined(TIOCGLTC_BROKEN) - ioctl (0, TIOCSLTC, <c_ours); + result = ioctl (0, TIOCSLTC, <c_ours); #endif #ifdef TIOCLGET - ioctl (0, TIOCLSET, &lmode_ours); + result = ioctl (0, TIOCLSET, &lmode_ours); #endif #ifdef HAVE_TERMIO @@ -270,12 +293,20 @@ child_terminal_info (args, from_tty) { register int i; + if (!gdb_has_a_terminal) { + printf_filtered ("This GDB does not control a terminal.\n"); + return; + } + printf_filtered ("Inferior's terminal status (currently saved by GDB):\n"); + printf_filtered ("owner pgrp = %d, fcntl flags = 0x%x.\n", + pgrp_inferior, tflags_inferior); + #ifdef HAVE_TERMIO - printf_filtered ("fcntl flags = 0x%x, c_iflag = 0x%x, c_oflag = 0x%x,\n", - tflags_inferior, sg_inferior.c_iflag, sg_inferior.c_oflag); + printf_filtered (c_iflag = 0x%x, c_oflag = 0x%x,\n", + sg_inferior.c_iflag, sg_inferior.c_oflag); printf_filtered ("c_cflag = 0x%x, c_lflag = 0x%x, c_line = 0x%x.\n", sg_inferior.c_cflag, sg_inferior.c_lflag, sg_inferior.c_line); printf_filtered ("c_cc: "); @@ -285,22 +316,21 @@ child_terminal_info (args, from_tty) #else /* not HAVE_TERMIO */ - printf_filtered ("fcntl flags = 0x%x, sgttyb.sg_flags = 0x%x, owner pid = %d.\n", - tflags_inferior, sg_inferior.sg_flags, pgrp_inferior); + printf_filtered ("sgttyb.sg_flags = 0x%x.\n", sg_inferior.sg_flags); #endif /* not HAVE_TERMIO */ #if defined(TIOCGETC) && !defined(TIOCGETC_BROKEN) printf_filtered ("tchars: "); for (i = 0; i < (int)sizeof (struct tchars); i++) - printf_filtered ("0x%x ", ((char *)&tc_inferior)[i]); + printf_filtered ("0x%x ", ((unsigned char *)&tc_inferior)[i]); printf_filtered ("\n"); #endif #if defined(TIOCGLTC) && !defined(TIOCGLTC_BROKEN) printf_filtered ("ltchars: "); for (i = 0; i < (int)sizeof (struct ltchars); i++) - printf_filtered ("0x%x ", ((char *)<c_inferior)[i]); + printf_filtered ("0x%x ", ((unsigned char *)<c_inferior)[i]); printf_filtered ("\n"); #endif @@ -472,6 +502,8 @@ try_writing_regs_command (arg, from_tty) void _initialize_inflow () { + int result; + add_info ("terminal", term_info, "Print inferior's saved terminal status."); @@ -486,23 +518,31 @@ Report which ones can be written."); inferior_pid = 0; - ioctl (0, TIOCGETP, &sg_ours); + /* Get all the current tty settings (including whether we have a tty at + all!). */ + tflags_ours = fcntl (0, F_GETFL, 0); + OOPSY ("fcntl F_GETFL"); /* Should always work */ + result = ioctl (0, TIOCGETP, &sg_ours); + if (result == 0) { + gdb_has_a_terminal = 1; + /* Get the rest of the tty settings, then... */ #if defined(TIOCGETC) && !defined(TIOCGETC_BROKEN) - ioctl (0, TIOCGETC, &tc_ours); + ioctl (0, TIOCGETC, &tc_ours); #endif #if defined(TIOCGLTC) && !defined(TIOCGLTC_BROKEN) - ioctl (0, TIOCGLTC, <c_ours); + ioctl (0, TIOCGLTC, <c_ours); #endif #ifdef TIOCLGET - ioctl (0, TIOCLGET, &lmode_ours); + ioctl (0, TIOCLGET, &lmode_ours); #endif - #ifdef TIOCGPGRP - ioctl (0, TIOCGPGRP, &pgrp_ours); + ioctl (0, TIOCGPGRP, &pgrp_ours); #endif /* TIOCGPGRP */ + } else { + gdb_has_a_terminal = 0; + } terminal_is_ours = 1; } - diff --git a/gdb/valops.c b/gdb/valops.c index 45cca2e2eeb..0becbf4e331 100644 --- a/gdb/valops.c +++ b/gdb/valops.c @@ -69,7 +69,7 @@ value_cast (type, arg2) offset the pointer rather than just change its type. */ struct type *t1 = TYPE_TARGET_TYPE (type); struct type *t2 = TYPE_TARGET_TYPE (VALUE_TYPE (arg2)); - if (TYPE_CODE (t1) == TYPE_CODE_STRUCT + if ( TYPE_CODE (t1) == TYPE_CODE_STRUCT && TYPE_CODE (t2) == TYPE_CODE_STRUCT && TYPE_NAME (t1) != 0) /* if name unknown, can't have supercl */ { @@ -565,10 +565,11 @@ value_arg_coerce (arg) type = VALUE_TYPE (arg); if (TYPE_CODE (type) == TYPE_CODE_INT - && TYPE_LENGTH (type) < sizeof (int)) + && TYPE_LENGTH (type) < TYPE_LENGTH (builtin_type_int)) return value_cast (builtin_type_int, arg); - if (type == builtin_type_float) + if (TYPE_CODE (type) == TYPE_CODE_FLT + && TYPE_LENGTH (type) < TYPE_LENGTH (builtin_type_double)) return value_cast (builtin_type_double, arg); return arg; @@ -949,7 +950,7 @@ value_string (ptr, len) /* Helper function used by value_struct_elt to recurse through baseclasses. Look for a field NAME in ARG1. Adjust the address of ARG1 by OFFSET bytes, - and treat the result as having type TYPE. + and search in it assuming it has (class) type TYPE. If found, return value, else return NULL. If LOOKING_FOR_BASECLASS, then instead of looking for struct fields, @@ -1019,7 +1020,7 @@ search_struct_field (name, arg1, offset, type, looking_for_baseclass) /* Helper function used by value_struct_elt to recurse through baseclasses. Look for a field NAME in ARG1. Adjust the address of ARG1 by OFFSET bytes, - and treat the result as having type TYPE. + and search in it assuming it has (class) type TYPE. If found, return value, else return NULL. */ static value @@ -1127,7 +1128,7 @@ value_struct_elt (argp, args, name, static_memfuncp, err) if (TYPE_CODE (t) == TYPE_CODE_MEMBER) error ("not implemented: member type in value_struct_elt"); - if (TYPE_CODE (t) != TYPE_CODE_STRUCT + if ( TYPE_CODE (t) != TYPE_CODE_STRUCT && TYPE_CODE (t) != TYPE_CODE_UNION) error ("Attempt to extract a component of a value that is not a %s.", err); @@ -1275,7 +1276,7 @@ check_field (arg1, name) if (TYPE_CODE (t) == TYPE_CODE_MEMBER) error ("not implemented: member type in check_field"); - if (TYPE_CODE (t) != TYPE_CODE_STRUCT + if ( TYPE_CODE (t) != TYPE_CODE_STRUCT && TYPE_CODE (t) != TYPE_CODE_UNION) error ("Internal error: `this' is not an aggregate"); @@ -1283,10 +1284,11 @@ check_field (arg1, name) } /* C++: Given an aggregate type DOMAIN, and a member name NAME, - return the address of this member as a pointer to member + return the address of this member as a "pointer to member" type. If INTYPE is non-null, then it will be the type of the member we are looking for. This will help us resolve - pointers to member functions. */ + "pointers to member functions". This function is only used + to resolve user expressions of the form "&class::member". */ value value_struct_elt_for_address (domain, intype, name) @@ -1299,7 +1301,7 @@ value_struct_elt_for_address (domain, intype, name) struct type *baseclass; - if (TYPE_CODE (t) != TYPE_CODE_STRUCT + if ( TYPE_CODE (t) != TYPE_CODE_STRUCT && TYPE_CODE (t) != TYPE_CODE_UNION) error ("Internal error: non-aggregate type to value_struct_elt_for_address"); @@ -1310,6 +1312,7 @@ value_struct_elt_for_address (domain, intype, name) for (i = TYPE_NFIELDS (t) - 1; i >= TYPE_N_BASECLASSES (t); i--) { char *t_field_name = TYPE_FIELD_NAME (t, i); + if (t_field_name && !strcmp (t_field_name, name)) { if (TYPE_FIELD_STATIC (t, i)) @@ -1317,7 +1320,10 @@ value_struct_elt_for_address (domain, intype, name) char *phys_name = TYPE_FIELD_STATIC_PHYSNAME (t, i); struct symbol *sym = lookup_symbol (phys_name, 0, VAR_NAMESPACE, 0, NULL); - if (! sym) error ("Internal error: could not find physical static variable named %s", phys_name); + if (! sym) + error ( + "Internal error: could not find physical static variable named %s", + phys_name); return value_from_longest ( lookup_pointer_type (TYPE_FIELD_TYPE (t, i)), (LONGEST)SYMBOL_BLOCK_VALUE (sym)); @@ -1345,7 +1351,7 @@ value_struct_elt_for_address (domain, intype, name) /* Destructors are a special case. */ if (destructor_name_p (name, t)) { - error ("pointers to destructors not implemented yet"); + error ("member pointers to destructors not implemented yet"); } /* Perform all necessary dereferencing. */ @@ -1374,7 +1380,8 @@ value_struct_elt_for_address (domain, intype, name) else j = 0; - check_stub_method (t, i, j); + if (TYPE_FLAGS (TYPE_FN_FIELD_TYPE (f, j)) & TYPE_FLAG_STUB) + check_stub_method (t, i, j); if (TYPE_FN_FIELD_VIRTUAL_P (f, j)) { return value_from_longest ( @@ -1388,7 +1395,9 @@ value_struct_elt_for_address (domain, intype, name) struct symbol *s = lookup_symbol (TYPE_FN_FIELD_PHYSNAME (f, j), 0, VAR_NAMESPACE, 0, NULL); v = locate_var_value (s, 0); - VALUE_TYPE (v) = lookup_pointer_type (lookup_member_type (TYPE_FN_FIELD_TYPE (f, j), baseclass)); + VALUE_TYPE (v) = lookup_pointer_type ( + lookup_member_type (TYPE_FN_FIELD_TYPE (f, j), + baseclass)); return v; } } diff --git a/gdb/valprint.c b/gdb/valprint.c index 96808501b12..139679ac418 100644 --- a/gdb/valprint.c +++ b/gdb/valprint.c @@ -671,11 +671,7 @@ val_print (type, valaddr, address, stream, format, switch (TYPE_CODE (type)) { case TYPE_CODE_ARRAY: - /* FIXME: TYPE_LENGTH (type) is unsigned and therefore always - >= 0. Is "> 0" meant? I'm not sure what an "array of - unspecified length" (mentioned in the comment for the else-part - of this if) is. */ - if (TYPE_LENGTH (type) >= 0 + if (TYPE_LENGTH (type) > 0 && TYPE_LENGTH (TYPE_TARGET_TYPE (type)) > 0) { elttype = TYPE_TARGET_TYPE (type); @@ -772,7 +768,7 @@ val_print (type, valaddr, address, stream, format, addr = unpack_pointer (lookup_pointer_type (builtin_type_void), valaddr); - if (addr < 128) + if (addr < 128) /* FIXME! What is this 128? */ { len = TYPE_NFN_FIELDS (domain); for (i = 0; i < len; i++) @@ -854,7 +850,7 @@ val_print (type, valaddr, address, stream, format, /* Somehow pointing into a field. */ i -= 1; extra = (val - TYPE_FIELD_BITPOS (domain, i)); - if (extra & 0x3) + if (extra & 0x7) bits = 1; else extra >>= 3; @@ -1463,6 +1459,7 @@ type_print_varspec_prefix (type, stream, show, passed_a_ptr) 0); if (passed_a_ptr) fprintf_filtered (stream, "("); + break; case TYPE_CODE_UNDEF: case TYPE_CODE_STRUCT: -- 2.30.2