"""
This python script adds a new gdb command, "dump-guest-memory". It
should be loaded with "source dump-guest-memory.py" at the (gdb)
prompt.

Copyright (C) 2013, Red Hat, Inc.

Authors:
   Laszlo Ersek <lersek@redhat.com>
   Janosch Frank <frankja@linux.vnet.ibm.com>

This work is licensed under the terms of the GNU GPL, version 2 or later. See
the COPYING file in the top-level directory.
"""

import ctypes
import struct

try:
    UINTPTR_T = gdb.lookup_type("uintptr_t")
except Exception as inst:
    raise gdb.GdbError("Symbols must be loaded prior to sourcing dump-guest-memory.\n"
                       "Symbols may be loaded by 'attach'ing a QEMU process id or by "
                       "'load'ing a QEMU binary.")

TARGET_PAGE_SIZE = 0x1000
TARGET_PAGE_MASK = 0xFFFFFFFFFFFFF000

# Special value for e_phnum. This indicates that the real number of
# program headers is too large to fit into e_phnum. Instead the real
# value is in the field sh_info of section 0.
PN_XNUM = 0xFFFF

EV_CURRENT = 1

ELFCLASS32 = 1
ELFCLASS64 = 2

ELFDATA2LSB = 1
ELFDATA2MSB = 2

ET_CORE = 4

PT_LOAD = 1
PT_NOTE = 4

EM_386 = 3
EM_PPC = 20
EM_PPC64 = 21
EM_S390 = 22
EM_AARCH = 183
EM_X86_64 = 62

VMCOREINFO_FORMAT_ELF = 1

def le16_to_cpu(val):
    return struct.unpack("<H", struct.pack("=H", val))[0]

def le32_to_cpu(val):
    return struct.unpack("<I", struct.pack("=I", val))[0]

def le64_to_cpu(val):
    return struct.unpack("<Q", struct.pack("=Q", val))[0]

