mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-09-12 09:39:30 +08:00
* defs.h (CC_HAS_LONG_LONG): Set up to define CC_HAS_LONG_LONG
when compiling with gcc, but disable it for now. See comment. * defs.h (LONGEST): Define as either "long" or "long long" based on CC_HAS_LONG_LONG. * defs.h (longest_to_int): Use CC_HAS_LONG_LONG to control how longest_to_int is defined. * c-valprint.c (c_val_print): Call print_longest. * expprint.c (dump_expression): Use PRINTF_HAS_LONG_LONG instead of LONG_LONG. * {printcmd.c, gdbtypes.h} (LONG_LONG): Replace usages with CC_HAS_LONG_LONG. * printcmd.c (print_scalar_formatted): Call print_longest and let it figure out what to do for PRINTF_HAS_LONG_LONG. * typeprint.c (print_type_scalar): Call print_longest and let it figure out what to do for PRINTF_HAS_LONG_LONG. * valprint.c (val_print_type_code_int): Call print_longest and let it figure out what to do for PRINTF_HAS_LONG_LONG. * stabsread.c (LONG_LONG): Replace usages with CC_HAS_LONG_LONG. * value.h (struct value): Replace usage of LONG_LONG with CC_HAS_LONG_LONG. * value.h (print_longest): Add prototype. * values.c (LONG_LONG): Replace usages with CC_HAS_LONG_LONG. * values.c (unpack_double): Collapse code that was unnecessarily dependent on CC_HAS_LONG_LONG. Use LONGEST instead of direct types. * values.c (value_from_longest): Remove dependency on CC_HAS_LONG_LONG and just use LONGEST. * solib.c (solib_map_sections): Use bfd_get_filename to access filename field. * solib.c (clear_solib): Save filename and free it later, after bfd_close, since bfd_close may reference it. Use bfd_get_filename to access the field. * config/convex/xm-convex.h (LONG_LONG): Replace with CC_HAS_LONG_LONG. Add define for PRINTF_HAS_LONG_LONG. * doc/gdbint.texinfo (LONG_LONG): Replace with CC_HAS_LONG_LONG. Add PRINTF_HAS_LONG_LONG references.
This commit is contained in:
@ -1,3 +1,41 @@
|
|||||||
|
Thu Apr 29 00:03:59 1993 Fred Fish (fnf@cygnus.com)
|
||||||
|
|
||||||
|
* defs.h (CC_HAS_LONG_LONG): Set up to define CC_HAS_LONG_LONG
|
||||||
|
when compiling with gcc, but disable it for now. See comment.
|
||||||
|
* defs.h (LONGEST): Define as either "long" or "long long"
|
||||||
|
based on CC_HAS_LONG_LONG.
|
||||||
|
* defs.h (longest_to_int): Use CC_HAS_LONG_LONG to control
|
||||||
|
how longest_to_int is defined.
|
||||||
|
* c-valprint.c (c_val_print): Call print_longest.
|
||||||
|
* expprint.c (dump_expression): Use PRINTF_HAS_LONG_LONG
|
||||||
|
instead of LONG_LONG.
|
||||||
|
* {printcmd.c, gdbtypes.h} (LONG_LONG): Replace usages with
|
||||||
|
CC_HAS_LONG_LONG.
|
||||||
|
* printcmd.c (print_scalar_formatted): Call print_longest
|
||||||
|
and let it figure out what to do for PRINTF_HAS_LONG_LONG.
|
||||||
|
* typeprint.c (print_type_scalar): Call print_longest and let
|
||||||
|
it figure out what to do for PRINTF_HAS_LONG_LONG.
|
||||||
|
* valprint.c (val_print_type_code_int): Call print_longest
|
||||||
|
and let it figure out what to do for PRINTF_HAS_LONG_LONG.
|
||||||
|
* stabsread.c (LONG_LONG): Replace usages with CC_HAS_LONG_LONG.
|
||||||
|
* value.h (struct value): Replace usage of LONG_LONG with
|
||||||
|
CC_HAS_LONG_LONG.
|
||||||
|
* value.h (print_longest): Add prototype.
|
||||||
|
* values.c (LONG_LONG): Replace usages with CC_HAS_LONG_LONG.
|
||||||
|
* values.c (unpack_double): Collapse code that was unnecessarily
|
||||||
|
dependent on CC_HAS_LONG_LONG. Use LONGEST instead of direct types.
|
||||||
|
* values.c (value_from_longest): Remove dependency on
|
||||||
|
CC_HAS_LONG_LONG and just use LONGEST.
|
||||||
|
* solib.c (solib_map_sections): Use bfd_get_filename
|
||||||
|
to access filename field.
|
||||||
|
* solib.c (clear_solib): Save filename and free it later, after
|
||||||
|
bfd_close, since bfd_close may reference it. Use bfd_get_filename
|
||||||
|
to access the field.
|
||||||
|
* config/convex/xm-convex.h (LONG_LONG): Replace with
|
||||||
|
CC_HAS_LONG_LONG. Add define for PRINTF_HAS_LONG_LONG.
|
||||||
|
* doc/gdbint.texinfo (LONG_LONG): Replace with CC_HAS_LONG_LONG.
|
||||||
|
Add PRINTF_HAS_LONG_LONG references.
|
||||||
|
|
||||||
Wed Apr 28 06:11:38 1993 Jim Kingdon (kingdon@cygnus.com)
|
Wed Apr 28 06:11:38 1993 Jim Kingdon (kingdon@cygnus.com)
|
||||||
|
|
||||||
* inflow.c (kill_command), infcmd.c (attach_command),
|
* inflow.c (kill_command), infcmd.c (attach_command),
|
||||||
|
@ -304,11 +304,7 @@ c_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
#ifdef LONG_LONG
|
print_longest (stream, 'd', 0, val);
|
||||||
fprintf_filtered (stream, "%lld", val);
|
|
||||||
#else
|
|
||||||
fprintf_filtered (stream, "%ld", val);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
61
gdb/defs.h
61
gdb/defs.h
@ -506,29 +506,48 @@ enum val_prettyprint
|
|||||||
#define TARGET_PTR_BIT TARGET_INT_BIT
|
#define TARGET_PTR_BIT TARGET_INT_BIT
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Convert a LONGEST to an int. This is used in contexts (e.g. number
|
/* Default to support for "long long" if the host compiler being used is gcc.
|
||||||
of arguments to a function, number in a value history, register
|
Config files must define CC_HAS_LONG_LONG to use other host compilers
|
||||||
number, etc.) where the value must not be larger than can fit
|
that are capable of supporting "long long", and to cause gdb to use that
|
||||||
in an int. */
|
support. Not defining CC_HAS_LONG_LONG will suppress use of "long long"
|
||||||
#if !defined (longest_to_int)
|
regardless of what compiler is used.
|
||||||
#if defined (LONG_LONG)
|
|
||||||
#define longest_to_int(x) (((x) > INT_MAX || (x) < INT_MIN) \
|
|
||||||
? (error ("Value out of range."),0) : (int) (x))
|
|
||||||
#else /* No LONG_LONG. */
|
|
||||||
/* Assume sizeof (int) == sizeof (long). */
|
|
||||||
#define longest_to_int(x) ((int) (x))
|
|
||||||
#endif /* No LONG_LONG. */
|
|
||||||
#endif /* No longest_to_int. */
|
|
||||||
|
|
||||||
/* This should not be a typedef, because "unsigned LONGEST" needs
|
FIXME: For now, automatic selection of "long long" as the default when
|
||||||
to work. LONG_LONG is defined if the host has "long long". */
|
gcc is used is disabled, pending further testing. Concerns include the
|
||||||
|
impact on gdb performance and the universality of bugfree long long
|
||||||
|
support on platforms that do have gcc. Compiling with FORCE_LONG_LONG
|
||||||
|
will select "long long" use for testing purposes. -fnf */
|
||||||
|
|
||||||
|
#ifndef CC_HAS_LONG_LONG
|
||||||
|
# if defined (__GNUC__) && defined (FORCE_LONG_LONG) /* See FIXME above */
|
||||||
|
# define CC_HAS_LONG_LONG 1
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* LONGEST should not be a typedef, because "unsigned LONGEST" needs to work.
|
||||||
|
CC_HAS_LONG_LONG is defined if the host compiler supports "long long"
|
||||||
|
variables and we wish to make use of that support. */
|
||||||
|
|
||||||
#ifndef LONGEST
|
#ifndef LONGEST
|
||||||
# ifdef LONG_LONG
|
# ifdef CC_HAS_LONG_LONG
|
||||||
# define LONGEST long long
|
# define LONGEST long long
|
||||||
# else
|
# else
|
||||||
# define LONGEST long
|
# define LONGEST long
|
||||||
# endif
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Convert a LONGEST to an int. This is used in contexts (e.g. number of
|
||||||
|
arguments to a function, number in a value history, register number, etc.)
|
||||||
|
where the value must not be larger than can fit in an int. */
|
||||||
|
|
||||||
|
#ifndef longest_to_int
|
||||||
|
# ifdef CC_HAS_LONG_LONG
|
||||||
|
# define longest_to_int(x) (((x) > INT_MAX || (x) < INT_MIN) \
|
||||||
|
? (error ("Value out of range."),0) : (int) (x))
|
||||||
|
# else
|
||||||
|
/* Assume sizeof (int) == sizeof (long). */
|
||||||
|
# define longest_to_int(x) ((int) (x))
|
||||||
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* If we picked up a copy of CHAR_BIT from a configuration file
|
/* If we picked up a copy of CHAR_BIT from a configuration file
|
||||||
@ -653,7 +672,7 @@ strsignal PARAMS ((int));
|
|||||||
|
|
||||||
#ifndef PSIGNAL_IN_SIGNAL_H
|
#ifndef PSIGNAL_IN_SIGNAL_H
|
||||||
extern void
|
extern void
|
||||||
psignal PARAMS ((unsigned, char *));
|
psignal PARAMS ((unsigned, const char *));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* For now, we can't include <stdlib.h> because it conflicts with
|
/* For now, we can't include <stdlib.h> because it conflicts with
|
||||||
|
@ -511,19 +511,19 @@ extern struct type *builtin_type_chill_long;
|
|||||||
extern struct type *builtin_type_chill_ulong;
|
extern struct type *builtin_type_chill_ulong;
|
||||||
extern struct type *builtin_type_chill_real;
|
extern struct type *builtin_type_chill_real;
|
||||||
|
|
||||||
/* LONG_LONG is defined if the host has "long long". */
|
/* CC_HAS_LONG_LONG is defined if the host has "long long". */
|
||||||
|
|
||||||
#ifdef LONG_LONG
|
#ifdef CC_HAS_LONG_LONG
|
||||||
|
|
||||||
#define BUILTIN_TYPE_LONGEST builtin_type_long_long
|
#define BUILTIN_TYPE_LONGEST builtin_type_long_long
|
||||||
#define BUILTIN_TYPE_UNSIGNED_LONGEST builtin_type_unsigned_long_long
|
#define BUILTIN_TYPE_UNSIGNED_LONGEST builtin_type_unsigned_long_long
|
||||||
|
|
||||||
#else /* not LONG_LONG. */
|
#else /* not CC_HAS_LONG_LONG. */
|
||||||
|
|
||||||
#define BUILTIN_TYPE_LONGEST builtin_type_long
|
#define BUILTIN_TYPE_LONGEST builtin_type_long
|
||||||
#define BUILTIN_TYPE_UNSIGNED_LONGEST builtin_type_unsigned_long
|
#define BUILTIN_TYPE_UNSIGNED_LONGEST builtin_type_unsigned_long
|
||||||
|
|
||||||
#endif /* not LONG_LONG. */
|
#endif /* not CC_HAS_LONG_LONG. */
|
||||||
|
|
||||||
/* Maximum and minimum values of built-in types */
|
/* Maximum and minimum values of built-in types */
|
||||||
|
|
||||||
|
@ -2966,7 +2966,7 @@ read_range_type (pp, typenums, objfile)
|
|||||||
*dbx_lookup_type (rangenums) == lookup_fundamental_type (objfile, FT_INTEGER)))
|
*dbx_lookup_type (rangenums) == lookup_fundamental_type (objfile, FT_INTEGER)))
|
||||||
{
|
{
|
||||||
/* an unsigned type */
|
/* an unsigned type */
|
||||||
#ifdef LONG_LONG
|
#ifdef CC_HAS_LONG_LONG
|
||||||
if (n3 == - sizeof (long long))
|
if (n3 == - sizeof (long long))
|
||||||
return (lookup_fundamental_type (objfile, FT_UNSIGNED_LONG_LONG));
|
return (lookup_fundamental_type (objfile, FT_UNSIGNED_LONG_LONG));
|
||||||
#endif
|
#endif
|
||||||
@ -2984,7 +2984,7 @@ read_range_type (pp, typenums, objfile)
|
|||||||
if (n3 == (unsigned char)~0L)
|
if (n3 == (unsigned char)~0L)
|
||||||
return (lookup_fundamental_type (objfile, FT_UNSIGNED_CHAR));
|
return (lookup_fundamental_type (objfile, FT_UNSIGNED_CHAR));
|
||||||
}
|
}
|
||||||
#ifdef LONG_LONG
|
#ifdef CC_HAS_LONG_LONG
|
||||||
else if (n3 == 0 && n2 == -sizeof (long long))
|
else if (n3 == 0 && n2 == -sizeof (long long))
|
||||||
return (lookup_fundamental_type (objfile, FT_LONG_LONG));
|
return (lookup_fundamental_type (objfile, FT_LONG_LONG));
|
||||||
#endif
|
#endif
|
||||||
|
@ -198,20 +198,12 @@ print_type_scalar (type, val, stream)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
#ifdef LONG_LONG
|
print_longest (stream, 'd', 0, val);
|
||||||
fprintf_filtered (stream, "%lld", val);
|
|
||||||
#else
|
|
||||||
fprintf_filtered (stream, "%ld", val);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TYPE_CODE_INT:
|
case TYPE_CODE_INT:
|
||||||
#ifdef LONG_LONG
|
print_longest (stream, TYPE_UNSIGNED (type) ? 'u' : 'd', 0, val);
|
||||||
fprintf_filtered (stream, TYPE_UNSIGNED (type) ? "%llu" : "%lld", val);
|
|
||||||
#else
|
|
||||||
fprintf_filtered (stream, TYPE_UNSIGNED (type) ? "%u" : "%d", val);
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TYPE_CODE_CHAR:
|
case TYPE_CODE_CHAR:
|
||||||
|
247
gdb/valprint.c
247
gdb/valprint.c
@ -263,14 +263,8 @@ val_print_type_code_int (type, valaddr, stream)
|
|||||||
if (len <= sizeof (LONGEST))
|
if (len <= sizeof (LONGEST))
|
||||||
{
|
{
|
||||||
/* We can print it in decimal. */
|
/* We can print it in decimal. */
|
||||||
fprintf_filtered
|
print_longest (stream, 'u', 0,
|
||||||
(stream,
|
unpack_long (BUILTIN_TYPE_LONGEST, first_addr));
|
||||||
#if defined (LONG_LONG)
|
|
||||||
"%llu",
|
|
||||||
#else
|
|
||||||
"%lu",
|
|
||||||
#endif
|
|
||||||
unpack_long (BUILTIN_TYPE_LONGEST, first_addr));
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -291,17 +285,130 @@ val_print_type_code_int (type, valaddr, stream)
|
|||||||
#ifdef PRINT_TYPELESS_INTEGER
|
#ifdef PRINT_TYPELESS_INTEGER
|
||||||
PRINT_TYPELESS_INTEGER (stream, type, unpack_long (type, valaddr));
|
PRINT_TYPELESS_INTEGER (stream, type, unpack_long (type, valaddr));
|
||||||
#else
|
#else
|
||||||
fprintf_filtered (stream, TYPE_UNSIGNED (type) ?
|
print_longest (stream, TYPE_UNSIGNED (type) ? 'u' : 'd', 0,
|
||||||
#if defined (LONG_LONG)
|
unpack_long (type, valaddr));
|
||||||
"%llu" : "%lld",
|
|
||||||
#else
|
|
||||||
"%u" : "%d",
|
|
||||||
#endif
|
|
||||||
unpack_long (type, valaddr));
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Print a number according to FORMAT which is one of d,u,x,o,b,h,w,g.
|
||||||
|
The raison d'etre of this function is to consolidate printing of LONG_LONG's
|
||||||
|
into this one function. Some platforms have long longs but don't have a
|
||||||
|
printf() that supports "ll" in the format string. We handle these by seeing
|
||||||
|
if the number is actually a long, and if not we just bail out and print the
|
||||||
|
number in hex. The format chars b,h,w,g are from
|
||||||
|
print_scalar_formatted(). USE_LOCAL says whether or not to call the
|
||||||
|
local formatting routine to get the format. */
|
||||||
|
|
||||||
|
void
|
||||||
|
print_longest (stream, format, use_local, val_long)
|
||||||
|
FILE *stream;
|
||||||
|
char format;
|
||||||
|
int use_local;
|
||||||
|
LONGEST val_long;
|
||||||
|
{
|
||||||
|
#if defined (CC_HAS_LONG_LONG) && !defined (PRINTF_HAS_LONG_LONG)
|
||||||
|
long vtop, vbot;
|
||||||
|
|
||||||
|
vtop = val_long >> (sizeof (long) * HOST_CHAR_BIT);
|
||||||
|
vbot = (long) val_long;
|
||||||
|
|
||||||
|
if ((format == 'd' && (val_long < INT_MIN || val_long > INT_MAX))
|
||||||
|
|| ((format == 'u' || format == 'x') && val_long > UINT_MAX))
|
||||||
|
{
|
||||||
|
fprintf_filtered (stream, "0x%x%08x", vtop, vbot);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef PRINTF_HAS_LONG_LONG
|
||||||
|
switch (format)
|
||||||
|
{
|
||||||
|
case 'd':
|
||||||
|
fprintf_filtered (stream,
|
||||||
|
use_local ? local_decimal_format_custom ("ll")
|
||||||
|
: "%lld",
|
||||||
|
val_long);
|
||||||
|
break;
|
||||||
|
case 'u':
|
||||||
|
fprintf_filtered (stream, "%llu", val_long);
|
||||||
|
break;
|
||||||
|
case 'x':
|
||||||
|
fprintf_filtered (stream,
|
||||||
|
use_local ? local_hex_format_custom ("ll")
|
||||||
|
: "%llx",
|
||||||
|
val_long);
|
||||||
|
break;
|
||||||
|
case 'o':
|
||||||
|
fprintf_filtered (stream,
|
||||||
|
use_local ? local_octal_format_custom ("ll")
|
||||||
|
: "%llo",
|
||||||
|
break;
|
||||||
|
case 'b':
|
||||||
|
fprintf_filtered (stream, local_hex_format_custom ("02ll"), val_long);
|
||||||
|
break;
|
||||||
|
case 'h':
|
||||||
|
fprintf_filtered (stream, local_hex_format_custom ("04ll"), val_long);
|
||||||
|
break;
|
||||||
|
case 'w':
|
||||||
|
fprintf_filtered (stream, local_hex_format_custom ("08ll"), val_long);
|
||||||
|
break;
|
||||||
|
case 'g':
|
||||||
|
fprintf_filtered (stream, local_hex_format_custom ("016ll"), val_long);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
abort ();
|
||||||
|
}
|
||||||
|
#else /* !PRINTF_HAS_LONG_LONG */
|
||||||
|
/* In the following it is important to coerce (val_long) to a long. It does
|
||||||
|
nothing if !LONG_LONG, but it will chop off the top half (which we know
|
||||||
|
we can ignore) if the host supports long longs. */
|
||||||
|
|
||||||
|
switch (format)
|
||||||
|
{
|
||||||
|
case 'd':
|
||||||
|
fprintf_filtered (stream,
|
||||||
|
use_local ? local_decimal_format_custom ("l")
|
||||||
|
: "%ld",
|
||||||
|
(long) val_long);
|
||||||
|
break;
|
||||||
|
case 'u':
|
||||||
|
fprintf_filtered (stream, "%lu", (unsigned long) val_long);
|
||||||
|
break;
|
||||||
|
case 'x':
|
||||||
|
fprintf_filtered (stream,
|
||||||
|
use_local ? local_hex_format_custom ("l")
|
||||||
|
: "%lx",
|
||||||
|
(long) val_long);
|
||||||
|
break;
|
||||||
|
case 'o':
|
||||||
|
fprintf_filtered (stream,
|
||||||
|
use_local ? local_octal_format_custom ("l")
|
||||||
|
: "%lo",
|
||||||
|
(long) val_long);
|
||||||
|
break;
|
||||||
|
case 'b':
|
||||||
|
fprintf_filtered (stream, local_hex_format_custom ("02l"),
|
||||||
|
(long) val_long);
|
||||||
|
break;
|
||||||
|
case 'h':
|
||||||
|
fprintf_filtered (stream, local_hex_format_custom ("04l"),
|
||||||
|
(long) val_long);
|
||||||
|
break;
|
||||||
|
case 'w':
|
||||||
|
fprintf_filtered (stream, local_hex_format_custom ("08l"),
|
||||||
|
(long) val_long);
|
||||||
|
break;
|
||||||
|
case 'g':
|
||||||
|
fprintf_filtered (stream, local_hex_format_custom ("016l"),
|
||||||
|
(long) val_long);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
abort ();
|
||||||
|
}
|
||||||
|
#endif /* !PRINTF_HAS_LONG_LONG */
|
||||||
|
}
|
||||||
|
|
||||||
/* Print a floating point value of type TYPE, pointed to in GDB by VALADDR,
|
/* Print a floating point value of type TYPE, pointed to in GDB by VALADDR,
|
||||||
on STREAM. */
|
on STREAM. */
|
||||||
|
|
||||||
@ -550,17 +657,46 @@ value_print_array_elements (val, stream, format, pretty)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Print a string from the inferior, starting at ADDR and printing up to LEN
|
||||||
|
characters, to STREAM. If LEN is zero, printing stops at the first null
|
||||||
|
byte, otherwise printing proceeds (including null bytes) until either
|
||||||
|
print_max or LEN characters have been printed.
|
||||||
|
|
||||||
|
Always fetch print_max+1 characters, even though LA_PRINT_STRING might want
|
||||||
|
to print more or fewer (with repeated characters). This is so that we
|
||||||
|
don't spend forever fetching if we print a long string consisting of the
|
||||||
|
same character repeated. Also so we can do it all in one memory operation,
|
||||||
|
which is faster. However, this will be slower if print_max is set high,
|
||||||
|
e.g. if you set print_max to 1000, not only will it take a long time to
|
||||||
|
fetch short strings, but if you are near the end of the address space, it
|
||||||
|
might not work.
|
||||||
|
|
||||||
|
If the number of characters we actually print is limited because of hitting
|
||||||
|
print_max, when LEN would have explicitly or implicitly (in the case of a
|
||||||
|
null terminated string with another non-null character available to print)
|
||||||
|
allowed us to print more, we print ellipsis ("...") after the printed string
|
||||||
|
to indicate that more characters were available to print but that we were
|
||||||
|
limited by print_max. To do this correctly requires that we always fetch
|
||||||
|
one more than the number of characters we could potentially print, so that
|
||||||
|
if we do print the maximum number, we can tell whether or not a null byte
|
||||||
|
would have been the next character, in the case of C style strings.
|
||||||
|
For non-C style strings, only the value of LEN is pertinent in deciding
|
||||||
|
whether or not to print ellipsis.
|
||||||
|
|
||||||
|
FIXME: If LEN is nonzero and less than print_max, we could get away
|
||||||
|
with only fetching the specified number of characters from the inferior. */
|
||||||
|
|
||||||
int
|
int
|
||||||
val_print_string (addr, stream)
|
val_print_string (addr, len, stream)
|
||||||
CORE_ADDR addr;
|
CORE_ADDR addr;
|
||||||
|
unsigned int len;
|
||||||
FILE *stream;
|
FILE *stream;
|
||||||
{
|
{
|
||||||
int first_addr_err;
|
int first_addr_err = 0; /* Nonzero if first address out of bounds */
|
||||||
|
int force_ellipsis = 0; /* Force ellipsis to be printed if nonzero */
|
||||||
int errcode;
|
int errcode;
|
||||||
unsigned char c;
|
unsigned char c;
|
||||||
char *string;
|
char *string;
|
||||||
int force_ellipses;
|
|
||||||
unsigned int i = 0; /* Number of characters printed. */
|
|
||||||
|
|
||||||
/* Get first character. */
|
/* Get first character. */
|
||||||
errcode = target_read_memory (addr, (char *)&c, 1);
|
errcode = target_read_memory (addr, (char *)&c, 1);
|
||||||
@ -569,53 +705,58 @@ val_print_string (addr, stream)
|
|||||||
/* First address out of bounds. */
|
/* First address out of bounds. */
|
||||||
first_addr_err = 1;
|
first_addr_err = 1;
|
||||||
}
|
}
|
||||||
else
|
else if (print_max < UINT_MAX)
|
||||||
{
|
{
|
||||||
first_addr_err = 0;
|
string = (char *) alloca (print_max + 1);
|
||||||
/* A real string. */
|
memset (string, 0, print_max + 1);
|
||||||
string = (char *) alloca (print_max);
|
|
||||||
|
|
||||||
/* If the loop ends by us hitting print_max characters,
|
|
||||||
we need to have elipses at the end. */
|
|
||||||
force_ellipses = 1;
|
|
||||||
|
|
||||||
/* This loop always fetches print_max characters, even
|
|
||||||
though LA_PRINT_STRING might want to print more or fewer
|
|
||||||
(with repeated characters). This is so that
|
|
||||||
we don't spend forever fetching if we print
|
|
||||||
a long string consisting of the same character
|
|
||||||
repeated. Also so we can do it all in one memory
|
|
||||||
operation, which is faster. However, this will be
|
|
||||||
slower if print_max is set high, e.g. if you set
|
|
||||||
print_max to 1000, not only will it take a long
|
|
||||||
time to fetch short strings, but if you are near
|
|
||||||
the end of the address space, it might not work. */
|
|
||||||
QUIT;
|
QUIT;
|
||||||
errcode = target_read_memory (addr, string, print_max);
|
errcode = target_read_memory (addr, string, print_max + 1);
|
||||||
if (errcode != 0)
|
if (errcode != 0)
|
||||||
{
|
{
|
||||||
/* Try reading just one character. If that succeeds,
|
/* Try reading just one character. If that succeeds, assume we hit
|
||||||
assume we hit the end of the address space, but
|
the end of the address space, but the initial part of the string
|
||||||
the initial part of the string is probably safe. */
|
is probably safe. */
|
||||||
char x[1];
|
char x[1];
|
||||||
errcode = target_read_memory (addr, x, 1);
|
errcode = target_read_memory (addr, x, 1);
|
||||||
}
|
}
|
||||||
if (errcode != 0)
|
if (len == 0)
|
||||||
force_ellipses = 0;
|
{
|
||||||
else
|
/* When the length is unspecified, such as when printing C style
|
||||||
for (i = 0; i < print_max; i++)
|
null byte terminated strings, then scan the string looking for
|
||||||
if (string[i] == '\0')
|
the terminator in the first print_max characters. If a terminator
|
||||||
|
is found, then it determines the length, otherwise print_max
|
||||||
|
determines the length. */
|
||||||
|
for (;len < print_max; len++)
|
||||||
{
|
{
|
||||||
force_ellipses = 0;
|
if (string[len] == '\0')
|
||||||
break;
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
/* If the first unprinted character is not the null terminator, set
|
||||||
|
the flag to force ellipses. This is true whether or not we broke
|
||||||
|
out of the above loop because we found a terminator, or whether
|
||||||
|
we simply hit the limit on how many characters to print. */
|
||||||
|
if (string[len] != '\0')
|
||||||
|
{
|
||||||
|
force_ellipsis = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (len > print_max)
|
||||||
|
{
|
||||||
|
/* Printing less than the number of characters actually requested
|
||||||
|
always makes us print ellipsis. */
|
||||||
|
len = print_max;
|
||||||
|
force_ellipsis = 1;
|
||||||
|
}
|
||||||
QUIT;
|
QUIT;
|
||||||
|
|
||||||
if (addressprint)
|
if (addressprint)
|
||||||
{
|
{
|
||||||
fputs_filtered (" ", stream);
|
fputs_filtered (" ", stream);
|
||||||
}
|
}
|
||||||
LA_PRINT_STRING (stream, string, i, force_ellipses);
|
LA_PRINT_STRING (stream, string, len, force_ellipsis);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (errcode != 0)
|
if (errcode != 0)
|
||||||
@ -624,16 +765,16 @@ val_print_string (addr, stream)
|
|||||||
{
|
{
|
||||||
fprintf_filtered (stream,
|
fprintf_filtered (stream,
|
||||||
(" <Address 0x%x out of bounds>" + first_addr_err),
|
(" <Address 0x%x out of bounds>" + first_addr_err),
|
||||||
addr + i);
|
addr + len);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
error ("Error reading memory address 0x%x: %s.", addr + i,
|
error ("Error reading memory address 0x%x: %s.", addr + len,
|
||||||
safe_strerror (errcode));
|
safe_strerror (errcode));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fflush (stream);
|
fflush (stream);
|
||||||
return (i);
|
return (len);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
17
gdb/value.h
17
gdb/value.h
@ -102,7 +102,7 @@ struct value
|
|||||||
union {
|
union {
|
||||||
long contents[1];
|
long contents[1];
|
||||||
double force_double_align;
|
double force_double_align;
|
||||||
#ifdef LONG_LONG
|
#ifdef CC_HAS_LONG_LONG
|
||||||
long long force_longlong_align;
|
long long force_longlong_align;
|
||||||
#endif
|
#endif
|
||||||
} aligner;
|
} aligner;
|
||||||
@ -271,6 +271,12 @@ value_free_to_mark PARAMS ((value mark));
|
|||||||
extern value
|
extern value
|
||||||
value_string PARAMS ((char *ptr, int len));
|
value_string PARAMS ((char *ptr, int len));
|
||||||
|
|
||||||
|
extern value
|
||||||
|
value_array PARAMS ((int lowbound, int highbound, value *elemvec));
|
||||||
|
|
||||||
|
extern value
|
||||||
|
value_concat PARAMS ((value arg1, value arg2));
|
||||||
|
|
||||||
extern value
|
extern value
|
||||||
value_binop PARAMS ((value arg1, value arg2, enum exp_opcode op));
|
value_binop PARAMS ((value arg1, value arg2, enum exp_opcode op));
|
||||||
|
|
||||||
@ -419,9 +425,6 @@ binop_user_defined_p PARAMS ((enum exp_opcode op, value arg1, value arg2));
|
|||||||
extern int
|
extern int
|
||||||
unop_user_defined_p PARAMS ((enum exp_opcode op, value arg1));
|
unop_user_defined_p PARAMS ((enum exp_opcode op, value arg1));
|
||||||
|
|
||||||
extern int
|
|
||||||
typecmp PARAMS ((int staticp, struct type *t1[], value t2[]));
|
|
||||||
|
|
||||||
extern int
|
extern int
|
||||||
destructor_name_p PARAMS ((const char *name, const struct type *type));
|
destructor_name_p PARAMS ((const char *name, const struct type *type));
|
||||||
|
|
||||||
@ -474,6 +477,10 @@ extern char *
|
|||||||
baseclass_addr PARAMS ((struct type *type, int index, char *valaddr,
|
baseclass_addr PARAMS ((struct type *type, int index, char *valaddr,
|
||||||
value *valuep, int *errp));
|
value *valuep, int *errp));
|
||||||
|
|
||||||
|
extern void
|
||||||
|
print_longest PARAMS ((FILE *stream, char format, int use_local,
|
||||||
|
LONGEST value));
|
||||||
|
|
||||||
extern void
|
extern void
|
||||||
print_floating PARAMS ((char *valaddr, struct type *type, FILE *stream));
|
print_floating PARAMS ((char *valaddr, struct type *type, FILE *stream));
|
||||||
|
|
||||||
@ -487,7 +494,7 @@ val_print PARAMS ((struct type *type, char *valaddr, CORE_ADDR address,
|
|||||||
int recurse, enum val_prettyprint pretty));
|
int recurse, enum val_prettyprint pretty));
|
||||||
|
|
||||||
extern int
|
extern int
|
||||||
val_print_string PARAMS ((CORE_ADDR addr, FILE *stream));
|
val_print_string PARAMS ((CORE_ADDR addr, unsigned int len, FILE *stream));
|
||||||
|
|
||||||
/* FIXME: Assumes equivalence of "struct frame_info *" and "FRAME" */
|
/* FIXME: Assumes equivalence of "struct frame_info *" and "FRAME" */
|
||||||
extern void
|
extern void
|
||||||
|
25
gdb/values.c
25
gdb/values.c
@ -637,7 +637,7 @@ unpack_long (type, valaddr)
|
|||||||
SWAP_TARGET_AND_HOST (&retval, sizeof (retval));
|
SWAP_TARGET_AND_HOST (&retval, sizeof (retval));
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
#ifdef LONG_LONG
|
#ifdef CC_HAS_LONG_LONG
|
||||||
if (len == sizeof (long long))
|
if (len == sizeof (long long))
|
||||||
{
|
{
|
||||||
unsigned long long retval;
|
unsigned long long retval;
|
||||||
@ -685,7 +685,7 @@ unpack_long (type, valaddr)
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef LONG_LONG
|
#ifdef CC_HAS_LONG_LONG
|
||||||
if (len == sizeof (long long))
|
if (len == sizeof (long long))
|
||||||
{
|
{
|
||||||
long long retval;
|
long long retval;
|
||||||
@ -717,6 +717,15 @@ unpack_long (type, valaddr)
|
|||||||
SWAP_TARGET_AND_HOST (&retval, len);
|
SWAP_TARGET_AND_HOST (&retval, len);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
#ifdef CC_HAS_LONG_LONG
|
||||||
|
else if (len == sizeof(long long))
|
||||||
|
{
|
||||||
|
unsigned long long retval;
|
||||||
|
memcpy (&retval, valaddr, len);
|
||||||
|
SWAP_TARGET_AND_HOST (&retval, len);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else if (code == TYPE_CODE_MEMBER)
|
else if (code == TYPE_CODE_MEMBER)
|
||||||
error ("not implemented: member types in unpack_long");
|
error ("not implemented: member types in unpack_long");
|
||||||
@ -775,11 +784,7 @@ unpack_double (type, valaddr, invp)
|
|||||||
}
|
}
|
||||||
else if (nosign) {
|
else if (nosign) {
|
||||||
/* Unsigned -- be sure we compensate for signed LONGEST. */
|
/* Unsigned -- be sure we compensate for signed LONGEST. */
|
||||||
#ifdef LONG_LONG
|
return (unsigned LONGEST) unpack_long (type, valaddr);
|
||||||
return (unsigned long long) unpack_long (type, valaddr);
|
|
||||||
#else
|
|
||||||
return (unsigned long ) unpack_long (type, valaddr);
|
|
||||||
#endif
|
|
||||||
} else {
|
} else {
|
||||||
/* Signed -- we are OK with unpack_long. */
|
/* Signed -- we are OK with unpack_long. */
|
||||||
return unpack_long (type, valaddr);
|
return unpack_long (type, valaddr);
|
||||||
@ -1393,10 +1398,8 @@ value_from_longest (type, num)
|
|||||||
* (int *) VALUE_CONTENTS_RAW (val) = num;
|
* (int *) VALUE_CONTENTS_RAW (val) = num;
|
||||||
else if (len == sizeof (long))
|
else if (len == sizeof (long))
|
||||||
* (long *) VALUE_CONTENTS_RAW (val) = num;
|
* (long *) VALUE_CONTENTS_RAW (val) = num;
|
||||||
#ifdef LONG_LONG
|
else if (len == sizeof (LONGEST))
|
||||||
else if (len == sizeof (long long))
|
* (LONGEST *) VALUE_CONTENTS_RAW (val) = num;
|
||||||
* (long long *) VALUE_CONTENTS_RAW (val) = num;
|
|
||||||
#endif
|
|
||||||
else
|
else
|
||||||
error ("Integer type encountered with unexpected data length.");
|
error ("Integer type encountered with unexpected data length.");
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user