[linux-x86 aarch64] GCC 4.8 / Binutils 2.24 / GDB 7.7 refresh

Change-Id: I30d0fef6bd39e095a8264e20574fa5a46f50c045
diff --git a/share/gdb/python/gdb/command/frame_filters.py b/share/gdb/python/gdb/command/frame_filters.py
new file mode 100644
index 0000000..450c5bf
--- /dev/null
+++ b/share/gdb/python/gdb/command/frame_filters.py
@@ -0,0 +1,467 @@
+# Frame-filter commands.
+# Copyright (C) 2013-2014 Free Software Foundation, Inc.
+
+# 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 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# 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, see <http://www.gnu.org/licenses/>.
+
+"""GDB commands for working with frame-filters."""
+
+import sys
+import gdb
+import copy
+from gdb.FrameIterator import FrameIterator
+from gdb.FrameDecorator import FrameDecorator
+import gdb.frames
+import itertools
+
+# GDB Commands.
+class SetFilterPrefixCmd(gdb.Command):
+    """Prefix command for 'set' frame-filter related operations."""
+
+    def __init__(self):
+        super(SetFilterPrefixCmd, self).__init__("set frame-filter",
+                                                 gdb.COMMAND_OBSCURE,
+                                                 gdb.COMPLETE_NONE, True)
+
+class ShowFilterPrefixCmd(gdb.Command):
+    """Prefix command for 'show' frame-filter related operations."""
+    def __init__(self):
+        super(ShowFilterPrefixCmd, self).__init__("show frame-filter",
+                                                  gdb.COMMAND_OBSCURE,
+                                                  gdb.COMPLETE_NONE, True)
+class InfoFrameFilter(gdb.Command):
+    """List all registered Python frame-filters.
+
+    Usage: info frame-filters
+    """
+
+    def __init__(self):
+        super(InfoFrameFilter, self).__init__("info frame-filter",
+                                              gdb.COMMAND_DATA)
+    @staticmethod
+    def enabled_string(state):
+        """Return "Yes" if filter is enabled, otherwise "No"."""
+        if state:
+            return "Yes"
+        else:
+            return "No"
+
+    def list_frame_filters(self, frame_filters):
+        """ Internal worker function to list and print frame filters
+        in a dictionary.
+
+        Arguments:
+           frame_filters: The name of the dictionary, as
+           specified by GDB user commands.
+        """
+
+        sorted_frame_filters = sorted(frame_filters.items(),
+                                      key=lambda i: gdb.frames.get_priority(i[1]),
+                                      reverse=True)
+
+        if len(sorted_frame_filters) == 0:
+            print("  No frame filters registered.")
+        else:
+            print("  Priority  Enabled  Name")
+            for frame_filter in sorted_frame_filters:
+                name = frame_filter[0]
+                try:
+                    priority = '{:<8}'.format(
+                        str(gdb.frames.get_priority(frame_filter[1])))
+                    enabled = '{:<7}'.format(
+                        self.enabled_string(gdb.frames.get_enabled(frame_filter[1])))
+                except Exception:
+                    e = sys.exc_info()[1]
+                    print("  Error printing filter '"+name+"': "+str(e))
+                else:
+                    print("  %s  %s  %s" % (priority, enabled, name))
+
+    def print_list(self, title, filter_list, blank_line):
+        print(title)
+        self.list_frame_filters(filter_list)
+        if blank_line:
+            print("")
+
+    def invoke(self, arg, from_tty):
+        self.print_list("global frame-filters:", gdb.frame_filters, True)
+
+        cp = gdb.current_progspace()
+        self.print_list("progspace %s frame-filters:" % cp.filename,
+                        cp.frame_filters, True)
+
+        for objfile in gdb.objfiles():
+            self.print_list("objfile %s frame-filters:" % objfile.filename,
+                            objfile.frame_filters, False)
+
+# Internal enable/disable functions.
+
+def _enable_parse_arg(cmd_name, arg):
+    """ Internal worker function to take an argument from
+    enable/disable and return a tuple of arguments.
+
+    Arguments:
+        cmd_name: Name of the command invoking this function.
+        args: The argument as a string.
+
+    Returns:
+        A tuple containing the dictionary, and the argument, or just
+        the dictionary in the case of "all".
+    """
+
+    argv = gdb.string_to_argv(arg);
+    argc = len(argv)
+    if argv[0] == "all" and argc > 1:
+        raise gdb.GdbError(cmd_name + ": with 'all' " \
+                          "you may not specify a filter.")
+    else:
+        if argv[0] != "all" and argc != 2:
+            raise gdb.GdbError(cmd_name + " takes exactly two arguments.")
+
+    return argv
+
+def _do_enable_frame_filter(command_tuple, flag):
+    """Worker for enabling/disabling frame_filters.
+
+    Arguments:
+        command_type: A tuple with the first element being the
+                      frame filter dictionary, and the second being
+                      the frame filter name.
+        flag: True for Enable, False for Disable.
+    """
+
+    list_op = command_tuple[0]
+    op_list = gdb.frames.return_list(list_op)
+
+    if list_op == "all":
+        for item in op_list:
+            gdb.frames.set_enabled(item, flag)
+    else:
+        frame_filter = command_tuple[1]
+        try:
+            ff = op_list[frame_filter]
+        except KeyError:
+            msg = "frame-filter '" + str(name) + "' not found."
+            raise gdb.GdbError(msg)
+
+        gdb.frames.set_enabled(ff, flag)
+
+def _complete_frame_filter_list(text, word, all_flag):
+    """Worker for frame filter dictionary name completion.
+
+    Arguments:
+        text: The full text of the command line.
+        word: The most recent word of the command line.
+        all_flag: Whether to include the word "all" in completion.
+
+    Returns:
+        A list of suggested frame filter dictionary name completions
+        from text/word analysis.  This list can be empty when there
+        are no suggestions for completion.
+        """
+    if all_flag == True:
+        filter_locations = ["all", "global", "progspace"]
+    else:
+        filter_locations = ["global", "progspace"]
+    for objfile in gdb.objfiles():
+        filter_locations.append(objfile.filename)
+
+    # If the user just asked for completions with no completion
+    # hints, just return all the frame filter dictionaries we know
+    # about.
+    if (text == ""):
+        return filter_locations
+
+    # Otherwise filter on what we know.
+    flist = filter(lambda x,y=text:x.startswith(y), filter_locations)
+
+    # If we only have one completion, complete it and return it.
+    if len(flist) == 1:
+        flist[0] = flist[0][len(text)-len(word):]
+
+    # Otherwise, return an empty list, or a list of frame filter
+    # dictionaries that the previous filter operation returned.
+    return flist
+
+def _complete_frame_filter_name(word, printer_dict):
+    """Worker for frame filter name completion.
+
+    Arguments:
+
+        word: The most recent word of the command line.
+
+        printer_dict: The frame filter dictionary to search for frame
+        filter name completions.
+
+        Returns: A list of suggested frame filter name completions
+        from word analysis of the frame filter dictionary.  This list
+        can be empty when there are no suggestions for completion.
+    """
+
+    printer_keys = printer_dict.keys()
+    if (word == ""):
+        return printer_keys
+
+    flist = filter(lambda x,y=word:x.startswith(y), printer_keys)
+    return flist
+
+class EnableFrameFilter(gdb.Command):
+    """GDB command to disable the specified frame-filter.
+
+    Usage: enable frame-filter enable DICTIONARY [NAME]
+
+    DICTIONARY is the name of the frame filter dictionary on which to
+    operate.  If dictionary is set to "all", perform operations on all
+    dictionaries.  Named dictionaries are: "global" for the global
+    frame filter dictionary, "progspace" for the program space's frame
+    filter dictionary.  If either all, or the two named dictionaries
+    are not specified, the dictionary name is assumed to be the name
+    of the object-file name.
+
+    NAME matches the name of the frame-filter to operate on.  If
+    DICTIONARY is "all", NAME is ignored.
+    """
+    def __init__(self):
+        super(EnableFrameFilter, self).__init__("enable frame-filter",
+                                                 gdb.COMMAND_DATA)
+    def complete(self, text, word):
+        """Completion function for both frame filter dictionary, and
+        frame filter name."""
+        if text.count(" ") == 0:
+            return _complete_frame_filter_list(text, word, True)
+        else:
+            printer_list = gdb.frames.return_list(text.split()[0].rstrip())
+            return _complete_frame_filter_name(word, printer_list)
+
+    def invoke(self, arg, from_tty):
+        command_tuple = _enable_parse_arg("enable frame-filter", arg)
+        _do_enable_frame_filter(command_tuple, True)
+
+
+class DisableFrameFilter(gdb.Command):
+    """GDB command to disable the specified frame-filter.
+
+    Usage: disable frame-filter disable DICTIONARY [NAME]
+
+    DICTIONARY is the name of the frame filter dictionary on which to
+    operate.  If dictionary is set to "all", perform operations on all
+    dictionaries.  Named dictionaries are: "global" for the global
+    frame filter dictionary, "progspace" for the program space's frame
+    filter dictionary.  If either all, or the two named dictionaries
+    are not specified, the dictionary name is assumed to be the name
+    of the object-file name.
+
+    NAME matches the name of the frame-filter to operate on.  If
+    DICTIONARY is "all", NAME is ignored.
+    """
+    def __init__(self):
+        super(DisableFrameFilter, self).__init__("disable frame-filter",
+                                                  gdb.COMMAND_DATA)
+
+    def complete(self, text, word):
+        """Completion function for both frame filter dictionary, and
+        frame filter name."""
+        if text.count(" ") == 0:
+            return _complete_frame_filter_list(text, word, True)
+        else:
+            printer_list = gdb.frames.return_list(text.split()[0].rstrip())
+            return _complete_frame_filter_name(word, printer_list)
+
+    def invoke(self, arg, from_tty):
+        command_tuple = _enable_parse_arg("disable frame-filter", arg)
+        _do_enable_frame_filter(command_tuple, False)
+
+class SetFrameFilterPriority(gdb.Command):
+    """GDB command to set the priority of the specified frame-filter.
+
+    Usage: set frame-filter priority DICTIONARY NAME PRIORITY
+
+    DICTIONARY is the name of the frame filter dictionary on which to
+    operate.  Named dictionaries are: "global" for the global frame
+    filter dictionary, "progspace" for the program space's framefilter
+    dictionary.  If either of these two are not specified, the
+    dictionary name is assumed to be the name of the object-file name.
+
+    NAME matches the name of the frame filter to operate on.
+
+    PRIORITY is the an integer to assign the new priority to the frame
+    filter.
+    """
+
+    def __init__(self):
+        super(SetFrameFilterPriority, self).__init__("set frame-filter " \
+                                                     "priority",
+                                                     gdb.COMMAND_DATA)
+
+    def _parse_pri_arg(self, arg):
+        """Internal worker to parse a priority from a tuple.
+
+        Arguments:
+            arg: Tuple which contains the arguments from the command.
+
+        Returns:
+            A tuple containing the dictionary, name and priority from
+            the arguments.
+
+        Raises:
+            gdb.GdbError: An error parsing the arguments.
+        """
+
+        argv = gdb.string_to_argv(arg);
+        argc = len(argv)
+        if argc != 3:
+            print("set frame-filter priority " \
+                  "takes exactly three arguments.")
+            return None
+
+        return argv
+
+    def _set_filter_priority(self, command_tuple):
+        """Internal worker for setting priority of frame-filters, by
+        parsing a tuple and calling _set_priority with the parsed
+        tuple.
+
+        Arguments:
+            command_tuple: Tuple which contains the arguments from the
+                           command.
+        """
+
+        list_op = command_tuple[0]
+        frame_filter = command_tuple[1]
+
+        # GDB returns arguments as a string, so convert priority to
+        # a number.
+        priority = int(command_tuple[2])
+
+        op_list = gdb.frames.return_list(list_op)
+
+        try:
+            ff = op_list[frame_filter]
+        except KeyError:
+            msg = "frame-filter '" + str(name) + "' not found."
+            raise gdb.GdbError(msg)
+
+        gdb.frames.set_priority(ff, priority)
+
+    def complete(self, text, word):
+        """Completion function for both frame filter dictionary, and
+        frame filter name."""
+        if text.count(" ") == 0:
+            return _complete_frame_filter_list(text, word, False)
+        else:
+            printer_list = gdb.frames.return_list(text.split()[0].rstrip())
+            return _complete_frame_filter_name(word, printer_list)
+
+    def invoke(self, arg, from_tty):
+        command_tuple = self._parse_pri_arg(arg)
+        if command_tuple != None:
+            self._set_filter_priority(command_tuple)
+
+class ShowFrameFilterPriority(gdb.Command):
+    """GDB command to show the priority of the specified frame-filter.
+
+    Usage: show frame-filter priority DICTIONARY NAME
+
+    DICTIONARY is the name of the frame filter dictionary on which to
+    operate.  Named dictionaries are: "global" for the global frame
+    filter dictionary, "progspace" for the program space's framefilter
+    dictionary.  If either of these two are not specified, the
+    dictionary name is assumed to be the name of the object-file name.
+
+    NAME matches the name of the frame-filter to operate on.
+    """
+
+    def __init__(self):
+        super(ShowFrameFilterPriority, self).__init__("show frame-filter " \
+                                                      "priority",
+                                                      gdb.COMMAND_DATA)
+
+    def _parse_pri_arg(self, arg):
+        """Internal worker to parse a dictionary and name from a
+        tuple.
+
+        Arguments:
+            arg: Tuple which contains the arguments from the command.
+
+        Returns:
+            A tuple containing the dictionary,  and frame filter name.
+
+        Raises:
+            gdb.GdbError: An error parsing the arguments.
+        """
+
+        argv = gdb.string_to_argv(arg);
+        argc = len(argv)
+        if argc != 2:
+            print("show frame-filter priority " \
+                  "takes exactly two arguments.")
+            return None
+
+        return argv
+
+    def get_filter_priority(self, frame_filters, name):
+        """Worker for retrieving the priority of frame_filters.
+
+        Arguments:
+            frame_filters: Name of frame filter dictionary.
+            name: object to select printers.
+
+        Returns:
+            The priority of the frame filter.
+
+        Raises:
+            gdb.GdbError: A frame filter cannot be found.
+        """
+
+        op_list = gdb.frames.return_list(frame_filters)
+
+        try:
+            ff = op_list[name]
+        except KeyError:
+            msg = "frame-filter '" + str(name) + "' not found."
+            raise gdb.GdbError(msg)
+
+        return gdb.frames.get_priority(ff)
+
+    def complete(self, text, word):
+        """Completion function for both frame filter dictionary, and
+        frame filter name."""
+
+        if text.count(" ") == 0:
+            return _complete_frame_filter_list(text, word, False)
+        else:
+            printer_list = frame._return_list(text.split()[0].rstrip())
+            return _complete_frame_filter_name(word, printer_list)
+
+    def invoke(self, arg, from_tty):
+        command_tuple = self._parse_pri_arg(arg)
+        if command_tuple == None:
+            return
+        filter_name = command_tuple[1]
+        list_name = command_tuple[0]
+        try:
+            priority = self.get_filter_priority(list_name, filter_name);
+        except Exception:
+            e = sys.exc_info()[1]
+            print("Error printing filter priority for '"+name+"':"+str(e))
+        else:
+            print("Priority of filter '" + filter_name + "' in list '" \
+                + list_name + "' is: " + str(priority))
+
+# Register commands
+SetFilterPrefixCmd()
+ShowFilterPrefixCmd()
+InfoFrameFilter()
+EnableFrameFilter()
+DisableFrameFilter()
+SetFrameFilterPriority()
+ShowFrameFilterPriority()