class ELF(object):
    """Representation of a ELF file."""

    def __init__(self, arch):
        self.ehdr = None
        self.notes = []
        self.segments = []
        self.notes_size = 0
        self.endianness = None
        self.elfclass = ELFCLASS64

        if arch == 'aarch64-le':
            self.endianness = ELFDATA2LSB
            self.elfclass = ELFCLASS64
            self.ehdr = get_arch_ehdr(self.endianness, self.elfclass)
            self.ehdr.e_machine = EM_AARCH

        elif arch == 'aarch64-be':
            self.endianness = ELFDATA2MSB
            self.ehdr = get_arch_ehdr(self.endianness, self.elfclass)
            self.ehdr.e_machine = EM_AARCH

        elif arch == 'X86_64':
            self.endianness = ELFDATA2LSB
            self.ehdr = get_arch_ehdr(self.endianness, self.elfclass)
            self.ehdr.e_machine = EM_X86_64

        elif arch == '386':
            self.endianness = ELFDATA2LSB
            self.elfclass = ELFCLASS32
            self.ehdr = get_arch_ehdr(self.endianness, self.elfclass)
            self.ehdr.e_machine = EM_386

        elif arch == 's390':
            self.endianness = ELFDATA2MSB
            self.ehdr = get_arch_ehdr(self.endianness, self.elfclass)
            self.ehdr.e_machine = EM_S390

        elif arch == 'ppc64-le':
            self.endianness = ELFDATA2LSB
            self.ehdr = get_arch_ehdr(self.endianness, self.elfclass)
            self.ehdr.e_machine = EM_PPC64

        elif arch == 'ppc64-be':
            self.endianness = ELFDATA2MSB
            self.ehdr = get_arch_ehdr(self.endianness, self.elfclass)
            self.ehdr.e_machine = EM_PPC64

        else:
            raise gdb.GdbError("No valid arch type specified.\n"
                               "Currently supported types:\n"
                               "aarch64-be, aarch64-le, X86_64, 386, s390, "
                               "ppc64-be, ppc64-le")

        self.add_segment(PT_NOTE, 0, 0)

    def add_note(self, n_name, n_desc, n_type):
        """Adds a note to the ELF."""

        note = get_arch_note(self.endianness, len(n_name), len(n_desc))
        note.n_namesz = len(n_name) + 1
        note.n_descsz = len(n_desc)
        note.n_name = n_name.encode()
        note.n_type = n_type

        # Desc needs to be 4 byte aligned (although the 64bit spec
        # specifies 8 byte). When defining n_desc as uint32 it will be
        # automatically aligned but we need the memmove to copy the
        # string into it.
        ctypes.memmove(note.n_desc, n_desc.encode(), len(n_desc))

        self.notes.append(note)
        self.segments[0].p_filesz += ctypes.sizeof(note)
        self.segments[0].p_memsz += ctypes.sizeof(note)


    def add_vmcoreinfo_note(self, vmcoreinfo):
        """Adds a vmcoreinfo note to the ELF dump."""
        # compute the header size, and copy that many bytes from the note
        header = get_arch_note(self.endianness, 0, 0)
        ctypes.memmove(ctypes.pointer(header),
                       vmcoreinfo, ctypes.sizeof(header))
        if header.n_descsz > 1 << 20:
            print('warning: invalid vmcoreinfo size')
            return
        # now get the full note
        note = get_arch_note(self.endianness,
                             header.n_namesz - 1, header.n_descsz)
        ctypes.memmove(ctypes.pointer(note), vmcoreinfo, ctypes.sizeof(note))

        self.notes.append(note)
        self.segments[0].p_filesz += ctypes.sizeof(note)
        self.segments[0].p_memsz += ctypes.sizeof(note)

    def add_segment(self, p_type, p_paddr, p_size):
        """Adds a segment to the elf."""

        phdr = get_arch_phdr(self.endianness, self.elfclass)
        phdr.p_type = p_type
        phdr.p_paddr = p_paddr
        phdr.p_filesz = p_size
        phdr.p_memsz = p_size
        self.segments.append(phdr)
        self.ehdr.e_phnum += 1

    def to_file(self, elf_file):
        """Writes all ELF structures to the the passed file.

        Structure:
        Ehdr
        Segment 0:PT_NOTE
        Segment 1:PT_LOAD
        Segment N:PT_LOAD
        Note    0..N
        Dump contents
        """
        elf_file.write(self.ehdr)
        off = ctypes.sizeof(self.ehdr) + \
              len(self.segments) * ctypes.sizeof(self.segments[0])

        for phdr in self.segments:
            phdr.p_offset = off
            elf_file.write(phdr)
            off += phdr.p_filesz

        for note in self.notes:
            elf_file.write(note)


