/*
 * QEMU dump
 *
 * Copyright Fujitsu, Corp. 2011, 2012
 *
 * Authors:
 *     Wen Congyang <wency@cn.fujitsu.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.
 *
 */

#include "qemu/osdep.h"
#include "qemu/cutils.h"
#include "elf.h"
#include "qemu/bswap.h"
#include "exec/target_page.h"
#include "monitor/monitor.h"
#include "sysemu/dump.h"
#include "sysemu/runstate.h"
#include "sysemu/cpus.h"
#include "qapi/error.h"
#include "qapi/qapi-commands-dump.h"
#include "qapi/qapi-events-dump.h"
#include "qapi/qmp/qerror.h"
#include "qemu/main-loop.h"
#include "hw/misc/vmcoreinfo.h"
#include "migration/blocker.h"
#include "hw/core/cpu.h"
#include "win_dump.h"

#include <zlib.h>
#ifdef CONFIG_LZO
#include <lzo/lzo1x.h>
#endif
#ifdef CONFIG_SNAPPY
#include <snappy-c.h>
#endif
#ifndef ELF_MACHINE_UNAME
#define ELF_MACHINE_UNAME "Unknown"
#endif

#define MAX_GUEST_NOTE_SIZE (1 << 20) /* 1MB should be enough */

static Error *dump_migration_blocker;

#define ELF_NOTE_SIZE(hdr_size, name_size, desc_size)   \
    ((DIV_ROUND_UP((hdr_size), 4) +                     \
      DIV_ROUND_UP((name_size), 4) +                    \
      DIV_ROUND_UP((desc_size), 4)) * 4)

static inline bool dump_is_64bit(DumpState *s)
{
    return s->dump_info.d_class == ELFCLASS64;
}

static inline bool dump_has_filter(DumpState *s)
{
    return s->filter_area_length > 0;
}

uint16_t cpu_to_dump16(DumpState *s, uint16_t val)
{
    if (s->dump_info.d_endian == ELFDATA2LSB) {
        val = cpu_to_le16(val);
    } else {
        val = cpu_to_be16(val);
    }

    return val;
}

uint32_t cpu_to_dump32(DumpState *s, uint32_t val)
{
    if (s->dump_info.d_endian == ELFDATA2LSB) {
        val = cpu_to_le32(val);
    } else {
        val = cpu_to_be32(val);
    }

    return val;
}

uint64_t cpu_to_dump64(DumpState *s, uint64_t val)
{
    if (s->dump_info.d_endian == ELFDATA2LSB) {
        val = cpu_to_le64(val);
    } else {
        val = cpu_to_be64(val);
    }

    return val;
}

static int dump_cleanup(DumpState *s)
{
    guest_phys_blocks_free(&s->guest_phys_blocks);
    memory_mapping_list_free(&s->list);
    close(s->fd);
    g_free(s->guest_note);
    g_array_unref(s->string_table_buf);
    s->guest_note = NULL;
    if (s->resume) {
        if (s->detached) {
            qemu_mutex_lock_iothread();
        }
        vm_start();
        if (s->detached) {
            qemu_mutex_unlock_iothread();
        }
    }
    migrate_del_blocker(dump_migration_blocker);

    return 0;
}

static int fd_write_vmcore(const void *buf, size_t size, void *opaque)
{
    DumpState *s = opaque;
    size_t written_size;

    written_size = qemu_write_full(s->fd, buf, size);
    if (written_size != size) {
        return -errno;
    }

    return 0;
}

static void prepare_elf64_header(DumpState *s, Elf64_Ehdr *elf_header)
{
    /*
     * phnum in the elf header is 16 bit, if we have more segments we
     * set phnum to PN_XNUM and write the real number of segments to a
     * special section.
     */
    uint16_t phnum = MIN(s->phdr_num, PN_XNUM);

    memset(elf_header, 0, sizeof(Elf64_Ehdr));
    memcpy(elf_header, ELFMAG, SELFMAG);
    elf_header->e_ident[EI_CLASS] = ELFCLASS64;
    elf_header->e_ident[EI_DATA] = s->dump_info.d_endian;
    elf_header->e_ident[EI_VERSION] = EV_CURRENT;
    elf_header->e_type = cpu_to_dump16(s, ET_CORE);
    elf_header->e_machine = cpu_to_dump16(s, s->dump_info.d_machine);
    elf_header->e_version = cpu_to_dump32(s, EV_CURRENT);
    elf_header->e_ehsize = cpu_to_dump16(s, sizeof(elf_header));
    elf_header->e_phoff = cpu_to_dump64(s, s->phdr_offset);
    elf_header->e_phentsize = cpu_to_dump16(s, sizeof(Elf64_Phdr));
    elf_header->e_phnum = cpu_to_dump16(s, phnum);
    elf_header->e_shoff = cpu_to_dump64(s, s->shdr_offset);
    elf_header->e_shentsize = cpu_to_dump16(s, sizeof(Elf64_Shdr));
    elf_header->e_shnum = cpu_to_dump16(s, s->shdr_num);
    elf_header->e_shstrndx = cpu_to_dump16(s, s->shdr_num - 1);
}

static void prepare_elf32_header(DumpState *s, Elf32_Ehdr *elf_header)
{
    /*
     * phnum in the elf header is 16 bit, if we have more segments we
     * set phnum to PN_XNUM and write the real number of segments to a
     * special section.
     */
    uint16_t phnum = MIN(s->phdr_num, PN_XNUM);

    memset(elf_header, 0, sizeof(Elf32_Ehdr));
    memcpy(elf_header, ELFMAG, SELFMAG);
    elf_header->e_ident[EI_CLASS] = ELFCLASS32;
    elf_header->e_ident[EI_DATA] = s->dump_info.d_endian;
    elf_header->e_ident[EI_VERSION] = EV_CURRENT;
    elf_header->e_type = cpu_to_dump16(s, ET_CORE);
    elf_header->e_machine = cpu_to_dump16(s, s->dump_info.d_machine);
    elf_header->e_version = cpu_to_dump32(s, EV_CURRENT);
    elf_header->e_ehsize = cpu_to_dump16(s, sizeof(elf_header));
    elf_header->e_phoff = cpu_to_dump32(s, s->phdr_offset);
    elf_header->e_phentsize = cpu_to_dump16(s, sizeof(Elf32_Phdr));
    elf_header->e_phnum = cpu_to_dump16(s, phnum);
    elf_header->e_shoff = cpu_to_dump32(s, s->shdr_offset);
    elf_header->e_shentsize = cpu_to_dump16(s, sizeof(Elf32_Shdr));
    elf_header->e_shnum = cpu_to_dump16(s, s->shdr_num);
    elf_header->e_shstrndx = cpu_to_dump16(s, s->shdr_num - 1);
}

static void write_elf_header(DumpState *s, Error **errp)
{
    Elf32_Ehdr elf32_header;
    Elf64_Ehdr elf64_header;
    size_t header_size;
    void *header_ptr;
    int ret;

    /* The NULL header and the shstrtab are always defined */
    assert(s->shdr_num >= 2);
    if (dump_is_64bit(s)) {
        prepare_elf64_header(s, &elf64_header);
        header_size = sizeof(elf64_header);
        header_ptr = &elf64_header;
    } else {
        prepare_elf32_header(s, &elf32_header);
        header_size = sizeof(elf32_header);
        header_ptr = &elf32_header;
    }

    ret = fd_write_vmcore(header_ptr, header_size, s);
    if (ret < 0) {
        error_setg_errno(errp, -ret, "dump: failed to write elf header");
    }
}

static void write_elf64_load(DumpState *s, MemoryMapping *memory_mapping,
                             int phdr_index, hwaddr offset,
                             hwaddr filesz, Error **errp)
{
    Elf64_Phdr phdr;
    int ret;

    memset(&phdr, 0, sizeof(Elf64_Phdr));
    phdr.p_type = cpu_to_dump32(s, PT_LOAD);
    phdr.p_offset = cpu_to_dump64(s, offset);
    phdr.p_paddr = cpu_to_dump64(s, memory_mapping->phys_addr);
    phdr.p_filesz = cpu_to_dump64(s, filesz);
    phdr.p_memsz = cpu_to_dump64(s, memory_mapping->length);
    phdr.p_vaddr = cpu_to_dump64(s, memory_mapping->virt_addr) ?: phdr.p_paddr;

    assert(memory_mapping->length >= filesz);

    ret = fd_write_vmcore(&phdr, sizeof(Elf64_Phdr), s);
    if (ret < 0) {
        error_setg_errno(errp, -ret,
                         "dump: failed to write program header table");
    }
}

static void write_elf32_load(DumpState *s, MemoryMapping *memory_mapping,
                             int phdr_index, hwaddr offset,
                             hwaddr filesz, Error **errp)
{
    Elf32_Phdr phdr;
    int ret;

    memset(&phdr, 0, sizeof(Elf32_Phdr));
    phdr.p_type = cpu_to_dump32(s, PT_LOAD);
    phdr.p_offset = cpu_to_dump32(s, offset);
    phdr.p_paddr = cpu_to_dump32(s, memory_mapping->phys_addr);
    phdr.p_filesz = cpu_to_dump32(s, filesz);
    phdr.p_memsz = cpu_to_dump32(s, memory_mapping->length);
    phdr.p_vaddr =
        cpu_to_dump32(s, memory_mapping->virt_addr) ?: phdr.p_paddr;

    assert(memory_mapping->length >= filesz);

    ret = fd_write_vmcore(&phdr, sizeof(Elf32_Phdr), s);
    if (ret < 0) {
        error_setg_errno(errp, -ret,
                         "dump: failed to write program header table");
    }
}

