* config/m68k/monitor.mt (TDEPFILE): Add remote-es.o.
[deliverable/binutils-gdb.git] / gdb / printcmd.c
index ce6b96623bf7d67ca09bfbc3421df1eb4e434a33..f6be18420a28b71edb02d173c28a86a0661229a0 100644 (file)
@@ -1,5 +1,6 @@
 /* Print values for GNU debugger GDB.
-   Copyright 1986, 1987, 1988, 1989, 1990, 1991 Free Software Foundation, Inc.
+   Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1993, 1994
+             Free Software Foundation, Inc.
 
 This file is part of GDB.
 
@@ -73,6 +74,11 @@ static unsigned int max_symbolic_offset = UINT_MAX;
    printing a symbolic value as `<symbol at filename:linenum>' if set.  */
 static int print_symbol_filename = 0;
 
+/* Switch for quick display of symbolic addresses -- only uses minsyms,
+   not full search of symtabs.  */
+
+int fast_symbolic_addr = 1;
+
 /* Number of auto-display expression currently being displayed.
    So that we can disable it if we get an error or a signal within it.
    -1 when not doing one.  */
@@ -497,10 +503,11 @@ set_next_address (addr)
 
 /* Optionally print address ADDR symbolically as <SYMBOL+OFFSET> on STREAM,
    after LEADIN.  Print nothing if no symbolic name is found nearby.
+   Optionally also print source file and line number, if available.
    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.  However note that DO_DEMANGLE can be overridden by the specific
-   settings of the demangle and asm_demangle variables. */
+   settings of the demangle and asm_demangle variables.  */
 
 void
 print_address_symbolic (addr, stream, do_demangle, leadin)
@@ -509,37 +516,51 @@ print_address_symbolic (addr, stream, do_demangle, leadin)
      int do_demangle;
      char *leadin;
 {
-  CORE_ADDR name_location;
-  register struct symbol *symbol;
+  struct minimal_symbol *msymbol;
+  struct symbol *symbol;
+  struct symtab *symtab = 0;
+  CORE_ADDR name_location = 0;
   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.  */
-  
-  symbol = find_pc_function (addr);
-  if (symbol)
+  /* First try to find the address in the symbol table, then
+     in the minsyms.  Take the closest one.  */
+
+  if (fast_symbolic_addr)
     {
-    name_location = BLOCK_START (SYMBOL_BLOCK_VALUE (symbol));
-    if (do_demangle)
-      name = SYMBOL_SOURCE_NAME (symbol);
-    else
-      name = SYMBOL_LINKAGE_NAME (symbol);
+      /* This is defective in the sense that it only finds text symbols.  */
+      symbol = find_pc_function (addr);
+      if (symbol)
+       name_location = BLOCK_START (SYMBOL_BLOCK_VALUE (symbol));
     }
   else
+    find_addr_symbol (addr, &symtab, &name_location);
+
+  if (symbol)
     {
-    register struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (addr);
+      if (do_demangle)
+       name = SYMBOL_SOURCE_NAME (symbol);
+      else
+       name = SYMBOL_LINKAGE_NAME (symbol);
+    }
 
-    /* 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);
+  msymbol = lookup_minimal_symbol_by_pc (addr);
+  if (msymbol != NULL)
+    {
+      if (SYMBOL_VALUE_ADDRESS (msymbol) > name_location || symbol == NULL)
+       {
+         /* The msymbol is closer to the address than the symbol;
+            use the msymbol instead.  */
+         symbol = 0;
+         symtab = 0;
+         name_location = SYMBOL_VALUE_ADDRESS (msymbol);
+         if (do_demangle)
+           name = SYMBOL_SOURCE_NAME (msymbol);
+         else
+           name = SYMBOL_LINKAGE_NAME (msymbol);
+       }
     }
+  if (symbol == NULL && msymbol == NULL)
+    return;
 
   /* If the nearest symbol is too far away, don't print anything symbolic.  */
 
@@ -558,18 +579,35 @@ print_address_symbolic (addr, stream, do_demangle, leadin)
   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)
+  /* Append source filename and line number if desired.  Give specific
+     line # of this addr, if we have it; else line # of the nearest symbol.  */
+  if (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);
+      else if (symtab && symbol && symbol->line)
+       fprintf_filtered (stream, " at %s:%d", symtab->filename, symbol->line);
+      else if (symtab)
+       fprintf_filtered (stream, " in %s", symtab->filename);
     }
   fputs_filtered (">", stream);
 }
 
+/* Print address ADDR on STREAM.  */
+void
+print_address_numeric (addr, stream)
+     CORE_ADDR addr;
+     GDB_FILE *stream;
+{
+  /* This assumes a CORE_ADDR can fit in a LONGEST.  Probably a safe
+     assumption.  We pass use_local but I'm not completely sure whether
+     that is correct.  When (if ever) should we *not* use_local?  */
+  print_longest (stream, 'x', 1, (unsigned LONGEST) addr);
+}
+
 /* Print address ADDR symbolically on STREAM.
    First print it as a number.  Then perhaps print
    <SYMBOL + OFFSET> after the number.  */
