use remote-utils facilities for baud_rate
[deliverable/binutils-gdb.git] / gdb / printcmd.c
index 9e75ab2d22b7648c976ccf4efeedd1dec244dd47..bd9035376c85d2caceceb0838b2f42345015529f 100644 (file)
@@ -17,9 +17,9 @@ You should have received a copy of the GNU General Public License
 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 <string.h>
+#include <varargs.h>
 #include "frame.h"
 #include "symtab.h"
 #include "gdbtypes.h"
@@ -30,6 +30,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "gdbcmd.h"
 #include "target.h"
 #include "breakpoint.h"
+#include "demangle.h"
 
 extern int asm_demangle;       /* Whether to demangle syms in asm printouts */
 extern int addressprint;       /* Whether to print hex addresses in HLL " */
@@ -62,8 +63,17 @@ static CORE_ADDR last_examine_address;
 
 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;
@@ -75,8 +85,6 @@ int current_display_number;
 
 int inspect_it = 0;
 
-enum display_status {disabled, enabled};
-
 struct display
 {
   /* Chain link to next auto-display item.  */
@@ -90,7 +98,7 @@ struct display
   /* Innermost block required by this expression when evaluated */
   struct block *block;
   /* Status of this display (enabled or disabled) */
-  enum display_status status;
+  enum enable status;
 };
 
 /* Chain of expressions whose values should be displayed
@@ -106,7 +114,7 @@ static void
 delete_display PARAMS ((int));
 
 static void
-enable_display PARAMS ((char *));
+enable_display PARAMS ((char *, int));
 
 static void
 disable_display_command PARAMS ((char *, int));
@@ -114,23 +122,21 @@ 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 ((CORE_ADDR, long, int, int, FILE *));
+print_frame_nameless_args PARAMS ((struct frame_info *, long, int, int,
+                                  FILE *));
 
 static void
-display_info PARAMS ((void));
+display_info PARAMS ((char *, int));
 
 static void
 do_one_display PARAMS ((struct display *));
 
 static void
-undisplay_command PARAMS ((char *));
+undisplay_command PARAMS ((char *, int));
 
 static void
 free_display PARAMS ((struct display *));
@@ -138,18 +144,6 @@ free_display PARAMS ((struct display *));
 static void
 display_command PARAMS ((char *, int));
 
-static void
-ptype_command PARAMS ((char *, int));
-
-static struct type *
-ptype_eval PARAMS ((struct expression *));
-
-static void
-whatis_command PARAMS ((char *, int));
-
-static void
-whatis_exp PARAMS ((char *, int));
-
 static void
 x_command PARAMS ((char *, int));
 
@@ -220,7 +214,7 @@ decode_format (string_ptr, oformat, osize)
     {
       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';
@@ -233,7 +227,7 @@ decode_format (string_ptr, oformat, osize)
        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')
@@ -311,7 +305,12 @@ print_formatted (val, format, size)
       break;
 
     case 'i':
-      wrap_here ("");  /* Force output out, print_insn not using _filtered */
+      /* 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 ("    ");
       next_address = VALUE_ADDRESS (val)
        + print_insn (VALUE_ADDRESS (val), stdout);
       break;
@@ -319,6 +318,7 @@ print_formatted (val, format, size)
     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))
@@ -347,39 +347,25 @@ print_scalar_formatted (valaddr, type, format, size, stream)
   LONGEST val_long;
   int len = TYPE_LENGTH (type);
 
-  if (size == 'g' && sizeof (LONGEST) < 8
-      && format == 'x')
+  if (len > sizeof (LONGEST)
+      && (format == 't'
+         || format == 'c'
+         || format == 'o'
+         || format == 'u'
+         || format == 'd'
+         || format == 'x'))
     {
-      /* ok, we're going to have to get fancy here.  Assumption: a
-         long is four bytes.  FIXME.  */
-      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 */
-      {
-        unsigned long tmp;
-
-        tmp = v1;
-        v1 = v2;
-        v2 = tmp;
-      }
-#endif
-  
-      switch (format)
-       {
-       case 'x':
-         fprintf_filtered (stream, local_hex_format_custom("08x%08"), v1, v2);
-         break;
-       default:
-         error ("Output size \"g\" unimplemented for format \"%c\".",
-                format);
-       }
+      /* We can't print it normally, but we can print it in hex.
+         Printing it in the wrong radix is more useful than saying
+        "use /x, you dummy".  */
+      /* FIXME:  we could also do octal or binary if that was the
+        desired format.  */
+      /* FIXME:  we should be using the size field to give us a minimum
+        field width to print.  */
+      val_print_type_code_int (type, valaddr, stream);
       return;
     }