static void prepare_elf64_phdr_note(DumpState *s, Elf64_Phdr *phdr)
{
    memset(phdr, 0, sizeof(*phdr));
    phdr->p_type = cpu_to_dump32(s, PT_NOTE);
    phdr->p_offset = cpu_to_dump64(s, s->note_offset);
    phdr->p_paddr = 0;
    phdr->p_filesz = cpu_to_dump64(s, s->note_size);
    phdr->p_memsz = cpu_to_dump64(s, s->note_size);
    phdr->p_vaddr = 0;
}

static inline int cpu_index(CPUState *cpu)
{
    return cpu->cpu_index + 1;
}

static void write_guest_note(WriteCoreDumpFunction f, DumpState *s,
                             Error **errp)
{
    int ret;

    if (s->guest_note) {
        ret = f(s->guest_note, s->guest_note_size, s);
        if (ret < 0) {
            error_setg(errp, "dump: failed to write guest note");
        }
    }
}

static void write_elf64_notes(WriteCoreDumpFunction f, DumpState *s,
                              Error **errp)
{
    CPUState *cpu;
    int ret;
    int id;

    CPU_FOREACH(cpu) {
        id = cpu_index(cpu);
        ret = cpu_write_elf64_note(f, cpu, id, s);
        if (ret < 0) {
            error_setg(errp, "dump: failed to write elf notes");
            return;
        }
    }

    CPU_FOREACH(cpu) {
        ret = cpu_write_elf64_qemunote(f, cpu, s);
        if (ret < 0) {
            error_setg(errp, "dump: failed to write CPU status");
            return;
        }
    }

    write_guest_note(f, s, errp);
}

static void prepare_elf32_phdr_note(DumpState *s, Elf32_Phdr *phdr)
{
    memset(phdr, 0, sizeof(*phdr));
    phdr->p_type = cpu_to_dump32(s, PT_NOTE);
    phdr->p_offset = cpu_to_dump32(s, s->note_offset);
    phdr->p_paddr = 0;
    phdr->p_filesz = cpu_to_dump32(s, s->note_size);
    phdr->p_memsz = cpu_to_dump32(s, s->note_size);
    phdr->p_vaddr = 0;
}

static void write_elf32_notes(WriteCoreDumpFunction f, DumpState *s,
                              Error **errp)
{
    CPUState *cpu;
    int ret;
    int id;

    CPU_FOREACH(cpu) {
        id = cpu_index(cpu);
        ret = cpu_write_elf32_note(f, cpu, id, s);
        if (ret < 0) {
            error_setg(errp, "dump: failed to write elf notes");
            return;
        }
    }

    CPU_FOREACH(cpu) {
        ret = cpu_write_elf32_qemunote(f, cpu, s);
        if (ret < 0) {
            error_setg(errp, "dump: failed to write CPU status");
            return;
        }
    }

    write_guest_note(f, s, errp);
}

static void write_elf_phdr_note(DumpState *s, Error **errp)
{
    Elf32_Phdr phdr32;
    Elf64_Phdr phdr64;
    void *phdr;
    size_t size;
    int ret;

    if (dump_is_64bit(s)) {
        prepare_elf64_phdr_note(s, &phdr64);
        size = sizeof(phdr64);
        phdr = &phdr64;
    } else {
        prepare_elf32_phdr_note(s, &phdr32);
        size = sizeof(phdr32);
        phdr = &phdr32;
    }

    ret = fd_write_vmcore(phdr, size, s);
    if (ret < 0) {
        error_setg_errno(errp, -ret,
                         "dump: failed to write program header table");
    }
}

static void prepare_elf_section_hdr_zero(DumpState *s)
{
    if (dump_is_64bit(s)) {
        Elf64_Shdr *shdr64 = s->elf_section_hdrs;

        shdr64->sh_info = cpu_to_dump32(s, s->phdr_num);
    } else {
        Elf32_Shdr *shdr32 = s->elf_section_hdrs;

        shdr32->sh_info = cpu_to_dump32(s, s->phdr_num);
    }
}

static void prepare_elf_section_hdr_string(DumpState *s, void *buff)
{
    uint64_t index = s->string_table_buf->len;
    const char strtab[] = ".shstrtab";
    Elf32_Shdr shdr32 = {};
    Elf64_Shdr shdr64 = {};
    int shdr_size;
    void *shdr;

    g_array_append_vals(s->string_table_buf, strtab, sizeof(strtab));
    if (dump_is_64bit(s)) {
        shdr_size = sizeof(Elf64_Shdr);
        shdr64.sh_type = SHT_STRTAB;
        shdr64.sh_offset = s->section_offset + s->elf_section_data_size;
        shdr64.sh_name = index;
        shdr64.sh_size = s->string_table_buf->len;
        shdr = &shdr64;
    } else {
        shdr_size = sizeof(Elf32_Shdr);
        shdr32.sh_type = SHT_STRTAB;
        shdr32.sh_offset = s->section_offset + s->elf_section_data_size;
        shdr32.sh_name = index;
        shdr32.sh_size = s->string_table_buf->len;
        shdr = &shdr32;
    }
    memcpy(buff, shdr, shdr_size);
}

static bool prepare_elf_section_hdrs(DumpState *s, Error **errp)
{
    size_t len, sizeof_shdr;
    void *buff_hdr;

    /*
     * Section ordering:
     * - HDR zero
     * - Arch section hdrs
     * - String table hdr
     */
    sizeof_shdr = dump_is_64bit(s) ? sizeof(Elf64_Shdr) : sizeof(Elf32_Shdr);
    len = sizeof_shdr * s->shdr_num;
    s->elf_section_hdrs = g_malloc0(len);
    buff_hdr = s->elf_section_hdrs;

    /*
     * The first section header is ALWAYS a special initial section
     * header.
     *
     * The header should be 0 with one exception being that if
     * phdr_num is PN_XNUM then the sh_info field contains the real
     * number of segment entries.
     *
     * As we zero allocate the buffer we will only need to modify
     * sh_info for the PN_XNUM case.
     */
    if (s->phdr_num >= PN_XNUM) {
        prepare_elf_section_hdr_zero(s);
    }
    buff_hdr += sizeof_shdr;

    /* Add architecture defined section headers */
    if (s->dump_info.arch_sections_write_hdr_fn
        && s->shdr_num > 2) {
        buff_hdr += s->dump_info.arch_sections_write_hdr_fn(s, buff_hdr);

        if (s->shdr_num >= SHN_LORESERVE) {
            error_setg_errno(errp, EINVAL,
                             "dump: too many architecture defined sections");
            return false;
        }
    }

    /*
     * String table is the last section since strings are added via
     * arch_sections_write_hdr().
     */
    prepare_elf_section_hdr_string(s, buff_hdr);
    return true;
}

static void write_elf_section_headers(DumpState *s, Error **errp)
{
    size_t sizeof_shdr = dump_is_64bit(s) ? sizeof(Elf64_Shdr) : sizeof(Elf32_Shdr);
    int ret;

    if (!prepare_elf_section_hdrs(s, errp)) {
        return;
    }

    ret = fd_write_vmcore(s->elf_section_hdrs, s->shdr_num * sizeof_shdr, s);
    if (ret < 0) {
        error_setg_errno(errp, -ret, "dump: failed to write section headers");
    }

    g_free(s->elf_section_hdrs);
}

static void write_elf_sections(DumpState *s, Error **errp)
{
    int ret;

    if (s->elf_section_data_size) {
        /* Write architecture section data */
        ret = fd_write_vmcore(s->elf_section_data,
                              s->elf_section_data_size, s);
        if (ret < 0) {
            error_setg_errno(errp, -ret,
                             "dump: failed to write architecture section data");
            return;
        }
    }

    /* Write string table */
    ret = fd_write_vmcore(s->string_table_buf->data,
                          s->string_table_buf->len, s);
    if (ret < 0) {
        error_setg_errno(errp, -ret, "dump: failed to write string table data");
    }
}

static void write_data(DumpState *s, void *buf, int length, Error **errp)
{
    int ret;

    ret = fd_write_vmcore(buf, length, s);
    if (ret < 0) {
        error_setg_errno(errp, -ret, "dump: failed to save memory");
    } else {
        s->written_size += length;
    }
}

/* write the memory to vmcore. 1 page per I/O. */
static void write_memory(DumpState *s, GuestPhysBlock *block, ram_addr_t start,
                         int64_t size, Error **errp)
{
    ERRP_GUARD();
    int64_t i;

    for (i = 0; i < size / s->dump_info.page_size; i++) {
        write_data(s, block->host_addr + start + i * s->dump_info.page_size,
                   s->dump_info.page_size, errp);
        if (*errp) {
            return;
        }
    }

    if ((size % s->dump_info.page_size) != 0) {
        write_data(s, block->host_addr + start + i * s->dump_info.page_size,
                   size % s->dump_info.page_size, errp);
        if (*errp) {
            return;
        }
    }
}

