Add a symbol's value to the computed frag offset, rather than overwriting it.
[deliverable/binutils-gdb.git] / gdb / stack.c
index 30486be7c926541f6a3890ff5881bc96d0043efc..c586f4573dae1e1ad4d0053e646a25377cd7a1d7 100644 (file)
@@ -1,6 +1,5 @@
 /* Print and select stack frames for GDB, the GNU debugger.
-   Copyright 1986, 87, 89, 91, 92, 93, 94, 95, 96, 98, 1999
-   Free Software Foundation, Inc.
+   Copyright 1986, 1987, 1989, 1991-1996, 1998-2000 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -37,6 +36,9 @@
 #include "annotate.h"
 #include "symfile.h"
 #include "objfiles.h"
+#ifdef UI_OUT
+#include "ui-out.h"
+#endif
 
 /* Prototypes for exported functions. */
 
@@ -70,27 +72,31 @@ static void current_frame_command PARAMS ((char *, int));
 
 static void select_frame_command PARAMS ((char *, int));
 
-static void print_frame_arg_vars PARAMS ((struct frame_info *, GDB_FILE *));
+static void print_frame_arg_vars (struct frame_info *, struct ui_file *);
 
 static void catch_info PARAMS ((char *, int));
 
 static void args_plus_locals_info PARAMS ((char *, int));
 
-static void print_frame_label_vars PARAMS ((struct frame_info *,
-                                           int,
-                                           GDB_FILE *));
+static void print_frame_label_vars (struct frame_info *, int,
+                                   struct ui_file *);
+
+static void print_frame_local_vars (struct frame_info *, int,
+                                   struct ui_file *);
 
-static void print_frame_local_vars PARAMS ((struct frame_info *,
-                                           int,
-                                           GDB_FILE *));
+static int print_block_frame_labels (struct block *, int *,
+                                    struct ui_file *);
 
-static int print_block_frame_labels PARAMS ((struct block *, int *,
-                                            GDB_FILE *));
+static int print_block_frame_locals (struct block *,
+                                    struct frame_info *,
+                                    int,
+                                    struct ui_file *);
 
-static int print_block_frame_locals PARAMS ((struct block *,
-                                            struct frame_info *,
-                                            int,
-                                            GDB_FILE *));
+static void print_frame (struct frame_info *fi, 
+                        int level, 
+                        int source, 
+                        int args, 
+                        struct symtab_and_line sal);
 
 static void print_frame_info_base PARAMS ((struct frame_info *, int, int, int));
 
@@ -308,7 +314,7 @@ struct print_args_args
 {
   struct symbol *func;
   struct frame_info *fi;
-  GDB_FILE *stream;
+  struct ui_file *stream;
 };
 
 static int print_args_stub PARAMS ((PTR));
@@ -328,14 +334,14 @@ print_args_stub (args)
 }
 
 /* Print information about a frame for frame "fi" at level "level".
- * Used in "where" output, also used to emit breakpoint or step messages.
- * LEVEL is the level of the frame, or -1 if it is the innermost frame
- * but we don't want to print the level.
- * The meaning of the SOURCE argument is:
- * -1: Print only source line
- *  0: Print only location
- *  1: Print location and source line
- */
+   Used in "where" output, also used to emit breakpoint or step
+   messages.  
+   LEVEL is the level of the frame, or -1 if it is the
+   innermost frame but we don't want to print the level.  
+   The meaning of the SOURCE argument is: 
+   SRC_LINE: Print only source line
+   LOCATION: Print only location 
  LOC_AND_SRC: Print location and source line.  */
 
 static void
 print_frame_info_base (fi, level, source, args)
@@ -345,9 +351,8 @@ print_frame_info_base (fi, level, source, args)
      int args;
 {
   struct symtab_and_line sal;
-  struct symbol *func;
-  register char *funname = 0;
-  enum language funlang = language_unknown;
+  int source_print;
+  int location_print;
 
 #if 0
   char buf[MAX_REGISTER_RAW_SIZE];
@@ -406,6 +411,69 @@ print_frame_info_base (fi, level, source, args)
                  && !fi->next->signal_handler_caller
                  && !frame_in_dummy (fi->next));
 
+  location_print = (source == LOCATION 
+                   || source == LOC_AND_ADDRESS
+                   || source == SRC_AND_LOC);
+
+  if (location_print || !sal.symtab)
+    print_frame (fi, level, source, args, sal);
+
+  source_print = (source == SRC_LINE || source == SRC_AND_LOC);
+
+  if (source_print && sal.symtab)
+    {
+      int done = 0;
+      int mid_statement = (source == SRC_LINE) && (fi->pc != sal.pc);
+
+      if (annotation_level)
+       done = identify_source_line (sal.symtab, sal.line, mid_statement,
+                                    fi->pc);
+      if (!done)
+       {
+         if (addressprint && mid_statement && !tui_version)
+           {
+#ifdef UI_OUT
+             ui_out_field_core_addr (uiout, "addr", fi->pc);
+             ui_out_text (uiout, "\t");
+#else
+             print_address_numeric (fi->pc, 1, gdb_stdout);
+             printf_filtered ("\t");
+#endif
+           }
+         if (print_frame_info_listing_hook)
+           print_frame_info_listing_hook (sal.symtab, sal.line, sal.line + 1, 0);
+         else if (!tui_version)
+           print_source_lines (sal.symtab, sal.line, sal.line + 1, 0);
+       }
+      current_source_line = max (sal.line - lines_to_list / 2, 1);
+    }
+
+  if (source != 0)
+    set_default_breakpoint (1, fi->pc, sal.symtab, sal.line);
+
+  annotate_frame_end ();
+
+  gdb_flush (gdb_stdout);
+}
+
+static void
+print_frame (struct frame_info *fi, 
+            int level, 
+            int source, 
+            int args, 
+            struct symtab_and_line sal)
+{
+  struct symbol *func;
+  register char *funname = 0;
+  enum language funlang = language_unknown;
+#ifdef UI_OUT
+  struct ui_stream *stb;
+  struct cleanup *old_chain;
+
+  stb = ui_out_stream_new (uiout);
+  old_chain = make_cleanup ((make_cleanup_func) ui_out_stream_delete, stb);
+#endif /* UI_OUT */
+
   func = find_pc_function (fi->pc);
   if (func)
     {
@@ -446,19 +514,17 @@ print_frame_info_base (fi, level, source, args)
        }
       else
        {
-         /* I'd like to use SYMBOL_SOURCE_NAME() here, to display
-          * the demangled name that we already have stored in
-          * the symbol table, but we stored a version with
-          * DMGL_PARAMS turned on, and here we don't want
-          * to display parameters. So call the demangler again,
-          * with DMGL_ANSI only. RT
-          * (Yes, I know that printf_symbol_filtered() will
-          * again try to demangle the name on the fly, but
-          * the issue is that if cplus_demangle() fails here,
-          * it'll fail there too. So we want to catch the failure
-          * ("demangled==NULL" case below) here, while we still
-          * have our hands on the function symbol.)
-          */
+         /* I'd like to use SYMBOL_SOURCE_NAME() here, to display the
+            demangled name that we already have stored in the symbol
+            table, but we stored a version with DMGL_PARAMS turned
+            on, and here we don't want to display parameters. So call
+            the demangler again, with DMGL_ANSI only. (Yes, I know
+            that printf_symbol_filtered() will again try to demangle
+            the name on the fly, but the issue is that if
+            cplus_demangle() fails here, it'll fail there too. So we
+            want to catch the failure ("demangled==NULL" case below)
+            here, while we still have our hands on the function
+            symbol.) */
          char *demangled;
          funname = SYMBOL_NAME (func);
          funlang = SYMBOL_LANGUAGE (func);
@@ -466,10 +532,9 @@ print_frame_info_base (fi, level, source, args)
            {
              demangled = cplus_demangle (funname, DMGL_ANSI);
              if (demangled == NULL)
-               /* If the demangler fails, try the demangled name
-                * from the symbol table. This'll have parameters,
-                * but that's preferable to diplaying a mangled name.
-                */
+               /* If the demangler fails, try the demangled name from
+                  the symbol table. This'll have parameters, but
+                  that's preferable to diplaying a mangled name. */
                funname = SYMBOL_SOURCE_NAME (func);
            }
        }
@@ -484,103 +549,145 @@ print_frame_info_base (fi, level, source, args)
        }
     }
 
-  if (source >= 0 || !sal.symtab)
-    {
-      annotate_frame_begin (level == -1 ? 0 : level, fi->pc);
+  annotate_frame_begin (level == -1 ? 0 : level, fi->pc);
 
-      if (level >= 0)
-       printf_filtered ("#%-2d ", level);
-      if (addressprint)
-       if (fi->pc != sal.pc || !sal.symtab)
-         {
-           annotate_frame_address ();
-           print_address_numeric (fi->pc, 1, gdb_stdout);
-           annotate_frame_address_end ();
-           printf_filtered (" in ");
-         }
-      annotate_frame_function_name ();
-      fprintf_symbol_filtered (gdb_stdout, funname ? funname : "??", funlang,
-                              DMGL_ANSI);
+#ifdef UI_OUT
+  ui_out_list_begin (uiout, "frame");
+#endif
+
+  if (level >= 0)
+    {
+#ifdef UI_OUT
+      ui_out_text (uiout, "#");
+      ui_out_field_fmt (uiout, "level", "%-2d", level);
+      ui_out_spaces (uiout, 1);
+#else
+      printf_filtered ("#%-2d ", level);
+#endif
+    }
+  if (addressprint)
+    if (fi->pc != sal.pc || !sal.symtab || source == LOC_AND_ADDRESS)
+      {
+       annotate_frame_address ();
+#ifdef UI_OUT
+       ui_out_field_core_addr (uiout, "addr", fi->pc);
+       annotate_frame_address_end ();
+       ui_out_text (uiout, " in ");
+#else
+       print_address_numeric (fi->pc, 1, gdb_stdout);
+       annotate_frame_address_end ();
+       printf_filtered (" in ");
+#endif
+      }
+  annotate_frame_function_name ();
+#ifdef UI_OUT
+  fprintf_symbol_filtered (stb->stream, funname ? funname : "??", funlang,
+                          DMGL_ANSI);
+  ui_out_field_stream (uiout, "func", stb);
+  ui_out_wrap_hint (uiout, "   ");
+#else
+  fprintf_symbol_filtered (gdb_stdout, funname ? funname : "??", funlang,
+                          DMGL_ANSI);
+  wrap_here ("   ");
+#endif
+  annotate_frame_args ();
+      
+#ifdef UI_OUT
+  ui_out_text (uiout, " (");
+#else
+  fputs_filtered (" (", gdb_stdout);
+#endif
+  if (args)
+    {
+      struct print_args_args args;
+      args.fi = fi;
+      args.func = func;
+      args.stream = gdb_stdout;
+#ifdef UI_OUT
+      ui_out_list_begin (uiout, "args");
+      catch_errors (print_args_stub, &args, "", RETURN_MASK_ALL);
+      /* FIXME: args must be a list. If one argument is a string it will
+                have " that will not be properly escaped.  */
+      ui_out_list_end (uiout);
+#else
+      catch_errors (print_args_stub, &args, "", RETURN_MASK_ALL);
+#endif
+      QUIT;
+    }
+#ifdef UI_OUT
+  ui_out_text (uiout, ")");
+#else
+  printf_filtered (")");
+#endif
+  if (sal.symtab && sal.symtab->filename)
+    {
+      annotate_frame_source_begin ();
+#ifdef UI_OUT
+      ui_out_wrap_hint (uiout, "   ");
+      ui_out_text (uiout, " at ");
+      annotate_frame_source_file ();
+      ui_out_field_string (uiout, "file", sal.symtab->filename);
+      annotate_frame_source_file_end ();
+      ui_out_text (uiout, ":");
+      annotate_frame_source_line ();
+      ui_out_field_int (uiout, "line", sal.line);
+#else
       wrap_here ("   ");
-      annotate_frame_args ();
-      fputs_filtered (" (", gdb_stdout);
-      if (args)
-       {
-         struct print_args_args args;
-         args.fi = fi;
-         args.func = func;
-         args.stream = gdb_stdout;
-         catch_errors (print_args_stub, &args, "", RETURN_MASK_ALL);
-         QUIT;
-       }
-      printf_filtered (")");
-      if (sal.symtab && sal.symtab->filename)
-       {
-         annotate_frame_source_begin ();
-         wrap_here ("   ");
-         printf_filtered (" at ");
-         annotate_frame_source_file ();
-         printf_filtered ("%s", sal.symtab->filename);
-         annotate_frame_source_file_end ();
-         printf_filtered (":");
-         annotate_frame_source_line ();
-         printf_filtered ("%d", sal.line);
-         annotate_frame_source_end ();
-       }
+      printf_filtered (" at ");
+      annotate_frame_source_file ();
+      printf_filtered ("%s", sal.symtab->filename);
+      annotate_frame_source_file_end ();
+      printf_filtered (":");
+      annotate_frame_source_line ();
+      printf_filtered ("%d", sal.line);
+#endif
+      annotate_frame_source_end ();
+    }
 
 #ifdef PC_LOAD_SEGMENT
-      /* If we couldn't print out function name but if can figure out what
+  /* If we couldn't print out function name but if can figure out what
          load segment this pc value is from, at least print out some info
          about its load segment. */
-      if (!funname)
-       {
-         annotate_frame_where ();
-         wrap_here ("  ");
-         printf_filtered (" from %s", PC_LOAD_SEGMENT (fi->pc));
-       }
-#endif
-#ifdef PC_SOLIB
-      if (!funname || (!sal.symtab || !sal.symtab->filename))
-       {
-         char *lib = PC_SOLIB (fi->pc);
-         if (lib)
-           {
-             annotate_frame_where ();
-             wrap_here ("  ");
-             printf_filtered (" from %s", lib);
-           }
-       }
+  if (!funname)
+    {
+      annotate_frame_where ();
+#ifdef UI_OUT
+      ui_out_wrap_hint (uiout, "  ");
+      ui_out_text (uiout, " from ");
+      ui_out_field_string (uiout, "from", PC_LOAD_SEGMENT (fi->pc));
+#else
+      wrap_here ("  ");
+      printf_filtered (" from %s", PC_LOAD_SEGMENT (fi->pc));
 #endif
-      printf_filtered ("\n");
     }
+#endif /* PC_LOAD_SEGMENT */
 
-  if ((source != 0) && sal.symtab)
+#ifdef PC_SOLIB
+  if (!funname || (!sal.symtab || !sal.symtab->filename))
     {
-      int done = 0;
-      int mid_statement = source < 0 && fi->pc != sal.pc;
-      if (annotation_level)
-       done = identify_source_line (sal.symtab, sal.line, mid_statement,
-                                    fi->pc);
-      if (!done)
+      char *lib = PC_SOLIB (fi->pc);
+      if (lib)
        {
-         if (addressprint && mid_statement && !tui_version)
-           {
-             print_address_numeric (fi->pc, 1, gdb_stdout);
-             printf_filtered ("\t");
-           }
-         if (print_frame_info_listing_hook)
-           print_frame_info_listing_hook (sal.symtab, sal.line, sal.line + 1, 0);
-         else if (!tui_version)
-           print_source_lines (sal.symtab, sal.line, sal.line + 1, 0);
+         annotate_frame_where ();
+#ifdef UI_OUT
+         ui_out_wrap_hint (uiout, "  ");
+         ui_out_text (uiout, " from ");
+         ui_out_field_string (uiout, "from", lib);
+#else
+         wrap_here ("  ");
+         printf_filtered (" from %s", lib);
+#endif
        }
-      current_source_line = max (sal.line - lines_to_list / 2, 1);
     }
-  if (source != 0)
-    set_default_breakpoint (1, fi->pc, sal.symtab, sal.line);
-
-  annotate_frame_end ();
+#endif /* PC_SOLIB */
 
-  gdb_flush (gdb_stdout);
+#ifdef UI_OUT
+  ui_out_list_end (uiout);
+  ui_out_text (uiout, "\n");
+  do_cleanups (old_chain);
+#else
+  printf_filtered ("\n");
+#endif
 }
 \f
 
@@ -1097,7 +1204,7 @@ backtrace_command (arg, from_tty)
       argc = 0;
       for (i = 0; (argv[i] != (char *) NULL); i++)
        {
-         int j;
+         unsigned int j;
 
          for (j = 0; (j < strlen (argv[i])); j++)
            argv[i][j] = tolower (argv[i][j]);
@@ -1163,7 +1270,7 @@ print_block_frame_locals (b, fi, num_tabs, stream)
      struct block *b;
      register struct frame_info *fi;
      int num_tabs;
-     register GDB_FILE *stream;
+     register struct ui_file *stream;
 {
   int nsyms;
   register int i, j;
@@ -1204,7 +1311,7 @@ static int
 print_block_frame_labels (b, have_default, stream)
      struct block *b;
      int *have_default;
-     register GDB_FILE *stream;
+     register struct ui_file *stream;
 {
   int nsyms;
   register int i;
@@ -1252,7 +1359,7 @@ static void
 print_frame_local_vars (fi, num_tabs, stream)
      register struct frame_info *fi;
      register int num_tabs;
-     register GDB_FILE *stream;
+     register struct ui_file *stream;
 {
   register struct block *block = get_frame_block (fi);
   register int values_printed = 0;
@@ -1287,7 +1394,7 @@ static void
 print_frame_label_vars (fi, this_level_only, stream)
      register struct frame_info *fi;
      int this_level_only;
-     register GDB_FILE *stream;
+     register struct ui_file *stream;
 {
   register struct blockvector *bl;
   register struct block *block = get_frame_block (fi);
@@ -1397,7 +1504,7 @@ catch_info (ignore, from_tty)
 static void
 print_frame_arg_vars (fi, stream)
      register struct frame_info *fi;
-     register GDB_FILE *stream;
+     register struct ui_file *stream;
 {
   struct symbol *func = get_frame_function (fi);
   register struct block *b;
@@ -1626,6 +1733,15 @@ find_relative_frame (frame, level_offset_ptr)
    frame expressions. */
 
 /* ARGSUSED */
+#ifdef UI_OUT
+void
+select_frame_command_wrapper (level_exp, from_tty)
+     char *level_exp;
+     int from_tty;
+{
+  select_frame_command (level_exp, from_tty);
+}
+#endif
 static void
 select_frame_command (level_exp, from_tty)
      char *level_exp;
@@ -1775,6 +1891,15 @@ down_command (count_exp, from_tty)
   show_and_print_stack_frame (selected_frame, selected_frame_level, 1);
 }
 \f
+#ifdef UI_OUT
+void
+return_command_wrapper (retval_exp, from_tty)
+     char *retval_exp;
+     int from_tty;
+{
+  return_command (retval_exp, from_tty);
+}
+#endif
 static void
 return_command (retval_exp, from_tty)
      char *retval_exp;
This page took 0.05044 seconds and 4 git commands to generate.