#!/usr/bin/python3
'''
Copyright 2021 (c) Apple Inc. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent

EFI gdb commands based on efi_debugging classes.

Example usage:
OvmfPkg/build.sh qemu -gdb tcp::9000
gdb -ex "target remote localhost:9000" -ex "source efi_gdb.py"

(gdb) help efi
Commands for debugging EFI. efi <cmd>

List of efi subcommands:

efi devicepath -- Display an EFI device path.
efi guid -- Display info about EFI GUID's.
efi hob -- Dump EFI HOBs. Type 'hob -h' for more info.
efi symbols -- Load Symbols for EFI. Type 'efi_symbols -h' for more info.
efi table -- Dump EFI System Tables. Type 'table -h' for more info.

This module is coded against a generic gdb remote serial stub. It should work
with QEMU, JTAG debugger, or a generic EFI gdb remote serial stub.

If you are debugging with QEMU or a JTAG hardware debugger you can insert
a CpuDeadLoop(); in your code, attach with gdb, and then `p Index=1` to
step past. If you have a debug stub in EFI you can use CpuBreakpoint();.
'''

from gdb.printing import RegexpCollectionPrettyPrinter
from gdb.printing import register_pretty_printer
import gdb
import os
import sys
import uuid
import optparse
import shlex

# gdb will not import from the same path as this script.
# so lets fix that for gdb...
sys.path.append(os.path.dirname(os.path.abspath(__file__)))

from efi_debugging import PeTeImage, patch_ctypes            # noqa: E402
from efi_debugging import EfiHob, GuidNames, EfiStatusClass  # noqa: E402
from efi_debugging import EfiBootMode, EfiDevicePath         # noqa: E402
from efi_debugging import EfiConfigurationTable, EfiTpl      # noqa: E402


class GdbFileObject(object):
    '''Provide a file like object required by efi_debugging'''

    def __init__(self):
        self.inferior = gdb.selected_inferior()
        self.offset = 0

    def tell(self):
        return self.offset

    def read(self, size=-1):
        if size == -1:
            # arbitrary default size
            size = 0x1000000

        try:
            data = self.inferior.read_memory(self.offset, size)
        except MemoryError:
            data = bytearray(size)
            assert False
        if len(data) != size:
            raise MemoryError(
                f'gdb could not read memory 0x{size:x}'
                + f' bytes from 0x{self.offset:08x}')
        else:
            # convert memoryview object to a bytestring.
            return data.tobytes()

    def readable(self):
        return True

    def seek(self, offset, whence=0):
        if whence == 0:
            self.offset = offset
        elif whence == 1:
            self.offset += offset
        else:
            # whence == 2 is seek from end
            raise NotImplementedError

    def seekable(self):
        return True

    def write(self, data):
        self.inferior.write_memory(self.offset, data)
        return len(data)

    def writable(self):
        return True

    def truncate(self, size=None):
        raise NotImplementedError

    def flush(self):
        raise NotImplementedError

    def fileno(self):
        raise NotImplementedError