/* get the memory's offset and size in the vmcore */
static void get_offset_range(hwaddr phys_addr,
                             ram_addr_t mapping_length,
                             DumpState *s,
                             hwaddr *p_offset,
                             hwaddr *p_filesz)
{
    GuestPhysBlock *block;
    hwaddr offset = s->memory_offset;
    int64_t size_in_block, start;

    /* When the memory is not stored into vmcore, offset will be -1 */
    *p_offset = -1;
    *p_filesz = 0;

    if (dump_has_filter(s)) {
        if (phys_addr < s->filter_area_begin ||
            phys_addr >= s->filter_area_begin + s->filter_area_length) {
            return;
        }
    }

    QTAILQ_FOREACH(block, &s->guest_phys_blocks.head, next) {
        if (dump_has_filter(s)) {
            if (block->target_start >= s->filter_area_begin + s->filter_area_length ||
                block->target_end <= s->filter_area_begin) {
                /* This block is out of the range */
                continue;
            }

            if (s->filter_area_begin <= block->target_start) {
                start = block->target_start;
            } else {
                start = s->filter_area_begin;
            }

            size_in_block = block->target_end - start;
            if (s->filter_area_begin + s->filter_area_length < block->target_end) {
                size_in_block -= block->target_end - (s->filter_area_begin + s->filter_area_length);
            }
        } else {
            start = block->target_start;
            size_in_block = block->target_end - block->target_start;
        }

        if (phys_addr >= start && phys_addr < start + size_in_block) {
            *p_offset = phys_addr - start + offset;

            /* The offset range mapped from the vmcore file must not spill over
             * the GuestPhysBlock, clamp it. The rest of the mapping will be
             * zero-filled in memory at load time; see
             * <http://refspecs.linuxbase.org/elf/gabi4+/ch5.pheader.html>.
             */
            *p_filesz = phys_addr + mapping_length <= start + size_in_block ?
                        mapping_length :
                        size_in_block - (phys_addr - start);
            return;
        }

        offset += size_in_block;
    }
}

static void write_elf_phdr_loads(DumpState *s, Error **errp)
{
    ERRP_GUARD();
    hwaddr offset, filesz;
    MemoryMapping *memory_mapping;
    uint32_t phdr_index = 1;

    QTAILQ_FOREACH(memory_mapping, &s->list.head, next) {
        get_offset_range(memory_mapping->phys_addr,
                         memory_mapping->length,
                         s, &offset, &filesz);
        if (dump_is_64bit(s)) {
            write_elf64_load(s, memory_mapping, phdr_index++, offset,
                             filesz, errp);
        } else {
            write_elf32_load(s, memory_mapping, phdr_index++, offset,
                             filesz, errp);
        }

        if (*errp) {
            return;
        }

        if (phdr_index >= s->phdr_num) {
            break;
        }
    }
}

static void write_elf_notes(DumpState *s, Error **errp)
{
    if (dump_is_64bit(s)) {
        write_elf64_notes(fd_write_vmcore, s, errp);
    } else {
        write_elf32_notes(fd_write_vmcore, s, errp);
    }
}

/* write elf header, PT_NOTE and elf note to vmcore. */
static void dump_begin(DumpState *s, Error **errp)
{
    ERRP_GUARD();

    /*
     * the vmcore's format is:
     *   --------------
     *   |  elf header |
     *   --------------
     *   |  sctn_hdr   |
     *   --------------
     *   |  PT_NOTE    |
     *   --------------
     *   |  PT_LOAD    |
     *   --------------
     *   |  ......     |
     *   --------------
     *   |  PT_LOAD    |
     *   --------------
     *   |  elf note   |
     *   --------------
     *   |  memory     |
     *   --------------
     *
     * we only know where the memory is saved after we write elf note into
     * vmcore.
     */

    /* write elf header to vmcore */
    write_elf_header(s, errp);
    if (*errp) {
        return;
    }

    /* write section headers to vmcore */
    write_elf_section_headers(s, errp);
    if (*errp) {
        return;
    }

    /* write PT_NOTE to vmcore */
    write_elf_phdr_note(s, errp);
    if (*errp) {
        return;
    }

    /* write all PT_LOADs to vmcore */
    write_elf_phdr_loads(s, errp);
    if (*errp) {
        return;
    }

    /* write notes to vmcore */
    write_elf_notes(s, errp);
}

int64_t dump_filtered_memblock_size(GuestPhysBlock *block,
                                    int64_t filter_area_start,
                                    int64_t filter_area_length)
{
    int64_t size, left, right;

    /* No filter, return full size */
    if (!filter_area_length) {
        return block->target_end - block->target_start;
    }

    /* calculate the overlapped region. */
    left = MAX(filter_area_start, block->target_start);
    right = MIN(filter_area_start + filter_area_length, block->target_end);
    size = right - left;
    size = size > 0 ? size : 0;

    return size;
}

int64_t dump_filtered_memblock_start(GuestPhysBlock *block,
                                     int64_t filter_area_start,
                                     int64_t filter_area_length)
{
    if (filter_area_length) {
        /* return -1 if the block is not within filter area */
        if (block->target_start >= filter_area_start + filter_area_length ||
            block->target_end <= filter_area_start) {
            return -1;
        }

        if (filter_area_start > block->target_start) {
            return filter_area_start - block->target_start;
        }
    }

    return 0;
}

/* write all memory to vmcore */
static void dump_iterate(DumpState *s, Error **errp)
{
    ERRP_GUARD();
    GuestPhysBlock *block;
    int64_t memblock_size, memblock_start;

    QTAILQ_FOREACH(block, &s->guest_phys_blocks.head, next) {
        memblock_start = dump_filtered_memblock_start(block, s->filter_area_begin, s->filter_area_length);
        if (memblock_start == -1) {
            continue;
        }

        memblock_size = dump_filtered_memblock_size(block, s->filter_area_begin, s->filter_area_length);

        /* Write the memory to file */
        write_memory(s, block, memblock_start, memblock_size, errp);
        if (*errp) {
            return;
        }
    }
}

static void dump_end(DumpState *s, Error **errp)
{
    int rc;

    if (s->elf_section_data_size) {
        s->elf_section_data = g_malloc0(s->elf_section_data_size);
    }

    /* Adds the architecture defined section data to s->elf_section_data  */
    if (s->dump_info.arch_sections_write_fn &&
        s->elf_section_data_size) {
        rc = s->dump_info.arch_sections_write_fn(s, s->elf_section_data);
        if (rc) {
            error_setg_errno(errp, rc,
                             "dump: failed to get arch section data");
            g_free(s->elf_section_data);
            return;
        }
    }

    /* write sections to vmcore */
    write_elf_sections(s, errp);
}

static void create_vmcore(DumpState *s, Error **errp)
{
    ERRP_GUARD();

    dump_begin(s, errp);
    if (*errp) {
        return;
    }

    /* Iterate over memory and dump it to file */
    dump_iterate(s, errp);
    if (*errp) {
        return;
    }

    /* Write the section data */
    dump_end(s, errp);
}

static int write_start_flat_header(int fd)
{
    MakedumpfileHeader *mh;
    int ret = 0;

    QEMU_BUILD_BUG_ON(sizeof *mh > MAX_SIZE_MDF_HEADER);
    mh = g_malloc0(MAX_SIZE_MDF_HEADER);

    memcpy(mh->signature, MAKEDUMPFILE_SIGNATURE,
           MIN(sizeof mh->signature, sizeof MAKEDUMPFILE_SIGNATURE));

    mh->type = cpu_to_be64(TYPE_FLAT_HEADER);
    mh->version = cpu_to_be64(VERSION_FLAT_HEADER);

    size_t written_size;
    written_size = qemu_write_full(fd, mh, MAX_SIZE_MDF_HEADER);
    if (written_size != MAX_SIZE_MDF_HEADER) {
        ret = -1;
    }

    g_free(mh);
    return ret;
}

static int write_end_flat_header(int fd)
{
    MakedumpfileDataHeader mdh;

    mdh.offset = END_FLAG_FLAT_HEADER;
    mdh.buf_size = END_FLAG_FLAT_HEADER;

    size_t written_size;
    written_size = qemu_write_full(fd, &mdh, sizeof(mdh));
    if (written_size != sizeof(mdh)) {
        return -1;
    }

    return 0;
}

static int write_buffer(int fd, off_t offset, const void *buf, size_t size)
{
    size_t written_size;
    MakedumpfileDataHeader mdh;

    mdh.offset = cpu_to_be64(offset);
    mdh.buf_size = cpu_to_be64(size);

    written_size = qemu_write_full(fd, &mdh, sizeof(mdh));
    if (written_size != sizeof(mdh)) {
        return -1;
    }

    written_size = qemu_write_full(fd, buf, size);
    if (written_size != size) {
        return -1;
    }

    return 0;
}

static int buf_write_note(const void *buf, size_t size, void *opaque)
{
    DumpState *s = opaque;

    /* note_buf is not enough */
    if (s->note_buf_offset + size > s->note_size) {
        return -1;
    }

    memcpy(s->note_buf + s->note_buf_offset, buf, size);

    s->note_buf_offset += size;

    return 0;
}

