X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=dump.c;h=e99554628c9da5b6133ad0bc8530bf47bc088754;hb=6b7ac49d570c66754fad1b80cc200c7596d1facd;hp=669f715274d96fb9d81611a173e550397d332fe1;hpb=0c33659d09f4a8ab926846295538d6a67e8c2c63;p=mirror_qemu.git diff --git a/dump.c b/dump.c index 669f715274..e99554628c 100644 --- a/dump.c +++ b/dump.c @@ -12,6 +12,7 @@ */ #include "qemu/osdep.h" +#include "qemu-common.h" #include "qemu/cutils.h" #include "elf.h" #include "cpu.h" @@ -29,6 +30,10 @@ #include "qemu/error-report.h" #include "hw/misc/vmcoreinfo.h" +#ifdef TARGET_X86_64 +#include "win_dump.h" +#endif + #include #ifdef CONFIG_LZO #include @@ -188,7 +193,7 @@ static void write_elf64_load(DumpState *s, MemoryMapping *memory_mapping, 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_vaddr = cpu_to_dump64(s, memory_mapping->virt_addr) ?: phdr.p_paddr; assert(memory_mapping->length >= filesz); @@ -212,7 +217,8 @@ static void write_elf32_load(DumpState *s, MemoryMapping *memory_mapping, 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_vaddr = + cpu_to_dump32(s, memory_mapping->virt_addr) ?: phdr.p_paddr; assert(memory_mapping->length >= filesz); @@ -814,7 +820,7 @@ static void create_header32(DumpState *s, Error **errp) size = sizeof(DiskDumpHeader32); dh = g_malloc0(size); - strncpy(dh->signature, KDUMP_SIGNATURE, strlen(KDUMP_SIGNATURE)); + 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); @@ -926,7 +932,7 @@ static void create_header64(DumpState *s, Error **errp) size = sizeof(DiskDumpHeader64); dh = g_malloc0(size); - strncpy(dh->signature, KDUMP_SIGNATURE, strlen(KDUMP_SIGNATURE)); + 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); @@ -1553,7 +1559,7 @@ static void get_max_mapnr(DumpState *s) { GuestPhysBlock *last_block; - last_block = QTAILQ_LAST(&s->guest_phys_blocks.head, GuestPhysBlockHead); + last_block = QTAILQ_LAST(&s->guest_phys_blocks.head); s->max_mapnr = dump_paddr_to_pfn(s, last_block->target_end); } @@ -1738,7 +1744,7 @@ static void dump_init(DumpState *s, int fd, bool has_format, 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 != VMCOREINFO_FORMAT_ELF) { + } 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 */ @@ -1866,7 +1872,11 @@ static void dump_process(DumpState *s, Error **errp) Error *local_err = NULL; DumpQueryResult *result = NULL; - if (s->has_format && s->format != DUMP_GUEST_MEMORY_FORMAT_ELF) { + if (s->has_format && s->format == DUMP_GUEST_MEMORY_FORMAT_WIN_DMP) { +#ifdef TARGET_X86_64 + create_win_dump(s, &local_err); +#endif + } else if (s->has_format && s->format != DUMP_GUEST_MEMORY_FORMAT_ELF) { create_kdump_vmcore(s, &local_err); } else { create_vmcore(s, &local_err); @@ -1882,8 +1892,7 @@ static void dump_process(DumpState *s, Error **errp) /* should never fail */ assert(result); qapi_event_send_dump_completed(result, !!local_err, (local_err ? \ - error_get_pretty(local_err) : NULL), - &error_abort); + error_get_pretty(local_err) : NULL)); qapi_free_DumpQueryResult(result); error_propagate(errp, local_err); @@ -1970,6 +1979,13 @@ void qmp_dump_guest_memory(bool paging, const char *file, } #endif +#ifndef TARGET_X86_64 + if (has_format && format == DUMP_GUEST_MEMORY_FORMAT_WIN_DMP) { + error_setg(errp, "Windows dump is only available for x86-64"); + return; + } +#endif + #if !defined(WIN32) if (strstart(file, "fd:", &p)) { fd = monitor_get_fd(cur_mon, p, errp); @@ -2044,5 +2060,12 @@ DumpGuestMemoryCapability *qmp_query_dump_guest_memory_capability(Error **errp) item->value = DUMP_GUEST_MEMORY_FORMAT_KDUMP_SNAPPY; #endif + /* Windows dump is available only if target is x86_64 */ +#ifdef TARGET_X86_64 + item->next = g_malloc0(sizeof(DumpGuestMemoryFormatList)); + item = item->next; + item->value = DUMP_GUEST_MEMORY_FORMAT_WIN_DMP; +#endif + return cap; }