コード例 #1
0
    def testEncodeOrder(self):
        address_unwind1 = AddressUnwind(address_offset=0,
                                        unwind_type=UnwindType.RETURN_TO_LR,
                                        sp_offset=0,
                                        registers=tuple())
        address_unwind2 = AddressUnwind(
            address_offset=4,
            unwind_type=UnwindType.UPDATE_SP_AND_OR_POP_REGISTERS,
            sp_offset=0,
            registers=(4, 14))

        def MockEncodeAddressUnwind(address_unwind):
            return {
                address_unwind1: bytes([1]),
                address_unwind2: bytes([2]),
            }[address_unwind]

        with unittest.mock.patch("create_unwind_table.EncodeAddressUnwind",
                                 side_effect=MockEncodeAddressUnwind):
            encoded_unwinds = EncodeAddressUnwinds(
                (address_unwind1, address_unwind2))
            self.assertEqual((
                EncodedAddressUnwind(4,
                                     bytes([2]) + bytes([1])),
                EncodedAddressUnwind(0, bytes([1])),
            ), encoded_unwinds)
コード例 #2
0
    def testUpdateSpAndOrPopRegisters(self):
        self.assertEqual(
            bytes([0b0, 0b10101000]),
            EncodeAddressUnwind(
                AddressUnwind(
                    address_offset=0,
                    unwind_type=UnwindType.UPDATE_SP_AND_OR_POP_REGISTERS,
                    sp_offset=0x4,
                    registers=(4, 14))))

        self.assertEqual(
            bytes([0b0]),
            EncodeAddressUnwind(
                AddressUnwind(
                    address_offset=0,
                    unwind_type=UnwindType.UPDATE_SP_AND_OR_POP_REGISTERS,
                    sp_offset=0x4,
                    registers=tuple())))

        self.assertEqual(
            bytes([0b10101000]),
            EncodeAddressUnwind(
                AddressUnwind(
                    address_offset=0,
                    unwind_type=UnwindType.UPDATE_SP_AND_OR_POP_REGISTERS,
                    sp_offset=0,
                    registers=(4, 14))))
コード例 #3
0
 def testSuccessUnwind(self):
     self.assertEqual(
         [
             FunctionUnwind(address=0x100,
                            size=1024,
                            address_unwinds=(
                                AddressUnwind(
                                    address_offset=0x0,
                                    unwind_type=UnwindType.RETURN_TO_LR,
                                    sp_offset=0,
                                    registers=(),
                                ),
                                AddressUnwind(
                                    address_offset=0x200,
                                    unwind_type=UnwindType.RETURN_TO_LR,
                                    sp_offset=0,
                                    registers=(),
                                ),
                            ))
         ],
         list(
             GenerateUnwinds([
                 FunctionCfi(size=1024,
                             address_cfi=(
                                 AddressCfi(address=0x100,
                                            unwind_instructions='RETURN'),
                                 AddressCfi(address=0x300,
                                            unwind_instructions='RETURN'),
                             ))
             ],
                             parsers=[MockReturnParser()])))
コード例 #4
0
 def testReturnToLr(self):
     self.assertEqual(
         bytes([0b10110000]),
         EncodeAddressUnwind(
             AddressUnwind(address_offset=0,
                           unwind_type=UnwindType.RETURN_TO_LR,
                           sp_offset=0,
                           registers=tuple())))
コード例 #5
0
 def testNoAction(self):
     self.assertEqual(
         bytes([]),
         EncodeAddressUnwind(
             AddressUnwind(address_offset=0,
                           unwind_type=UnwindType.NO_ACTION,
                           sp_offset=0,
                           registers=tuple())))
コード例 #6
0
    def testCfaAndRegistersChange(self):
        parser = StoreSpParser()
        match = parser.GetBreakpadInstructionsRegex().search('.cfa: r7 8 +')
        self.assertIsNotNone(match)

        address_unwind, new_cfa_sp_offset = parser.ParseFromMatch(
            address_offset=20, cfa_sp_offset=12, match=match)

        self.assertEqual(8, new_cfa_sp_offset)
        self.assertEqual(
            AddressUnwind(address_offset=20,
                          unwind_type=UnwindType.RESTORE_SP_FROM_REGISTER,
                          sp_offset=-4,
                          registers=(7, )), address_unwind)
コード例 #7
0
    def testRestoreSpFromRegisters(self):
        self.assertEqual(
            bytes([0b10010100, 0b0]),
            EncodeAddressUnwind(
                AddressUnwind(address_offset=0,
                              unwind_type=UnwindType.RESTORE_SP_FROM_REGISTER,
                              sp_offset=0x4,
                              registers=(4, ))))

        self.assertEqual(
            bytes([0b10010100]),
            EncodeAddressUnwind(
                AddressUnwind(address_offset=0,
                              unwind_type=UnwindType.RESTORE_SP_FROM_REGISTER,
                              sp_offset=0,
                              registers=(4, ))))

        self.assertRaises(
            AssertionError, lambda: EncodeAddressUnwind(
                AddressUnwind(address_offset=0,
                              unwind_type=UnwindType.RESTORE_SP_FROM_REGISTER,
                              sp_offset=0x4,
                              registers=tuple())))
コード例 #8
0
    def testParsePrecedence(self):
        address_unwind = AddressUnwind(
            address_offset=0x300,
            unwind_type=UnwindType.RETURN_TO_LR,
            sp_offset=0,
            registers=(),
        )

        self.assertEqual(
            (address_unwind, False, 0),
            ParseAddressCfi(AddressCfi(address=0x800,
                                       unwind_instructions='RETURN'),
                            function_start_address=0x500,
                            parsers=(MockReturnParser(), MockWildcardParser()),
                            prev_cfa_sp_offset=0))
