Fix things pointed up by Fred Fish's test suite; see ChangeLog.

This commit is contained in:
John Gilmore 1991-12-05 11:56:20 +00:00
parent 98618bf78a
commit 2a5ec41d88
6 changed files with 276 additions and 140 deletions

View file

@ -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) Wed Dec 4 21:05:30 1991 Fred Fish (fnf at cygnus.com)
* dwarfread (enum_type): Arrange for the order of enumeration * dwarfread (enum_type): Arrange for the order of enumeration

View file

@ -1,5 +1,5 @@
/* Build symbol tables in GDB's internal format. /* 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. 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 #define BELIEVE_PCC_PROMOTION 0
#endif #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. */ /* Make a list of forward references which haven't been defined. */
static struct type **undef_types; static struct type **undef_types;
static int undef_types_allocated, undef_types_length; static int undef_types_allocated, undef_types_length;
@ -1117,6 +1125,14 @@ define_symbol (valu, string, desc, type)
strlen (SYMBOL_NAME (sym))); 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); type_read = read_type (&p);
if ((deftype == 'F' || deftype == 'f') if ((deftype == 'F' || deftype == 'f')
@ -1230,16 +1246,18 @@ define_symbol (valu, string, desc, type)
up). I made this code adapt so that it will offset the symbol up). I made this code adapt so that it will offset the symbol
if it was pointing at an int-aligned location and not 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 otherwise. This way you can use the same gdb for 4.0.x and
4.1 systems. */ 4.1 systems.
if (0 == SYMBOL_VALUE (sym) % sizeof (int)) If the parameter is shorter than an int, and is integral
{ (e.g. char, short, or unsigned equivalent), and is claimed to
if (SYMBOL_TYPE (sym) == builtin_type_char be passed on an integer boundary, don't believe it! Offset the
|| SYMBOL_TYPE (sym) == builtin_type_unsigned_char) parameter's address to the tail-end of that integer. */
SYMBOL_VALUE (sym) += 3;
else if (SYMBOL_TYPE (sym) == builtin_type_short if (TYPE_LENGTH (SYMBOL_TYPE (sym)) < TYPE_LENGTH (builtin_type_int)
|| SYMBOL_TYPE (sym) == builtin_type_unsigned_short) && TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_INT
SYMBOL_VALUE (sym) += 2; && 0 == SYMBOL_VALUE (sym) % TYPE_LENGTH (builtin_type_int)) {
SYMBOL_VALUE (sym) += TYPE_LENGTH (builtin_type_int)
- TYPE_LENGTH (SYMBOL_TYPE (sym));
} }
break; break;
@ -1247,12 +1265,12 @@ define_symbol (valu, string, desc, type)
/* If PCC says a parameter is a short or a char, /* If PCC says a parameter is a short or a char,
it is really an int. */ it is really an int. */
if (SYMBOL_TYPE (sym) == builtin_type_char if (TYPE_LENGTH (SYMBOL_TYPE (sym)) < TYPE_LENGTH (builtin_type_int)
|| SYMBOL_TYPE (sym) == builtin_type_short) && TYPE_CODE (SYMBOL_TYPE (sym) == TYPE_CODE_INT) {
SYMBOL_TYPE (sym) = builtin_type_int; SYMBOL_TYPE (sym) = TYPE_UNSIGNED (SYMBOL_TYPE (sym))?
else if (SYMBOL_TYPE (sym) == builtin_type_unsigned_char builtin_type_unsigned_int:
|| SYMBOL_TYPE (sym) == builtin_type_unsigned_short) builtin_type_int;
SYMBOL_TYPE (sym) = builtin_type_unsigned_int; }
break; break;
#endif /* no BELIEVE_PCC_PROMOTION_TYPE. */ #endif /* no BELIEVE_PCC_PROMOTION_TYPE. */
@ -1386,14 +1404,25 @@ add_undefined_type (type)
undef_types[undef_types_length++] = type; undef_types[undef_types_length++] = type;
} }
/* Add here something to go through each undefined type, see if it's /* Go through each undefined type, see if it's still undefined, and fix it
still undefined, and do a full lookup if so. */ 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 static void
cleanup_undefined_types () cleanup_undefined_types ()
{ {
struct type **type; struct type **type;
for (type = undef_types; type < undef_types + undef_types_length; type++) for (type = undef_types; type < undef_types + undef_types_length; type++) {
switch (TYPE_CODE (*type)) {
case TYPE_CODE_STRUCT:
case TYPE_CODE_UNION:
{ {
/* Reasonable test to see if it's been defined since. */ /* Reasonable test to see if it's been defined since. */
if (TYPE_NFIELDS (*type) == 0) if (TYPE_NFIELDS (*type) == 0)
@ -1425,6 +1454,36 @@ cleanup_undefined_types ()
/* It has been defined; don't mark it as a stub. */ /* It has been defined; don't mark it as a stub. */
TYPE_FLAGS (*type) &= ~TYPE_FLAG_STUB; TYPE_FLAGS (*type) &= ~TYPE_FLAG_STUB;
} }
break;
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));
}
break;
default:
badtype:
error ("GDB internal error. cleanup_undefined_types with bad type.");
break;
}
}
undef_types_length = 0; undef_types_length = 0;
} }
@ -2579,6 +2638,11 @@ read_array_type (pp, type)
sizeof (struct field)); sizeof (struct field));
TYPE_FIELD_TYPE (type, 0) = range_type; 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; return type;
} }
@ -2881,7 +2945,9 @@ read_range_type (pp, typenums)
and they give no way to distinguish between double and single-complex! 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! 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 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) if (n3 == 0 && n2 > 0)
{ {
@ -2894,11 +2960,15 @@ read_range_type (pp, typenums)
else if (n2 == 0 && n3 == -1) else if (n2 == 0 && n3 == -1)
{ {
/* FIXME -- this confuses host and target type sizes. */ /* FIXME -- the only way to distinguish `unsigned int' from `unsigned
if (sizeof (int) == sizeof (long)) long' is to look at its name! */
return builtin_type_unsigned_int; if (
else 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; return builtin_type_unsigned_long;
else
return builtin_type_unsigned_int;
} }
/* Special case: char is defined (Who knows why) as a subrange of /* 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 /* Assumptions made here: Subrange of self is equivalent to subrange
of int. FIXME: Host and target type-sizes assumed the same. */ 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 else if (n2 == 0
&& (self_subrange || && (self_subrange ||
*dbx_lookup_type (rangenums) == builtin_type_int)) *dbx_lookup_type (rangenums) == builtin_type_int))
@ -2917,10 +2989,15 @@ read_range_type (pp, typenums)
if (n3 == - sizeof (long long)) if (n3 == - sizeof (long long))
return builtin_type_unsigned_long_long; return builtin_type_unsigned_long_long;
#endif #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) if (n3 == (unsigned int)~0L)
return builtin_type_unsigned_int; return builtin_type_unsigned_int;
if (n3 == (unsigned long)~0L)
return builtin_type_unsigned_long;
if (n3 == (unsigned short)~0L) if (n3 == (unsigned short)~0L)
return builtin_type_unsigned_short; return builtin_type_unsigned_short;
if (n3 == (unsigned char)~0L) if (n3 == (unsigned char)~0L)
@ -2933,10 +3010,13 @@ read_range_type (pp, typenums)
else if (n2 == -n3 -1) else if (n2 == -n3 -1)
{ {
/* a signed type */ /* 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) if (n3 == (1 << (8 * sizeof (int) - 1)) - 1)
return builtin_type_int; return builtin_type_int;
if (n3 == (1 << (8 * sizeof (long) - 1)) - 1)
return builtin_type_long;
if (n3 == (1 << (8 * sizeof (short) - 1)) - 1) if (n3 == (1 << (8 * sizeof (short) - 1)) - 1)
return builtin_type_short; return builtin_type_short;
if (n3 == (1 << (8 * sizeof (char) - 1)) - 1) 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, 0) = n2;
TYPE_FIELD_BITPOS (result_type, 1) = n3; 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)); TYPE_LENGTH (result_type) = TYPE_LENGTH (TYPE_TARGET_TYPE (result_type));
return result_type; return result_type;

View file

@ -977,10 +977,11 @@ parse_number (p, len, parsed_float, putithere)
} }
if (i >= base) if (i >= base)
return ERROR; /* Invalid digit in this 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 */ unsigned_p=1; /* Try something unsigned */
/* Don't do the range check if n==i and i==0, since that special /* If range checking enabled, portably test for unsigned overflow. */
case will give an overflow error. */
if(RANGE_CHECK && n!=0) if(RANGE_CHECK && n!=0)
{ {
if((unsigned_p && (unsigned)prevn >= (unsigned)n)) if((unsigned_p && (unsigned)prevn >= (unsigned)n))

View file

@ -38,6 +38,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <sys/dir.h> #include <sys/dir.h>
#include <signal.h> #include <signal.h>
extern char *strerror(); /* strings corresponding to errno */
extern struct target_ops child_ops; extern struct target_ops child_ops;
/* Nonzero if we are debugging an attached outside process /* Nonzero if we are debugging an attached outside process
@ -48,6 +50,9 @@ int attach_flag;
/* Record terminal status separately for debugger and inferior. */ /* 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_inferior;
static TERMINAL sg_ours; static TERMINAL sg_ours;
@ -82,15 +87,25 @@ static void (*sigint_ours) ();
static void (*sigquit_ours) (); static void (*sigquit_ours) ();
#endif /* TIOCGPGRP */ #endif /* TIOCGPGRP */
/* Copy of inferior_io_terminal when inferior was last started. */ /* The name of the tty (from the `tty' command) that we gave to the inferior
static char *inferior_thisrun_terminal; when it was last started. */
static void terminal_ours_1 (); static char *inferior_thisrun_terminal;
/* Nonzero if our terminal settings are in effect. /* Nonzero if our terminal settings are in effect.
Zero if the inferior's settings are in effect. */ Zero if the inferior's settings are in effect. */
static int terminal_is_ours; 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, /* Initialize the terminal settings we record for the inferior,
before we actually run the inferior. */ before we actually run the inferior. */
@ -125,24 +140,32 @@ terminal_init_inferior ()
void void
terminal_inferior () 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); result = fcntl (0, F_SETFL, tflags_inferior);
fcntl (0, F_SETFL, tflags_inferior); result = fcntl (0, F_SETFL, tflags_inferior);
ioctl (0, TIOCSETN, &sg_inferior); OOPSY ("fcntl F_SETFL");
result = ioctl (0, TIOCSETN, &sg_inferior);
OOPSY ("ioctl TIOCSETN");
#if defined(TIOCGETC) && !defined(TIOCGETC_BROKEN) #if defined(TIOCGETC) && !defined(TIOCGETC_BROKEN)
ioctl (0, TIOCSETC, &tc_inferior); result = ioctl (0, TIOCSETC, &tc_inferior);
OOPSY ("ioctl TIOCSETC");
#endif #endif
#if defined(TIOCGLTC) && !defined(TIOCGLTC_BROKEN) #if defined(TIOCGLTC) && !defined(TIOCGLTC_BROKEN)
ioctl (0, TIOCSLTC, &ltc_inferior); result = ioctl (0, TIOCSLTC, &ltc_inferior);
OOPSY ("ioctl TIOCSLTC");
#endif #endif
#ifdef TIOCLGET #ifdef TIOCLGET
ioctl (0, TIOCLSET, &lmode_inferior); result = ioctl (0, TIOCLSET, &lmode_inferior);
OOPSY ("ioctl TIOCLSET");
#endif #endif
#ifdef TIOCGPGRP #ifdef TIOCGPGRP
ioctl (0, TIOCSPGRP, &pgrp_inferior); result = ioctl (0, TIOCSPGRP, &pgrp_inferior);
OOPSY ("ioctl TIOCSPGRP");
#else #else
sigint_ours = (void (*) ()) signal (SIGINT, SIG_IGN); sigint_ours = (void (*) ()) signal (SIGINT, SIG_IGN);
sigquit_ours = (void (*) ()) signal (SIGQUIT, SIG_IGN); sigquit_ours = (void (*) ()) signal (SIGQUIT, SIG_IGN);
@ -179,17 +202,17 @@ static void
terminal_ours_1 (output_only) terminal_ours_1 (output_only)
int output_only; int output_only;
{ {
int result;
#ifdef TIOCGPGRP #ifdef TIOCGPGRP
/* Ignore this signal since it will happen when we try to set the pgrp. */ /* Ignore this signal since it will happen when we try to set the pgrp. */
void (*osigttou) (); void (*osigttou) ();
#endif /* TIOCGPGRP */ #endif /* TIOCGPGRP */
/* The check for inferior_thisrun_terminal had been commented out /* Checking inferior_thisrun_terminal is necessary so that
when the call to ioctl (TIOCNOTTY) was commented out.
Checking inferior_thisrun_terminal is necessary so that
if GDB is running in the background, it won't block trying if GDB is running in the background, it won't block trying
to do the ioctl()'s below. */ to do the ioctl()'s below. Checking gdb_has_a_terminal
if (inferior_thisrun_terminal != 0) avoids attempting all the ioctl's when running in batch. */
if (inferior_thisrun_terminal != 0 || gdb_has_a_terminal == 0)
return; return;
if (!terminal_is_ours) if (!terminal_is_ours)
@ -199,8 +222,8 @@ terminal_ours_1 (output_only)
#ifdef TIOCGPGRP #ifdef TIOCGPGRP
osigttou = (void (*) ()) signal (SIGTTOU, SIG_IGN); osigttou = (void (*) ()) signal (SIGTTOU, SIG_IGN);
ioctl (0, TIOCGPGRP, &pgrp_inferior); result = ioctl (0, TIOCGPGRP, &pgrp_inferior);
ioctl (0, TIOCSPGRP, &pgrp_ours); result = ioctl (0, TIOCSPGRP, &pgrp_ours);
signal (SIGTTOU, osigttou); signal (SIGTTOU, osigttou);
#else #else
@ -209,16 +232,16 @@ terminal_ours_1 (output_only)
#endif /* TIOCGPGRP */ #endif /* TIOCGPGRP */
tflags_inferior = fcntl (0, F_GETFL, 0); tflags_inferior = fcntl (0, F_GETFL, 0);
ioctl (0, TIOCGETP, &sg_inferior); result = ioctl (0, TIOCGETP, &sg_inferior);
#if defined(TIOCGETC) && !defined(TIOCGETC_BROKEN) #if defined(TIOCGETC) && !defined(TIOCGETC_BROKEN)
ioctl (0, TIOCGETC, &tc_inferior); result = ioctl (0, TIOCGETC, &tc_inferior);
#endif #endif
#if defined(TIOCGLTC) && !defined(TIOCGLTC_BROKEN) #if defined(TIOCGLTC) && !defined(TIOCGLTC_BROKEN)
ioctl (0, TIOCGLTC, &ltc_inferior); result = ioctl (0, TIOCGLTC, &ltc_inferior);
#endif #endif
#ifdef TIOCLGET #ifdef TIOCLGET
ioctl (0, TIOCLGET, &lmode_inferior); result = ioctl (0, TIOCLGET, &lmode_inferior);
#endif #endif
} }
@ -232,18 +255,18 @@ terminal_ours_1 (output_only)
sg_ours.sg_flags |= (RAW | CBREAK) & sg_inferior.sg_flags; sg_ours.sg_flags |= (RAW | CBREAK) & sg_inferior.sg_flags;
#endif /* not HAVE_TERMIO */ #endif /* not HAVE_TERMIO */
fcntl (0, F_SETFL, tflags_ours); result = fcntl (0, F_SETFL, tflags_ours);
fcntl (0, F_SETFL, tflags_ours); result = fcntl (0, F_SETFL, tflags_ours);
ioctl (0, TIOCSETN, &sg_ours); result = ioctl (0, TIOCSETN, &sg_ours);
#if defined(TIOCGETC) && !defined(TIOCGETC_BROKEN) #if defined(TIOCGETC) && !defined(TIOCGETC_BROKEN)
ioctl (0, TIOCSETC, &tc_ours); result = ioctl (0, TIOCSETC, &tc_ours);
#endif #endif
#if defined(TIOCGLTC) && !defined(TIOCGLTC_BROKEN) #if defined(TIOCGLTC) && !defined(TIOCGLTC_BROKEN)
ioctl (0, TIOCSLTC, &ltc_ours); result = ioctl (0, TIOCSLTC, &ltc_ours);
#endif #endif
#ifdef TIOCLGET #ifdef TIOCLGET
ioctl (0, TIOCLSET, &lmode_ours); result = ioctl (0, TIOCLSET, &lmode_ours);
#endif #endif
#ifdef HAVE_TERMIO #ifdef HAVE_TERMIO
@ -270,12 +293,20 @@ child_terminal_info (args, from_tty)
{ {
register int i; 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 ("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 #ifdef HAVE_TERMIO
printf_filtered ("fcntl flags = 0x%x, c_iflag = 0x%x, c_oflag = 0x%x,\n", printf_filtered (c_iflag = 0x%x, c_oflag = 0x%x,\n",
tflags_inferior, sg_inferior.c_iflag, sg_inferior.c_oflag); sg_inferior.c_iflag, sg_inferior.c_oflag);
printf_filtered ("c_cflag = 0x%x, c_lflag = 0x%x, c_line = 0x%x.\n", 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); sg_inferior.c_cflag, sg_inferior.c_lflag, sg_inferior.c_line);
printf_filtered ("c_cc: "); printf_filtered ("c_cc: ");
@ -285,22 +316,21 @@ child_terminal_info (args, from_tty)
#else /* not HAVE_TERMIO */ #else /* not HAVE_TERMIO */
printf_filtered ("fcntl flags = 0x%x, sgttyb.sg_flags = 0x%x, owner pid = %d.\n", printf_filtered ("sgttyb.sg_flags = 0x%x.\n", sg_inferior.sg_flags);
tflags_inferior, sg_inferior.sg_flags, pgrp_inferior);
#endif /* not HAVE_TERMIO */ #endif /* not HAVE_TERMIO */
#if defined(TIOCGETC) && !defined(TIOCGETC_BROKEN) #if defined(TIOCGETC) && !defined(TIOCGETC_BROKEN)
printf_filtered ("tchars: "); printf_filtered ("tchars: ");
for (i = 0; i < (int)sizeof (struct tchars); i++) 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"); printf_filtered ("\n");
#endif #endif
#if defined(TIOCGLTC) && !defined(TIOCGLTC_BROKEN) #if defined(TIOCGLTC) && !defined(TIOCGLTC_BROKEN)
printf_filtered ("ltchars: "); printf_filtered ("ltchars: ");
for (i = 0; i < (int)sizeof (struct ltchars); i++) for (i = 0; i < (int)sizeof (struct ltchars); i++)
printf_filtered ("0x%x ", ((char *)&ltc_inferior)[i]); printf_filtered ("0x%x ", ((unsigned char *)&ltc_inferior)[i]);
printf_filtered ("\n"); printf_filtered ("\n");
#endif #endif
@ -472,6 +502,8 @@ try_writing_regs_command (arg, from_tty)
void void
_initialize_inflow () _initialize_inflow ()
{ {
int result;
add_info ("terminal", term_info, add_info ("terminal", term_info,
"Print inferior's saved terminal status."); "Print inferior's saved terminal status.");
@ -486,9 +518,16 @@ Report which ones can be written.");
inferior_pid = 0; inferior_pid = 0;
ioctl (0, TIOCGETP, &sg_ours); /* Get all the current tty settings (including whether we have a tty at
tflags_ours = fcntl (0, F_GETFL, 0); 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) #if defined(TIOCGETC) && !defined(TIOCGETC_BROKEN)
ioctl (0, TIOCGETC, &tc_ours); ioctl (0, TIOCGETC, &tc_ours);
#endif #endif
@ -498,11 +537,12 @@ Report which ones can be written.");
#ifdef TIOCLGET #ifdef TIOCLGET
ioctl (0, TIOCLGET, &lmode_ours); ioctl (0, TIOCLGET, &lmode_ours);
#endif #endif
#ifdef TIOCGPGRP #ifdef TIOCGPGRP
ioctl (0, TIOCGPGRP, &pgrp_ours); ioctl (0, TIOCGPGRP, &pgrp_ours);
#endif /* TIOCGPGRP */ #endif /* TIOCGPGRP */
} else {
gdb_has_a_terminal = 0;
}
terminal_is_ours = 1; terminal_is_ours = 1;
} }

View file

@ -69,7 +69,7 @@ value_cast (type, arg2)
offset the pointer rather than just change its type. */ offset the pointer rather than just change its type. */
struct type *t1 = TYPE_TARGET_TYPE (type); struct type *t1 = TYPE_TARGET_TYPE (type);
struct type *t2 = TYPE_TARGET_TYPE (VALUE_TYPE (arg2)); 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_CODE (t2) == TYPE_CODE_STRUCT
&& TYPE_NAME (t1) != 0) /* if name unknown, can't have supercl */ && TYPE_NAME (t1) != 0) /* if name unknown, can't have supercl */
{ {
@ -565,10 +565,11 @@ value_arg_coerce (arg)
type = VALUE_TYPE (arg); type = VALUE_TYPE (arg);
if (TYPE_CODE (type) == TYPE_CODE_INT 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); 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 value_cast (builtin_type_double, arg);
return arg; return arg;
@ -949,7 +950,7 @@ value_string (ptr, len)
/* Helper function used by value_struct_elt to recurse through baseclasses. /* 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, 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 found, return value, else return NULL.
If LOOKING_FOR_BASECLASS, then instead of looking for struct fields, 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. /* 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, 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 found, return value, else return NULL. */
static value static value
@ -1127,7 +1128,7 @@ value_struct_elt (argp, args, name, static_memfuncp, err)
if (TYPE_CODE (t) == TYPE_CODE_MEMBER) if (TYPE_CODE (t) == TYPE_CODE_MEMBER)
error ("not implemented: member type in value_struct_elt"); 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) && TYPE_CODE (t) != TYPE_CODE_UNION)
error ("Attempt to extract a component of a value that is not a %s.", err); 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) if (TYPE_CODE (t) == TYPE_CODE_MEMBER)
error ("not implemented: member type in check_field"); 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) && TYPE_CODE (t) != TYPE_CODE_UNION)
error ("Internal error: `this' is not an aggregate"); 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, /* 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 type. If INTYPE is non-null, then it will be the type
of the member we are looking for. This will help us resolve 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
value_struct_elt_for_address (domain, intype, name) value_struct_elt_for_address (domain, intype, name)
@ -1299,7 +1301,7 @@ value_struct_elt_for_address (domain, intype, name)
struct type *baseclass; struct type *baseclass;
if (TYPE_CODE (t) != TYPE_CODE_STRUCT if ( TYPE_CODE (t) != TYPE_CODE_STRUCT
&& TYPE_CODE (t) != TYPE_CODE_UNION) && TYPE_CODE (t) != TYPE_CODE_UNION)
error ("Internal error: non-aggregate type to value_struct_elt_for_address"); 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--) for (i = TYPE_NFIELDS (t) - 1; i >= TYPE_N_BASECLASSES (t); i--)
{ {
char *t_field_name = TYPE_FIELD_NAME (t, i); char *t_field_name = TYPE_FIELD_NAME (t, i);
if (t_field_name && !strcmp (t_field_name, name)) if (t_field_name && !strcmp (t_field_name, name))
{ {
if (TYPE_FIELD_STATIC (t, i)) 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); char *phys_name = TYPE_FIELD_STATIC_PHYSNAME (t, i);
struct symbol *sym = struct symbol *sym =
lookup_symbol (phys_name, 0, VAR_NAMESPACE, 0, NULL); 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 ( return value_from_longest (
lookup_pointer_type (TYPE_FIELD_TYPE (t, i)), lookup_pointer_type (TYPE_FIELD_TYPE (t, i)),
(LONGEST)SYMBOL_BLOCK_VALUE (sym)); (LONGEST)SYMBOL_BLOCK_VALUE (sym));
@ -1345,7 +1351,7 @@ value_struct_elt_for_address (domain, intype, name)
/* Destructors are a special case. */ /* Destructors are a special case. */
if (destructor_name_p (name, t)) 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. */ /* Perform all necessary dereferencing. */
@ -1374,6 +1380,7 @@ value_struct_elt_for_address (domain, intype, name)
else else
j = 0; j = 0;
if (TYPE_FLAGS (TYPE_FN_FIELD_TYPE (f, j)) & TYPE_FLAG_STUB)
check_stub_method (t, i, j); check_stub_method (t, i, j);
if (TYPE_FN_FIELD_VIRTUAL_P (f, j)) if (TYPE_FN_FIELD_VIRTUAL_P (f, j))
{ {
@ -1388,7 +1395,9 @@ value_struct_elt_for_address (domain, intype, name)
struct symbol *s = lookup_symbol (TYPE_FN_FIELD_PHYSNAME (f, j), struct symbol *s = lookup_symbol (TYPE_FN_FIELD_PHYSNAME (f, j),
0, VAR_NAMESPACE, 0, NULL); 0, VAR_NAMESPACE, 0, NULL);
v = locate_var_value (s, 0); 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; return v;
} }
} }