-      
+
   val_long = unpack_long (type, valaddr);
 
   /* If value is unsigned, truncate it in case negative.  */
@@ -399,75 +385,33 @@ print_scalar_formatted (valaddr, type, format, size, stream)
       if (!size)
        {
          /* no size specified, like in print.  Print varying # of digits. */
-#if defined (LONG_LONG)
-         fprintf_filtered (stream, local_hex_format_custom("ll"), val_long);
-#else /* not LONG_LONG.  */
-         fprintf_filtered (stream, local_hex_format_custom("l"), 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, 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:
-         error ("Undefined output size \"%c\".", size);
-       }
-#else /* not LONG_LONG.  */
-      switch (size)
-       {
-       case 'b':
-         fprintf_filtered (stream, local_hex_format_custom("02"), val_long);
-         break;
-       case 'h':
-         fprintf_filtered (stream, local_hex_format_custom("04"), val_long);
-         break;
-       case 'w':
-         fprintf_filtered (stream, local_hex_format_custom("08"), val_long);
-         break;
-       case 'g':
-         fprintf_filtered (stream, local_hex_format_custom("016"), 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, local_octal_format_custom("ll"), val_long);
-#else
-       fprintf_filtered (stream, local_octal_format(), val_long);
-#endif
+       print_longest (stream, 'o', 1, val_long);
       else
        fprintf_filtered (stream, "0");
       break;
@@ -533,7 +477,9 @@ print_scalar_formatted (valaddr, type, format, size, stream)
            if (*cp == '\0')
              cp--;
          }
+       fprintf_filtered (stream, local_binary_format_prefix());
         fprintf_filtered (stream, cp);
+       fprintf_filtered (stream, local_binary_format_suffix());
       }
       break;
 
@@ -561,7 +507,8 @@ set_next_address (addr)
    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)
