示例#1
0
文件: datatype.py 项目: st-rnd/ADBI-1
    def __eval_offset(self):
        bitoffset = get_attr_val(self.die, 'DW_AT_data_bit_offset')
        if bitoffset is not None:
            # Bit offset is given directly
            return bitoffset

        location = get_attr_val(self.die, 'DW_AT_data_member_location')
        if location is None:
            # no offset attribute exists -- the member is located at the beginning of its parent
            return 0
        elif isinstance(location, (int, long)):
            # the attribute is a number -- this is the offset in bytes
            return location * 8
        elif isinstance(location, list):
            # the attribute is an expression
            dwxpr = location
            if dwxpr[0] == dwarf_expr.DW_OP_name2opcode['DW_OP_plus_uconst']:
                # Right now we only support location descriptions in the form [DW_OP_plus_uconst, <ULEB128>].
                # This is the only form GCC and clang produce.
                return LEB.decode(BytesIO(bytearray(dwxpr[1:]))) * 8
            else:
                opcode = dwarf_expr.DW_OP_opcode2name.get(
                    dwxpr[0], '<unknown>')
                raise NotImplementedError(
                    'Unsupported opcode in data member location %s (%02x)' %
                    (opcode, dwxpr[0]))

        assert False, 'Unreachable code.'
示例#2
0
    def __eval_offset(self):
        bitoffset = get_attr_val(self.die, 'DW_AT_data_bit_offset')
        if bitoffset is not None:
            # Bit offset is given directly
            return bitoffset

        location = get_attr_val(self.die, 'DW_AT_data_member_location')
        if location is None:
            # no offset attribute exists -- the member is located at the beginning of its parent
            return 0
        elif isinstance(location, (int, long)):
            # the attribute is a number -- this is the offset in bytes
            return location * 8
        elif isinstance(location, list):
            # the attribute is an expression
            dwxpr = location
            if dwxpr[0] == dwarf_expr.DW_OP_name2opcode['DW_OP_plus_uconst']:
                # Right now we only support location descriptions in the form [DW_OP_plus_uconst, <ULEB128>].
                # This is the only form GCC and clang produce.
                return LEB.decode(BytesIO(bytearray(dwxpr[1:]))) * 8
            else:
                opcode = dwarf_expr.DW_OP_opcode2name.get(dwxpr[0], '<unknown>')
                raise NotImplementedError('Unsupported opcode in data member location %s (%02x)' % (opcode, dwxpr[0]))

        assert False, 'Unreachable code.'
示例#3
0
def decode_offset(member_location):
    '''Convert dwarf expression in DW_AT_data_member_location to offset from structure start.'''
    if member_location is None:
        # the attribute does not exist -- the member is located at the beginning of its parent
        return 0
    elif isinstance(member_location, int):
        # the attribute is a number -- this is the offset
        return member_location
    elif isinstance(member_location, list):
        # the attribute is an expression
        dwxpr = member_location
        if dwxpr[0] == dwarf_expr.DW_OP_name2opcode['DW_OP_plus_uconst']:
            # Right now we only support location descriptions in the form [DW_OP_plus_uconst, <ULEB128>].
            # This is the only form GCC and clang produce.
            return LEB.decode(BytesIO(bytearray(dwxpr[1:])))
        else:
            opcode = dwarf_expr.DW_OP_opcode2name.get(dwxpr[0], '<unknown>')
            raise NotImplementedError('Unsupported opcode in data member location %s (%02x)' % (opcode, dwxpr[0]))
示例#4
0
        def iter_entries():
            if not self.debug_info.dwarf.has_CFI():
                logging.warn('ELF has no call frame information.')
                return

            for fde in self.debug_info.dwarf.CFI_entries():

                if not isinstance(fde, FDE):
                    continue

                low = fde.header.initial_location
                high = low + fde.header.address_range

                invalid = False
                decoded = fde.get_decoded().table
                for n, each in enumerate(decoded, 0):
                    try:
                        entry_low = debug_info.addr2fo(each['pc'])
                        entry_high = debug_info.addr2fo(
                            high if n >= len(decoded) -
                            1 else decoded[n + 1]['pc'])
                    except ValueError:
                        invalid = True
                        continue

                    cfa_rule = each['cfa']
                    if cfa_rule.expr is not None:
                        # CFA is a regular DWARF expressions
                        expr = cfa_rule.expr
                    else:
                        assert cfa_rule.reg is not None
                        # CFA is a register + offset -- convert it to a DWARF expression
                        expr = bytearray([0x92])  # DW_OP_bregx
                        expr += LEB.encode(cfa_rule.reg)  # Register index
                        expr += SLEB.encode(
                            cfa_rule.offset)  # Offset from register
                    yield CallFrameInfoEntry(entry_low, entry_high,
                                             b64encode(expr))

                if invalid:
                    logging.warn(
                        'Invalid call frame information entry encountered in FDE at %#x.',
                        fde.offset)