@@ -579,14 +617,7 @@ print_address (addr, stream)
      CORE_ADDR addr;
      GDB_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(),
-                   (unsigned long) ADDR_BITS_REMOVE(addr));
-#else
-  fprintf_filtered (stream, local_hex_format(), (unsigned long) addr);
-#endif
+  print_address_numeric (addr, stream);
   print_address_symbolic (addr, stream, asm_demangle, " ");
 }
 
@@ -601,14 +632,19 @@ print_address_demangle (addr, stream, do_demangle)
      GDB_FILE *stream;
      int do_demangle;
 {
-  if (addr == 0) {
-    fprintf_filtered (stream, "0");
-  } else if (addressprint) {
-    fprintf_filtered (stream, local_hex_format(), (unsigned long) addr);
-    print_address_symbolic (addr, stream, do_demangle, " ");
-  } else {
-    print_address_symbolic (addr, stream, do_demangle, "");
-  }
+  if (addr == 0)
+    {
+      fprintf_filtered (stream, "0");
+    }
+  else if (addressprint)
+    {
+      print_address_numeric (addr, stream);
+      print_address_symbolic (addr, stream, do_demangle, " ");
+    }
+  else
+    {
+      print_address_symbolic (addr, stream, do_demangle, "");
+    }
 }
 \f
 
@@ -883,22 +919,33 @@ address_info (exp, from_tty)
     {
       if (is_a_field_of_this)
        {
-         printf_unfiltered ("Symbol \"%s\" is a field of the local class variable `this'\n", exp);
+         printf_filtered ("Symbol \"");
+         fprintf_symbol_filtered (gdb_stdout, exp,
+                                  current_language->la_language, DMGL_ANSI);
+         printf_filtered ("\" is a field of the local class variable `this'\n");
          return;
        }
 
       msymbol = lookup_minimal_symbol (exp, (struct objfile *) NULL);
 
       if (msymbol != NULL)
-       printf_unfiltered ("Symbol \"%s\" is at %s in a file compiled without debugging.\n",
-               exp,
-               local_hex_string((unsigned long) SYMBOL_VALUE_ADDRESS (msymbol)));
+       {
+         printf_filtered ("Symbol \"");
+         fprintf_symbol_filtered (gdb_stdout, exp,
+                                  current_language->la_language, DMGL_ANSI);
+         printf_filtered ("\" is at ");
+         print_address_numeric (SYMBOL_VALUE_ADDRESS (msymbol), gdb_stdout);
+         printf_filtered (" in a file compiled without debugging.\n");
+       }
       else
        error ("No symbol \"%s\" in current context.", exp);
       return;
     }
 
-  printf_unfiltered ("Symbol \"%s\" is ", SYMBOL_NAME (sym));
+  printf_filtered ("Symbol \"");
+  fprintf_symbol_filtered (gdb_stdout, SYMBOL_NAME (sym),
+                          current_language->la_language, DMGL_ANSI);
+  printf_filtered ("\" is ", SYMBOL_NAME (sym));
   val = SYMBOL_VALUE (sym);
   basereg = SYMBOL_BASEREG (sym);
 