@@ -570,25 +517,65 @@ print_address_symbolic (addr, stream, do_demangle, leadin)
      int do_demangle;
      char *leadin;
 {
-  int name_location;
-  register struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (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 (msymbol == NULL)
+  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 (msymbol -> name, stream, 1);
-  else
-    fputs_filtered (msymbol -> name, stream);
-  name_location = msymbol -> 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.
@@ -600,7 +587,13 @@ print_address (addr, stream)
      CORE_ADDR addr;
      FILE *stream;
 {
+#if 0 && defined (ADDR_BITS_REMOVE)
+  /* This is wrong for pointer to char, in which we do want to print
+     the low bits.  */
+  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, " ");
 }
 
@@ -658,7 +651,7 @@ do_examine (fmt, addr)
   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;
@@ -710,6 +703,11 @@ validate_format (fmt, cmdname)
           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;
@@ -839,7 +837,7 @@ output_command (exp, from_tty)
     {
       exp++;
       fmt = decode_format (&exp, 0, 0);
-      validate_format (fmt, "print");
+      validate_format (fmt, "output");
       format = fmt.format;
     }
 
@@ -875,6 +873,7 @@ address_info (exp, 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'. */
 
@@ -883,7 +882,7 @@ address_info (exp, from_tty)
 
   sym = lookup_symbol (exp, get_selected_block (), VAR_NAMESPACE, 
                       &is_a_field_of_this, (struct symtab **)NULL);
-  if (sym == 0)
+  if (sym == NULL)
     {
       if (is_a_field_of_this)
        {
@@ -895,7 +894,7 @@ address_info (exp, from_tty)
 
       if (msymbol != NULL)
        printf ("Symbol \"%s\" is at %s in a file compiled without debugging.\n",
-               exp, local_hex_string(msymbol -> address));
+               exp, local_hex_string(SYMBOL_VALUE_ADDRESS (msymbol)));
       else
        error ("No symbol \"%s\" in current context.", exp);
       return;
@@ -903,6 +902,7 @@ address_info (exp, from_tty)
 
   printf ("Symbol \"%s\" is ", SYMBOL_NAME (sym));
   val = SYMBOL_VALUE (sym);
+  basereg = SYMBOL_BASEREG (sym);
 
   switch (SYMBOL_CLASS (sym))
     {
@@ -926,7 +926,11 @@ address_info (exp, from_tty)
     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);
       break;
@@ -943,6 +947,16 @@ address_info (exp, from_tty)
       printf ("a reference argument at offset %ld", val);
       break;
 
+    case LOC_BASEREG:
+      printf ("a variable at offset %ld from register %s",
+             val, reg_names[basereg]);
+      break;
+
+    case LOC_BASEREG_ARG:
+      printf ("an argument at offset %ld from register %s",
+             val, reg_names[basereg]);
+      break;
+
     case LOC_TYPEDEF:
       printf ("a typedef");
       break;
@@ -952,6 +966,10 @@ address_info (exp, from_tty)
              local_hex_string(BLOCK_START (SYMBOL_BLOCK_VALUE (sym))));
       break;
 
+    case LOC_OPTIMIZED_OUT:
+      printf_filtered ("optimized out");
+      break;
+      
     default:
       printf ("of unknown (botched) type");
       break;
@@ -977,8 +995,6 @@ x_command (exp, from_tty)
     {
       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.  */
@@ -1008,6 +1024,10 @@ x_command (exp, from_tty)
 
   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)
     {
@@ -1022,94 +1042,7 @@ x_command (exp, from_tty)
       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_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);
-}
-
-/* Simple subroutine for ptype_command.  */
-static
-struct type *
-ptype_eval(exp)
-   struct expression *exp;
-{
-   if(exp->elts[0].opcode==OP_TYPE)
-      return exp->elts[1].type;
-   else
-      return 0;
-}
-
-/* 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 struct type *type;
-  struct expression *expr;
-  register struct cleanup *old_chain;
-
-  if (typename)
-  {
-     expr = parse_expression (typename);
-     old_chain = make_cleanup (free_current_contents, &expr);
-     type = ptype_eval (expr);
-
-     if(type)
-     {
-       printf_filtered ("type = ");
-       type_print (type, "", stdout, 1);
-       printf_filtered ("\n");
-       do_cleanups (old_chain);
-     }
-     else
-     {
-       do_cleanups (old_chain);
-       whatis_exp (typename, 1);
-     }
-  }
-  else
-     whatis_exp (typename, 1);
-}
 \f
 /* Add an expression to the auto-display chain.
    Specify the expression.  */
@@ -1168,8 +1101,8 @@ static void
 free_display (d)
      struct display *d;
 {
-  free (d->exp);
-  free (d);
+  free ((PTR)d->exp);
+  free ((PTR)d);
 }
 
 /* Clear out the display_chain.
@@ -1181,11 +1114,11 @@ clear_displays ()
 {
   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);
     }
 }
 
@@ -1225,8 +1158,9 @@ delete_display (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;
@@ -1361,7 +1295,9 @@ disable_current_display ()
 }
 
 static void
-display_info ()
+display_info (ignore, from_tty)
+     char *ignore;
+     int from_tty;
 {
   register struct display *d;
 
@@ -1388,8 +1324,9 @@ Num Enb Expression\n");
 }
 
 static void
-enable_display (args)
+enable_display (args, from_tty)
      char *args;
+     int from_tty;
 {
   register char *p = args;
   register char *p1;
@@ -1541,7 +1478,9 @@ print_frame_args (func, fi, num, stream)
       /* 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:
+      case LOC_BASEREG_ARG:
        break;
 
       /* Other types of symbols we just skip over.  */
@@ -1549,18 +1488,31 @@ print_frame_args (func, fi, num, stream)
        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);