class EfiSymbols:
    """Class to manage EFI Symbols"""

    loaded = {}
    stride = None
    range = None
    verbose = False

    def __init__(self, file=None):
        EfiSymbols.file = file if file else GdbFileObject()

    @ classmethod
    def __str__(cls):
        return ''.join(f'{value}\n' for value in cls.loaded.values())

    @ classmethod
    def configure_search(cls, stride, range=None, verbose=False):
        cls.stride = stride
        cls.range = range
        cls.verbose = verbose

    @ classmethod
    def clear(cls):
        cls.loaded = {}

    @ classmethod
    def add_symbols_for_pecoff(cls, pecoff):
        '''Tell lldb the location of the .text and .data sections.'''

        if pecoff.TextAddress in cls.loaded:
            return 'Already Loaded: '
        try:
            res = 'Loading Symbols Failed:'
            res = gdb.execute('add-symbol-file ' + pecoff.CodeViewPdb +
                              ' ' + hex(pecoff.TextAddress) +
                              ' -s .data ' + hex(pecoff.DataAddress),
                              False, True)

            cls.loaded[pecoff.TextAddress] = pecoff
            if cls.verbose:
                print(f'\n{res:s}\n')
            return ''
        except gdb.error:
            return res

    @ classmethod
    def address_to_symbols(cls, address, reprobe=False):
        '''
        Given an address search backwards for a PE/COFF (or TE) header
        and load symbols. Return a status string.
        '''
        if not isinstance(address, int):
            address = int(address)

        pecoff = cls.address_in_loaded_pecoff(address)
        if not reprobe and pecoff is not None:
            # skip the probe of the remote
            return f'{pecoff} is already loaded'

        pecoff = PeTeImage(cls.file, None)
        if pecoff.pcToPeCoff(address, cls.stride, cls.range):
            res = cls.add_symbols_for_pecoff(pecoff)
            return f'{res}{pecoff}'
        else:
            return f'0x{address:08x} not in a PE/COFF (or TE) image'

    @ classmethod
    def address_in_loaded_pecoff(cls, address):
        if not isinstance(address, int):
            address = int(address)

        for value in cls.loaded.values():
            if (address >= value.LoadAddress and
                    address <= value.EndLoadAddress):
                return value

        return None

    @ classmethod
    def unload_symbols(cls, address):
        if not isinstance(address, int):
            address = int(address)

        pecoff = cls.address_in_loaded_pecoff(address)
        try:
            res = 'Unloading Symbols Failed:'
            res = gdb.execute(
                f'remove-symbol-file -a {hex(pecoff.TextAddress):s}',
                False, True)
            del cls.loaded[pecoff.LoadAddress]
            return res
        except gdb.error:
            return res


class CHAR16_PrettyPrinter(object):

    def __init__(self, val):
        self.val = val

    def to_string(self):
        if int(self.val) < 0x20:
            return f"L'\\x{int(self.val):02x}'"
        else:
            return f"L'{chr(self.val):s}'"


class EFI_TPL_PrettyPrinter(object):

    def __init__(self, val):
        self.val = val

    def to_string(self):
        return str(EfiTpl(int(self.val)))


class EFI_STATUS_PrettyPrinter(object):

    def __init__(self, val):
        self.val = val

    def to_string(self):
        status = int(self.val)
        return f'{str(EfiStatusClass(status)):s} (0x{status:08x})'


class EFI_BOOT_MODE_PrettyPrinter(object):

    def __init__(self, val):
        self.val = val

    def to_string(self):
        return str(EfiBootMode(int(self.val)))


class EFI_GUID_PrettyPrinter(object):
    """Print 'EFI_GUID' as 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'"""

    def __init__(self, val):
        self.val = val

    def to_string(self):
        # if we could get a byte like object of *(unsigned char (*)[16])
        # then we could just use uuid.UUID() to convert
        Data1 = int(self.val['Data1'])
        Data2 = int(self.val['Data2'])
        Data3 = int(self.val['Data3'])
        Data4 = self.val['Data4']
        guid = f'{Data1:08X}-{Data2:04X}-'
        guid += f'{Data3:04X}-'
        guid += f'{int(Data4[0]):02X}{int(Data4[1]):02X}-'
        guid += f'{int(Data4[2]):02X}{int(Data4[3]):02X}'
        guid += f'{int(Data4[4]):02X}{int(Data4[5]):02X}'
        guid += f'{int(Data4[6]):02X}{int(Data4[7]):02X}'
        return str(GuidNames(guid))


def build_pretty_printer():
    # Turn off via: disable pretty-printer global EFI
    pp = RegexpCollectionPrettyPrinter("EFI")
    # you can also tell gdb `x/sh <address>` to print CHAR16 string
    pp.add_printer('CHAR16', '^CHAR16$', CHAR16_PrettyPrinter)
    pp.add_printer('EFI_BOOT_MODE', '^EFI_BOOT_MODE$',
                   EFI_BOOT_MODE_PrettyPrinter)
    pp.add_printer('EFI_GUID', '^EFI_GUID$', EFI_GUID_PrettyPrinter)
    pp.add_printer('EFI_STATUS', '^EFI_STATUS$', EFI_STATUS_PrettyPrinter)
    pp.add_printer('EFI_TPL', '^EFI_TPL$', EFI_TPL_PrettyPrinter)
    return pp