@@ -906,64 +953,65 @@ address_info (exp, from_tty)
     {
     case LOC_CONST:
     case LOC_CONST_BYTES:
-      printf_unfiltered ("constant");
+      printf_filtered ("constant");
       break;
 
     case LOC_LABEL:
-      printf_unfiltered ("a label at address %s",
-             local_hex_string((unsigned long) SYMBOL_VALUE_ADDRESS (sym)));
+      printf_filtered ("a label at address ");
+      print_address_numeric (SYMBOL_VALUE_ADDRESS (sym), gdb_stdout);
       break;
 
     case LOC_REGISTER:
-      printf_unfiltered ("a variable in register %s", reg_names[val]);
+      printf_filtered ("a variable in register %s", reg_names[val]);
       break;
 
     case LOC_STATIC:
-      printf_unfiltered ("static storage at address %s",
-             local_hex_string((unsigned long) SYMBOL_VALUE_ADDRESS (sym)));
+      printf_filtered ("static storage at address ");
+      print_address_numeric (SYMBOL_VALUE_ADDRESS (sym), gdb_stdout);
       break;
 
     case LOC_REGPARM:
-      printf_unfiltered ("an argument in register %s", reg_names[val]);
+      printf_filtered ("an argument in register %s", reg_names[val]);
       break;
 
     case LOC_REGPARM_ADDR:
-      printf_unfiltered ("address of an argument in register %s", reg_names[val]);
+      printf_filtered ("address of an argument in register %s", reg_names[val]);
       break;
 
     case LOC_ARG:
-      printf_unfiltered ("an argument at offset %ld", val);
+      printf_filtered ("an argument at offset %ld", val);
       break;
 
     case LOC_LOCAL_ARG:
-      printf_unfiltered ("an argument at frame offset %ld", val);
+      printf_filtered ("an argument at frame offset %ld", val);
       break;
 
     case LOC_LOCAL:
-      printf_unfiltered ("a local variable at frame offset %ld", val);
+      printf_filtered ("a local variable at frame offset %ld", val);
       break;
 
     case LOC_REF_ARG:
-      printf_unfiltered ("a reference argument at offset %ld", val);
+      printf_filtered ("a reference argument at offset %ld", val);
       break;
 
     case LOC_BASEREG:
-      printf_unfiltered ("a variable at offset %ld from register %s",
+      printf_filtered ("a variable at offset %ld from register %s",
              val, reg_names[basereg]);
       break;
 
     case LOC_BASEREG_ARG:
-      printf_unfiltered ("an argument at offset %ld from register %s",
+      printf_filtered ("an argument at offset %ld from register %s",
              val, reg_names[basereg]);
       break;
 
     case LOC_TYPEDEF:
-      printf_unfiltered ("a typedef");
+      printf_filtered ("a typedef");
       break;
 
     case LOC_BLOCK:
-      printf_unfiltered ("a function at address %s",
-             local_hex_string((unsigned long) BLOCK_START (SYMBOL_BLOCK_VALUE (sym))));
+      printf_filtered ("a function at address ");
+      print_address_numeric (BLOCK_START (SYMBOL_BLOCK_VALUE (sym)),
+                            gdb_stdout);
       break;
 
     case LOC_OPTIMIZED_OUT:
@@ -971,10 +1019,10 @@ address_info (exp, from_tty)
       break;
       
     default:
-      printf_unfiltered ("of unknown (botched) type");
+      printf_filtered ("of unknown (botched) type");
       break;
     }
-  printf_unfiltered (".\n");
+  printf_filtered (".\n");
 }
 \f
 static void
@@ -1496,16 +1544,50 @@ print_frame_args (func, fi, num, stream)
         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.  */
+        float).  */
       /* 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);
+       {
+         struct symbol *nsym;
+         nsym = lookup_symbol
+           (SYMBOL_NAME (sym),
+            b, VAR_NAMESPACE, (int *)NULL, (struct symtab **)NULL);
+         if (SYMBOL_CLASS (nsym) == LOC_REGISTER)
+           {
+             /* There is a LOC_ARG/LOC_REGISTER pair.  This means that
+                it was passed on the stack and loaded into a register,
+                or passed in a register and stored in a stack slot.
+                GDB 3.x used the LOC_ARG; GDB 4.0-4.11 used the LOC_REGISTER.
+
+                Reasons for using the LOC_ARG:
+                (1) because find_saved_registers may be slow for remote
+                debugging,
+                (2) because registers are often re-used and stack slots
+                rarely (never?) are.  Therefore using the stack slot is
+                much less likely to print garbage.
+
+                Reasons why we might want to use the LOC_REGISTER:
+                (1) So that the backtrace prints the same value as
+                "print foo".  I see no compelling reason why this needs
+                to be the case; having the backtrace print the value which
+                was passed in, and "print foo" print the value as modified
+                within the called function, makes perfect sense to me.
+
+                Additional note:  It might be nice if "info args" displayed
+                both values.
+                One more note:  There is a case with sparc sturcture passing
+                where we need to use the LOC_REGISTER, but this is dealt with
+                by creating a single LOC_REGPARM in symbol reading.  */
+
+             /* Leave sym (the LOC_ARG) alone.  */
+             ;
+           }
+         else
+           sym = nsym;
+       }
 
       /* Print the current arg.  */
       if (! first)
@@ -1908,8 +1990,11 @@ disassemble_command (arg, from_tty)
     }
   else
     {
-      printf_filtered ("from %s ", local_hex_string((unsigned long) low));
-      printf_filtered ("to %s:\n", local_hex_string((unsigned long) high));
+      printf_filtered ("from ");
+      print_address_numeric (low, gdb_stdout);
+      printf_filtered (" to ");
+      print_address_numeric (high, gdb_stdout);
+      printf_filtered (":\n");
     }
 
   /* Dump the specified range.  */
@@ -1918,6 +2003,8 @@ disassemble_command (arg, from_tty)
       QUIT;
       print_address (pc, gdb_stdout);
       printf_filtered (":\t");
+      /* We often wrap here if there are long symbolic names.  */
+      wrap_here ("    ");
       pc += print_insn (pc, gdb_stdout);
       printf_filtered ("\n");
     }
@@ -2071,6 +2158,13 @@ environment, the value is printed in its own window.");
                   &setprintlist),
       &showprintlist);
 
+  add_show_from_set (
+      add_set_cmd ("fast-symbolic-addr", no_class, var_boolean,
+                  (char *)&fast_symbolic_addr,
+       "Set fast printing of symbolic addresses (using minimal symbols).",
+                  &setprintlist),
+      &showprintlist);
+
   examine_b_type = init_type (TYPE_CODE_INT, 1, 0, NULL, NULL);
   examine_h_type = init_type (TYPE_CODE_INT, 2, 0, NULL, NULL);
   examine_w_type = init_type (TYPE_CODE_INT, 4, 0, NULL, NULL);
This page took 0.028544 seconds and 4 git commands to generate.