Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
# Copyright (C) 2017 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 GCC; see the file COPYING3. If not see # <http://www.gnu.org/licenses/>.
# Data structures to represent DWARF compilation units, DIEs and attributes, # and helpers to perform various checks on them.
"""DWARF abbreviation entry."""
""" :param int number: Abbreviation number, which is 1-based, as in the DWARF standard. :param str|int tag: Tag name or, if unknown, tag number. :param bool has_children: Whether DIEs will have children. :param list[(str|int, str)] attributes: List of attributes. """
""" :param str|int name: Attribute name or, if unknown, attribute number. :param str form: Form for this attribute. """
"""DWARF compilation unit."""
pointer_size): """ :param int offset: Offset of this compilation unit in the .debug_info section. :param int length: Value of the length field for this compilation unit. :param bool is_32bit: Whether this compilation unit is encoded in the 32-bit format. If not, it must be the 64-bit one. :param int version: DWARF version used by this compilation unit. :param list[Abbrev] abbrevs: List of abbreviations for this compilation unit. :param int pointer_size: Size of pointers for this architecture. """
' compilation unit that already has one')
""" Fetch the DIE that starts at the given offset. Raise a KeyError if not found.
:param int offset: DIE offset in this compilation unit. :rtype: DIE """
"""DWARF information entry."""
""" :param CompilationUnit cu: Compilation unit this DIE belongs to. :param int level: Depth for this DIE. :param int offset: Offset of this DIE in the .debug_info section. :param int abbrev_number: Abbreviation number for this DIE. """
def abbrev(self): """Abbreviation for this DIE.
:rtype: Abbrev """ # The abbreviation number is 1-based, but list indexes are 0-based
def tag(self): """Tag for this DIE.
:rtype: str|int """
def has_children(self):
"""Look for an attribute in this DIE.
:param str|int name: Attribute name, or number if name is unknown. :param bool single: If true, this will raise a KeyError for zero/multiple matches and return an Attribute instance when found. Otherwise, return a potentially empty list of attributes. :param bool or_error: When true, if `single` is true and no attribute is found, return None instead of raising a KeyError. :rtype: Attribute|list[Attribute] """
self)) else: self)) else:
"""Check for the presence/value of an attribute.
:param str|int name: Attribute name, or number if name is unknown. :param value: If None, check that the attribute is not present. Otherwise, check that the attribute exists and that its value matches `value`. """ m.succeeded, m.mismatch_reason or 'check attribute {0} of {1}'.format(name, self) )
"""Get a DIE child.
:param int child_index: Index of the child to fetch (zero-based index). :rtype: DIE """
def name(self): """Return the name (DW_AT_name) for this DIE, if any.
:rtype: str|None """
'DIE {0}'.format(self.tag))
"""Return whether this DIE matches expectations.
:rtype: bool """ (name is None or self.name == name))
"""Match this DIE against the given match object.
:param Matcher matcher: Match object used to check the structure of this DIE. :rtype: MatchResult """
"""Like `tree_matches`, but also check that the DIE matches.""" m.succeeded, m.mismatch_reason or 'check structure of {0}'.format(self) )
single=True): """Look for a DIE that satisfies the given expectations.
:param None|(DIE) -> bool predicate: If provided, function that filters out DIEs when it returns false. :param str|int|None tag: If provided, filter out DIEs whose tag does not match. :param str|None name: If provided, filter out DIEs whose name (see the `name` property) does not match. :param bool recursive: If true, perform the search recursively in self's children. :param bool single: If true, look for a single DIE and raise a ValueError if none or several DIEs are found. Otherwise, return a potentially empty list of DIEs.
:rtype: DIE|list[DIE] """ (predicate is None or predicate(die)))
else:
else:
"""Return the form of the next attribute this DIE requires.
Used during DIE tree construction.
:param str name: Expected name for this attribute. The abbreviation will confirm it. :rtype: str """ 'Attribute desynchronization in {0}'.format(self) )
"""Add an attribute to this DIE.
Used during DIE tree construction. See Attribute's constructor for the meaning of arguments. """
"""Add a DIE child to this DIE.
Used during DIE tree construction.
:param DIE child: DIE to append. """
"""DIE attribute."""
""" :param DIE die: DIE that will own this attribute. :param str|int name: Attribute name, or attribute number if unknown. :param str form: Attribute form. :param int offset: Offset of this attribute in the .debug_info section. :param value: Decoded value for this attribute. If it's a Defer instance, decoding will happen the first time the "value" property is evaluated. """
else:
def value(self):
# If we hold a location expression, bind it to this attribute
'Attribute {0}'.format(self.name))
"""DWARF location expression."""
""" :param list[int] byte_list: List of bytes that encode this expression. :param list[(str, ...)] operations: List of operations this expression contains. Each expression is a tuple whose first element is the opcode name (DW_OP_...) and whose other elements are operands. """
def die(self): return self.attribute.die
def format_operation(operation): if operands else opcode)
"""Match this list of operations to `operations`.
:param list[(str, ...)] operations: List of operations to match. :rtype: bool """
' '.join(hex(b) for b in self.byte_list), '; '.join(self.format_operation(op) for op in self.operations) )
"""Helper to defer a computation."""
""" :param () -> T func: Callback to perform the computation. """
""" :rtype: T """
"""Specification for DIE tree pattern matching."""
capture=None): """ :param None|str tag: If provided, name of the tag that DIEs must match. :param None|str name: If provided, name that DIEs must match (see the DIE.name property). :param attrs: If provided, dictionary that specifies attribute expectations. Keys are attribute names. Values can be:
* None, so that attribute must be undefined in the DIE; * a value, so that attribute must be defined and the value must match; * a Capture instance, so that the attribute value (or None, if undefined) is captured.
:param None | list[DIE|Capture] children: If provided, list of DIEs that children must match. Capture instances match any DIE and captures it.
:param str|None capture: If provided, capture the DIE to match with the given name. """
"""Pattern match the given DIE.
:param DIE die: DIE to match. :rtype: MatchResult """
"""Helper for the "matches" method.
Return whether DIE could be matched. If not, a message to describe why is recorded in `result`.
:param DIE die: DIE to match. :param MatchResult result: Holder for the result of the match. :rtype: bool """
# If asked to, check the DIE tag die, self.tag )
# If asked to, check the DIE name '{0} is expected to be called "{1}"'.format(die, self.name) )
# Check attribute expectations
# Check children expectations
# The number of children must match '{0} has {1} children, {2} expected'.format( die, len(die.children), len(self.children) ) )
# Then each child must match the corresponding child matcher die.children): # Capture instances matches anything and captures it
# Capture the input DIE if asked to
# If no check failed, the DIE matches the pattern
def _match_attr(die, attr_name, attr_value, result): """Helper for the "matches" method.
Return whether the `attr_name` attribute in DIE matches the `attr_value` expectation. If not, a message to describe why is recorded in `result`.
:param DIE die: DIE that contain the attribute to match. :param str attr_name: Attribute name. :param attr_value: Attribute expectation. See attrs's description in Match.__init__ docstring for possible values. """
# The attribute is expected not to be defined
'{0} has a {1} attribute, none expected'.format( die, attr_name ) )
# Capture instances matches anything and capture it
# If we reach this point, the attribute is supposed to be defined: # check it is. '{0} is missing a {1} attribute'.format(die, attr_name) )
# Check the value of the attribute matches else: '{0}: {1} is {2}, expected to be {3}'.format( die, attr_name, attr.value, attr_value ) )
# If no check failed, the attribute matches the pattern
"""Placeholder in Matcher tree patterns.
This is used to capture specific elements during pattern matching. """ """ :param str name: Capture name. """
"""Holder for the result of a DIE tree pattern match."""
If left to None, the match succeeded. Otherwise, must be set to a string that describes why the match failed.
:type: None|str """
def succeeded(self):
"""Return what has been captured by the `name` capture.
This is valid iff the match succeeded.
:param str name: Capture name: """ |