示例#5
0
文件: datatype.py 项目: st-rnd/ADBI-1
def decode_offset(member_location):
    '''Convert dwarf expression in DW_AT_data_member_location to offset from structure start.'''
    if member_location is None:
        # the attribute does not exist -- the member is located at the beginning of its parent
        return 0
    elif isinstance(member_location, int):
        # the attribute is a number -- this is the offset
        return member_location
    elif isinstance(member_location, list):
        # the attribute is an expression
        dwxpr = member_location
        if dwxpr[0] == dwarf_expr.DW_OP_name2opcode['DW_OP_plus_uconst']:
            # Right now we only support location descriptions in the form [DW_OP_plus_uconst, <ULEB128>].
            # This is the only form GCC and clang produce.
            return LEB.decode(BytesIO(bytearray(dwxpr[1:])))
        else:
            opcode = dwarf_expr.DW_OP_opcode2name.get(dwxpr[0], '<unknown>')
            raise NotImplementedError(
                'Unsupported opcode in data member location %s (%02x)' %
                (opcode, dwxpr[0]))
示例#6
0
文件: cfi.py 项目: Jarlene/ADBI-1
        def iter_entries():
            if not self.debug_info.dwarf.has_CFI():
                logging.warn('ELF has no call frame information.')
                return 

            for fde in self.debug_info.dwarf.CFI_entries():
                
                if not isinstance(fde, FDE):
                    continue
                
                low = fde.header.initial_location
                high = low + fde.header.address_range
                            
                invalid = False
                decoded = fde.get_decoded().table
                for n, each in enumerate(decoded, 0):
                    try:
                        entry_low = debug_info.addr2fo(each['pc'])
                        entry_high = debug_info.addr2fo(high if n >= len(decoded) - 1 else decoded[n + 1]['pc'])
                    except ValueError:
                        invalid = True
                        continue

                    cfa_rule = each['cfa']
                    if cfa_rule.expr is not None:
                        # CFA is a regular DWARF expressions
                        expr = cfa_rule.expr
                    else:
                        assert cfa_rule.reg is not None
                        # CFA is a register + offset -- convert it to a DWARF expression
                        expr = bytearray([0x92])                # DW_OP_bregx 
                        expr += LEB.encode(cfa_rule.reg)        # Register index
                        expr += SLEB.encode(cfa_rule.offset)    # Offset from register
                    yield CallFrameInfoEntry(entry_low, entry_high, b64encode(expr)) 

                if invalid:
                    logging.warn('Invalid call frame information entry encountered in FDE at %#x.', fde.offset)
示例#7
0
文件: machine.py 项目: st-rnd/ADBI-1
 def regx(self):
     regnum = LEB.decode(self.expression)
     return 'get_reg(%i)' % regnum
示例#8
0
文件: machine.py 项目: st-rnd/ADBI-1
 def bregx(self):
     '''The DW_OP_bregx operation has two operands: a register which is specified by an unsigned LEB128 number, 
     followed by a signed LEB128 offset.'''
     regnum = LEB.decode(self.expression)
     return self.bregN(regnum)
示例#9
0
文件: machine.py 项目: st-rnd/ADBI-1
 def constu(self):
     '''The single operand of the DW_OP_constu operation provides an unsigned LEB128 integer constant.'''
     val = LEB.decode(self.expression)
     self.push('%#x' % val)
示例#10
0
文件: machine.py 项目: Jarlene/ADBI-1
 def regx(self):
     regnum = LEB.decode(self.expression)
     return 'get_reg(%i)' % regnum
示例#11
0
文件: machine.py 项目: Jarlene/ADBI-1
 def bregx(self):
     '''The DW_OP_bregx operation has two operands: a register which is specified by an unsigned LEB128 number, 
     followed by a signed LEB128 offset.'''
     regnum = LEB.decode(self.expression)
     return self.bregN(regnum)
示例#12
0
文件: machine.py 项目: Jarlene/ADBI-1
 def constu(self):
     '''The single operand of the DW_OP_constu operation provides an unsigned LEB128 integer constant.'''
     val = LEB.decode(self.expression)
     self.push('%#x' % val)