class EfiDevicePathCmd (gdb.Command):
    """Display an EFI device path. Type 'efi devicepath -h' for more info"""

    def __init__(self):
        super(EfiDevicePathCmd, self).__init__(
            "efi devicepath", gdb.COMMAND_NONE)

        self.file = GdbFileObject()

    def create_options(self, arg, from_tty):
        usage = "usage: %prog [options] [arg]"
        description = (
            "Command that can load EFI PE/COFF and TE image symbols. ")

        self.parser = optparse.OptionParser(
            description=description,
            prog='efi devicepath',
            usage=usage,
            add_help_option=False)

        self.parser.add_option(
            '-v',
            '--verbose',
            action='store_true',
            dest='verbose',
            help='hex dump extra data',
            default=False)

        self.parser.add_option(
            '-n',
            '--node',
            action='store_true',
            dest='node',
            help='dump a single device path node',
            default=False)

        self.parser.add_option(
            '-h',
            '--help',
            action='store_true',
            dest='help',
            help='Show help for the command',
            default=False)

        return self.parser.parse_args(shlex.split(arg))

    def invoke(self, arg, from_tty):
        '''gdb command to dump EFI device paths'''

        try:
            (options, _) = self.create_options(arg, from_tty)
            if options.help:
                self.parser.print_help()
                return

            dev_addr = int(gdb.parse_and_eval(arg))
        except ValueError:
            print("Invalid argument!")
            return

        if options.node:
            print(EfiDevicePath(
                self.file).device_path_node_str(dev_addr,
                                                options.verbose))
        else:
            device_path = EfiDevicePath(self.file, dev_addr, options.verbose)
            if device_path.valid():
                print(device_path)


class EfiGuidCmd (gdb.Command):
    """Display info about EFI GUID's. Type 'efi guid -h' for more info"""

    def __init__(self):
        super(EfiGuidCmd, self).__init__("efi guid",
                                         gdb.COMMAND_NONE,
                                         gdb.COMPLETE_EXPRESSION)
        self.file = GdbFileObject()

    def create_options(self, arg, from_tty):
        usage = "usage: %prog [options] [arg]"
        description = (
            "Show EFI_GUID values and the C name of the EFI_GUID variables"
            "in the C code. If symbols are loaded the Guid.xref file"
            "can be processed and the complete GUID database can be shown."
            "This command also suports generating new GUID's, and showing"
            "the value used to initialize the C variable.")

        self.parser = optparse.OptionParser(
            description=description,
            prog='efi guid',
            usage=usage,
            add_help_option=False)

        self.parser.add_option(
            '-n',
            '--new',
            action='store_true',
            dest='new',
            help='Generate a new GUID',
            default=False)

        self.parser.add_option(
            '-v',
            '--verbose',
            action='store_true',
            dest='verbose',
            help='Also display GUID C structure values',
            default=False)

        self.parser.add_option(
            '-h',
            '--help',
            action='store_true',
            dest='help',
            help='Show help for the command',
            default=False)

        return self.parser.parse_args(shlex.split(arg))

    def invoke(self, arg, from_tty):
        '''gdb command to dump EFI System Tables'''

        try:
            (options, args) = self.create_options(arg, from_tty)
            if options.help:
                self.parser.print_help()
                return
            if len(args) >= 1:
                # guid { 0x414e6bdd, 0xe47b, 0x47cc,
                #        { 0xb2, 0x44, 0xbb, 0x61, 0x02, 0x0c,0xf5, 0x16 }}
                # this generates multiple args
                guid = ' '.join(args)
        except ValueError:
            print('bad arguments!')
            return

        if options.new:
            guid = uuid.uuid4()
            print(str(guid).upper())
            print(GuidNames.to_c_guid(guid))
            return

        if len(args) > 0:
            if GuidNames.is_guid_str(arg):
                # guid 05AD34BA-6F02-4214-952E-4DA0398E2BB9
                key = guid.upper()
                name = GuidNames.to_name(key)
            elif GuidNames.is_c_guid(arg):
                # guid { 0x414e6bdd, 0xe47b, 0x47cc,
                #        { 0xb2, 0x44, 0xbb, 0x61, 0x02, 0x0c,0xf5, 0x16 }}
                key = GuidNames.from_c_guid(arg)
                name = GuidNames.to_name(key)
            else:
                # guid gEfiDxeServicesTableGuid
                name = guid
                try:
                    key = GuidNames.to_guid(name)
                    name = GuidNames.to_name(key)
                except ValueError:
                    return

            extra = f'{GuidNames.to_c_guid(key)}: ' if options.verbose else ''
            print(f'{key}: {extra}{name}')

        else:
            for key, value in GuidNames._dict_.items():
                if options.verbose:
                    extra = f'{GuidNames.to_c_guid(key)}: '
                else:
                    extra = ''
                print(f'{key}: {extra}{value}')


