use remote-utils facilities for baud_rate
[deliverable/binutils-gdb.git] / gdb / printcmd.c
index 54b5d942bcb85eb317d11ac109892c534dd72102..bd9035376c85d2caceceb0838b2f42345015529f 100644 (file)
@@ -19,6 +19,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
 #include "defs.h"
 #include <string.h>
+#include <varargs.h>
 #include "frame.h"
 #include "symtab.h"
 #include "gdbtypes.h"
@@ -31,12 +32,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #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 " */
 
@@ -127,9 +122,6 @@ 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));
 
@@ -318,7 +310,7 @@ print_formatted (val, format, size)
         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");
+      wrap_here ("    ");
       next_address = VALUE_ADDRESS (val)
        + print_insn (VALUE_ADDRESS (val), stdout);
       break;
@@ -595,7 +587,9 @@ print_address (addr, stream)
      CORE_ADDR addr;
      FILE *stream;
 {
-#ifdef ADDR_BITS_REMOVE
+#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);
@@ -933,50 +927,36 @@ address_info (exp, from_tty)
       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_REGPARM_ADDR:
+      printf ("address of an argument in register %s", reg_names[val]);
+      break;
+
     case LOC_ARG:
-      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);
-       }
+      printf ("an argument at offset %ld", val);
       break;
 
     case LOC_LOCAL_ARG:
-      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);
-       }
+      printf ("an argument at frame offset %ld", val);
       break;
 
     case LOC_LOCAL:
-      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);
-       }
+      printf ("a local variable at frame offset %ld", val);
       break;
 
     case LOC_REF_ARG:
       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;
@@ -1500,6 +1480,7 @@ print_frame_args (func, fi, num, stream)
       case LOC_REGPARM:
       case LOC_REGPARM_ADDR:
       case LOC_LOCAL_ARG:
+      case LOC_BASEREG_ARG:
        break;
 
       /* Other types of symbols we just skip over.  */
@@ -1611,6 +1592,86 @@ print_frame_nameless_args (fi, start, num, first, stream)
     }
 }
 \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)
@@ -1623,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));
 
@@ -1698,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;
@@ -1725,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;
@@ -1757,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)
@@ -1788,86 +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 CC_HAS_LONG_LONG
          if (argclass[i] == long_long_arg)
            {
-             *(LONGEST *) &arg_bytes[argindex] = value_as_long (val_args[i]);
-             argindex += sizeof (LONGEST);
+             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)
-  /* This is defined by an 88k using gcc1.  Do other machines use it?  */
-  {
-    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.  */
-#ifdef VPRINTF
-  VPRINTF (string, arg_bytes);
-#else /* No VPRINTF.  */
-  vprintf (string, (PTR) arg_bytes);
-#endif /* No VPRINTF.  */
-#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;
-{
-  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;
-  while (scan < limit)
-    {
-      ++scan;
-      if (!find_pc_partial_function (scan, 0, high))
-       return 0;
-      if (*low != *high)
-       return 1;
-    }
-  *high = limit;
-  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
@@ -1882,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
     {
@@ -1910,10 +1933,8 @@ 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
This page took 0.027993 seconds and 4 git commands to generate.