View file

@ -671,11 +671,7 @@ val_print (type, valaddr, address, stream, format,
switch (TYPE_CODE (type)) switch (TYPE_CODE (type))
{ {
case TYPE_CODE_ARRAY: case TYPE_CODE_ARRAY:
/* FIXME: TYPE_LENGTH (type) is unsigned and therefore always if (TYPE_LENGTH (type) > 0
>= 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
&& TYPE_LENGTH (TYPE_TARGET_TYPE (type)) > 0) && TYPE_LENGTH (TYPE_TARGET_TYPE (type)) > 0)
{ {
elttype = TYPE_TARGET_TYPE (type); 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), addr = unpack_pointer (lookup_pointer_type (builtin_type_void),
valaddr); valaddr);
if (addr < 128) if (addr < 128) /* FIXME! What is this 128? */
{ {
len = TYPE_NFN_FIELDS (domain); len = TYPE_NFN_FIELDS (domain);
for (i = 0; i < len; i++) for (i = 0; i < len; i++)
@ -854,7 +850,7 @@ val_print (type, valaddr, address, stream, format,
/* Somehow pointing into a field. */ /* Somehow pointing into a field. */
i -= 1; i -= 1;
extra = (val - TYPE_FIELD_BITPOS (domain, i)); extra = (val - TYPE_FIELD_BITPOS (domain, i));
if (extra & 0x3) if (extra & 0x7)
bits = 1; bits = 1;
else else
extra >>= 3; extra >>= 3;
@ -1463,6 +1459,7 @@ type_print_varspec_prefix (type, stream, show, passed_a_ptr)
0); 0);
if (passed_a_ptr) if (passed_a_ptr)
fprintf_filtered (stream, "("); fprintf_filtered (stream, "(");
break;
case TYPE_CODE_UNDEF: case TYPE_CODE_UNDEF:
case TYPE_CODE_STRUCT: case TYPE_CODE_STRUCT: