AArch64: Constraint disassembler and assembler changes.
[deliverable/binutils-gdb.git] / gdb / tui / tui-stack.c
index acbe5d7ad051a6ef7ff111ac6fec2ad2998632fa..07767bbb82a52ab96f1b59c377fdbd91fb8fe4b9 100644 (file)
@@ -1,7 +1,6 @@
 /* TUI display locator.
 
-   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006, 2007
-   Free Software Foundation, Inc.
+   Copyright (C) 1998-2018 Free Software Foundation, Inc.
 
    Contributed by Hewlett-Packard Company.
 
@@ -9,7 +8,7 @@
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
@@ -18,9 +17,7 @@
    GNU General Public License for more details.
 
    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., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
 #include "symtab.h"
@@ -30,7 +27,8 @@
 #include "inferior.h"
 #include "target.h"
 #include "top.h"
-#include "gdb_string.h"
+#include "gdb-demangle.h"
+#include "source.h"
 #include "tui/tui.h"
 #include "tui/tui-data.h"
 #include "tui/tui-stack.h"
    Returns a pointer to a static area holding the result.  */
 static char *tui_get_function_from_frame (struct frame_info *fi);
 
-/* Set the filename portion of the locator.  */
-static void tui_set_locator_filename (const char *filename);
+/* Set the full_name portion of the locator.  */
+static void tui_set_locator_fullname (const char *fullname);
 
 /* Update the locator, with the provided arguments.  */
-static void tui_set_locator_info (const char *filename, const char *procname,
-                                  int lineno, CORE_ADDR addr);
+static int tui_set_locator_info (struct gdbarch *gdbarch,
+                                const char *fullname,
+                                const char *procname,
+                                 int lineno, CORE_ADDR addr);
 
-static void tui_update_command (char *, int);
+static void tui_update_command (const char *, int);
 \f
 
-/* Create the status line to display as much information as we
-   can on this single line: target name, process number, current
-   function, current line, current PC, SingleKey mode.  */
+/* Create the status line to display as much information as we can on
+   this single line: target name, process number, current function,
+   current line, current PC, SingleKey mode.  */
 static char*
 tui_make_status_line (struct tui_locator_element *loc)
 {
@@ -68,14 +68,11 @@ tui_make_status_line (struct tui_locator_element *loc)
   int status_size;
   int i, proc_width;
   const char *pid_name;
-  const char *pc_buf;
   int target_width;
   int pid_width;
   int line_width;
-  int pc_width;
-  struct ui_file *pc_out;
 
-  if (ptid_equal (inferior_ptid, null_ptid))
+  if (inferior_ptid == null_ptid)
     pid_name = "No process";
   else
     pid_name = target_pid_to_str (inferior_ptid);
@@ -94,7 +91,7 @@ tui_make_status_line (struct tui_locator_element *loc)
 
   /* Translate line number and obtain its size.  */
   if (loc->line_no > 0)
-    sprintf (line_buf, "%d", loc->line_no);
+    xsnprintf (line_buf, sizeof (line_buf), "%d", loc->line_no);
   else
     strcpy (line_buf, "??");
   line_width = strlen (line_buf);
@@ -102,11 +99,14 @@ tui_make_status_line (struct tui_locator_element *loc)
     line_width = MIN_LINE_WIDTH;
 
   /* Translate PC address.  */
-  pc_out = tui_sfileopen (128);
-  deprecated_print_address_numeric (loc->addr, 1, pc_out);
-  pc_buf = tui_file_get_strbuf (pc_out);
-  pc_width = strlen (pc_buf);
-  
+  string_file pc_out;
+
+  fputs_filtered (loc->gdbarch? paddress (loc->gdbarch, loc->addr) : "??",
+                 &pc_out);
+
+  const char *pc_buf = pc_out.c_str ();
+  int pc_width = pc_out.size ();
+
   /* First determine the amount of proc name width we have available.
      The +1 are for a space separator between fields.
      The -1 are to take into account the \0 counted by sizeof.  */
@@ -145,13 +145,13 @@ tui_make_status_line (struct tui_locator_element *loc)
         }
     }
 
-  /* Now convert elements to string form */
+  /* Now convert elements to string form */
   pname = loc->proc_name;
 
-  /* Now create the locator line from the string version
-     of the elements.  We could use sprintf() here but
-     that wouldn't ensure that we don't overrun the size
-     of the allocated buffer.  strcat_to_buf() will.  */
+  /* Now create the locator line from the string version of the
+     elements.  We could use sprintf() here but that wouldn't ensure
+     that we don't overrun the size of the allocated buffer.
+     strcat_to_buf() will.  */
   *string = (char) 0;
 
   if (target_width > 0)
@@ -174,7 +174,7 @@ tui_make_status_line (struct tui_locator_element *loc)
       strcat_to_buf (string, status_size, " ");
     }
 
-  /* procedure/class name */
+  /* Procedure/class name.  */
   if (proc_width > 0)
     {
       if (strlen (pname) > proc_width)
@@ -203,30 +203,31 @@ tui_make_status_line (struct tui_locator_element *loc)
     string[i] = ' ';
   string[status_size] = (char) 0;
 
-  ui_file_delete (pc_out);
   return string;
 }
 
-/* Get a printable name for the function at the address.
-   The symbol name is demangled if demangling is turned on.
-   Returns a pointer to a static area holding the result.  */
+/* Get a printable name for the function at the address.  The symbol
+   name is demangled if demangling is turned on.  Returns a pointer to
+   a static area holding the result.  */
 static char*
 tui_get_function_from_frame (struct frame_info *fi)
 {
   static char name[256];
-  struct ui_file *stream = tui_sfileopen (256);
-  char *p;
-
-  print_address_symbolic (get_frame_pc (fi), stream, demangle, "");
-  p = tui_file_get_strbuf (stream);
-
-  /* Use simple heuristics to isolate the function name.  The symbol can
-     be demangled and we can have function parameters.  Remove them because
-     the status line is too short to display them.  */
-  if (*p == '<')
-    p++;
-  strncpy (name, p, sizeof (name));
-  p = strchr (name, '(');
+  string_file stream;
+
+  print_address_symbolic (get_frame_arch (fi), get_frame_pc (fi),
+                         &stream, demangle, "");
+
+  /* Use simple heuristics to isolate the function name.  The symbol
+     can be demangled and we can have function parameters.  Remove
+     them because the status line is too short to display them.  */
+  const char *d = stream.c_str ();
+  if (*d == '<')
+    d++;
+  strncpy (name, d, sizeof (name) - 1);
+  name[sizeof (name) - 1] = 0;
+
+  char *p = strchr (name, '(');
   if (!p)
     p = strchr (name, '>');
   if (p)
@@ -234,7 +235,6 @@ tui_get_function_from_frame (struct frame_info *fi)
   p = strchr (name, '+');
   if (p)
     *p = 0;
-  ui_file_delete (stream);
   return name;
 }
 
@@ -250,14 +250,19 @@ tui_show_locator_content (void)
     {
       struct tui_win_element *element;
 
-      element = (struct tui_win_element *) locator->content[0];
+      element = locator->content[0];
 
       string = tui_make_status_line (&element->which_element.locator);
       wmove (locator->handle, 0, 0);
-      wstandout (locator->handle);
+      /* We ignore the return value from wstandout and wstandend, casting
+        them to void in order to avoid a compiler warning.  The warning
+        itself was introduced by a patch to ncurses 5.7 dated 2009-08-29,
+        changing these macro to expand to code that causes the compiler
+        to generate an unused-value warning.  */
+      (void) wstandout (locator->handle);
       waddstr (locator->handle, string);
       wclrtoeol (locator->handle);
-      wstandend (locator->handle);
+      (void) wstandend (locator->handle);
       tui_refresh_win (locator);
       wmove (locator->handle, 0, 0);
       xfree (string);
@@ -268,58 +273,91 @@ tui_show_locator_content (void)
 
 /* Set the filename portion of the locator.  */
 static void
-tui_set_locator_filename (const char *filename)
+tui_set_locator_fullname (const char *fullname)
 {
   struct tui_gen_win_info *locator = tui_locator_win_info_ptr ();
   struct tui_locator_element *element;
 
   if (locator->content[0] == NULL)
     {
-      tui_set_locator_info (filename, NULL, 0, 0);
+      tui_set_locator_info (NULL, fullname, NULL, 0, 0);
       return;
     }
 
-  element = &((struct tui_win_element *) locator->content[0])->which_element.locator;
-  element->file_name[0] = 0;
-  strcat_to_buf (element->file_name, MAX_LOCATOR_ELEMENT_LEN, filename);
+  element = &locator->content[0]->which_element.locator;
+  element->full_name[0] = 0;
+  strcat_to_buf (element->full_name, MAX_LOCATOR_ELEMENT_LEN, fullname);
 }
 
-/* Update the locator, with the provided arguments.  */
-static void
-tui_set_locator_info (const char *filename, const char *procname, int lineno,
+/* Update the locator, with the provided arguments.
+
+   Returns 1 if any of the locator's fields were actually changed,
+   and 0 otherwise.  */
+
+static int
+tui_set_locator_info (struct gdbarch *gdbarch,
+                     const char *fullname,
+                     const char *procname, 
+                     int lineno,
                       CORE_ADDR addr)
 {
   struct tui_gen_win_info *locator = tui_locator_win_info_ptr ();
   struct tui_locator_element *element;
+  int locator_changed_p = 0;
 
   /* Allocate the locator content if necessary.  */
   if (locator->content_size <= 0)
     {
-      locator->content = (void **) tui_alloc_content (1, locator->type);
+      locator->content = tui_alloc_content (1, LOCATOR_WIN);
       locator->content_size = 1;
+      locator_changed_p = 1;
     }
 
-  element = &((struct tui_win_element *) locator->content[0])->which_element.locator;
+  if (procname == NULL)
+    procname = "";
+
+  if (fullname == NULL)
+    fullname = "";
+
+  element = &locator->content[0]->which_element.locator;
+
+  locator_changed_p |= strncmp (element->proc_name, procname,
+                               MAX_LOCATOR_ELEMENT_LEN) != 0;
+  locator_changed_p |= lineno != element->line_no;
+  locator_changed_p |= addr != element->addr;
+  locator_changed_p |= gdbarch != element->gdbarch;
+  locator_changed_p |= strncmp (element->full_name, fullname,
+                               MAX_LOCATOR_ELEMENT_LEN) != 0;
+
   element->proc_name[0] = (char) 0;
   strcat_to_buf (element->proc_name, MAX_LOCATOR_ELEMENT_LEN, procname);
   element->line_no = lineno;
   element->addr = addr;
-  tui_set_locator_filename (filename);
+  element->gdbarch = gdbarch;
+  tui_set_locator_fullname (fullname);
+
+  return locator_changed_p;
 }
 
-/* Update only the filename portion of the locator.  */
+/* Update only the full_name portion of the locator.  */
 void
-tui_update_locator_filename (const char *filename)
+tui_update_locator_fullname (const char *fullname)
 {
-  tui_set_locator_filename (filename);
+  tui_set_locator_fullname (fullname);
   tui_show_locator_content ();
 }
 
-/* Function to print the frame information for the TUI.  */
-void
+/* Function to print the frame information for the TUI.  The windows are
+   refreshed only if frame information has changed since the last refresh.
+
+   Return 1 if frame information has changed (and windows subsequently
+   refreshed), 0 otherwise.  */
+
+int
 tui_show_frame_info (struct frame_info *fi)
 {
   struct tui_win_info *win_info;
+  int locator_changed_p;
   int i;
 
   if (fi)
@@ -328,24 +366,41 @@ tui_show_frame_info (struct frame_info *fi)
       CORE_ADDR low;
       struct tui_gen_win_info *locator = tui_locator_win_info_ptr ();
       int source_already_displayed;
-      struct symtab_and_line sal;
+      CORE_ADDR pc;
 
-      find_frame_sal (fi, &sal);
+      symtab_and_line sal = find_frame_sal (fi);
 
       source_already_displayed = sal.symtab != 0
-        && tui_source_is_displayed (sal.symtab->filename);
-      tui_set_locator_info (sal.symtab == 0 ? "??" : sal.symtab->filename,
-                            tui_get_function_from_frame (fi),
-                            sal.line,
-                            get_frame_pc (fi));
+        && tui_source_is_displayed (symtab_to_fullname (sal.symtab));
+
+      if (get_frame_pc_if_available (fi, &pc))
+       locator_changed_p
+         = tui_set_locator_info (get_frame_arch (fi),
+                                 (sal.symtab == 0
+                                  ? "??" : symtab_to_fullname (sal.symtab)),
+                                 tui_get_function_from_frame (fi),
+                                 sal.line,
+                                 pc);
+      else
+       locator_changed_p
+         = tui_set_locator_info (get_frame_arch (fi),
+                                 "??", _("<unavailable>"), sal.line, 0);
+
+      /* If the locator information has not changed, then frame information has
+        not changed.  If frame information has not changed, then the windows'
+        contents will not change.  So don't bother refreshing the windows.  */
+      if (!locator_changed_p)
+       return 0;
+
       tui_show_locator_content ();
       start_line = 0;
       for (i = 0; i < (tui_source_windows ())->count; i++)
        {
          union tui_which_element *item;
+
          win_info = (tui_source_windows ())->list[i];
 
-         item = &((struct tui_win_element *) locator->content[0])->which_element;
+         item = &locator->content[0]->which_element;
          if (win_info == TUI_SRC_WIN)
            {
              start_line = (item->locator.line_no -
@@ -355,21 +410,30 @@ tui_show_frame_info (struct frame_info *fi)
            }
          else
            {
-             if (find_pc_partial_function (get_frame_pc (fi), (char **) NULL,
-                                           &low, (CORE_ADDR) 0) == 0)
-               error (_("No function contains program counter for selected frame."));
+             if (find_pc_partial_function (get_frame_pc (fi),
+                                           (const char **) NULL,
+                                           &low, NULL) == 0)
+               {
+                 /* There is no symbol available for current PC.  There is no
+                    safe way how to "disassemble backwards".  */
+                 low = get_frame_pc (fi);
+               }
              else
-               low = tui_get_low_disassembly_address (low, get_frame_pc (fi));
+               low = tui_get_low_disassembly_address (get_frame_arch (fi),
+                                                      low, get_frame_pc (fi));
            }
 
          if (win_info == TUI_SRC_WIN)
            {
              struct tui_line_or_address l;
+
              l.loa = LOA_LINE;
              l.u.line_no = start_line;
              if (!(source_already_displayed
-                   && tui_line_is_displayed (item->locator.line_no, win_info, TRUE)))
-               tui_update_source_window (win_info, sal.symtab, l, TRUE);
+                   && tui_line_is_displayed (item->locator.line_no,
+                                             win_info, TRUE)))
+               tui_update_source_window (win_info, get_frame_arch (fi),
+                                         sal.symtab, l, TRUE);
              else
                {
                  l.u.line_no = item->locator.line_no;
@@ -381,10 +445,13 @@ tui_show_frame_info (struct frame_info *fi)
              if (win_info == TUI_DISASM_WIN)
                {
                  struct tui_line_or_address a;
+
                  a.loa = LOA_ADDRESS;
                  a.u.addr = low;
-                 if (!tui_addr_is_displayed (item->locator.addr, win_info, TRUE))
-                   tui_update_source_window (win_info, sal.symtab, a, TRUE);
+                 if (!tui_addr_is_displayed (item->locator.addr,
+                                             win_info, TRUE))
+                   tui_update_source_window (win_info, get_frame_arch (fi),
+                                             sal.symtab, a, TRUE);
                  else
                    {
                      a.u.addr = item->locator.addr;
@@ -394,10 +461,17 @@ tui_show_frame_info (struct frame_info *fi)
            }
          tui_update_exec_info (win_info);
        }
+
+      return 1;
     }
   else
     {
-      tui_set_locator_info (NULL, NULL, 0, (CORE_ADDR) 0);
+      locator_changed_p
+       = tui_set_locator_info (NULL, NULL, NULL, 0, (CORE_ADDR) 0);
+
+      if (!locator_changed_p)
+       return 0;
+
       tui_show_locator_content ();
       for (i = 0; i < (tui_source_windows ())->count; i++)
        {
@@ -405,24 +479,25 @@ tui_show_frame_info (struct frame_info *fi)
          tui_clear_source_content (win_info, EMPTY_SOURCE_PROMPT);
          tui_update_exec_info (win_info);
        }
+
+      return 1;
     }
 }
 
 /* Function to initialize gdb commands, for tui window stack
    manipulation.  */
+
 void
 _initialize_tui_stack (void)
 {
-  add_com ("update", class_tui, tui_update_command, _("\
-Update the source window and locator to display the current execution point.\n"));
+  add_com ("update", class_tui, tui_update_command,
+          _("Update the source window and locator to "
+            "display the current execution point.\n"));
 }
 
 /* Command to update the display with the current execution point.  */
 static void
-tui_update_command (char *arg, int from_tty)
+tui_update_command (const char *arg, int from_tty)
 {
-  char cmd[sizeof("frame 0")];
-
-  strcpy (cmd, "frame 0");
-  execute_command (cmd, from_tty);
+  execute_command ("frame 0", from_tty);
 }
This page took 0.031254 seconds and 4 git commands to generate.