# 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>
#
# This work is licensed under the terms of the GNU GPL, version 2 or later. See
# the COPYING file in the top-level directory.
#
# 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.

import struct

class DumpGuestMemory(gdb.Command):
    """Extract guest vmcore from qemu process coredump.

The sole argument is FILE, identifying the target file to write the
guest vmcore to.

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".

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.

Only x86_64 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."""

    TARGET_PAGE_SIZE = 0x1000
    TARGET_PAGE_MASK = 0xFFFFFFFFFFFFF000

    # Various ELF constants
    EM_X86_64   = 62        # AMD x86-64 target machine
    ELFDATA2LSB = 1         # little endian
    ELFCLASS64  = 2
    ELFMAG      = "\x7FELF"
    EV_CURRENT  = 1
    ET_CORE     = 4
    PT_LOAD     = 1
    PT_NOTE     = 4

    # 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

    # Format strings for packing and header size calculation.
    ELF64_EHDR = ("4s" # e_ident/magic
                  "B"  # e_ident/class
                  "B"  # e_ident/data
                  "B"  # e_ident/version
                  "B"  # e_ident/osabi
                  "8s" # e_ident/pad
                  "H"  # e_type
                  "H"  # e_machine
                  "I"  # e_version
                  "Q"  # e_entry
                  "Q"  # e_phoff
                  "Q"  # e_shoff
                  "I"  # e_flags
                  "H"  # e_ehsize
                  "H"  # e_phentsize
                  "H"  # e_phnum
                  "H"  # e_shentsize
                  "H"  # e_shnum
                  "H"  # e_shstrndx
                 )
    ELF64_PHDR = ("I"  # p_type
                  "I"  # p_flags
                  "Q"  # p_offset
                  "Q"  # p_vaddr
                  "Q"  # p_paddr
                  "Q"  # p_filesz
                  "Q"  # p_memsz
                  "Q"  # p_align
                 )

    def __init__(self):
        super(DumpGuestMemory, self).__init__("dump-guest-memory",
                                              gdb.COMMAND_DATA,
                                              gdb.COMPLETE_FILENAME)
        self.uintptr_t     = gdb.lookup_type("uintptr_t")
        self.elf64_ehdr_le = struct.Struct("<%s" % self.ELF64_EHDR)
        self.elf64_phdr_le = struct.Struct("<%s" % self.ELF64_PHDR)

    def int128_get64(self, val):
        assert (val["hi"] == 0)
        return val["lo"]

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

    def qemu_get_ram_block(self, ram_addr):
        ram_blocks = gdb.parse_and_eval("ram_list.blocks")
        for block in self.qlist_foreach(ram_blocks, "next"):
            if (ram_addr - block["offset"] < block["length"]):
                return block
        raise gdb.GdbError("Bad ram offset %x" % ram_addr)

    def qemu_get_ram_ptr(self, ram_addr):
        block = self.qemu_get_ram_block(ram_addr)
        return block["host"] + (ram_addr - block["offset"])

    def memory_region_get_ram_ptr(self, mr):
        if (mr["alias"] != 0):
            return (self.memory_region_get_ram_ptr(mr["alias"].dereference()) +
                    mr["alias_offset"])
        return self.qemu_get_ram_ptr(mr["ram_addr"] & self.TARGET_PAGE_MASK)

    def guest_phys_blocks_init(self):
        self.guest_phys_blocks = []

    def guest_phys_blocks_append(self):
        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()
        for cur in range(current_map["nr"]):
            flat_range   = (current_map["ranges"] + cur).dereference()
            mr           = flat_range["mr"].dereference()

            # we only care about RAM
            if (not mr["ram"]):
                continue

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

            # find continuity in guest physical address space
            if (len(self.guest_phys_blocks) > 0):
                predecessor = self.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
                self.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(self.uintptr_t),
                    message, len(self.guest_phys_blocks)))

    def cpu_get_dump_info(self):
        # We can't synchronize the registers with KVM post-mortem, and
        # the bits in (first_x86_cpu->env.hflags) seem to be stale; they
        # may not reflect long mode for example. Hence just assume the
        # most common values. This also means that instruction pointer
        # etc. will be bogus in the dump, but at least the RAM contents
        # should be valid.
        self.dump_info = {"d_machine": self.EM_X86_64,
                          "d_endian" : self.ELFDATA2LSB,
                          "d_class"  : self.ELFCLASS64}

    def encode_elf64_ehdr_le(self):
        return self.elf64_ehdr_le.pack(
                                 self.ELFMAG,                 # e_ident/magic
                                 self.dump_info["d_class"],   # e_ident/class
                                 self.dump_info["d_endian"],  # e_ident/data
                                 self.EV_CURRENT,             # e_ident/version
                                 0,                           # e_ident/osabi
                                 "",                          # e_ident/pad
                                 self.ET_CORE,                # e_type
                                 self.dump_info["d_machine"], # e_machine
                                 self.EV_CURRENT,             # e_version
                                 0,                           # e_entry
                                 self.elf64_ehdr_le.size,     # e_phoff
                                 0,                           # e_shoff
                                 0,                           # e_flags
                                 self.elf64_ehdr_le.size,     # e_ehsize
                                 self.elf64_phdr_le.size,     # e_phentsize
                                 self.phdr_num,               # e_phnum
                                 0,                           # e_shentsize
                                 0,                           # e_shnum
                                 0                            # e_shstrndx
                                )

    def encode_elf64_note_le(self):
        return self.elf64_phdr_le.pack(self.PT_NOTE,         # p_type
                                       0,                    # p_flags
                                       (self.memory_offset -
                                        len(self.note)),     # p_offset
                                       0,                    # p_vaddr
                                       0,                    # p_paddr
                                       len(self.note),       # p_filesz
                                       len(self.note),       # p_memsz
                                       0                     # p_align
                                      )

    def encode_elf64_load_le(self, offset, start_hwaddr, range_size):
        return self.elf64_phdr_le.pack(self.PT_LOAD, # p_type
                                       0,            # p_flags
                                       offset,       # p_offset
                                       0,            # p_vaddr
                                       start_hwaddr, # p_paddr
                                       range_size,   # p_filesz
                                       range_size,   # p_memsz
                                       0             # p_align
                                      )

    def note_init(self, name, desc, type):
        # name must include a trailing NUL
        namesz = (len(name) + 1 + 3) / 4 * 4
        descsz = (len(desc)     + 3) / 4 * 4
        fmt = ("<"   # little endian
               "I"   # n_namesz
               "I"   # n_descsz
               "I"   # n_type
               "%us" # name
               "%us" # desc
               % (namesz, descsz))
        self.note = struct.pack(fmt,
                                len(name) + 1, len(desc), type, name, desc)

    def dump_init(self):
        self.guest_phys_blocks_init()
        self.guest_phys_blocks_append()
        self.cpu_get_dump_info()
        # we have no way to retrieve the VCPU status from KVM
        # post-mortem
        self.note_init("NONE", "EMPTY", 0)

        # Account for PT_NOTE.
        self.phdr_num = 1

        # We should never reach PN_XNUM for paging=false dumps: there's
        # just a handful of discontiguous ranges after merging.
        self.phdr_num += len(self.guest_phys_blocks)
        assert (self.phdr_num < self.PN_XNUM)

        # Calculate the ELF file offset where the memory dump commences:
        #
        #   ELF header
        #   PT_NOTE
        #   PT_LOAD: 1
        #   PT_LOAD: 2
        #   ...
        #   PT_LOAD: len(self.guest_phys_blocks)
        #   ELF note
        #   memory dump
        self.memory_offset = (self.elf64_ehdr_le.size +
                              self.elf64_phdr_le.size * self.phdr_num +
                              len(self.note))

    def dump_begin(self, vmcore):
        vmcore.write(self.encode_elf64_ehdr_le())
        vmcore.write(self.encode_elf64_note_le())
        running = self.memory_offset
        for block in self.guest_phys_blocks:
            range_size = block["target_end"] - block["target_start"]
            vmcore.write(self.encode_elf64_load_le(running,
                                                   block["target_start"],
                                                   range_size))
            running += range_size
        vmcore.write(self.note)

    def dump_iterate(self, vmcore):
        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(self.uintptr_t), left))
            while (left > 0):
                chunk_size = min(self.TARGET_PAGE_SIZE, left)
                chunk = qemu_core.read_memory(cur, chunk_size)
                vmcore.write(chunk)
                cur  += chunk_size
                left -= chunk_size

    def create_vmcore(self, filename):
        vmcore = open(filename, "wb")
        self.dump_begin(vmcore)
        self.dump_iterate(vmcore)
        vmcore.close()

    def invoke(self, args, from_tty):
        # 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) != 1):
            raise gdb.GdbError("usage: dump-guest-memory FILE")

        self.dump_init()
        self.create_vmcore(argv[0])

DumpGuestMemory()