/*
 * This function retrieves various sizes from an elf header.
 *
 * @note has to be a valid ELF note. The return sizes are unmodified
 * (not padded or rounded up to be multiple of 4).
 */
static void get_note_sizes(DumpState *s, const void *note,
                           uint64_t *note_head_size,
                           uint64_t *name_size,
                           uint64_t *desc_size)
{
    uint64_t note_head_sz;
    uint64_t name_sz;
    uint64_t desc_sz;

    if (dump_is_64bit(s)) {
        const Elf64_Nhdr *hdr = note;
        note_head_sz = sizeof(Elf64_Nhdr);
        name_sz = cpu_to_dump64(s, hdr->n_namesz);
        desc_sz = cpu_to_dump64(s, hdr->n_descsz);
    } else {
        const Elf32_Nhdr *hdr = note;
        note_head_sz = sizeof(Elf32_Nhdr);
        name_sz = cpu_to_dump32(s, hdr->n_namesz);
        desc_sz = cpu_to_dump32(s, hdr->n_descsz);
    }

    if (note_head_size) {
        *note_head_size = note_head_sz;
    }
    if (name_size) {
        *name_size = name_sz;
    }
    if (desc_size) {
        *desc_size = desc_sz;
    }
}

static bool note_name_equal(DumpState *s,
                            const uint8_t *note, const char *name)
{
    int len = strlen(name) + 1;
    uint64_t head_size, name_size;

    get_note_sizes(s, note, &head_size, &name_size, NULL);
    head_size = ROUND_UP(head_size, 4);

    return name_size == len && memcmp(note + head_size, name, len) == 0;
}

/* write common header, sub header and elf note to vmcore */
static void create_header32(DumpState *s, Error **errp)
{
    ERRP_GUARD();
    DiskDumpHeader32 *dh = NULL;
    KdumpSubHeader32 *kh = NULL;
    size_t size;
    uint32_t block_size;
    uint32_t sub_hdr_size;
    uint32_t bitmap_blocks;
    uint32_t status = 0;
    uint64_t offset_note;

    /* write common header, the version of kdump-compressed format is 6th */
    size = sizeof(DiskDumpHeader32);
    dh = g_malloc0(size);

    memcpy(dh->signature, KDUMP_SIGNATURE, SIG_LEN);
    dh->header_version = cpu_to_dump32(s, 6);
    block_size = s->dump_info.page_size;
    dh->block_size = cpu_to_dump32(s, block_size);
    sub_hdr_size = sizeof(struct KdumpSubHeader32) + s->note_size;
    sub_hdr_size = DIV_ROUND_UP(sub_hdr_size, block_size);
    dh->sub_hdr_size = cpu_to_dump32(s, sub_hdr_size);
    /* dh->max_mapnr may be truncated, full 64bit is in kh.max_mapnr_64 */
    dh->max_mapnr = cpu_to_dump32(s, MIN(s->max_mapnr, UINT_MAX));
    dh->nr_cpus = cpu_to_dump32(s, s->nr_cpus);
    bitmap_blocks = DIV_ROUND_UP(s->len_dump_bitmap, block_size) * 2;
    dh->bitmap_blocks = cpu_to_dump32(s, bitmap_blocks);
    strncpy(dh->utsname.machine, ELF_MACHINE_UNAME, sizeof(dh->utsname.machine));

    if (s->flag_compress & DUMP_DH_COMPRESSED_ZLIB) {
        status |= DUMP_DH_COMPRESSED_ZLIB;
    }
#ifdef CONFIG_LZO
    if (s->flag_compress & DUMP_DH_COMPRESSED_LZO) {
        status |= DUMP_DH_COMPRESSED_LZO;
    }
#endif
#ifdef CONFIG_SNAPPY
    if (s->flag_compress & DUMP_DH_COMPRESSED_SNAPPY) {
        status |= DUMP_DH_COMPRESSED_SNAPPY;
    }
#endif
    dh->status = cpu_to_dump32(s, status);

    if (write_buffer(s->fd, 0, dh, size) < 0) {
        error_setg(errp, "dump: failed to write disk dump header");
        goto out;
    }

    /* write sub header */
    size = sizeof(KdumpSubHeader32);
    kh = g_malloc0(size);

    /* 64bit max_mapnr_64 */
    kh->max_mapnr_64 = cpu_to_dump64(s, s->max_mapnr);
    kh->phys_base = cpu_to_dump32(s, s->dump_info.phys_base);
    kh->dump_level = cpu_to_dump32(s, DUMP_LEVEL);

    offset_note = DISKDUMP_HEADER_BLOCKS * block_size + size;
    if (s->guest_note &&
        note_name_equal(s, s->guest_note, "VMCOREINFO")) {
        uint64_t hsize, name_size, size_vmcoreinfo_desc, offset_vmcoreinfo;

        get_note_sizes(s, s->guest_note,
                       &hsize, &name_size, &size_vmcoreinfo_desc);
        offset_vmcoreinfo = offset_note + s->note_size - s->guest_note_size +
            (DIV_ROUND_UP(hsize, 4) + DIV_ROUND_UP(name_size, 4)) * 4;
        kh->offset_vmcoreinfo = cpu_to_dump64(s, offset_vmcoreinfo);
        kh->size_vmcoreinfo = cpu_to_dump32(s, size_vmcoreinfo_desc);
    }

    kh->offset_note = cpu_to_dump64(s, offset_note);
    kh->note_size = cpu_to_dump32(s, s->note_size);

    if (write_buffer(s->fd, DISKDUMP_HEADER_BLOCKS *
                     block_size, kh, size) < 0) {
        error_setg(errp, "dump: failed to write kdump sub header");
        goto out;
    }

    /* write note */
    s->note_buf = g_malloc0(s->note_size);
    s->note_buf_offset = 0;

    /* use s->note_buf to store notes temporarily */
    write_elf32_notes(buf_write_note, s, errp);
    if (*errp) {
        goto out;
    }
    if (write_buffer(s->fd, offset_note, s->note_buf,
                     s->note_size) < 0) {
        error_setg(errp, "dump: failed to write notes");
        goto out;
    }

    /* get offset of dump_bitmap */
    s->offset_dump_bitmap = (DISKDUMP_HEADER_BLOCKS + sub_hdr_size) *
                             block_size;

    /* get offset of page */
    s->offset_page = (DISKDUMP_HEADER_BLOCKS + sub_hdr_size + bitmap_blocks) *
                     block_size;

out:
    g_free(dh);
    g_free(kh);
    g_free(s->note_buf);
}

/* write common header, sub header and elf note to vmcore */
static void create_header64(DumpState *s, Error **errp)
{
    ERRP_GUARD();
    DiskDumpHeader64 *dh = NULL;
    KdumpSubHeader64 *kh = NULL;
    size_t size;
    uint32_t block_size;
    uint32_t sub_hdr_size;
    uint32_t bitmap_blocks;
    uint32_t status = 0;
    uint64_t offset_note;

    /* write common header, the version of kdump-compressed format is 6th */
    size = sizeof(DiskDumpHeader64);
    dh = g_malloc0(size);

    memcpy(dh->signature, KDUMP_SIGNATURE, SIG_LEN);
    dh->header_version = cpu_to_dump32(s, 6);
    block_size = s->dump_info.page_size;
    dh->block_size = cpu_to_dump32(s, block_size);
    sub_hdr_size = sizeof(struct KdumpSubHeader64) + s->note_size;
    sub_hdr_size = DIV_ROUND_UP(sub_hdr_size, block_size);
    dh->sub_hdr_size = cpu_to_dump32(s, sub_hdr_size);
    /* dh->max_mapnr may be truncated, full 64bit is in kh.max_mapnr_64 */
    dh->max_mapnr = cpu_to_dump32(s, MIN(s->max_mapnr, UINT_MAX));
    dh->nr_cpus = cpu_to_dump32(s, s->nr_cpus);
    bitmap_blocks = DIV_ROUND_UP(s->len_dump_bitmap, block_size) * 2;
    dh->bitmap_blocks = cpu_to_dump32(s, bitmap_blocks);
    strncpy(dh->utsname.machine, ELF_MACHINE_UNAME, sizeof(dh->utsname.machine));

    if (s->flag_compress & DUMP_DH_COMPRESSED_ZLIB) {
        status |= DUMP_DH_COMPRESSED_ZLIB;
    }
#ifdef CONFIG_LZO
    if (s->flag_compress & DUMP_DH_COMPRESSED_LZO) {
        status |= DUMP_DH_COMPRESSED_LZO;
    }
#endif
#ifdef CONFIG_SNAPPY
    if (s->flag_compress & DUMP_DH_COMPRESSED_SNAPPY) {
        status |= DUMP_DH_COMPRESSED_SNAPPY;
    }
#endif
    dh->status = cpu_to_dump32(s, status);

    if (write_buffer(s->fd, 0, dh, size) < 0) {
        error_setg(errp, "dump: failed to write disk dump header");
        goto out;
    }

    /* write sub header */
    size = sizeof(KdumpSubHeader64);
    kh = g_malloc0(size);

    /* 64bit max_mapnr_64 */
    kh->max_mapnr_64 = cpu_to_dump64(s, s->max_mapnr);
    kh->phys_base = cpu_to_dump64(s, s->dump_info.phys_base);
    kh->dump_level = cpu_to_dump32(s, DUMP_LEVEL);

    offset_note = DISKDUMP_HEADER_BLOCKS * block_size + size;
    if (s->guest_note &&
        note_name_equal(s, s->guest_note, "VMCOREINFO")) {
        uint64_t hsize, name_size, size_vmcoreinfo_desc, offset_vmcoreinfo;

        get_note_sizes(s, s->guest_note,
                       &hsize, &name_size, &size_vmcoreinfo_desc);
        offset_vmcoreinfo = offset_note + s->note_size - s->guest_note_size +
            (DIV_ROUND_UP(hsize, 4) + DIV_ROUND_UP(name_size, 4)) * 4;
        kh->offset_vmcoreinfo = cpu_to_dump64(s, offset_vmcoreinfo);
        kh->size_vmcoreinfo = cpu_to_dump64(s, size_vmcoreinfo_desc);
    }

    kh->offset_note = cpu_to_dump64(s, offset_note);
    kh->note_size = cpu_to_dump64(s, s->note_size);

    if (write_buffer(s->fd, DISKDUMP_HEADER_BLOCKS *
                     block_size, kh, size) < 0) {
        error_setg(errp, "dump: failed to write kdump sub header");
        goto out;
    }

    /* write note */
    s->note_buf = g_malloc0(s->note_size);
    s->note_buf_offset = 0;

    /* use s->note_buf to store notes temporarily */
    write_elf64_notes(buf_write_note, s, errp);
    if (*errp) {
        goto out;
    }

    if (write_buffer(s->fd, offset_note, s->note_buf,
                     s->note_size) < 0) {
        error_setg(errp, "dump: failed to write notes");
        goto out;
    }

    /* get offset of dump_bitmap */
    s->offset_dump_bitmap = (DISKDUMP_HEADER_BLOCKS + sub_hdr_size) *
                             block_size;

    /* get offset of page */
    s->offset_page = (DISKDUMP_HEADER_BLOCKS + sub_hdr_size + bitmap_blocks) *
                     block_size;

out:
    g_free(dh);
    g_free(kh);
    g_free(s->note_buf);
}

