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

Change-Id: I30d0fef6bd39e095a8264e20574fa5a46f50c045
diff --git a/share/gdb/python/gdb/FrameDecorator.py b/share/gdb/python/gdb/FrameDecorator.py
new file mode 100644
index 0000000..1bbc5ab
--- /dev/null
+++ b/share/gdb/python/gdb/FrameDecorator.py
@@ -0,0 +1,302 @@
+# 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/>.
+
+import gdb
+
+# This small code snippet deals with problem of strings in Python 2.x
+# and Python 3.x.  Python 2.x has str and unicode classes which are
+# sub-classes of basestring.  In Python 3.x all strings are encoded
+# and basestring has been removed.
+try:
+    basestring
+except NameError:
+    basestring = str
+
+class FrameDecorator(object):
+    """Basic implementation of a Frame Decorator"""
+
+    """ This base frame decorator decorates a frame or another frame
+    decorator, and provides convenience methods.  If this object is
+    wrapping a frame decorator, defer to that wrapped object's method
+    if it has one.  This allows for frame decorators that have
+    sub-classed FrameDecorator object, but also wrap other frame
+    decorators on the same frame to correctly execute.
+
+    E.g
+
+    If the result of frame filters running means we have one gdb.Frame
+    wrapped by multiple frame decorators, all sub-classed from
+    FrameDecorator, the resulting hierarchy will be:
+
+    Decorator1
+      -- (wraps) Decorator2
+        -- (wraps) FrameDecorator
+          -- (wraps) gdb.Frame
+
+    In this case we have two frame decorators, both of which are
+    sub-classed from FrameDecorator.  If Decorator1 just overrides the
+    'function' method, then all of the other methods are carried out
+    by the super-class FrameDecorator.  But Decorator2 may have
+    overriden other methods, so FrameDecorator will look at the
+    'base' parameter and defer to that class's methods.  And so on,
+    down the chain."""
+
+    # 'base' can refer to a gdb.Frame or another frame decorator.  In
+    # the latter case, the child class will have called the super
+    # method and _base will be an object conforming to the Frame Filter
+    # class.
+    def __init__(self, base):
+        self._base = base
+
+    @staticmethod
+    def _is_limited_frame(frame):
+        """Internal utility to determine if the frame is special or
+        limited."""
+        sal = frame.find_sal()
+
+        if (not sal.symtab or not sal.symtab.filename
+            or frame.type() == gdb.DUMMY_FRAME
+            or frame.type() == gdb.SIGTRAMP_FRAME):
+
+            return True
+
+        return False
+
+    def elided(self):
+        """Return any elided frames that this class might be
+        wrapping, or None."""
+        if hasattr(self._base, "elided"):
+            return self._base.elided()
+
+        return None
+
+    def function(self):
+        """ Return the name of the frame's function or an address of
+        the function of the frame.  First determine if this is a
+        special frame.  If not, try to determine filename from GDB's
+        frame internal function API.  Finally, if a name cannot be
+        determined return the address.  If this function returns an
+        address, GDB will attempt to determine the function name from
+        its internal minimal symbols store (for example, for inferiors
+        without debug-info)."""
+
+        # Both gdb.Frame, and FrameDecorator have a method called
+        # "function", so determine which object this is.
+        if not isinstance(self._base, gdb.Frame):
+            if hasattr(self._base, "function"):
+                # If it is not a gdb.Frame, and there is already a
+                # "function" method, use that.
+                return self._base.function()
+
+        frame = self.inferior_frame()
+
+        if frame.type() == gdb.DUMMY_FRAME:
+            return "<function called from gdb>"
+        elif frame.type() == gdb.SIGTRAMP_FRAME:
+            return "<signal handler called>"
+
+        func = frame.function()
+
+        # If we cannot determine the function name, return the
+        # address.  If GDB detects an integer value from this function
+        # it will attempt to find the function name from minimal
+        # symbols via its own internal functions.
+        if func == None:
+            pc = frame.pc()
+            return pc
+
+        return str(func)
+
+    def address(self):
+        """ Return the address of the frame's pc"""
+
+        if hasattr(self._base, "address"):
+            return self._base.address()
+
+        frame = self.inferior_frame()
+        return frame.pc()
+
+    def filename(self):
+        """ Return the filename associated with this frame, detecting
+        and returning the appropriate library name is this is a shared
+        library."""
+
+        if hasattr(self._base, "filename"):
+            return self._base.filename()
+
+        frame = self.inferior_frame()
+        sal = frame.find_sal()
+        if not sal.symtab or not sal.symtab.filename:
+            pc = frame.pc()
+            return gdb.solib_name(pc)
+        else:
+            return sal.symtab.filename
+
+    def frame_args(self):
+        """ Return an iterable of frame arguments for this frame, if
+        any.  The iterable object contains objects conforming with the
+        Symbol/Value interface.  If there are no frame arguments, or
+        if this frame is deemed to be a special case, return None."""
+
+        if hasattr(self._base, "frame_args"):
+            return self._base.frame_args()
+
+        frame = self.inferior_frame()
+        if self._is_limited_frame(frame):
+            return None
+
+        args = FrameVars(frame)
+        return args.fetch_frame_args()
+
+    def frame_locals(self):
+        """ Return an iterable of local variables for this frame, if
+        any.  The iterable object contains objects conforming with the
+        Symbol/Value interface.  If there are no frame locals, or if
+        this frame is deemed to be a special case, return None."""
+
+        if hasattr(self._base, "frame_locals"):
+            return self._base.frame_locals()
+
+        frame = self.inferior_frame()
+        if self._is_limited_frame(frame):
+            return None
+
+        args = FrameVars(frame)
+        return args.fetch_frame_locals()
+
+    def line(self):
+        """ Return line number information associated with the frame's
+        pc.  If symbol table/line information does not exist, or if
+        this frame is deemed to be a special case, return None"""
+
+        if hasattr(self._base, "line"):
+            return self._base.line()
+
+        frame = self.inferior_frame()
+        if self._is_limited_frame(frame):
+            return None
+
+        sal = frame.find_sal()
+        if (sal):
+            return sal.line
+        else:
+            return None
+
+    def inferior_frame(self):
+        """ Return the gdb.Frame underpinning this frame decorator."""
+
+        # If 'base' is a frame decorator, we want to call its inferior
+        # frame method.  If '_base' is a gdb.Frame, just return that.
+        if hasattr(self._base, "inferior_frame"):
+            return self._base.inferior_frame()
+        return self._base
+
+class SymValueWrapper(object):
+    """A container class conforming to the Symbol/Value interface
+    which holds frame locals or frame arguments."""
+    def __init__(self, symbol, value):
+        self.sym = symbol
+        self.val = value
+
+    def value(self):
+        """ Return the value associated with this symbol, or None"""
+        return self.val
+
+    def symbol(self):
+        """ Return the symbol, or Python text, associated with this
+        symbol, or None"""
+        return self.sym
+
+class FrameVars(object):
+
+    """Utility class to fetch and store frame local variables, or
+    frame arguments."""
+
+    def __init__(self, frame):
+        self.frame = frame
+        self.symbol_class = {
+            gdb.SYMBOL_LOC_STATIC: True,
+            gdb.SYMBOL_LOC_REGISTER: True,
+            gdb.SYMBOL_LOC_ARG: True,
+            gdb.SYMBOL_LOC_REF_ARG: True,
+            gdb.SYMBOL_LOC_LOCAL: True,
+	    gdb.SYMBOL_LOC_REGPARM_ADDR: True,
+	    gdb.SYMBOL_LOC_COMPUTED: True
+            }
+
+    def fetch_b(self, sym):
+        """ Local utility method to determine if according to Symbol
+        type whether it should be included in the iterator.  Not all
+        symbols are fetched, and only symbols that return
+        True from this method should be fetched."""
+
+        # SYM may be a string instead of a symbol in the case of
+        # synthetic local arguments or locals.  If that is the case,
+        # always fetch.
+        if isinstance(sym, basestring):
+            return True
+
+        sym_type = sym.addr_class
+
+        return self.symbol_class.get(sym_type, False)
+
+    def fetch_frame_locals(self):
+        """Public utility method to fetch frame local variables for
+        the stored frame.  Frame arguments are not fetched.  If there
+        are no frame local variables, return an empty list."""
+        lvars = []
+
+        try:
+            block = self.frame.block()
+        except RuntimeError:
+            block = None
+
+        while block != None:
+            if block.is_global or block.is_static:
+                break
+            for sym in block:
+                if sym.is_argument:
+                    continue;
+                if self.fetch_b(sym):
+                    lvars.append(SymValueWrapper(sym, None))
+
+            block = block.superblock
+
+        return lvars
+
+    def fetch_frame_args(self):
+        """Public utility method to fetch frame arguments for the
+        stored frame.  Frame arguments are the only type fetched.  If
+        there are no frame argument variables, return an empty list."""
+
+        args = []
+
+        try:
+            block = self.frame.block()
+        except RuntimeError:
+            block = None
+
+        while block != None:
+            if block.function != None:
+                break
+            block = block.superblock
+
+        if block != None:
+            for sym in block:
+                if not sym.is_argument:
+                    continue;
+                args.append(SymValueWrapper(sym, None))
+
+        return args