# Copyright (C) 2015-2022 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
from gdb.unwinder import Unwinder


# These are set to test whether invalid register names cause an error.
add_saved_register_error = False
read_register_error = False


class FrameId(object):
    def __init__(self, sp, pc):
        self._sp = sp
        self._pc = pc

    @property
    def sp(self):
        return self._sp

    @property
    def pc(self):
        return self._pc


class TestUnwinder(Unwinder):
    AMD64_RBP = 6
    AMD64_RSP = 7
    AMD64_RIP = None

    def __init__(self):
        Unwinder.__init__(self, "test unwinder")
        self.char_ptr_t = gdb.lookup_type("unsigned char").pointer()
        self.char_ptr_ptr_t = self.char_ptr_t.pointer()
        self._last_arch = None

    # Update the register descriptor AMD64_RIP based on ARCH.
    def _update_register_descriptors(self, arch):
        if self._last_arch != arch:
            TestUnwinder.AMD64_RIP = arch.registers().find("rip")
            self._last_arch = arch

    def _read_word(self, address):
        return address.cast(self.char_ptr_ptr_t).dereference()

    def __call__(self, pending_frame):
        """Test unwinder written in Python.

        This unwinder can unwind the frames that have been deliberately
        corrupted in a specific way (functions in the accompanying
        py-unwind.c file do that.)
        This code is only on AMD64.
        On AMD64 $RBP points to the innermost frame (unless the code
        was compiled with -fomit-frame-pointer), which contains the
        address of the previous frame at offset 0. The functions
        deliberately corrupt their frames as follows:
                     Before                 After
                   Corruption:           Corruption:
                +--------------+       +--------------+
        RBP-8   |              |       | Previous RBP |
                +--------------+       +--------------+
        RBP     + Previous RBP |       |    RBP       |
                +--------------+       +--------------+
        RBP+8   | Return RIP   |       | Return  RIP  |
                +--------------+       +--------------+
        Old SP  |              |       |              |

        This unwinder recognizes the corrupt frames by checking that
        *RBP == RBP, and restores previous RBP from the word above it.
        """

        # Check that we can access the architecture of the pending
        # frame, and that this is the same architecture as for the
        # currently selected inferior.
        inf_arch = gdb.selected_inferior().architecture()
        frame_arch = pending_frame.architecture()
        if inf_arch != frame_arch:
            raise gdb.GdbError("architecture mismatch")

        self._update_register_descriptors(frame_arch)

        try:
            # NOTE: the registers in Unwinder API can be referenced
            # either by name or by number. The code below uses both
            # to achieve more coverage.
            bp = pending_frame.read_register("rbp").cast(self.char_ptr_t)
            if self._read_word(bp) != bp:
                return None
            # Found the frame that the test program has corrupted for us.
            # The correct BP for the outer frame has been saved one word
            # above, previous IP and SP are at the expected places.
            previous_bp = self._read_word(bp - 8)
            previous_ip = self._read_word(bp + 8)
            previous_sp = bp + 16

            try:
                pending_frame.read_register("nosuchregister")
            except ValueError:
                global read_register_error
                read_register_error = True

            frame_id = FrameId(
                pending_frame.read_register(TestUnwinder.AMD64_RSP),
                pending_frame.read_register(TestUnwinder.AMD64_RIP),
            )
            unwind_info = pending_frame.create_unwind_info(frame_id)
            unwind_info.add_saved_register(TestUnwinder.AMD64_RBP, previous_bp)
            unwind_info.add_saved_register("rip", previous_ip)
            unwind_info.add_saved_register("rsp", previous_sp)
            try:
                unwind_info.add_saved_register("nosuchregister", previous_sp)
            except ValueError:
                global add_saved_register_error
                add_saved_register_error = True
            return unwind_info
        except (gdb.error, RuntimeError):
            return None


gdb.unwinder.register_unwinder(None, TestUnwinder(), True)
print("Python script imported")