+      /* 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
@@ -1582,53 +1534,144 @@ print_frame_args (func, fi, num, stream)
   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);
     }
 }
 \f
+/* This is an interface which allows to us make a va_list.  */
+typedef struct {
+  unsigned int nargs;
+  unsigned int max_arg_size;
+
+  /* Current position in bytes.  */
+  unsigned int argindex;
+
+#ifdef MAKEVA_EXTRA_INFO
+  /* For host dependent information.  */
+  MAKEVA_EXTRA_INFO
+#endif
+
+  /* Some systems (mips, pa) would like this to be aligned, and it never
+     will hurt.  */
+  union
+    {
+      char arg_bytes[1];
+      double force_double_align;
+      LONGEST force_long_align;
+    } aligner;
+} makeva_list;
+
+/* Tell the caller how many bytes to allocate for a makeva_list with NARGS
+   arguments and whose largest argument is MAX_ARG_SIZE bytes.  This
+   way the caller can use alloca, malloc, or some other allocator.  */
+unsigned int
+makeva_size (nargs, max_arg_size)
+     unsigned int nargs;
+     unsigned int max_arg_size;
+{
+  return sizeof (makeva_list) + nargs * max_arg_size;
+}
+
+/* Start working on LIST with NARGS arguments and whose largest
+   argument is MAX_ARG_SIZE bytes.  */
+void
+makeva_start (list, nargs, max_arg_size)
+     makeva_list *list;
+     unsigned int nargs;
+     unsigned int max_arg_size;
+{
+  list->nargs = nargs;
+  list->max_arg_size = max_arg_size;
+#if defined (MAKEVA_START)
+  MAKEVA_START (list);
+#else
+  list->argindex = 0;
+#endif
+}
+
+/* Add ARG to LIST.  */
+void
+makeva_arg (list, argaddr, argsize)
+     makeva_list *list;
+     PTR argaddr;
+     unsigned int argsize;
+{
+#if defined (MAKEVA_ARG)
+  MAKEVA_ARG (list, argaddr, argsize);
+#else
+  memcpy (&list->aligner.arg_bytes[list->argindex], argaddr, argsize);
+  list->argindex += argsize;
+#endif
+}
+
+/* From LIST, for which makeva_arg has been called for each arg,
+   return a va_list containing the args.  */
+va_list
+makeva_end (list)
+     makeva_list *list;
+{
+#if defined (MAKEVA_END)
+  MAKEVA_END (list);
+#else
+  /* This works if a va_list is just a pointer to the arguments.  */
+  return (va_list) list->aligner.arg_bytes;
+#endif
+}
+\f
 /* ARGSUSED */
 static void
 printf_command (arg, from_tty)
@@ -1641,7 +1684,7 @@ printf_command (arg, from_tty)
   value *val_args;
   int nargs = 0;
   int allocated_args = 20;
-  char *arg_bytes;
+  va_list args_to_vprintf;
 
   val_args = (value *) xmalloc (allocated_args * sizeof (value));
 
@@ -1716,10 +1759,15 @@ printf_command (arg, from_tty)
     enum argclass {int_arg, string_arg, double_arg, long_long_arg};
     enum argclass *argclass;
     int nargs_wanted;
-    int argindex;
     int lcount;
     int i;
+    /* We build up a va_list to pass to vprintf.  This is unnecessary;
+       instead of calling vprintf ("%d%f", <constructed va_list>) we
+       could just call printf ("%d", arg1); printf ("%f", arg2);.  Funny
+       how I thought of that right *after* I got the MAKEVA stuff pretty much
+       working...  */
+    makeva_list *args_makeva;
+
     argclass = (enum argclass *) alloca (strlen (s) * sizeof *argclass);
     nargs_wanted = 0;
     f = string;
@@ -1743,10 +1791,10 @@ printf_command (arg, from_tty)
            argclass[nargs_wanted++] = int_arg;
          f++;
        }
+
     /* Now, parse all arguments and evaluate them.
        Store the VALUEs in VAL_ARGS.  */
+
     while (*s != '\0')
       {
        char *s1;
@@ -1775,12 +1823,13 @@ printf_command (arg, from_tty)
  
     if (nargs != nargs_wanted)
       error ("Wrong number of arguments for specified format-string");
+
     /* Now lay out an argument-list containing the arguments
        as doubles, integers and C pointers.  */
-    arg_bytes = (char *) alloca (sizeof (double) * nargs);
-    argindex = 0;
+
+    args_makeva = (makeva_list *)
+      alloca (makeva_size (nargs, sizeof (double)));
+    makeva_start (args_makeva, nargs, sizeof (double));
     for (i = 0; i < nargs; i++)
       {
        if (argclass[i] == string_arg)
@@ -1806,71 +1855,40 @@ printf_command (arg, from_tty)
            str[j] = 0;
  
            /* Pass address of internal copy as the arg to vprintf.  */
-           *((int *) &arg_bytes[argindex]) = (int) str;
-           argindex += sizeof (int);
+           makeva_arg (args_makeva, &str, sizeof (str));
          }
        else if (VALUE_TYPE (val_args[i])->code == TYPE_CODE_FLT)
          {
-           *((double *) &arg_bytes[argindex]) = value_as_double (val_args[i]);
-           argindex += sizeof (double);
+           double val = value_as_double (val_args[i]);
+           makeva_arg (args_makeva, &val, sizeof (val));
          }
        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);