class EfiHobCmd (gdb.Command):
    """Dump EFI HOBs. Type 'hob -h' for more info."""

    def __init__(self):
        super(EfiHobCmd, self).__init__("efi hob", gdb.COMMAND_NONE)
        self.file = GdbFileObject()

    def create_options(self, arg, from_tty):
        usage = "usage: %prog [options] [arg]"
        description = (
            "Command that can load EFI PE/COFF and TE image symbols. ")

        self.parser = optparse.OptionParser(
            description=description,
            prog='efi hob',
            usage=usage,
            add_help_option=False)

        self.parser.add_option(
            '-a',
            '--address',
            type="int",
            dest='address',
            help='Parse HOBs from address',
            default=None)

        self.parser.add_option(
            '-t',
            '--type',
            type="int",
            dest='type',
            help='Only dump HOBS of his type',
            default=None)

        self.parser.add_option(
            '-v',
            '--verbose',
            action='store_true',
            dest='verbose',
            help='hex dump extra data',
            default=False)

        self.parser.add_option(
            '-h',
            '--help',
            action='store_true',
            dest='help',
            help='Show help for the command',
            default=False)

        return self.parser.parse_args(shlex.split(arg))

    def invoke(self, arg, from_tty):
        '''gdb command to dump EFI System Tables'''

        try:
            (options, _) = self.create_options(arg, from_tty)
            if options.help:
                self.parser.print_help()
                return
        except ValueError:
            print('bad arguments!')
            return

        if options.address:
            try:
                value = gdb.parse_and_eval(options.address)
                address = int(value)
            except ValueError:
                address = None
        else:
            address = None

        hob = EfiHob(self.file,
                     address,
                     options.verbose).get_hob_by_type(options.type)
        print(hob)


class EfiTablesCmd (gdb.Command):
    """Dump EFI System Tables. Type 'table -h' for more info."""

    def __init__(self):
        super(EfiTablesCmd, self).__init__("efi table", gdb.COMMAND_NONE)

        self.file = GdbFileObject()

    def create_options(self, arg, from_tty):
        usage = "usage: %prog [options] [arg]"
        description = "Dump EFI System Tables. Requires symbols to be loaded"

        self.parser = optparse.OptionParser(
            description=description,
            prog='efi table',
            usage=usage,
            add_help_option=False)

        self.parser.add_option(
            '-h',
            '--help',
            action='store_true',
            dest='help',
            help='Show help for the command',
            default=False)

        return self.parser.parse_args(shlex.split(arg))

    def invoke(self, arg, from_tty):
        '''gdb command to dump EFI System Tables'''

        try:
            (options, _) = self.create_options(arg, from_tty)
            if options.help:
                self.parser.print_help()
                return
        except ValueError:
            print('bad arguments!')
            return

        gST = gdb.lookup_global_symbol('gST')
        if gST is None:
            print('Error: This command requires symbols for gST to be loaded')
            return

        table = EfiConfigurationTable(
            self.file, int(gST.value(gdb.selected_frame())))
        if table:
            print(table, '\n')


