/* Print values for GNU debugger GDB.
- 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.
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-#include <stdio.h>
-#include <string.h>
#include "defs.h"
-#include "param.h"
+#include <string.h>
#include "frame.h"
#include "symtab.h"
+#include "gdbtypes.h"
#include "value.h"
+#include "language.h"
#include "expression.h"
#include "gdbcore.h"
#include "gdbcmd.h"
#include "target.h"
+#include "breakpoint.h"
+#include "demangle.h"
+
+/* These are just for containing_function_bounds. It might be better
+ to move containing_function_bounds to blockframe.c or thereabouts. */
+#include "bfd.h"
+#include "symfile.h"
+#include "objfiles.h"
extern int asm_demangle; /* Whether to demangle syms in asm printouts */
extern int addressprint; /* Whether to print hex addresses in HLL " */
-extern struct block *get_current_block ();
-
-static void print_frame_nameless_args ();
-
struct format_data
{
int count;
static value last_examine_value;
+/* Largest offset between a symbolic value and an address, that will be
+ printed as `0x1234 <symbol+offset>'. */
+
+static unsigned int max_symbolic_offset = UINT_MAX;
+
+/* Append the source filename and linenumber of the symbol when
+ printing a symbolic value as `<symbol at filename:linenum>' if set. */
+static int print_symbol_filename = 0;
+
/* Number of auto-display expression currently being displayed.
- So that we can deleted it if we get an error or a signal within it.
+ So that we can disable it if we get an error or a signal within it.
-1 when not doing one. */
int current_display_number;
int inspect_it = 0;
-static void do_one_display ();
+struct display
+{
+ /* Chain link to next auto-display item. */
+ struct display *next;
+ /* Expression to be evaluated and displayed. */
+ struct expression *exp;
+ /* Item number of this auto-display item. */
+ int number;
+ /* Display format specified. */
+ struct format_data format;
+ /* Innermost block required by this expression when evaluated */
+ struct block *block;
+ /* Status of this display (enabled or disabled) */
+ enum enable status;
+};
+
+/* Chain of expressions whose values should be displayed
+ automatically each time the program stops. */
+
+static struct display *display_chain;
-void do_displays ();
-void print_scalar_formatted ();
+static int display_number;
+
+/* Prototypes for local functions */
+
+static void
+delete_display PARAMS ((int));
+
+static void
+enable_display PARAMS ((char *, int));
+
+static void
+disable_display_command PARAMS ((char *, int));
+
+static void
+disassemble_command PARAMS ((char *, int));
+
+static int
+containing_function_bounds PARAMS ((CORE_ADDR, CORE_ADDR *, CORE_ADDR *));
+
+static void
+printf_command PARAMS ((char *, int));
+
+static void
+print_frame_nameless_args PARAMS ((struct frame_info *, long, int, int,
+ FILE *));
+
+static void
+display_info PARAMS ((char *, int));
+
+static void
+do_one_display PARAMS ((struct display *));
+
+static void
+undisplay_command PARAMS ((char *, int));
+
+static void
+free_display PARAMS ((struct display *));
+
+static void
+display_command PARAMS ((char *, int));
+
+static void
+x_command PARAMS ((char *, int));
+
+static void
+address_info PARAMS ((char *, int));
+
+static void
+set_command PARAMS ((char *, int));
+
+static void
+output_command PARAMS ((char *, int));
+
+static void
+call_command PARAMS ((char *, int));
+
+static void
+inspect_command PARAMS ((char *, int));
+
+static void
+print_command PARAMS ((char *, int));
+
+static void
+print_command_1 PARAMS ((char *, int, int));
+
+static void
+validate_format PARAMS ((struct format_data, char *));
+
+static void
+do_examine PARAMS ((struct format_data, CORE_ADDR));
+
+static void
+print_formatted PARAMS ((value, int, int));
+
+static struct format_data
+decode_format PARAMS ((char **, int, int));
\f
/* Decode a format specification. *STRING_PTR should point to it.
found in the specification. In addition, *STRING_PTR is advanced
past the specification and past all whitespace following it. */
-struct format_data
+static struct format_data
decode_format (string_ptr, oformat, osize)
char **string_ptr;
- char oformat;
- char osize;
+ int oformat;
+ int osize;
{
struct format_data val;
register char *p = *string_ptr;
{
if (*p == 'b' || *p == 'h' || *p == 'w' || *p == 'g')
val.size = *p++;
-#ifdef LONG_LONG
+#ifdef CC_HAS_LONG_LONG
else if (*p == 'l')
{
val.size = 'g';
break;
}
-#ifndef LONG_LONG
+#ifndef CC_HAS_LONG_LONG
/* Make sure 'g' size is not used on integer types.
Well, actually, we can handle hex. */
if (val.size == 'g' && val.format != 'f' && val.format != 'x')
static void
print_formatted (val, format, size)
register value val;
- register char format;
- char size;
+ register int format;
+ int size;
{
int len = TYPE_LENGTH (VALUE_TYPE (val));
break;
case 'i':
+ /* The old comment says
+ "Force output out, print_insn not using _filtered".
+ I'm not completely sure what that means, I suspect most print_insn
+ now do use _filtered, so I guess it's obsolete. */
+ /* We often wrap here if there are long symbolic names. */
+ wrap_here ("\t");
next_address = VALUE_ADDRESS (val)
+ print_insn (VALUE_ADDRESS (val), stdout);
break;
default:
if (format == 0
|| TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_ARRAY
+ || TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_STRING
|| TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_STRUCT
|| TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_UNION
|| VALUE_REPEATED (val))
print_scalar_formatted (valaddr, type, format, size, stream)
char *valaddr;
struct type *type;
- char format;
+ int format;
int size;
FILE *stream;
{
{
/* ok, we're going to have to get fancy here. Assumption: a
long is four bytes. FIXME. */
- unsigned long v1, v2, tmp;
+ unsigned long v1, v2;
v1 = unpack_long (builtin_type_long, valaddr);
v2 = unpack_long (builtin_type_long, valaddr + 4);
#if TARGET_BYTE_ORDER == LITTLE_ENDIAN
/* Swap the two for printing */
- tmp = v1;
- v1 = v2;
- v2 = tmp;
+ {
+ unsigned long tmp;
+
+ tmp = v1;
+ v1 = v2;
+ v2 = tmp;
+ }
#endif
switch (format)
{
case 'x':
- fprintf_filtered (stream, "0x%08x%08x", v1, v2);
+ fprintf_filtered (stream, local_hex_format_custom("08x%08"), v1, v2);
break;
default:
error ("Output size \"g\" unimplemented for format \"%c\".",
if (!size)
{
/* no size specified, like in print. Print varying # of digits. */
-#if defined (LONG_LONG)
- fprintf_filtered (stream, "0x%llx", val_long);
-#else /* not LONG_LONG. */
- fprintf_filtered (stream, "0x%lx", val_long);
-#endif /* not LONG_LONG. */
+ print_longest (stream, 'x', 1, val_long);
}
else
-#if defined (LONG_LONG)
- switch (size)
- {
- case 'b':
- fprintf_filtered (stream, "0x%02llx", val_long);
- break;
- case 'h':
- fprintf_filtered (stream, "0x%04llx", val_long);
- break;
- case 'w':
- fprintf_filtered (stream, "0x%08llx", val_long);
- break;
- case 'g':
- fprintf_filtered (stream, "0x%016llx", val_long);
- break;
- default:
- error ("Undefined output size \"%c\".", size);
- }
-#else /* not LONG_LONG. */
- switch (size)
- {
- case 'b':
- fprintf_filtered (stream, "0x%02x", val_long);
- break;
- case 'h':
- fprintf_filtered (stream, "0x%04x", val_long);
- break;
- case 'w':
- fprintf_filtered (stream, "0x%08x", val_long);
- break;
- case 'g':
- fprintf_filtered (stream, "0x%016x", val_long);
- break;
- default:
- error ("Undefined output size \"%c\".", size);
- }
-#endif /* not LONG_LONG */
+ switch (size)
+ {
+ case 'b':
+ case 'h':
+ case 'w':
+ case 'g':
+ print_longest (stream, size, 1, val_long);
+ break;
+ default:
+ error ("Undefined output size \"%c\".", size);
+ }
break;
case 'd':
-#ifdef LONG_LONG
- fprintf_filtered (stream, "%lld", val_long);
-#else
- fprintf_filtered (stream, "%d", val_long);
-#endif
+ print_longest (stream, 'd', 1, val_long);
break;
case 'u':
-#ifdef LONG_LONG
- fprintf_filtered (stream, "%llu", val_long);
-#else
- fprintf_filtered (stream, "%u", val_long);
-#endif
+ print_longest (stream, 'u', 0, val_long);
break;
case 'o':
if (val_long)
-#ifdef LONG_LONG
- fprintf_filtered (stream, "0%llo", val_long);
-#else
- fprintf_filtered (stream, "0%o", val_long);
-#endif
+ print_longest (stream, 'o', 1, val_long);
else
fprintf_filtered (stream, "0");
break;
break;
case 'c':
- value_print (value_from_long (builtin_type_char, val_long), stream, 0,
+ value_print (value_from_longest (builtin_type_char, val_long), stream, 0,
Val_pretty_default);
break;
if (*cp == '\0')
cp--;
}
+ fprintf_filtered (stream, local_binary_format_prefix());
fprintf_filtered (stream, cp);
+ fprintf_filtered (stream, local_binary_format_suffix());
}
break;
/* Make address available to the user as $_. */
set_internalvar (lookup_internalvar ("_"),
- value_from_long (builtin_type_int, (LONGEST) addr));
+ value_from_longest (lookup_pointer_type (builtin_type_void),
+ (LONGEST) addr));
}
/* Optionally print address ADDR symbolically as <SYMBOL+OFFSET> on STREAM,
after LEADIN. Print nothing if no symbolic name is found nearby.
DO_DEMANGLE controls whether to print a symbol in its native "raw" form,
or to interpret it as a possible C++ name and convert it back to source
- form. */
+ form. However note that DO_DEMANGLE can be overridden by the specific
+ settings of the demangle and asm_demangle variables. */
void
print_address_symbolic (addr, stream, do_demangle, leadin)
int do_demangle;
char *leadin;
{
- int name_location;
- register int i = find_pc_misc_function (addr);
-
- /* If nothing comes out, don't print anything symbolic. */
+ CORE_ADDR name_location;
+ register struct symbol *symbol;
+ char *name;
+
+ /* First try to find the address in the symbol tables to find
+ static functions. If that doesn't succeed we try the minimal symbol
+ vector for symbols in non-text space.
+ FIXME: Should find a way to get at the static non-text symbols too. */
- if (i < 0)
+ symbol = find_pc_function (addr);
+ if (symbol)
+ {
+ name_location = BLOCK_START (SYMBOL_BLOCK_VALUE (symbol));
+ if (do_demangle)
+ name = SYMBOL_SOURCE_NAME (symbol);
+ else
+ name = SYMBOL_LINKAGE_NAME (symbol);
+ }
+ else
+ {
+ register struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (addr);
+
+ /* If nothing comes out, don't print anything symbolic. */
+ if (msymbol == NULL)
+ return;
+ name_location = SYMBOL_VALUE_ADDRESS (msymbol);
+ if (do_demangle)
+ name = SYMBOL_SOURCE_NAME (msymbol);
+ else
+ name = SYMBOL_LINKAGE_NAME (msymbol);
+ }
+
+ /* If the nearest symbol is too far away, don't print anything symbolic. */
+
+ /* For when CORE_ADDR is larger than unsigned int, we do math in
+ CORE_ADDR. But when we detect unsigned wraparound in the
+ CORE_ADDR math, we ignore this test and print the offset,
+ because addr+max_symbolic_offset has wrapped through the end
+ of the address space back to the beginning, giving bogus comparison. */
+ if (addr > name_location + max_symbolic_offset
+ && name_location + max_symbolic_offset > name_location)
return;
fputs_filtered (leadin, stream);
fputs_filtered ("<", stream);
- if (do_demangle)
- fputs_demangled (misc_function_vector[i].name, stream, 1);
- else
- fputs_filtered (misc_function_vector[i].name, stream);
- name_location = misc_function_vector[i].address;
- if (addr - name_location)
- fprintf_filtered (stream, "+%d>", addr - name_location);
- else
- fputs_filtered (">", stream);
+ fputs_filtered (name, stream);
+ if (addr != name_location)
+ fprintf_filtered (stream, "+%u", (unsigned int)(addr - name_location));
+
+ /* Append source filename and line number if desired. */
+ if (symbol && print_symbol_filename)
+ {
+ struct symtab_and_line sal;
+
+ sal = find_pc_line (addr, 0);
+ if (sal.symtab)
+ fprintf_filtered (stream, " at %s:%d", sal.symtab->filename, sal.line);
+ }
+ fputs_filtered (">", stream);
}
/* Print address ADDR symbolically on STREAM.
CORE_ADDR addr;
FILE *stream;
{
- fprintf_filtered (stream, "0x%x", addr);
+#ifdef ADDR_BITS_REMOVE
+ fprintf_filtered (stream, local_hex_format(), ADDR_BITS_REMOVE(addr));
+#else
+ fprintf_filtered (stream, local_hex_format(), addr);
+#endif
print_address_symbolic (addr, stream, asm_demangle, " ");
}
if (addr == 0) {
fprintf_filtered (stream, "0");
} else if (addressprint) {
- fprintf_filtered (stream, "0x%x", addr);
+ fprintf_filtered (stream, local_hex_format(), addr);
print_address_symbolic (addr, stream, do_demangle, " ");
} else {
print_address_symbolic (addr, stream, do_demangle, "");
else if (size == 'w')
val_type = builtin_type_long;
else if (size == 'g')
-#ifndef LONG_LONG
+#ifndef CC_HAS_LONG_LONG
val_type = builtin_type_double;
#else
val_type = builtin_type_long_long;
fmt.format, cmdname);
}
+/* Evaluate string EXP as an expression in the current language and
+ print the resulting value. EXP may contain a format specifier as the
+ first argument ("/x myvar" for example, to print myvar in hex).
+ */
+
static void
print_command_1 (exp, inspect, voidprint)
char *exp;
{
extern int objectprint;
struct type *type;
- expr = parse_c_expression (exp);
+ expr = parse_expression (exp);
old_chain = make_cleanup (free_current_contents, &expr);
cleanup = 1;
val = evaluate_expression (expr);
type = VALUE_TYPE (val);
if (objectprint
- && (TYPE_CODE (type) == TYPE_CODE_PTR
+ && ( TYPE_CODE (type) == TYPE_CODE_PTR
|| TYPE_CODE (type) == TYPE_CODE_REF)
- && TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_STRUCT)
+ && ( TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_STRUCT
+ || TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_UNION))
{
value v;
{
exp++;
fmt = decode_format (&exp, 0, 0);
- validate_format (fmt, "print");
+ validate_format (fmt, "output");
format = fmt.format;
}
- expr = parse_c_expression (exp);
+ expr = parse_expression (exp);
old_chain = make_cleanup (free_current_contents, &expr);
val = evaluate_expression (expr);
char *exp;
int from_tty;
{
- struct expression *expr = parse_c_expression (exp);
+ struct expression *expr = parse_expression (exp);
register struct cleanup *old_chain
= make_cleanup (free_current_contents, &expr);
evaluate_expression (expr);
int from_tty;
{
register struct symbol *sym;
+ register struct minimal_symbol *msymbol;
register long val;
+ register long basereg;
int is_a_field_of_this; /* C++: lookup_symbol sets this to nonzero
if exp is a field of `this'. */
sym = lookup_symbol (exp, get_selected_block (), VAR_NAMESPACE,
&is_a_field_of_this, (struct symtab **)NULL);
- if (sym == 0)
+ if (sym == NULL)
{
- register int i;
-
if (is_a_field_of_this)
{
printf ("Symbol \"%s\" is a field of the local class variable `this'\n", exp);
return;
}
- for (i = 0; i < misc_function_count; i++)
- if (!strcmp (misc_function_vector[i].name, exp))
- break;
+ msymbol = lookup_minimal_symbol (exp, (struct objfile *) NULL);
- if (i < misc_function_count)
- printf ("Symbol \"%s\" is at 0x%x in a file compiled without -g.\n",
- exp, misc_function_vector[i].address);
+ if (msymbol != NULL)
+ printf ("Symbol \"%s\" is at %s in a file compiled without debugging.\n",
+ exp, local_hex_string(SYMBOL_VALUE_ADDRESS (msymbol)));
else
error ("No symbol \"%s\" in current context.", exp);
return;
printf ("Symbol \"%s\" is ", SYMBOL_NAME (sym));
val = SYMBOL_VALUE (sym);
+ basereg = SYMBOL_BASEREG (sym);
switch (SYMBOL_CLASS (sym))
{
break;
case LOC_LABEL:
- printf ("a label at address 0x%x", SYMBOL_VALUE_ADDRESS (sym));
+ printf ("a label at address %s", local_hex_string(SYMBOL_VALUE_ADDRESS (sym)));
break;
case LOC_REGISTER:
break;
case LOC_STATIC:
- printf ("static at address 0x%x", SYMBOL_VALUE_ADDRESS (sym));
+ printf ("static storage at address %s", local_hex_string(SYMBOL_VALUE_ADDRESS (sym)));
break;
case LOC_REGPARM:
printf ("an argument in register %s", reg_names[val]);
break;
+
+ case LOC_REGPARM_ADDR:
+ printf ("address of an argument in register %s", reg_names[val]);
+ break;
case LOC_ARG:
- printf ("an argument at offset %ld", val);
+ if (SYMBOL_BASEREG_VALID (sym))
+ {
+ printf ("an argument at offset %ld from register %s",
+ val, reg_names[basereg]);
+ }
+ else
+ {
+ printf ("an argument at offset %ld", val);
+ }
break;
case LOC_LOCAL_ARG:
- printf ("an argument at frame offset %ld", val);
+ if (SYMBOL_BASEREG_VALID (sym))
+ {
+ printf ("an argument at offset %ld from register %s",
+ val, reg_names[basereg]);
+ }
+ else
+ {
+ printf ("an argument at frame offset %ld", val);
+ }
break;
case LOC_LOCAL:
- printf ("a local variable at frame offset %ld", val);
+ if (SYMBOL_BASEREG_VALID (sym))
+ {
+ printf ("a local variable at offset %ld from register %s",
+ val, reg_names[basereg]);
+ }
+ else
+ {
+ printf ("a local variable at frame offset %ld", val);
+ }
break;
case LOC_REF_ARG:
break;
case LOC_BLOCK:
- printf ("a function at address 0x%x",
- BLOCK_START (SYMBOL_BLOCK_VALUE (sym)));
+ printf ("a function at address %s",
+ local_hex_string(BLOCK_START (SYMBOL_BLOCK_VALUE (sym))));
break;
- case LOC_EXTERNAL:
- printf ("an external symbol at address 0x%x",
- SYMBOL_VALUE_ADDRESS (sym));
+ case LOC_OPTIMIZED_OUT:
+ printf_filtered ("optimized out");
break;
-
+
default:
printf ("of unknown (botched) type");
break;
{
exp++;
fmt = decode_format (&exp, last_format, last_size);
- last_size = fmt.size;
- last_format = fmt.format;
}
/* If we have an expression, evaluate it and use it as the address. */
if (exp != 0 && *exp != 0)
{
- expr = parse_c_expression (exp);
+ expr = parse_expression (exp);
/* Cause expression not to be there any more
if this command is repeated with Newline.
But don't clobber a user-defined command's definition. */
do_examine (fmt, next_address);
+ /* If the examine succeeds, we remember its size and format for next time. */
+ last_size = fmt.size;
+ last_format = fmt.format;
+
/* Set a couple of internal variables if appropriate. */
if (last_examine_value)
{
- /* Make last address examined available to the user as $_. */
+ /* Make last address examined available to the user as $_. Use
+ the correct pointer type. */
set_internalvar (lookup_internalvar ("_"),
- value_from_long (builtin_type_int,
- (LONGEST) last_examine_address));
+ value_from_longest (
+ lookup_pointer_type (VALUE_TYPE (last_examine_value)),
+ (LONGEST) last_examine_address));
/* Make contents of last address examined available to the user as $__.*/
set_internalvar (lookup_internalvar ("__"), last_examine_value);
}
}
-\f
-/* Commands for printing types of things. */
-/* Print type of EXP, or last thing in value history if EXP == NULL.
- show is passed to type_print. */
-static void
-whatis_exp (exp, show)
- char *exp;
- int show;
-{
- struct expression *expr;
- register value val;
- register struct cleanup *old_chain;
-
- if (exp)
- {
- expr = parse_c_expression (exp);
- old_chain = make_cleanup (free_current_contents, &expr);
- val = evaluate_type (expr);
- }
- else
- val = access_value_history (0);
-
- printf_filtered ("type = ");
- type_print (VALUE_TYPE (val), "", stdout, show);
- printf_filtered ("\n");
-
- if (exp)
- do_cleanups (old_chain);
-}
-
-/* ARGSUSED */
-static void
-whatis_command (exp, from_tty)
- char *exp;
- int from_tty;
-{
- /* Most of the time users do not want to see all the fields
- in a structure. If they do they can use the "ptype" command.
- Hence the "-1" below. */
- whatis_exp (exp, -1);
-}
-
-/* TYPENAME is either the name of a type, or an expression. */
-/* ARGSUSED */
-static void
-ptype_command (typename, from_tty)
- char *typename;
- int from_tty;
-{
- register char *p = typename;
- register int len;
- register struct block *b
- = target_has_stack ? get_current_block () : 0;
- register struct type *type;
-
- if (typename == 0)
- {
- whatis_exp (typename, 1);
- return;
- }
-
- while (*p && *p != ' ' && *p != '\t') p++;
- len = p - typename;
- while (*p == ' ' || *p == '\t') p++;
-
- if (len == 6 && !strncmp (typename, "struct", 6))
- type = lookup_struct (p, b);
- else if (len == 5 && !strncmp (typename, "union", 5))
- type = lookup_union (p, b);
- else if (len == 4 && !strncmp (typename, "enum", 4))
- type = lookup_enum (p, b);
- else
- {
- type = lookup_typename (typename, b, 1);
- if (type == 0)
- {
- register struct symbol *sym
- = lookup_symbol (typename, b, STRUCT_NAMESPACE, 0,
- (struct symtab **)NULL);
- if (sym == 0)
- {
- /* It's not the name of a type, either VAR_NAMESPACE
- or STRUCT_NAMESPACE, so it must be an expression. */
- whatis_exp (typename, 1);
- return;
- }
- printf_filtered ("No type named %s, ", typename);
- wrap_here ("");
- printf_filtered ("but there is ");
- switch (TYPE_CODE (SYMBOL_TYPE (sym)))
- {
- case TYPE_CODE_STRUCT:
- printf_filtered ("a struct");
- break;
-
- case TYPE_CODE_UNION:
- printf_filtered ("a union");
- break;
-
- case TYPE_CODE_ENUM:
- printf_filtered ("an enum");
- break;
-
- default:
- printf_filtered ("(Internal error in gdb)");
- break;
- }
- printf_filtered (" %s. ", typename);
- wrap_here ("");
- printf_filtered ("(Type \"help ptype\".)\n");
- type = SYMBOL_TYPE (sym);
- }
- }
-
- type_print (type, "", stdout, 1);
- printf_filtered ("\n");
-}
\f
-#if 0
-/* This is not necessary. Instead, decode_line_1 takes any variable,
- so "info line foo" is a close equivalent to "whereis foo". */
-static void
-whereis_command (var, from_tty)
- char *var;
- int from_tty;
-{
- struct symtab *s;
- struct symbol *sym;
-
- if (var == NULL)
- error_no_arg ("Variable name.");
-
- sym = lookup_symbol (var, get_selected_block (), VAR_NAMESPACE,
- NULL, &s);
-
- if (sym != NULL && s != NULL)
- printf_filtered ("Symbol \"%s\" is at line %d of file %s\n",
- var, sym->line, s->filename);
- else
- {
- if (lookup_misc_func (var) >= 0)
- printf_filtered ("Symbol \"%s\" is in a file compiled without -g.",
- var);
- else
- error ("No symbol \"%s\" in current context.", var);
- }
-}
-#endif /* 0 */
-\f
-enum display_status {disabled, enabled};
-
-struct display
-{
- /* Chain link to next auto-display item. */
- struct display *next;
- /* Expression to be evaluated and displayed. */
- struct expression *exp;
- /* Item number of this auto-display item. */
- int number;
- /* Display format specified. */
- struct format_data format;
- /* Innermost block required by this expression when evaluated */
- struct block *block;
- /* Status of this display (enabled or disabled) */
- enum display_status status;
-};
-
-/* Chain of expressions whose values should be displayed
- automatically each time the program stops. */
-
-static struct display *display_chain;
-
-static int display_number;
-
/* Add an expression to the auto-display chain.
Specify the expression. */
}
innermost_block = 0;
- expr = parse_c_expression (exp);
+ expr = parse_expression (exp);
new = (struct display *) xmalloc (sizeof (struct display));
free_display (d)
struct display *d;
{
- free (d->exp);
- free (d);
+ free ((PTR)d->exp);
+ free ((PTR)d);
}
/* Clear out the display_chain.
{
register struct display *d;
- while (d = display_chain)
+ while ((d = display_chain) != NULL)
{
- free (d->exp);
+ free ((PTR)d->exp);
display_chain = d->next;
- free (d);
+ free ((PTR)d);
}
}
/* Delete the auto-display number NUM. */
-void
+static void
delete_display (num)
int num;
{
Specify the element numbers. */
static void
-undisplay_command (args)
+undisplay_command (args, from_tty)
char *args;
+ int from_tty;
{
register char *p = args;
register char *p1;
}
static void
-display_info ()
+display_info (ignore, from_tty)
+ char *ignore;
+ int from_tty;
{
register struct display *d;
}
}
-void
-enable_display (args)
+static void
+enable_display (args, from_tty)
char *args;
+ int from_tty;
{
register char *p = args;
register char *p1;
}
/* ARGSUSED */
-void
+static void
disable_display_command (args, from_tty)
char *args;
int from_tty;
QUIT;
sym = BLOCK_SYM (b, i);
- if (SYMBOL_CLASS (sym) != LOC_REGPARM
- && SYMBOL_CLASS (sym) != LOC_ARG
- && SYMBOL_CLASS (sym) != LOC_LOCAL_ARG
- && SYMBOL_CLASS (sym) != LOC_REF_ARG)
- continue;
-
- /* We have to re-look-up the symbol because arguments often have
- two entries (one a parameter, one a register or local), and the one
- we want is the non-parm, which lookup_symbol will find for
- us. After this, sym could be any SYMBOL_CLASS... */
- sym = lookup_symbol (SYMBOL_NAME (sym),
- b, VAR_NAMESPACE, (int *)NULL, (struct symtab **)NULL);
+ /* Keep track of the highest stack argument offset seen, and
+ skip over any kinds of symbols we don't care about. */
switch (SYMBOL_CLASS (sym)) {
-
- /* Keep track of the highest stack argument offset seen */
case LOC_ARG:
case LOC_REF_ARG:
{
args_printed += (arg_size + sizeof (int) - 1) / sizeof (int);
}
- /* Other types of symbols don't need to be kept track of. */
- default:
+ /* We care about types of symbols, but don't need to keep track of
+ stack offsets in them. */
+ case LOC_REGPARM:
+ case LOC_REGPARM_ADDR:
+ case LOC_LOCAL_ARG:
break;
+
+ /* Other types of symbols we just skip over. */
+ default:
+ continue;
}
+ /* We have to look up the symbol because arguments can have
+ two entries (one a parameter, one a local) and the one we
+ want is the local, which lookup_symbol will find for us.
+ This includes gcc1 (not gcc2) on the sparc when passing a
+ small structure and gcc2 when the argument type is float
+ and it is passed as a double and converted to float by
+ the prologue (in the latter case the type of the LOC_ARG
+ symbol is double and the type of the LOC_LOCAL symbol is
+ float). There are also LOC_ARG/LOC_REGISTER pairs which
+ are not combined in symbol-reading. */
+ /* But if the parameter name is null, don't try it.
+ Null parameter names occur on the RS/6000, for traceback tables.
+ FIXME, should we even print them? */
+
+ if (*SYMBOL_NAME (sym))
+ sym = lookup_symbol
+ (SYMBOL_NAME (sym),
+ b, VAR_NAMESPACE, (int *)NULL, (struct symtab **)NULL);
+
/* Print the current arg. */
if (! first)
fprintf_filtered (stream, ", ");
wrap_here (" ");
- fprint_symbol (stream, SYMBOL_NAME (sym));
+ fprintf_symbol_filtered (stream, SYMBOL_SOURCE_NAME (sym),
+ SYMBOL_LANGUAGE (sym), DMGL_PARAMS | DMGL_ANSI);
fputs_filtered ("=", stream);
/* Avoid value_print because it will deref ref parameters. We just
if (num != -1)
{
long start;
- CORE_ADDR addr;
if (highest_offset == -1)
start = FRAME_ARGS_SKIP;
else
start = highest_offset;
- addr = FRAME_ARGS_ADDRESS (fi);
- if (addr)
- print_frame_nameless_args (addr, start, num - args_printed,
- first, stream);
+ print_frame_nameless_args (fi, start, num - args_printed,
+ first, stream);
}
}
/* Print nameless args on STREAM.
- ARGSADDR is the address of the arglist, START is the offset
+ FI is the frameinfo for this frame, START is the offset
of the first nameless arg, and NUM is the number of nameless args to
print. FIRST is nonzero if this is the first argument (not just
the first nameless arg). */
static void
-print_frame_nameless_args (argsaddr, start, num, first, stream)
- CORE_ADDR argsaddr;
+print_frame_nameless_args (fi, start, num, first, stream)
+ struct frame_info *fi;
long start;
int num;
int first;
FILE *stream;
{
int i;
+ CORE_ADDR argsaddr;
+ long arg_value;
+
for (i = 0; i < num; i++)
{
QUIT;
+#ifdef NAMELESS_ARG_VALUE
+ NAMELESS_ARG_VALUE (fi, start, &arg_value);
+#else
+ argsaddr = FRAME_ARGS_ADDRESS (fi);
+ if (!argsaddr)
+ return;
+
+ arg_value = read_memory_integer (argsaddr + start, sizeof (int));
+#endif
+
if (!first)
fprintf_filtered (stream, ", ");
-#ifndef PRINT_TYPELESS_INTEGER
- fprintf_filtered (stream, "%d",
- read_memory_integer (argsaddr + start, sizeof (int)));
+
+#ifdef PRINT_NAMELESS_INTEGER
+ PRINT_NAMELESS_INTEGER (stream, arg_value);
#else
- PRINT_TYPELESS_INTEGER (stream, builtin_type_int,
- (LONGEST)
- read_memory_integer (argsaddr + start,
- sizeof (int)));
-#endif
+#ifdef PRINT_TYPELESS_INTEGER
+ PRINT_TYPELESS_INTEGER (stream, builtin_type_int, (LONGEST) arg_value);
+#else
+ fprintf_filtered (stream, "%d", arg_value);
+#endif /* PRINT_TYPELESS_INTEGER */
+#endif /* PRINT_NAMELESS_INTEGER */
first = 0;
start += sizeof (int);
}
{
char *s1;
if (nargs == allocated_args)
- val_args = (value *) xrealloc (val_args,
+ val_args = (value *) xrealloc ((char *) val_args,
(allocated_args *= 2)
* sizeof (value));
s1 = s;
argindex += sizeof (double);
}
else
-#ifdef LONG_LONG
+#ifdef CC_HAS_LONG_LONG
if (argclass[i] == long_long_arg)
{
- *(long long *) &arg_bytes[argindex] = value_as_long (val_args[i]);
- argindex += sizeof (long long);
+ *(LONGEST *) &arg_bytes[argindex] = value_as_long (val_args[i]);
+ argindex += sizeof (LONGEST);
}
else
#endif
containing_function_bounds (pc, low, high)
CORE_ADDR pc, *low, *high;
{
- int scan;
+ CORE_ADDR scan;
+ CORE_ADDR limit;
+ struct obj_section *sec;
if (!find_pc_partial_function (pc, 0, low))
return 0;
+ sec = find_pc_section (pc);
+ if (sec == NULL)
+ return 0;
+ limit = sec->endaddr;
+
scan = *low;
- do {
- scan++;
- if (!find_pc_partial_function (scan, 0, high))
- return 0;
- } while (*low == *high);
-
+ while (scan < limit)
+ {
+ ++scan;
+ if (!find_pc_partial_function (scan, 0, high))
+ return 0;
+ if (*low != *high)
+ return 1;
+ }
+ *high = limit;
return 1;
}
printf_filtered ("for function %s:\n", name);
}
else
- printf_filtered ("from 0x%x to 0x%x:\n", low, high);
+ {
+ printf_filtered ("from %s ", local_hex_string(low));
+ printf_filtered ("to %s:\n", local_hex_string(high));
+ }
/* Dump the specified range. */
for (pc = low; pc < high; )
ADDRESS is an expression for the memory address to examine.\n\
FMT is a repeat count followed by a format letter and a size letter.\n\
Format letters are o(octal), x(hex), d(decimal), u(unsigned decimal),\n\
- f(float), a(address), i(instruction), c(char) and s(string).\n\
+ t(binary), f(float), a(address), i(instruction), c(char) and s(string).\n\
Size letters are b(byte), h(halfword), w(word), g(giant, 8 bytes).\n\
- g is meaningful only with f, for type double.\n\
The specified number of objects of the specified size are printed\n\
according to the format.\n\n\
Defaults for format and size letters are those previously used.\n\
With a single argument, the function surrounding that address is dumped.\n\
Two arguments are taken as a range of memory to dump.");
- add_com ("ptype", class_vars, ptype_command,
- "Print definition of type TYPE.\n\
-Argument may be a type name defined by typedef, or \"struct STRUCTNAME\"\n\
-or \"union UNIONNAME\" or \"enum ENUMNAME\".\n\
-The selected stack frame's lexical context is used to look up the name.");
-
- add_com ("whatis", class_vars, whatis_command,
- "Print data type of expression EXP.");
-
#if 0
add_com ("whereis", class_vars, whereis_command,
"Print line number and file of definition of variable.");
This is useful in user-defined commands.");
add_prefix_cmd ("set", class_vars, set_command,
-"Perform an assignment VAR = EXP.\n\
-You must type the \"=\". VAR may be a debugger \"convenience\" variable\n\
-(names starting with $), a register (a few standard names starting with $),\n\
-or an actual variable in the program being debugged. EXP is any expression.\n\
+"Evaluate expression EXP and assign result to variable VAR, using assignment\n\
+syntax appropriate for the current language (VAR = EXP or VAR := EXP for\n\
+example). VAR may be a debugger \"convenience\" variable (names starting\n\
+with $), a register (a few standard names starting with $), or an actual\n\
+variable in the program being debugged. EXP is any valid expression.\n\
Use \"set variable\" for variables with names identical to set subcommands.\n\
\nWith a subcommand, this command modifies parts of the gdb environment.\n\
You can see these environment settings with the \"show\" command.",
/* "call" is the same as "set", but handy for dbx users to call fns. */
add_com ("call", class_vars, call_command,
- "Call a function in the inferior process.\n\
-The argument is the function name and arguments, in standard C notation.\n\
-The result is printed and saved in the value history, if it is not void.");
+ "Call a function in the program.\n\
+The argument is the function name and arguments, in the notation of the\n\
+current working language. The result is printed and saved in the value\n\
+history, if it is not void.");
add_cmd ("variable", class_vars, set_command,
- "Perform an assignment VAR = EXP.\n\
-You must type the \"=\". VAR may be a debugger \"convenience\" variable\n\
-(names starting with $), a register (a few standard names starting with $),\n\
-or an actual variable in the program being debugged. EXP is any expression.\n\
+"Evaluate expression EXP and assign result to variable VAR, using assignment\n\
+syntax appropriate for the current language (VAR = EXP or VAR := EXP for\n\
+example). VAR may be a debugger \"convenience\" variable (names starting\n\
+with $), a register (a few standard names starting with $), or an actual\n\
+variable in the program being debugged. EXP is any valid expression.\n\
This may usually be abbreviated to simply \"set\".",
&setlist);
resides in memory.\n",
"\n\
EXP may be preceded with /FMT, where FMT is a format letter\n\
-but no count or size letter (see \"x\" command)."));
+but no count or size letter (see \"x\" command).", NULL));
add_com_alias ("p", "print", class_vars, 1);
add_com ("inspect", class_vars, inspect_command,
"Same as \"print\" command, except that if you are running in the epoch\n\
environment, the value is printed in its own window.");
+
+ add_show_from_set (
+ add_set_cmd ("max-symbolic-offset", no_class, var_uinteger,
+ (char *)&max_symbolic_offset,
+ "Set the largest offset that will be printed in <symbol+1234> form.",
+ &setprintlist),
+ &showprintlist);
+ add_show_from_set (
+ add_set_cmd ("symbol-filename", no_class, var_boolean,
+ (char *)&print_symbol_filename,
+ "Set printing of source filename and line number with <symbol>.",
+ &setprintlist),
+ &showprintlist);
}