static void write_dump_header(DumpState *s, Error **errp)
{
    if (dump_is_64bit(s)) {
        create_header64(s, errp);
    } else {
        create_header32(s, errp);
    }
}

static size_t dump_bitmap_get_bufsize(DumpState *s)
{
    return s->dump_info.page_size;
}

/*
 * set dump_bitmap sequencely. the bit before last_pfn is not allowed to be
 * rewritten, so if need to set the first bit, set last_pfn and pfn to 0.
 * set_dump_bitmap will always leave the recently set bit un-sync. And setting
 * (last bit + sizeof(buf) * 8) to 0 will do flushing the content in buf into
 * vmcore, ie. synchronizing un-sync bit into vmcore.
 */
static int set_dump_bitmap(uint64_t last_pfn, uint64_t pfn, bool value,
                           uint8_t *buf, DumpState *s)
{
    off_t old_offset, new_offset;
    off_t offset_bitmap1, offset_bitmap2;
    uint32_t byte, bit;
    size_t bitmap_bufsize = dump_bitmap_get_bufsize(s);
    size_t bits_per_buf = bitmap_bufsize * CHAR_BIT;

    /* should not set the previous place */
    assert(last_pfn <= pfn);

    /*
     * if the bit needed to be set is not cached in buf, flush the data in buf
     * to vmcore firstly.
     * making new_offset be bigger than old_offset can also sync remained data
     * into vmcore.
     */
    old_offset = bitmap_bufsize * (last_pfn / bits_per_buf);
    new_offset = bitmap_bufsize * (pfn / bits_per_buf);

    while (old_offset < new_offset) {
        /* calculate the offset and write dump_bitmap */
        offset_bitmap1 = s->offset_dump_bitmap + old_offset;
        if (write_buffer(s->fd, offset_bitmap1, buf,
                         bitmap_bufsize) < 0) {
            return -1;
        }

        /* dump level 1 is chosen, so 1st and 2nd bitmap are same */
        offset_bitmap2 = s->offset_dump_bitmap + s->len_dump_bitmap +
                         old_offset;
        if (write_buffer(s->fd, offset_bitmap2, buf,
                         bitmap_bufsize) < 0) {
            return -1;
        }

        memset(buf, 0, bitmap_bufsize);
        old_offset += bitmap_bufsize;
    }

    /* get the exact place of the bit in the buf, and set it */
    byte = (pfn % bits_per_buf) / CHAR_BIT;
    bit = (pfn % bits_per_buf) % CHAR_BIT;
    if (value) {
        buf[byte] |= 1u << bit;
    } else {
        buf[byte] &= ~(1u << bit);
    }

    return 0;
}

static uint64_t dump_paddr_to_pfn(DumpState *s, uint64_t addr)
{
    int target_page_shift = ctz32(s->dump_info.page_size);

    return (addr >> target_page_shift) - ARCH_PFN_OFFSET;
}

static uint64_t dump_pfn_to_paddr(DumpState *s, uint64_t pfn)
{
    int target_page_shift = ctz32(s->dump_info.page_size);

    return (pfn + ARCH_PFN_OFFSET) << target_page_shift;
}

/*
 * Return the page frame number and the page content in *bufptr. bufptr can be
 * NULL. If not NULL, *bufptr must contains a target page size of pre-allocated
 * memory. This is not necessarily the memory returned.
 */
static bool get_next_page(GuestPhysBlock **blockptr, uint64_t *pfnptr,
                          uint8_t **bufptr, DumpState *s)
{
    GuestPhysBlock *block = *blockptr;
    uint32_t page_size = s->dump_info.page_size;
    uint8_t *buf = NULL, *hbuf;
    hwaddr addr;

    /* block == NULL means the start of the iteration */
    if (!block) {
        block = QTAILQ_FIRST(&s->guest_phys_blocks.head);
        *blockptr = block;
        addr = block->target_start;
        *pfnptr = dump_paddr_to_pfn(s, addr);
    } else {
        *pfnptr += 1;
        addr = dump_pfn_to_paddr(s, *pfnptr);
    }
    assert(block != NULL);

    while (1) {
        if (addr >= block->target_start && addr < block->target_end) {
            size_t n = MIN(block->target_end - addr, page_size - addr % page_size);
            hbuf = block->host_addr + (addr - block->target_start);
            if (!buf) {
                if (n == page_size) {
                    /* this is a whole target page, go for it */
                    assert(addr % page_size == 0);
                    buf = hbuf;
                    break;
                } else if (bufptr) {
                    assert(*bufptr);
                    buf = *bufptr;
                    memset(buf, 0, page_size);
                } else {
                    return true;
                }
            }

            memcpy(buf + addr % page_size, hbuf, n);
            addr += n;
            if (addr % page_size == 0) {
                /* we filled up the page */
                break;
            }
        } else {
            /* the next page is in the next block */
            *blockptr = block = QTAILQ_NEXT(block, next);
            if (!block) {
                break;
            }

            addr = block->target_start;
            /* are we still in the same page? */
            if (dump_paddr_to_pfn(s, addr) != *pfnptr) {
                if (buf) {
                    /* no, but we already filled something earlier, return it */
                    break;
                } else {
                    /* else continue from there */
                    *pfnptr = dump_paddr_to_pfn(s, addr);
                }
            }
        }
    }

    if (bufptr) {
        *bufptr = buf;
    }

    return buf != NULL;
}

static void write_dump_bitmap(DumpState *s, Error **errp)
{
    int ret = 0;
    uint64_t last_pfn, pfn;
    void *dump_bitmap_buf;
    size_t num_dumpable;
    GuestPhysBlock *block_iter = NULL;
    size_t bitmap_bufsize = dump_bitmap_get_bufsize(s);
    size_t bits_per_buf = bitmap_bufsize * CHAR_BIT;

    /* dump_bitmap_buf is used to store dump_bitmap temporarily */
    dump_bitmap_buf = g_malloc0(bitmap_bufsize);

    num_dumpable = 0;
    last_pfn = 0;

    /*
     * exam memory page by page, and set the bit in dump_bitmap corresponded
     * to the existing page.
     */
    while (get_next_page(&block_iter, &pfn, NULL, s)) {
        ret = set_dump_bitmap(last_pfn, pfn, true, dump_bitmap_buf, s);
        if (ret < 0) {
            error_setg(errp, "dump: failed to set dump_bitmap");
            goto out;
        }

        last_pfn = pfn;
        num_dumpable++;
    }

    /*
     * set_dump_bitmap will always leave the recently set bit un-sync. Here we
     * set the remaining bits from last_pfn to the end of the bitmap buffer to
     * 0. With those set, the un-sync bit will be synchronized into the vmcore.
     */
    if (num_dumpable > 0) {
        ret = set_dump_bitmap(last_pfn, last_pfn + bits_per_buf, false,
                              dump_bitmap_buf, s);
        if (ret < 0) {
            error_setg(errp, "dump: failed to sync dump_bitmap");
            goto out;
        }
    }

    /* number of dumpable pages that will be dumped later */
    s->num_dumpable = num_dumpable;

out:
    g_free(dump_bitmap_buf);
}