class EfiSymbolsCmd (gdb.Command):
    """Load Symbols for EFI. Type 'efi symbols -h' for more info."""

    def __init__(self):
        super(EfiSymbolsCmd, self).__init__("efi symbols",
                                            gdb.COMMAND_NONE,
                                            gdb.COMPLETE_EXPRESSION)
        self.file = GdbFileObject()
        self.gST = None
        self.efi_symbols = EfiSymbols(self.file)

    def create_options(self, arg, from_tty):
        usage = "usage: %prog [options]"
        description = (
            "Command that can load EFI PE/COFF and TE image symbols. "
            "If you are having trouble in PEI try adding --pei. "
            "Given any address search backward for the PE/COFF (or TE header) "
            "and then parse the PE/COFF image to get debug info. "
            "The address can come from the current pc, pc values in the "
            "frame, or an address provided to the command"
            "")

        self.parser = optparse.OptionParser(
            description=description,
            prog='efi symbols',
            usage=usage,
            add_help_option=False)

        self.parser.add_option(
            '-a',
            '--address',
            type="str",
            dest='address',
            help='Load symbols for image that contains address',
            default=None)

        self.parser.add_option(
            '-c',
            '--clear',
            action='store_true',
            dest='clear',
            help='Clear the cache of loaded images',
            default=False)

        self.parser.add_option(
            '-f',
            '--frame',
            action='store_true',
            dest='frame',
            help='Load symbols for current stack frame',
            default=False)

        self.parser.add_option(
            '-p',
            '--pc',
            action='store_true',
            dest='pc',
            help='Load symbols for pc',
            default=False)

        self.parser.add_option(
            '--pei',
            action='store_true',
            dest='pei',
            help='Load symbols for PEI (searches every 4 bytes)',
            default=False)

        self.parser.add_option(
            '-e',
            '--extended',
            action='store_true',
            dest='extended',
            help='Try to load all symbols based on config tables',
            default=False)

        self.parser.add_option(
            '-r',
            '--range',
            type="long",
            dest='range',
            help='How far to search backward for start of PE/COFF Image',
            default=None)

        self.parser.add_option(
            '-s',
            '--stride',
            type="long",
            dest='stride',
            help='Boundary to search for PE/COFF header',
            default=None)

        self.parser.add_option(
            '-t',
            '--thread',
            action='store_true',
            dest='thread',
            help='Load symbols for the frames of all threads',
            default=False)

        self.parser.add_option(
            '-v',
            '--verbose',
            action='store_true',
            dest='verbose',
            help='Show more info on symbols loading in gdb',
            default=False)

        self.parser.add_option(
            '-h',
            '--help',
            action='store_true',
            dest='help',
            help='Show help for the command',
            default=False)

        return self.parser.parse_args(shlex.split(arg))

    def save_user_state(self):
        self.pagination = gdb.parameter("pagination")
        if self.pagination:
            gdb.execute("set pagination off")

        self.user_selected_thread = gdb.selected_thread()
        self.user_selected_frame = gdb.selected_frame()

    def restore_user_state(self):
        self.user_selected_thread.switch()
        self.user_selected_frame.select()

        if self.pagination:
            gdb.execute("set pagination on")

    def canonical_address(self, address):
        '''
        Scrub out 48-bit non canonical addresses
        Raw frames in gdb can have some funky values
        '''

        # Skip lowest 256 bytes to avoid interrupt frames
        if address > 0xFF and address < 0x00007FFFFFFFFFFF:
            return True
        if address >= 0xFFFF800000000000:
            return True

        return False

    def pc_set_for_frames(self):
        '''Return a set for the PC's in the current frame'''
        pc_list = []
        frame = gdb.newest_frame()
        while frame:
            pc = int(frame.read_register('pc'))
            if self.canonical_address(pc):
                pc_list.append(pc)
            frame = frame.older()

        return set(pc_list)

    def invoke(self, arg, from_tty):
        '''gdb command to symbolicate all the frames from all the threads'''

        try:
            (options, _) = self.create_options(arg, from_tty)
            if options.help:
                self.parser.print_help()
                return
        except ValueError:
            print('bad arguments!')
            return

        self.dont_repeat()

        self.save_user_state()

        if options.clear:
            self.efi_symbols.clear()
            return

        if options.pei:
            # XIP code can be 4 byte aligned in the FV
            options.stride = 4
            options.range = 0x100000
        self.efi_symbols.configure_search(options.stride,
                                          options.range,
                                          options.verbose)

        if options.thread:
            thread_list = gdb.selected_inferior().threads()
        else:
            thread_list = (gdb.selected_thread(),)

        address = None
        if options.address:
            value = gdb.parse_and_eval(options.address)
            address = int(value)
        elif options.pc:
            address = gdb.selected_frame().pc()

        if address:
            res = self.efi_symbols.address_to_symbols(address)
            print(res)
        else:

            for thread in thread_list:
                thread.switch()

                # You can not iterate over frames as you load symbols. Loading
                # symbols changes the frames gdb can see due to inlining and
                # boom. So we loop adding symbols for the current frame, and
                # we test to see if new frames have shown up. If new frames
                # show up we process those new frames. Thus 1st pass is the
                # raw frame, and other passes are only new PC values.
                NewPcSet = self.pc_set_for_frames()
                while NewPcSet:
                    PcSet = self.pc_set_for_frames()
                    for pc in NewPcSet:
                        res = self.efi_symbols.address_to_symbols(pc)
                        print(res)

                    NewPcSet = PcSet.symmetric_difference(
                        self.pc_set_for_frames())

        # find the EFI System tables the 1st time
        if self.gST is None:
            gST = gdb.lookup_global_symbol('gST')
            if gST is not None:
                self.gST = int(gST.value(gdb.selected_frame()))
                table = EfiConfigurationTable(self.file, self.gST)
            else:
                table = None
        else:
            table = EfiConfigurationTable(self.file, self.gST)

        if options.extended and table:
            # load symbols from EFI System Table entry
            for address, _ in table.DebugImageInfo():
                res = self.efi_symbols.address_to_symbols(address)
                print(res)

        # sync up the GUID database from the build output
        for m in gdb.objfiles():
            if GuidNames.add_build_guid_file(str(m.filename)):
                break

        self.restore_user_state()