コード例 #9
0
    def testCfaChange(self):
        parser = PushOrSubSpParser()
        match = parser.GetBreakpadInstructionsRegex().search('.cfa: sp 4 +')
        self.assertIsNotNone(match)

        address_unwind, new_cfa_sp_offset = parser.ParseFromMatch(
            address_offset=20, cfa_sp_offset=0, match=match)

        self.assertEqual(4, new_cfa_sp_offset)
        self.assertEqual(
            AddressUnwind(
                address_offset=20,
                unwind_type=UnwindType.UPDATE_SP_AND_OR_POP_REGISTERS,
                sp_offset=4,
                registers=()), address_unwind)
コード例 #10
0
    def testCfaChange(self):
        parser = NullParser()
        match = parser.GetBreakpadInstructionsRegex().search(
            '.cfa: sp 0 + .ra: lr')
        self.assertIsNotNone(match)

        address_unwind, new_cfa_sp_offset = parser.ParseFromMatch(
            address_offset=0, cfa_sp_offset=0, match=match)

        self.assertEqual(0, new_cfa_sp_offset)
        self.assertEqual(
            AddressUnwind(address_offset=0,
                          unwind_type=UnwindType.RETURN_TO_LR,
                          sp_offset=0,
                          registers=()), address_unwind)
コード例 #11
0
    def testRegistersOrdering(self):
        parser = PushOrSubSpParser()
        match = parser.GetBreakpadInstructionsRegex().search(
            'r10: .cfa -8 + ^ r7: .cfa -4 + ^')
        self.assertIsNotNone(match)

        address_unwind, new_cfa_sp_offset = parser.ParseFromMatch(
            address_offset=20, cfa_sp_offset=0, match=match)

        self.assertEqual(0, new_cfa_sp_offset)
        self.assertEqual(
            AddressUnwind(
                address_offset=20,
                unwind_type=UnwindType.UPDATE_SP_AND_OR_POP_REGISTERS,
                sp_offset=0,
                registers=(7, 10)), address_unwind)
コード例 #12
0
    def testRegistersChange(self):
        parser = VPushParser()
        match = parser.GetBreakpadInstructionsRegex().search(
            'unnamed_register264: .cfa -40 + ^ unnamed_register265: .cfa -32 + ^'
        )
        self.assertIsNotNone(match)

        address_unwind, new_cfa_sp_offset = parser.ParseFromMatch(
            address_offset=20, cfa_sp_offset=24, match=match)

        self.assertEqual(24, new_cfa_sp_offset)
        self.assertEqual(
            AddressUnwind(address_offset=20,
                          unwind_type=UnwindType.NO_ACTION,
                          sp_offset=0,
                          registers=()), address_unwind)
コード例 #13
0
    def testCfaAndRaAndRegistersChangePopAndSpUpdate(self):
        parser = PushOrSubSpParser()
        match = parser.GetBreakpadInstructionsRegex().search(
            '.cfa: sp 16 + .ra: .cfa -4 + ^ r4: .cfa -12 + ^ r7: .cfa -8 + ^')
        self.assertIsNotNone(match)

        address_unwind, new_cfa_sp_offset = parser.ParseFromMatch(
            address_offset=20, cfa_sp_offset=0, match=match)

        self.assertEqual(16, new_cfa_sp_offset)
        self.assertEqual(
            AddressUnwind(
                address_offset=20,
                unwind_type=UnwindType.UPDATE_SP_AND_OR_POP_REGISTERS,
                sp_offset=4,
                registers=(4, 7, 14)), address_unwind)
コード例 #14
0
    def testCfaAndRegistersChange(self):
        parser = VPushParser()
        match = parser.GetBreakpadInstructionsRegex().search(
            '.cfa: sp 40 + unnamed_register264: .cfa -40 + ^ '
            'unnamed_register265: .cfa -32 + ^')
        self.assertIsNotNone(match)

        address_unwind, new_cfa_sp_offset = parser.ParseFromMatch(
            address_offset=20, cfa_sp_offset=24, match=match)

        self.assertEqual(40, new_cfa_sp_offset)
        self.assertEqual(
            AddressUnwind(
                address_offset=20,
                unwind_type=UnwindType.UPDATE_SP_AND_OR_POP_REGISTERS,
                sp_offset=16,
                registers=()), address_unwind)
コード例 #15
0
    def testPoppingCallerSaveRegisters(self):
        """Regression test for pop unwinds that encode caller-save registers.

    Callee-save registers: r0 ~ r3.
    """
        parser = PushOrSubSpParser()
        match = parser.GetBreakpadInstructionsRegex().search(
            '.cfa: sp 16 + .ra: .cfa -4 + ^ '
            'r3: .cfa -16 + ^ r4: .cfa -12 + ^ r5: .cfa -8 + ^')

        self.assertIsNotNone(match)

        address_unwind, new_cfa_sp_offset = parser.ParseFromMatch(
            address_offset=20, cfa_sp_offset=0, match=match)

        self.assertEqual(16, new_cfa_sp_offset)
        self.assertEqual(
            AddressUnwind(
                address_offset=20,
                unwind_type=UnwindType.UPDATE_SP_AND_OR_POP_REGISTERS,
                sp_offset=4,
                registers=(4, 5, 14)), address_unwind)
コード例 #16
0
 def ParseFromMatch(self, address_offset, cfa_sp_offset, match):
     return AddressUnwind(address_offset,
                          UnwindType.UPDATE_SP_AND_OR_POP_REGISTERS, 0,
                          ()), -200
コード例 #17
0
 def ParseFromMatch(self, address_offset, cfa_sp_offset, match):
     return AddressUnwind(address_offset, UnwindType.RETURN_TO_LR, 0, ()), 0