static void prepare_data_cache(DataCache *data_cache, DumpState *s,
                               off_t offset)
{
    data_cache->fd = s->fd;
    data_cache->data_size = 0;
    data_cache->buf_size = 4 * dump_bitmap_get_bufsize(s);
    data_cache->buf = g_malloc0(data_cache->buf_size);
    data_cache->offset = offset;
}

static int write_cache(DataCache *dc, const void *buf, size_t size,
                       bool flag_sync)
{
    /*
     * dc->buf_size should not be less than size, otherwise dc will never be
     * enough
     */
    assert(size <= dc->buf_size);

    /*
     * if flag_sync is set, synchronize data in dc->buf into vmcore.
     * otherwise check if the space is enough for caching data in buf, if not,
     * write the data in dc->buf to dc->fd and reset dc->buf
     */
    if ((!flag_sync && dc->data_size + size > dc->buf_size) ||
        (flag_sync && dc->data_size > 0)) {
        if (write_buffer(dc->fd, dc->offset, dc->buf, dc->data_size) < 0) {
            return -1;
        }

        dc->offset += dc->data_size;
        dc->data_size = 0;
    }

    if (!flag_sync) {
        memcpy(dc->buf + dc->data_size, buf, size);
        dc->data_size += size;
    }

    return 0;
}

static void free_data_cache(DataCache *data_cache)
{
    g_free(data_cache->buf);
}

static size_t get_len_buf_out(size_t page_size, uint32_t flag_compress)
{
    switch (flag_compress) {
    case DUMP_DH_COMPRESSED_ZLIB:
        return compressBound(page_size);

    case DUMP_DH_COMPRESSED_LZO:
        /*
         * LZO will expand incompressible data by a little amount. Please check
         * the following URL to see the expansion calculation:
         * http://www.oberhumer.com/opensource/lzo/lzofaq.php
         */
        return page_size + page_size / 16 + 64 + 3;

#ifdef CONFIG_SNAPPY
    case DUMP_DH_COMPRESSED_SNAPPY:
        return snappy_max_compressed_length(page_size);
#endif
    }
    return 0;
}

static void write_dump_pages(DumpState *s, Error **errp)
{
    int ret = 0;
    DataCache page_desc, page_data;
    size_t len_buf_out, size_out;
#ifdef CONFIG_LZO
    lzo_bytep wrkmem = NULL;
#endif
    uint8_t *buf_out = NULL;
    off_t offset_desc, offset_data;
    PageDescriptor pd, pd_zero;
    uint8_t *buf;
    GuestPhysBlock *block_iter = NULL;
    uint64_t pfn_iter;
    g_autofree uint8_t *page = NULL;

    /* get offset of page_desc and page_data in dump file */
    offset_desc = s->offset_page;
    offset_data = offset_desc + sizeof(PageDescriptor) * s->num_dumpable;

    prepare_data_cache(&page_desc, s, offset_desc);
    prepare_data_cache(&page_data, s, offset_data);

    /* prepare buffer to store compressed data */
    len_buf_out = get_len_buf_out(s->dump_info.page_size, s->flag_compress);
    assert(len_buf_out != 0);

#ifdef CONFIG_LZO
    wrkmem = g_malloc(LZO1X_1_MEM_COMPRESS);
#endif

    buf_out = g_malloc(len_buf_out);

    /*
     * init zero page's page_desc and page_data, because every zero page
     * uses the same page_data
     */
    pd_zero.size = cpu_to_dump32(s, s->dump_info.page_size);
    pd_zero.flags = cpu_to_dump32(s, 0);
    pd_zero.offset = cpu_to_dump64(s, offset_data);
    pd_zero.page_flags = cpu_to_dump64(s, 0);
    buf = g_malloc0(s->dump_info.page_size);
    ret = write_cache(&page_data, buf, s->dump_info.page_size, false);
    g_free(buf);
    if (ret < 0) {
        error_setg(errp, "dump: failed to write page data (zero page)");
        goto out;
    }

    offset_data += s->dump_info.page_size;
    page = g_malloc(s->dump_info.page_size);

    /*
     * dump memory to vmcore page by page. zero page will all be resided in the
     * first page of page section
     */
    for (buf = page; get_next_page(&block_iter, &pfn_iter, &buf, s); buf = page) {
        /* check zero page */
        if (buffer_is_zero(buf, s->dump_info.page_size)) {
            ret = write_cache(&page_desc, &pd_zero, sizeof(PageDescriptor),
                              false);
            if (ret < 0) {
                error_setg(errp, "dump: failed to write page desc");
                goto out;
            }
        } else {
            /*
             * not zero page, then:
             * 1. compress the page
             * 2. write the compressed page into the cache of page_data
             * 3. get page desc of the compressed page and write it into the
             *    cache of page_desc
             *
             * only one compression format will be used here, for
             * s->flag_compress is set. But when compression fails to work,
             * we fall back to save in plaintext.
             */
             size_out = len_buf_out;
             if ((s->flag_compress & DUMP_DH_COMPRESSED_ZLIB) &&
                    (compress2(buf_out, (uLongf *)&size_out, buf,
                               s->dump_info.page_size, Z_BEST_SPEED) == Z_OK) &&
                    (size_out < s->dump_info.page_size)) {
                pd.flags = cpu_to_dump32(s, DUMP_DH_COMPRESSED_ZLIB);
                pd.size  = cpu_to_dump32(s, size_out);

                ret = write_cache(&page_data, buf_out, size_out, false);
                if (ret < 0) {
                    error_setg(errp, "dump: failed to write page data");
                    goto out;
                }
#ifdef CONFIG_LZO
            } else if ((s->flag_compress & DUMP_DH_COMPRESSED_LZO) &&
                    (lzo1x_1_compress(buf, s->dump_info.page_size, buf_out,
                    (lzo_uint *)&size_out, wrkmem) == LZO_E_OK) &&
                    (size_out < s->dump_info.page_size)) {
                pd.flags = cpu_to_dump32(s, DUMP_DH_COMPRESSED_LZO);
                pd.size  = cpu_to_dump32(s, size_out);

                ret = write_cache(&page_data, buf_out, size_out, false);
                if (ret < 0) {
                    error_setg(errp, "dump: failed to write page data");
                    goto out;
                }
#endif
#ifdef CONFIG_SNAPPY
            } else if ((s->flag_compress & DUMP_DH_COMPRESSED_SNAPPY) &&
                    (snappy_compress((char *)buf, s->dump_info.page_size,
                    (char *)buf_out, &size_out) == SNAPPY_OK) &&
                    (size_out < s->dump_info.page_size)) {
                pd.flags = cpu_to_dump32(s, DUMP_DH_COMPRESSED_SNAPPY);
                pd.size  = cpu_to_dump32(s, size_out);

                ret = write_cache(&page_data, buf_out, size_out, false);
                if (ret < 0) {
                    error_setg(errp, "dump: failed to write page data");
                    goto out;
                }
#endif
            } else {
                /*
                 * fall back to save in plaintext, size_out should be
                 * assigned the target's page size
                 */
                pd.flags = cpu_to_dump32(s, 0);
                size_out = s->dump_info.page_size;
                pd.size = cpu_to_dump32(s, size_out);

                ret = write_cache(&page_data, buf,
                                  s->dump_info.page_size, false);
                if (ret < 0) {
                    error_setg(errp, "dump: failed to write page data");
                    goto out;
                }
            }

            /* get and write page desc here */
            pd.page_flags = cpu_to_dump64(s, 0);
            pd.offset = cpu_to_dump64(s, offset_data);
            offset_data += size_out;

            ret = write_cache(&page_desc, &pd, sizeof(PageDescriptor), false);
            if (ret < 0) {
                error_setg(errp, "dump: failed to write page desc");
                goto out;
            }
        }
        s->written_size += s->dump_info.page_size;
    }

    ret = write_cache(&page_desc, NULL, 0, true);
    if (ret < 0) {
        error_setg(errp, "dump: failed to sync cache for page_desc");
        goto out;
    }
    ret = write_cache(&page_data, NULL, 0, true);
    if (ret < 0) {
        error_setg(errp, "dump: failed to sync cache for page_data");
        goto out;
    }

out:
    free_data_cache(&page_desc);
    free_data_cache(&page_data);

#ifdef CONFIG_LZO
    g_free(wrkmem);
#endif

    g_free(buf_out);
}