+             long long val = value_as_long (val_args[i]);
+             makeva_arg (args_makeva, &val, sizeof (val));
            }
          else
 #endif
            {
-             *((long *) &arg_bytes[argindex]) = value_as_long (val_args[i]);
-             argindex += sizeof (long);
+             long val = value_as_long (val_args[i]);
+             makeva_arg (args_makeva, &val, sizeof (val));
            }
       }
+    args_to_vprintf = makeva_end (args_makeva);
   }
 
-  /* There is not a standard way to make a va_list, so we need
-     to do various things for different systems.  */
-#if defined (__INT_VARARGS_H)
-  {
-    va_list list;
+  /* FIXME: We should be using vprintf_filtered, but as long as it has an
+     arbitrary limit that is unacceptable.  Correct fix is for vprintf_filtered
+     to scan down the format string so it knows how big a buffer it needs.
 
-    list.__va_arg = 0;
-    list.__va_stk = (int *) arg_bytes;
-    list.__va_reg = (int *) arg_bytes;
-    vprintf (string, list);
-  }
-#else /* No __INT_VARARGS_H.  */
-  vprintf (string, arg_bytes);
-#endif /* No __INT_VARARGS_H.  */
+     But for now, just force out any pending output, so at least the output
+     appears in the correct order.  */
+  wrap_here ((char *)NULL);
+  vprintf (string, args_to_vprintf);
 }
 \f
-/* Helper function for asdump_command.  Finds the bounds of a function
-   for a specified section of text.  PC is an address within the
-   function which you want bounds for; *LOW and *HIGH are set to the
-   beginning (inclusive) and end (exclusive) of the function.  This
-   function returns 1 on success and 0 on failure.  */
-
-static int
-containing_function_bounds (pc, low, high)
-     CORE_ADDR pc, *low, *high;
-{
-  int scan;
-
-  if (!find_pc_partial_function (pc, 0, low))
-    return 0;
-
-  scan = *low;
-  do {
-    scan++;
-    if (!find_pc_partial_function (scan, 0, high))
-      return 0;
-  } while (*low == *high);
-
-  return 1;
-}
-
 /* Dump a specified section of assembly code.  With no command line
    arguments, this command will dump the assembly code for the
    function surrounding the pc value in the selected frame.  With one
@@ -1885,24 +1903,26 @@ disassemble_command (arg, from_tty)
      int from_tty;
 {
   CORE_ADDR low, high;
+  char *name;
   CORE_ADDR pc;
   char *space_index;
 
+  name = NULL;
   if (!arg)
     {
       if (!selected_frame)
        error ("No frame selected.\n");
 
       pc = get_frame_pc (selected_frame);
-      if (!containing_function_bounds (pc, &low, &high))
-       error ("No function contains pc specified by selected frame.\n");
+      if (find_pc_partial_function (pc, &name, &low, &high) == 0)
+       error ("No function contains program counter for selected frame.\n");
     }
   else if (!(space_index = (char *) strchr (arg, ' ')))
     {
       /* One argument.  */
       pc = parse_and_eval_address (arg);
-      if (!containing_function_bounds (pc, &low, &high))
-       error ("No function contains specified pc.\n");
+      if (find_pc_partial_function (pc, &name, &low, &high) == 0)
+       error ("No function contains specified address.\n");
     }
   else
     {
@@ -1913,15 +1933,15 @@ disassemble_command (arg, from_tty)
     }
 
   printf_filtered ("Dump of assembler code ");
-  if (!space_index)
+  if (name != NULL)
     {
-      char *name;
-      find_pc_partial_function (pc, &name, 0);
       printf_filtered ("for function %s:\n", name);
     }
   else
-    printf_filtered ("from %s ", local_hex_string(low));
-    printf_filtered ("to %s:\n", local_hex_string(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; )
@@ -1950,9 +1970,8 @@ _initialize_printcmd ()
 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\
@@ -1965,15 +1984,6 @@ Default is the function surrounding the pc of the selected frame.\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.");
@@ -2025,10 +2035,11 @@ This is useful for formatted output in user-defined commands.");
 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.",
@@ -2036,16 +2047,17 @@ 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\
+          "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);
 
@@ -2076,4 +2088,17 @@ but no count or size letter (see \"x\" command).", NULL));
   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);
 }
This page took 0.035757 seconds and 4 git commands to generate.