def get_arch_note(endianness, len_name, len_desc):
    """Returns a Note class with the specified endianness."""

    if endianness == ELFDATA2LSB:
        superclass = ctypes.LittleEndianStructure
    else:
        superclass = ctypes.BigEndianStructure

    len_name = len_name + 1

    class Note(superclass):
        """Represents an ELF note, includes the content."""

        _fields_ = [("n_namesz", ctypes.c_uint32),
                    ("n_descsz", ctypes.c_uint32),
                    ("n_type", ctypes.c_uint32),
                    ("n_name", ctypes.c_char * len_name),
                    ("n_desc", ctypes.c_uint32 * ((len_desc + 3) // 4))]
    return Note()


class Ident(ctypes.Structure):
    """Represents the ELF ident array in the ehdr structure."""

    _fields_ = [('ei_mag0', ctypes.c_ubyte),
                ('ei_mag1', ctypes.c_ubyte),
                ('ei_mag2', ctypes.c_ubyte),
                ('ei_mag3', ctypes.c_ubyte),
                ('ei_class', ctypes.c_ubyte),
                ('ei_data', ctypes.c_ubyte),
                ('ei_version', ctypes.c_ubyte),
                ('ei_osabi', ctypes.c_ubyte),
                ('ei_abiversion', ctypes.c_ubyte),
                ('ei_pad', ctypes.c_ubyte * 7)]

    def __init__(self, endianness, elfclass):
        self.ei_mag0 = 0x7F
        self.ei_mag1 = ord('E')
        self.ei_mag2 = ord('L')
        self.ei_mag3 = ord('F')
        self.ei_class = elfclass
        self.ei_data = endianness
        self.ei_version = EV_CURRENT


def get_arch_ehdr(endianness, elfclass):
    """Returns a EHDR64 class with the specified endianness."""

    if endianness == ELFDATA2LSB:
        superclass = ctypes.LittleEndianStructure
    else:
        superclass = ctypes.BigEndianStructure

    class EHDR64(superclass):
        """Represents the 64 bit ELF header struct."""

        _fields_ = [('e_ident', Ident),
                    ('e_type', ctypes.c_uint16),
                    ('e_machine', ctypes.c_uint16),
                    ('e_version', ctypes.c_uint32),
                    ('e_entry', ctypes.c_uint64),
                    ('e_phoff', ctypes.c_uint64),
                    ('e_shoff', ctypes.c_uint64),
                    ('e_flags', ctypes.c_uint32),
                    ('e_ehsize', ctypes.c_uint16),
                    ('e_phentsize', ctypes.c_uint16),
                    ('e_phnum', ctypes.c_uint16),
                    ('e_shentsize', ctypes.c_uint16),
                    ('e_shnum', ctypes.c_uint16),
                    ('e_shstrndx', ctypes.c_uint16)]

        def __init__(self):
            super(superclass, self).__init__()
            self.e_ident = Ident(endianness, elfclass)
            self.e_type = ET_CORE
            self.e_version = EV_CURRENT
            self.e_ehsize = ctypes.sizeof(self)
            self.e_phoff = ctypes.sizeof(self)
            self.e_phentsize = ctypes.sizeof(get_arch_phdr(endianness, elfclass))
            self.e_phnum = 0


    class EHDR32(superclass):
        """Represents the 32 bit ELF header struct."""

        _fields_ = [('e_ident', Ident),
                    ('e_type', ctypes.c_uint16),
                    ('e_machine', ctypes.c_uint16),
                    ('e_version', ctypes.c_uint32),
                    ('e_entry', ctypes.c_uint32),
                    ('e_phoff', ctypes.c_uint32),
                    ('e_shoff', ctypes.c_uint32),
                    ('e_flags', ctypes.c_uint32),
                    ('e_ehsize', ctypes.c_uint16),
                    ('e_phentsize', ctypes.c_uint16),
                    ('e_phnum', ctypes.c_uint16),
                    ('e_shentsize', ctypes.c_uint16),
                    ('e_shnum', ctypes.c_uint16),
                    ('e_shstrndx', ctypes.c_uint16)]

        def __init__(self):
            super(superclass, self).__init__()
            self.e_ident = Ident(endianness, elfclass)
            self.e_type = ET_CORE
            self.e_version = EV_CURRENT
            self.e_ehsize = ctypes.sizeof(self)
            self.e_phoff = ctypes.sizeof(self)
            self.e_phentsize = ctypes.sizeof(get_arch_phdr(endianness, elfclass))
            self.e_phnum = 0

    # End get_arch_ehdr
    if elfclass == ELFCLASS64:
        return EHDR64()
    else:
        return EHDR32()


def get_arch_phdr(endianness, elfclass):
    """Returns a 32 or 64 bit PHDR class with the specified endianness."""

    if endianness == ELFDATA2LSB:
        superclass = ctypes.LittleEndianStructure
    else:
        superclass = ctypes.BigEndianStructure

    class PHDR64(superclass):
        """Represents the 64 bit ELF program header struct."""

        _fields_ = [('p_type', ctypes.c_uint32),
                    ('p_flags', ctypes.c_uint32),
                    ('p_offset', ctypes.c_uint64),
                    ('p_vaddr', ctypes.c_uint64),
                    ('p_paddr', ctypes.c_uint64),
                    ('p_filesz', ctypes.c_uint64),
                    ('p_memsz', ctypes.c_uint64),
                    ('p_align', ctypes.c_uint64)]

    class PHDR32(superclass):
        """Represents the 32 bit ELF program header struct."""

        _fields_ = [('p_type', ctypes.c_uint32),
                    ('p_offset', ctypes.c_uint32),
                    ('p_vaddr', ctypes.c_uint32),
                    ('p_paddr', ctypes.c_uint32),
                    ('p_filesz', ctypes.c_uint32),
                    ('p_memsz', ctypes.c_uint32),
                    ('p_flags', ctypes.c_uint32),
                    ('p_align', ctypes.c_uint32)]

    # End get_arch_phdr
    if elfclass == ELFCLASS64:
        return PHDR64()
    else:
        return PHDR32()


def int128_get64(val):
    """Returns low 64bit part of Int128 struct."""

    try:
        assert val["hi"] == 0
        return val["lo"]
    except gdb.error:
        u64t = gdb.lookup_type('uint64_t').array(2)
        u64 = val.cast(u64t)
        if sys.byteorder == 'little':
            assert u64[1] == 0
            return u64[0]
        else:
            assert u64[0] == 0
            return u64[1]


def qlist_foreach(head, field_str):
    """Generator for qlists."""

    var_p = head["lh_first"]
    while var_p != 0:
        var = var_p.dereference()
        var_p = var[field_str]["le_next"]
        yield var


def qemu_map_ram_ptr(block, offset):
    """Returns qemu vaddr for given guest physical address."""

    return block["host"] + offset


def memory_region_get_ram_ptr(memory_region):
    if memory_region["alias"] != 0:
        return (memory_region_get_ram_ptr(memory_region["alias"].dereference())
                + memory_region["alias_offset"])

    return qemu_map_ram_ptr(memory_region["ram_block"], 0)


def get_guest_phys_blocks():
    """Returns a list of ram blocks.

    Each block entry contains:
    'target_start': guest block phys start address
    'target_end':   guest block phys end address
    'host_addr':    qemu vaddr of the block's start
    """

    guest_phys_blocks = []

    print("guest RAM blocks:")
    print("target_start     target_end       host_addr        message "
          "count")
    print("---------------- ---------------- ---------------- ------- "
          "-----")

    current_map_p = gdb.parse_and_eval("address_space_memory.current_map")
    current_map = current_map_p.dereference()

    # Conversion to int is needed for python 3
    # compatibility. Otherwise range doesn't cast the value itself and
    # breaks.
    for cur in range(int(current_map["nr"])):
        flat_range = (current_map["ranges"] + cur).dereference()
        memory_region = flat_range["mr"].dereference()

        # we only care about RAM
        if not memory_region["ram"]:
            continue

        section_size = int128_get64(flat_range["addr"]["size"])
        target_start = int128_get64(flat_range["addr"]["start"])
        target_end = target_start + section_size
        host_addr = (memory_region_get_ram_ptr(memory_region)
                     + flat_range["offset_in_region"])
        predecessor = None

        # find continuity in guest physical address space
        if len(guest_phys_blocks) > 0:
            predecessor = guest_phys_blocks[-1]
            predecessor_size = (predecessor["target_end"] -
                                predecessor["target_start"])

            # the memory API guarantees monotonically increasing
            # traversal
            assert predecessor["target_end"] <= target_start

            # we want continuity in both guest-physical and
            # host-virtual memory
            if (predecessor["target_end"] < target_start or
                predecessor["host_addr"] + predecessor_size != host_addr):
                predecessor = None

        if predecessor is None:
            # isolated mapping, add it to the list
            guest_phys_blocks.append({"target_start": target_start,
                                      "target_end":   target_end,
                                      "host_addr":    host_addr})
            message = "added"
        else:
            # expand predecessor until @target_end; predecessor's
            # start doesn't change
            predecessor["target_end"] = target_end
            message = "joined"

        print("%016x %016x %016x %-7s %5u" %
              (target_start, target_end, host_addr.cast(UINTPTR_T),
               message, len(guest_phys_blocks)))

    return guest_phys_blocks


# The leading docstring doesn't have idiomatic Python formatting. It is
# printed by gdb's "help" command (the first line is printed in the
# "help data" summary), and it should match how other help texts look in
# gdb.
class DumpGuestMemory(gdb.Command):
    """Extract guest vmcore from qemu process coredump.

The two required arguments are FILE and ARCH:
FILE identifies the target file to write the guest vmcore to.
ARCH specifies the architecture for which the core will be generated.

This GDB command reimplements the dump-guest-memory QMP command in
python, using the representation of guest memory as captured in the qemu
coredump. The qemu process that has been dumped must have had the
command line option "-machine dump-guest-core=on" which is the default.

For simplicity, the "paging", "begin" and "end" parameters of the QMP
command are not supported -- no attempt is made to get the guest's
internal paging structures (ie. paging=false is hard-wired), and guest
memory is always fully dumped.

Currently aarch64-be, aarch64-le, X86_64, 386, s390, ppc64-be,
ppc64-le guests are supported.

The CORE/NT_PRSTATUS and QEMU notes (that is, the VCPUs' statuses) are
not written to the vmcore. Preparing these would require context that is
only present in the KVM host kernel module when the guest is alive. A
fake ELF note is written instead, only to keep the ELF parser of "crash"
happy.

Dependent on how busted the qemu process was at the time of the
coredump, this command might produce unpredictable results. If qemu
deliberately called abort(), or it was dumped in response to a signal at
a halfway fortunate point, then its coredump should be in reasonable
shape and this command should mostly work."""

    def __init__(self):
        super(DumpGuestMemory, self).__init__("dump-guest-memory",
                                              gdb.COMMAND_DATA,
                                              gdb.COMPLETE_FILENAME)
        self.elf = None
        self.guest_phys_blocks = None

    def dump_init(self, vmcore):
        """Prepares and writes ELF structures to core file."""

        # Needed to make crash happy, data for more useful notes is
        # not available in a qemu core.
        self.elf.add_note("NONE", "EMPTY", 0)

        # We should never reach PN_XNUM for paging=false dumps,
        # there's just a handful of discontiguous ranges after
        # merging.
        # The constant is needed to account for the PT_NOTE segment.
        phdr_num = len(self.guest_phys_blocks) + 1
        assert phdr_num < PN_XNUM

        for block in self.guest_phys_blocks:
            block_size = block["target_end"] - block["target_start"]
            self.elf.add_segment(PT_LOAD, block["target_start"], block_size)

        self.elf.to_file(vmcore)

    def dump_iterate(self, vmcore):
        """Writes guest core to file."""

        qemu_core = gdb.inferiors()[0]
        for block in self.guest_phys_blocks:
            cur = block["host_addr"]
            left = block["target_end"] - block["target_start"]
            print("dumping range at %016x for length %016x" %
                  (cur.cast(UINTPTR_T), left))

            while left > 0:
                chunk_size = min(TARGET_PAGE_SIZE, left)
                chunk = qemu_core.read_memory(cur, chunk_size)
                vmcore.write(chunk)
                cur += chunk_size
                left -= chunk_size

    def phys_memory_read(self, addr, size):
        qemu_core = gdb.inferiors()[0]
        for block in self.guest_phys_blocks:
            if block["target_start"] <= addr \
               and addr + size <= block["target_end"]:
                haddr = block["host_addr"] + (addr - block["target_start"])
                return qemu_core.read_memory(haddr, size)
        return None

    def add_vmcoreinfo(self):
        if gdb.lookup_symbol("vmcoreinfo_realize")[0] is None:
            return
        vmci = 'vmcoreinfo_realize::vmcoreinfo_state'
        if not gdb.parse_and_eval("%s" % vmci) \
           or not gdb.parse_and_eval("(%s)->has_vmcoreinfo" % vmci):
            return

        fmt = gdb.parse_and_eval("(%s)->vmcoreinfo.guest_format" % vmci)
        addr = gdb.parse_and_eval("(%s)->vmcoreinfo.paddr" % vmci)
        size = gdb.parse_and_eval("(%s)->vmcoreinfo.size" % vmci)

        fmt = le16_to_cpu(fmt)
        addr = le64_to_cpu(addr)
        size = le32_to_cpu(size)

        if fmt != VMCOREINFO_FORMAT_ELF:
            return

        vmcoreinfo = self.phys_memory_read(addr, size)
        if vmcoreinfo:
            self.elf.add_vmcoreinfo_note(bytes(vmcoreinfo))

    def invoke(self, args, from_tty):
        """Handles command invocation from gdb."""

        # Unwittingly pressing the Enter key after the command should
        # not dump the same multi-gig coredump to the same file.
        self.dont_repeat()

        argv = gdb.string_to_argv(args)
        if len(argv) != 2:
            raise gdb.GdbError("usage: dump-guest-memory FILE ARCH")

        self.elf = ELF(argv[1])
        self.guest_phys_blocks = get_guest_phys_blocks()
        self.add_vmcoreinfo()

        with open(argv[0], "wb") as vmcore:
            self.dump_init(vmcore)
            self.dump_iterate(vmcore)

DumpGuestMemory()