static void create_kdump_vmcore(DumpState *s, Error **errp)
{
    ERRP_GUARD();
    int ret;

    /*
     * the kdump-compressed format is:
     *                                               File offset
     *  +------------------------------------------+ 0x0
     *  |    main header (struct disk_dump_header) |
     *  |------------------------------------------+ block 1
     *  |    sub header (struct kdump_sub_header)  |
     *  |------------------------------------------+ block 2
     *  |            1st-dump_bitmap               |
     *  |------------------------------------------+ block 2 + X blocks
     *  |            2nd-dump_bitmap               | (aligned by block)
     *  |------------------------------------------+ block 2 + 2 * X blocks
     *  |  page desc for pfn 0 (struct page_desc)  | (aligned by block)
     *  |  page desc for pfn 1 (struct page_desc)  |
     *  |                    :                     |
     *  |------------------------------------------| (not aligned by block)
     *  |         page data (pfn 0)                |
     *  |         page data (pfn 1)                |
     *  |                    :                     |
     *  +------------------------------------------+
     */

    ret = write_start_flat_header(s->fd);
    if (ret < 0) {
        error_setg(errp, "dump: failed to write start flat header");
        return;
    }

    write_dump_header(s, errp);
    if (*errp) {
        return;
    }

    write_dump_bitmap(s, errp);
    if (*errp) {
        return;
    }

    write_dump_pages(s, errp);
    if (*errp) {
        return;
    }

    ret = write_end_flat_header(s->fd);
    if (ret < 0) {
        error_setg(errp, "dump: failed to write end flat header");
        return;
    }
}

static int validate_start_block(DumpState *s)
{
    GuestPhysBlock *block;

    if (!dump_has_filter(s)) {
        return 0;
    }

    QTAILQ_FOREACH(block, &s->guest_phys_blocks.head, next) {
        /* This block is out of the range */
        if (block->target_start >= s->filter_area_begin + s->filter_area_length ||
            block->target_end <= s->filter_area_begin) {
            continue;
        }
        return 0;
   }

    return -1;
}

static void get_max_mapnr(DumpState *s)
{
    GuestPhysBlock *last_block;

    last_block = QTAILQ_LAST(&s->guest_phys_blocks.head);
    s->max_mapnr = dump_paddr_to_pfn(s, last_block->target_end);
}

static DumpState dump_state_global = { .status = DUMP_STATUS_NONE };

static void dump_state_prepare(DumpState *s)
{
    /* zero the struct, setting status to active */
    *s = (DumpState) { .status = DUMP_STATUS_ACTIVE };
}

bool qemu_system_dump_in_progress(void)
{
    DumpState *state = &dump_state_global;
    return (qatomic_read(&state->status) == DUMP_STATUS_ACTIVE);
}

/*
 * calculate total size of memory to be dumped (taking filter into
 * account.)
 */
static int64_t dump_calculate_size(DumpState *s)
{
    GuestPhysBlock *block;
    int64_t total = 0;

    QTAILQ_FOREACH(block, &s->guest_phys_blocks.head, next) {
        total += dump_filtered_memblock_size(block,
                                             s->filter_area_begin,
                                             s->filter_area_length);
    }

    return total;
}

static void vmcoreinfo_update_phys_base(DumpState *s)
{
    uint64_t size, note_head_size, name_size, phys_base;
    char **lines;
    uint8_t *vmci;
    size_t i;

    if (!note_name_equal(s, s->guest_note, "VMCOREINFO")) {
        return;
    }

    get_note_sizes(s, s->guest_note, &note_head_size, &name_size, &size);
    note_head_size = ROUND_UP(note_head_size, 4);

    vmci = s->guest_note + note_head_size + ROUND_UP(name_size, 4);
    *(vmci + size) = '\0';

    lines = g_strsplit((char *)vmci, "\n", -1);
    for (i = 0; lines[i]; i++) {
        const char *prefix = NULL;

        if (s->dump_info.d_machine == EM_X86_64) {
            prefix = "NUMBER(phys_base)=";
        } else if (s->dump_info.d_machine == EM_AARCH64) {
            prefix = "NUMBER(PHYS_OFFSET)=";
        }

        if (prefix && g_str_has_prefix(lines[i], prefix)) {
            if (qemu_strtou64(lines[i] + strlen(prefix), NULL, 16,
                              &phys_base) < 0) {
                warn_report("Failed to read %s", prefix);
            } else {
                s->dump_info.phys_base = phys_base;
            }
            break;
        }
    }

    g_strfreev(lines);
}

static void dump_init(DumpState *s, int fd, bool has_format,
                      DumpGuestMemoryFormat format, bool paging, bool has_filter,
                      int64_t begin, int64_t length, Error **errp)
{
    ERRP_GUARD();
    VMCoreInfoState *vmci = vmcoreinfo_find();
    CPUState *cpu;
    int nr_cpus;
    int ret;

    s->has_format = has_format;
    s->format = format;
    s->written_size = 0;

    /* kdump-compressed is conflict with paging and filter */
    if (has_format && format != DUMP_GUEST_MEMORY_FORMAT_ELF) {
        assert(!paging && !has_filter);
    }

    if (runstate_is_running()) {
        vm_stop(RUN_STATE_SAVE_VM);
        s->resume = true;
    } else {
        s->resume = false;
    }

    /* If we use KVM, we should synchronize the registers before we get dump
     * info or physmap info.
     */
    cpu_synchronize_all_states();
    nr_cpus = 0;
    CPU_FOREACH(cpu) {
        nr_cpus++;
    }

    s->fd = fd;
    if (has_filter && !length) {
        error_setg(errp, QERR_INVALID_PARAMETER, "length");
        goto cleanup;
    }
    s->filter_area_begin = begin;
    s->filter_area_length = length;

    /* First index is 0, it's the special null name */
    s->string_table_buf = g_array_new(FALSE, TRUE, 1);
    /*
     * Allocate the null name, due to the clearing option set to true
     * it will be 0.
     */
    g_array_set_size(s->string_table_buf, 1);

    memory_mapping_list_init(&s->list);

    guest_phys_blocks_init(&s->guest_phys_blocks);
    guest_phys_blocks_append(&s->guest_phys_blocks);
    s->total_size = dump_calculate_size(s);
#ifdef DEBUG_DUMP_GUEST_MEMORY
    fprintf(stderr, "DUMP: total memory to dump: %lu\n", s->total_size);
#endif

    /* it does not make sense to dump non-existent memory */
    if (!s->total_size) {
        error_setg(errp, "dump: no guest memory to dump");
        goto cleanup;
    }

    /* Is the filter filtering everything? */
    if (validate_start_block(s) == -1) {
        error_setg(errp, QERR_INVALID_PARAMETER, "begin");
        goto cleanup;
    }

    /* get dump info: endian, class and architecture.
     * If the target architecture is not supported, cpu_get_dump_info() will
     * return -1.
     */
    ret = cpu_get_dump_info(&s->dump_info, &s->guest_phys_blocks);
    if (ret < 0) {
        error_setg(errp,
                   "dumping guest memory is not supported on this target");
        goto cleanup;
    }

    if (!s->dump_info.page_size) {
        s->dump_info.page_size = qemu_target_page_size();
    }

    s->note_size = cpu_get_note_size(s->dump_info.d_class,
                                     s->dump_info.d_machine, nr_cpus);
    assert(s->note_size >= 0);

    /*
     * The goal of this block is to (a) update the previously guessed
     * phys_base, (b) copy the guest note out of the guest.
     * Failure to do so is not fatal for dumping.
     */
    if (vmci) {
        uint64_t addr, note_head_size, name_size, desc_size;
        uint32_t size;
        uint16_t format;

        note_head_size = dump_is_64bit(s) ?
            sizeof(Elf64_Nhdr) : sizeof(Elf32_Nhdr);

        format = le16_to_cpu(vmci->vmcoreinfo.guest_format);
        size = le32_to_cpu(vmci->vmcoreinfo.size);
        addr = le64_to_cpu(vmci->vmcoreinfo.paddr);
        if (!vmci->has_vmcoreinfo) {
            warn_report("guest note is not present");
        } else if (size < note_head_size || size > MAX_GUEST_NOTE_SIZE) {
            warn_report("guest note size is invalid: %" PRIu32, size);
        } else if (format != FW_CFG_VMCOREINFO_FORMAT_ELF) {
            warn_report("guest note format is unsupported: %" PRIu16, format);
        } else {
            s->guest_note = g_malloc(size + 1); /* +1 for adding \0 */
            cpu_physical_memory_read(addr, s->guest_note, size);

            get_note_sizes(s, s->guest_note, NULL, &name_size, &desc_size);
            s->guest_note_size = ELF_NOTE_SIZE(note_head_size, name_size,
                                               desc_size);
            if (name_size > MAX_GUEST_NOTE_SIZE ||
                desc_size > MAX_GUEST_NOTE_SIZE ||
                s->guest_note_size > size) {
                warn_report("Invalid guest note header");
                g_free(s->guest_note);
                s->guest_note = NULL;
            } else {
                vmcoreinfo_update_phys_base(s);
                s->note_size += s->guest_note_size;
            }
        }
    }

    /* get memory mapping */
    if (paging) {
        qemu_get_guest_memory_mapping(&s->list, &s->guest_phys_blocks, errp);
        if (*errp) {
            goto cleanup;
        }
    } else {
        qemu_get_guest_simple_memory_mapping(&s->list, &s->guest_phys_blocks);
    }

    s->nr_cpus = nr_cpus;

    get_max_mapnr(s);

    uint64_t tmp;
    tmp = DIV_ROUND_UP(DIV_ROUND_UP(s->max_mapnr, CHAR_BIT),
                       s->dump_info.page_size);
    s->len_dump_bitmap = tmp * s->dump_info.page_size;

    /* init for kdump-compressed format */
    if (has_format && format != DUMP_GUEST_MEMORY_FORMAT_ELF) {
        switch (format) {
        case DUMP_GUEST_MEMORY_FORMAT_KDUMP_ZLIB:
            s->flag_compress = DUMP_DH_COMPRESSED_ZLIB;
            break;

        case DUMP_GUEST_MEMORY_FORMAT_KDUMP_LZO:
#ifdef CONFIG_LZO
            if (lzo_init() != LZO_E_OK) {
                error_setg(errp, "failed to initialize the LZO library");
                goto cleanup;
            }
#endif
            s->flag_compress = DUMP_DH_COMPRESSED_LZO;
            break;

        case DUMP_GUEST_MEMORY_FORMAT_KDUMP_SNAPPY:
            s->flag_compress = DUMP_DH_COMPRESSED_SNAPPY;
            break;

        default:
            s->flag_compress = 0;
        }

        return;
    }

    if (dump_has_filter(s)) {
        memory_mapping_filter(&s->list, s->filter_area_begin, s->filter_area_length);
    }

    /*
     * The first section header is always a special one in which most
     * fields are 0. The section header string table is also always
     * set.
     */
    s->shdr_num = 2;

    /*
     * Adds the number of architecture sections to shdr_num and sets
     * elf_section_data_size so we know the offsets and sizes of all
     * parts.
     */
    if (s->dump_info.arch_sections_add_fn) {
        s->dump_info.arch_sections_add_fn(s);
    }

    /*
     * calculate shdr_num so we know the offsets and sizes of all
     * parts.
     * Calculate phdr_num
     *
     * The absolute maximum amount of phdrs is UINT32_MAX - 1 as
     * sh_info is 32 bit. There's special handling once we go over
     * UINT16_MAX - 1 but that is handled in the ehdr and section
     * code.
     */
    s->phdr_num = 1; /* Reserve PT_NOTE */
    if (s->list.num <= UINT32_MAX - 1) {
        s->phdr_num += s->list.num;
    } else {
        s->phdr_num = UINT32_MAX;
    }

    /*
     * Now that the number of section and program headers is known we
     * can calculate the offsets of the headers and data.
     */
    if (dump_is_64bit(s)) {
        s->shdr_offset = sizeof(Elf64_Ehdr);
        s->phdr_offset = s->shdr_offset + sizeof(Elf64_Shdr) * s->shdr_num;
        s->note_offset = s->phdr_offset + sizeof(Elf64_Phdr) * s->phdr_num;
    } else {
        s->shdr_offset = sizeof(Elf32_Ehdr);
        s->phdr_offset = s->shdr_offset + sizeof(Elf32_Shdr) * s->shdr_num;
        s->note_offset = s->phdr_offset + sizeof(Elf32_Phdr) * s->phdr_num;
    }
    s->memory_offset = s->note_offset + s->note_size;
    s->section_offset = s->memory_offset + s->total_size;

    return;

cleanup:
    dump_cleanup(s);
}

