Exemplo n.º 1
0
    def testFillingFirstPage(self, MockEncodeAddressUnwinds):
        MockEncodeAddressUnwinds.return_value = EncodedAddressUnwind(
            0, b'\x00')

        self.assertEqual(
            [
                EncodedFunctionUnwind(page_number=0,
                                      page_offset=0,
                                      address_unwinds=REFUSE_TO_UNWIND),
                EncodedFunctionUnwind(page_number=0,
                                      page_offset=100 >> 1,
                                      address_unwinds=EncodedAddressUnwind(
                                          0, b'\x00')),
                EncodedFunctionUnwind(page_number=0,
                                      page_offset=200 >> 1,
                                      address_unwinds=EncodedAddressUnwind(
                                          0, b'\x00')),
                EncodedFunctionUnwind(page_number=0,
                                      page_offset=300 >> 1,
                                      address_unwinds=REFUSE_TO_UNWIND),
            ],
            list(
                EncodeFunctionUnwinds([
                    FunctionUnwind(address=1100, size=100, address_unwinds=()),
                    FunctionUnwind(address=1200, size=100, address_unwinds=()),
                ],
                                      text_section_start_address=1000)))
Exemplo n.º 2
0
    def testFillingGaps(self, MockEncodeAddressUnwinds):
        MockEncodeAddressUnwinds.return_value = EncodedAddressUnwind(
            0, b'\x00')

        self.assertEqual(
            [
                EncodedFunctionUnwind(page_number=0,
                                      page_offset=0,
                                      address_unwinds=EncodedAddressUnwind(
                                          0, b'\x00')),
                EncodedFunctionUnwind(page_number=0,
                                      page_offset=50 >> 1,
                                      address_unwinds=TRIVIAL_UNWIND),
                EncodedFunctionUnwind(page_number=0,
                                      page_offset=100 >> 1,
                                      address_unwinds=EncodedAddressUnwind(
                                          0, b'\x00')),
            ],
            list(
                EncodeFunctionUnwinds([
                    FunctionUnwind(address=0, size=50, address_unwinds=()),
                    FunctionUnwind(
                        address=100, size=PAGE_SIZE - 100, address_unwinds=()),
                ],
                                      text_section_start_address=0)))
Exemplo n.º 3
0
    def testMultiPageFunction(self):
        address_unwind_sequence0 = (
            EncodedAddressUnwind(0x10, bytes([0, 3])),
            EncodedAddressUnwind(0x0, bytes([3])),
        )
        address_unwind_sequence1 = (
            EncodedAddressUnwind(0x10, bytes([1, 3])),
            EncodedAddressUnwind(0x0, bytes([3])),
        )
        address_unwind_sequence2 = (
            EncodedAddressUnwind(0x200, bytes([2, 3])),
            EncodedAddressUnwind(0x0, bytes([3])),
        )

        function_unwinds = [
            EncodedFunctionUnwind(page_number=0,
                                  page_offset=0,
                                  address_unwinds=address_unwind_sequence0),
            # Large function.
            EncodedFunctionUnwind(page_number=0,
                                  page_offset=0x8000,
                                  address_unwinds=address_unwind_sequence1),
            EncodedFunctionUnwind(page_number=4,
                                  page_offset=0x8000,
                                  address_unwinds=address_unwind_sequence2),
        ]

        function_offset_table_offsets = {
            address_unwind_sequence0: 0x100,
            address_unwind_sequence1: 0x200,
            address_unwind_sequence2: 0x300,
        }

        page_table, function_table = EncodePageTableAndFunctionTable(
            function_unwinds, function_offset_table_offsets)

        self.assertEqual(5 * 4, len(page_table))
        self.assertEqual((0, 2, 2, 2, 2), struct.unpack('5I', page_table))

        self.assertEqual(6 * 2, len(function_table))
        self.assertEqual((0, 0x100, 0x8000, 0x200, 0x8000, 0x300),
                         struct.unpack('6H', function_table))
Exemplo n.º 4
0
    def testEncodeOrder(self, MockEncodeAddressUnwinds):
        MockEncodeAddressUnwinds.return_value = EncodedAddressUnwind(
            0, b'\x00')

        self.assertEqual([
            EncodedFunctionUnwind(page_number=0,
                                  page_offset=0,
                                  address_unwinds=EncodedAddressUnwind(
                                      0, b'\x00')),
            EncodedFunctionUnwind(page_number=0,
                                  page_offset=100 >> 1,
                                  address_unwinds=EncodedAddressUnwind(
                                      0, b'\x00')),
        ],
                         list(
                             EncodeFunctionUnwinds([
                                 FunctionUnwind(address=100,
                                                size=PAGE_SIZE - 100,
                                                address_unwinds=()),
                                 FunctionUnwind(address=0,
                                                size=100,
                                                address_unwinds=()),
                             ])))
Exemplo n.º 5
0
    def testGenerateUnwindTables(self):
        """This is an integration test that hooks everything together. """
        address_unwind_sequence0 = (
            EncodedAddressUnwind(0x10, bytes([0, 0xb0])),
            EncodedAddressUnwind(0x0, bytes([0xb0])),
        )
        address_unwind_sequence1 = (
            EncodedAddressUnwind(0x10, bytes([1, 0xb0])),
            EncodedAddressUnwind(0x0, bytes([0xb0])),
        )
        address_unwind_sequence2 = (
            EncodedAddressUnwind(0x100, bytes([2, 0xb0])),
            EncodedAddressUnwind(0x0, bytes([0xb0])),
        )

        (page_table, function_table, function_offset_table,
         unwind_instruction_table) = GenerateUnwindTables([
             EncodedFunctionUnwind(page_number=0,
                                   page_offset=0,
                                   address_unwinds=TRIVIAL_UNWIND),
             EncodedFunctionUnwind(page_number=0,
                                   page_offset=0x1000,
                                   address_unwinds=address_unwind_sequence0),
             EncodedFunctionUnwind(page_number=1,
                                   page_offset=0x2000,
                                   address_unwinds=address_unwind_sequence1),
             EncodedFunctionUnwind(page_number=3,
                                   page_offset=0x1000,
                                   address_unwinds=address_unwind_sequence2),
         ])

        # Complete instruction sequences and their frequencies.
        # [0xb0]: 4
        # [0, 0xb0]: 1
        # [1, 0xb0]: 1
        # [2, 0xb0]: 1
        self.assertEqual(bytes([0xb0, 2, 0xb0, 1, 0xb0, 0, 0xb0]),
                         unwind_instruction_table)

        self.assertEqual(
            bytes([
                # Trivial unwind.
                0,
                0,
                # Address unwind sequence 0.
                0x10,
                5,
                0,
                0,
                # Address unwind sequence 1.
                0x10,
                3,
                0,
                0,
                # Address unwind sequence 2.
                0x80,
                2,
                1,
                0,
                0,
            ]),
            function_offset_table)

        self.assertEqual(8 * 2, len(function_table))
        self.assertEqual((0, 0, 0x1000, 2, 0x2000, 6, 0x1000, 10),
                         struct.unpack('8H', function_table))

        self.assertEqual(4 * 4, len(page_table))
        self.assertEqual((0, 2, 3, 3), struct.unpack('4I', page_table))