int addressprint; /* Controls printing of machine addresses */
\f
-/* Print data of type TYPE located at VALADDR (within GDB),
- which came from the inferior at address ADDRESS,
- onto stdio stream STREAM according to FORMAT
- (a letter or 0 for natural format). The data at VALADDR
- is in target byte order.
+/* Print data of type TYPE located at VALADDR (within GDB), which came from
+ the inferior at address ADDRESS, onto stdio stream STREAM according to
+ FORMAT (a letter, or 0 for natural format using TYPE).
- If the data are a string pointer, returns the number of
- sting characters printed.
+ If DEREF_REF is nonzero, then dereference references, otherwise just print
+ them like pointers.
- if DEREF_REF is nonzero, then dereference references,
- otherwise just print them like pointers.
+ The PRETTY parameter controls prettyprinting.
+
+ If the data are a string pointer, returns the number of string characters
+ printed.
+
+ FIXME: The data at VALADDR is in target byte order. If gdb is ever
+ enhanced to be able to debug more than the single target it was compiled
+ for (specific CPU type and thus specific target byte ordering), then
+ either the print routines are going to have to take this into account,
+ or the data is going to have to be passed into here already converted
+ to the host byte ordering, whichever is more convenient. */
- The PRETTY parameter controls prettyprinting. */
int
-val_print (type, valaddr, address, stream, format, deref_ref, recurse,
- pretty)
+val_print (type, valaddr, address, stream, format, deref_ref, recurse, pretty)
struct type *type;
char *valaddr;
CORE_ADDR address;
if (len <= sizeof (LONGEST))
{
/* We can print it in decimal. */
- fprintf_filtered
- (stream,
-#if defined (LONG_LONG)
- "%llu",
-#else
- "%lu",
-#endif
- unpack_long (BUILTIN_TYPE_LONGEST, first_addr));
+ print_longest (stream, 'u', 0,
+ unpack_long (BUILTIN_TYPE_LONGEST, first_addr));
}
else
{
#ifdef PRINT_TYPELESS_INTEGER
PRINT_TYPELESS_INTEGER (stream, type, unpack_long (type, valaddr));
#else
- fprintf_filtered (stream, TYPE_UNSIGNED (type) ?
-#if defined (LONG_LONG)
- "%llu" : "%lld",
-#else
- "%u" : "%d",
-#endif
- unpack_long (type, valaddr));
+ print_longest (stream, TYPE_UNSIGNED (type) ? 'u' : 'd', 0,
+ unpack_long (type, valaddr));
#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,
on STREAM. */
}
}
+/* 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
+val_print_string (addr, len, stream)
+ CORE_ADDR addr;
+ unsigned int len;
+ FILE *stream;
+{
+ 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;
+ unsigned char c;
+ char *string;
+
+ /* Get first character. */
+ errcode = target_read_memory (addr, (char *)&c, 1);
+ if (errcode != 0)
+ {
+ /* First address out of bounds. */
+ first_addr_err = 1;
+ }
+ else if (print_max < UINT_MAX)
+ {
+ string = (char *) alloca (print_max + 1);
+ memset (string, 0, print_max + 1);
+
+ QUIT;
+ errcode = target_read_memory (addr, string, print_max + 1);
+ if (errcode != 0)
+ {
+ /* Try reading just one character. If that succeeds, assume we hit
+ the end of the address space, but the initial part of the string
+ is probably safe. */
+ char x[1];
+ errcode = target_read_memory (addr, x, 1);
+ }
+ if (len == 0)
+ {
+ /* When the length is unspecified, such as when printing C style
+ null byte terminated strings, then scan the string looking for
+ 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++)
+ {
+ if (string[len] == '\0')
+ {
+ 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;
+
+ if (addressprint)
+ {
+ fputs_filtered (" ", stream);
+ }
+ LA_PRINT_STRING (stream, string, len, force_ellipsis);
+ }
+
+ if (errcode != 0)
+ {
+ if (errcode == EIO)
+ {
+ fprintf_filtered (stream,
+ (" <Address 0x%x out of bounds>" + first_addr_err),
+ addr + len);
+ }
+ else
+ {
+ error ("Error reading memory address 0x%x: %s.", addr + len,
+ safe_strerror (errcode));
+ }
+ }
+ fflush (stream);
+ return (len);
+}
\f
#if 0
/* Validate an input or output radix setting, and make sure the user