class EfiCmd (gdb.Command):
    """Commands for debugging EFI. efi <cmd>"""

    def __init__(self):
        super(EfiCmd, self).__init__("efi",
                                     gdb.COMMAND_NONE,
                                     gdb.COMPLETE_NONE,
                                     True)

    def invoke(self, arg, from_tty):
        '''default to loading symbols'''
        if '-h' in arg or '--help' in arg:
            gdb.execute('help efi')
        else:
            # default to loading all symbols
            gdb.execute('efi symbols --extended')


class LoadEmulatorEfiSymbols(gdb.Breakpoint):
    '''
    breakpoint for EmulatorPkg to load symbols
    Note: make sure SecGdbScriptBreak is not optimized away!
    Also turn off the dlopen() flow like on macOS.
    '''
    def stop(self):
        symbols = EfiSymbols()
        # Emulator adds SizeOfHeaders so we need file alignment to search
        symbols.configure_search(0x20)

        frame = gdb.newest_frame()

        try:
            # gdb was looking at spill address, pre spill :(
            LoadAddress = frame.read_register('rdx')
            AddSymbolFlag = frame.read_register('rcx')
        except gdb.error:
            LoadAddress = frame.read_var('LoadAddress')
            AddSymbolFlag = frame.read_var('AddSymbolFlag')

        if AddSymbolFlag == 1:
            res = symbols.address_to_symbols(LoadAddress)
        else:
            res = symbols.unload_symbols(LoadAddress)
        print(res)

        # keep running
        return False


# Get python backtraces to debug errors in this script
gdb.execute("set python print-stack full")

# tell efi_debugging how to walk data structures with pointers
try:
    pointer_width = gdb.lookup_type('int').pointer().sizeof
except ValueError:
    pointer_width = 8
patch_ctypes(pointer_width)

register_pretty_printer(None, build_pretty_printer(), replace=True)

# gdb commands that we are adding
# add `efi` prefix gdb command
EfiCmd()

# subcommands for `efi`
EfiSymbolsCmd()
EfiTablesCmd()
EfiHobCmd()
EfiDevicePathCmd()
EfiGuidCmd()

#
bp = LoadEmulatorEfiSymbols('SecGdbScriptBreak', internal=True)
if bp.pending:
    try:
        gdb.selected_frame()
        # Not the emulator so do this when you attach
        gdb.execute('efi symbols --frame --extended', True)
        gdb.execute('bt')
        # If you want to skip the above commands comment them out
        pass
    except gdb.error:
        # If you load the script and there is no target ignore the error.
        pass
else:
    # start the emulator
    gdb.execute('run')