/* this operation might be time consuming. */
static void dump_process(DumpState *s, Error **errp)
{
    ERRP_GUARD();
    DumpQueryResult *result = NULL;

    if (s->has_format && s->format == DUMP_GUEST_MEMORY_FORMAT_WIN_DMP) {
        create_win_dump(s, errp);
    } else if (s->has_format && s->format != DUMP_GUEST_MEMORY_FORMAT_ELF) {
        create_kdump_vmcore(s, errp);
    } else {
        create_vmcore(s, errp);
    }

    /* make sure status is written after written_size updates */
    smp_wmb();
    qatomic_set(&s->status,
               (*errp ? DUMP_STATUS_FAILED : DUMP_STATUS_COMPLETED));

    /* send DUMP_COMPLETED message (unconditionally) */
    result = qmp_query_dump(NULL);
    /* should never fail */
    assert(result);
    qapi_event_send_dump_completed(result,
                                   *errp ? error_get_pretty(*errp) : NULL);
    qapi_free_DumpQueryResult(result);

    dump_cleanup(s);
}

static void *dump_thread(void *data)
{
    DumpState *s = (DumpState *)data;
    dump_process(s, NULL);
    return NULL;
}

DumpQueryResult *qmp_query_dump(Error **errp)
{
    DumpQueryResult *result = g_new(DumpQueryResult, 1);
    DumpState *state = &dump_state_global;
    result->status = qatomic_read(&state->status);
    /* make sure we are reading status and written_size in order */
    smp_rmb();
    result->completed = state->written_size;
    result->total = state->total_size;
    return result;
}

void qmp_dump_guest_memory(bool paging, const char *file,
                           bool has_detach, bool detach,
                           bool has_begin, int64_t begin, bool has_length,
                           int64_t length, bool has_format,
                           DumpGuestMemoryFormat format, Error **errp)
{
    ERRP_GUARD();
    const char *p;
    int fd = -1;
    DumpState *s;
    bool detach_p = false;

    if (runstate_check(RUN_STATE_INMIGRATE)) {
        error_setg(errp, "Dump not allowed during incoming migration.");
        return;
    }

    /* if there is a dump in background, we should wait until the dump
     * finished */
    if (qemu_system_dump_in_progress()) {
        error_setg(errp, "There is a dump in process, please wait.");
        return;
    }

    /*
     * kdump-compressed format need the whole memory dumped, so paging or
     * filter is not supported here.
     */
    if ((has_format && format != DUMP_GUEST_MEMORY_FORMAT_ELF) &&
        (paging || has_begin || has_length)) {
        error_setg(errp, "kdump-compressed format doesn't support paging or "
                         "filter");
        return;
    }
    if (has_begin && !has_length) {
        error_setg(errp, QERR_MISSING_PARAMETER, "length");
        return;
    }
    if (!has_begin && has_length) {
        error_setg(errp, QERR_MISSING_PARAMETER, "begin");
        return;
    }
    if (has_detach) {
        detach_p = detach;
    }

    /* check whether lzo/snappy is supported */
#ifndef CONFIG_LZO
    if (has_format && format == DUMP_GUEST_MEMORY_FORMAT_KDUMP_LZO) {
        error_setg(errp, "kdump-lzo is not available now");
        return;
    }
#endif

#ifndef CONFIG_SNAPPY
    if (has_format && format == DUMP_GUEST_MEMORY_FORMAT_KDUMP_SNAPPY) {
        error_setg(errp, "kdump-snappy is not available now");
        return;
    }
#endif

    if (has_format && format == DUMP_GUEST_MEMORY_FORMAT_WIN_DMP
        && !win_dump_available(errp)) {
        return;
    }

#if !defined(WIN32)
    if (strstart(file, "fd:", &p)) {
        fd = monitor_get_fd(monitor_cur(), p, errp);
        if (fd == -1) {
            return;
        }
    }
#endif

    if  (strstart(file, "file:", &p)) {
        fd = qemu_open_old(p, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, S_IRUSR);
        if (fd < 0) {
            error_setg_file_open(errp, errno, p);
            return;
        }
    }

    if (fd == -1) {
        error_setg(errp, QERR_INVALID_PARAMETER, "protocol");
        return;
    }

    if (!dump_migration_blocker) {
        error_setg(&dump_migration_blocker,
                   "Live migration disabled: dump-guest-memory in progress");
    }

    /*
     * Allows even for -only-migratable, but forbid migration during the
     * process of dump guest memory.
     */
    if (migrate_add_blocker_internal(dump_migration_blocker, errp)) {
        /* Remember to release the fd before passing it over to dump state */
        close(fd);
        return;
    }

    s = &dump_state_global;
    dump_state_prepare(s);

    dump_init(s, fd, has_format, format, paging, has_begin,
              begin, length, errp);
    if (*errp) {
        qatomic_set(&s->status, DUMP_STATUS_FAILED);
        return;
    }

    if (detach_p) {
        /* detached dump */
        s->detached = true;
        qemu_thread_create(&s->dump_thread, "dump_thread", dump_thread,
                           s, QEMU_THREAD_DETACHED);
    } else {
        /* sync dump */
        dump_process(s, errp);
    }
}

DumpGuestMemoryCapability *qmp_query_dump_guest_memory_capability(Error **errp)
{
    DumpGuestMemoryCapability *cap =
                                  g_new0(DumpGuestMemoryCapability, 1);
    DumpGuestMemoryFormatList **tail = &cap->formats;

    /* elf is always available */
    QAPI_LIST_APPEND(tail, DUMP_GUEST_MEMORY_FORMAT_ELF);

    /* kdump-zlib is always available */
    QAPI_LIST_APPEND(tail, DUMP_GUEST_MEMORY_FORMAT_KDUMP_ZLIB);

    /* add new item if kdump-lzo is available */
#ifdef CONFIG_LZO
    QAPI_LIST_APPEND(tail, DUMP_GUEST_MEMORY_FORMAT_KDUMP_LZO);
#endif

    /* add new item if kdump-snappy is available */
#ifdef CONFIG_SNAPPY
    QAPI_LIST_APPEND(tail, DUMP_GUEST_MEMORY_FORMAT_KDUMP_SNAPPY);
#endif

    if (win_dump_available(NULL)) {
        QAPI_LIST_APPEND(tail, DUMP_GUEST_MEMORY_FORMAT_WIN_DMP);
    }

    return cap;
}
