* [Qemu-devel] [PATCH 1/5] dump: move Windows dump structures definitions
2018-08-29 12:41 [Qemu-devel] [PATCH 0/5] contrib: add elf2dmp tool Viktor Prutyanov
@ 2018-08-29 12:41 ` Viktor Prutyanov
2018-08-29 12:41 ` [Qemu-devel] [PATCH 3/5] contrib/elf2dmp: improve paging root selection Viktor Prutyanov
` (4 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Viktor Prutyanov @ 2018-08-29 12:41 UTC (permalink / raw)
To: qemu-devel
Cc: marcandre.lureau, pbonzini, armbru, dgilbert, rkagan,
viktor.prutyanov, Viktor Prutyanov
This patch moves definitions of Windows dump structures to
include/qemu/win_dump_defs.h to keep create_win_dump() prototype separate.
Signed-off-by: Viktor Prutyanov <viktor.prutyanov@virtuozzo.com>
---
include/qemu/win_dump_defs.h | 179 +++++++++++++++++++++++++++++++++++++++++++
win_dump.h | 166 +--------------------------------------
2 files changed, 183 insertions(+), 162 deletions(-)
create mode 100644 include/qemu/win_dump_defs.h
diff --git a/include/qemu/win_dump_defs.h b/include/qemu/win_dump_defs.h
new file mode 100644
index 0000000..145096e
--- /dev/null
+++ b/include/qemu/win_dump_defs.h
@@ -0,0 +1,179 @@
+/*
+ * Windows crashdump definitions
+ *
+ * Copyright (c) 2018 Virtuozzo International GmbH
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef QEMU_WIN_DUMP_DEFS_H
+#define QEMU_WIN_DUMP_DEFS_H
+
+typedef struct WinDumpPhyMemRun64 {
+ uint64_t BasePage;
+ uint64_t PageCount;
+} QEMU_PACKED WinDumpPhyMemRun64;
+
+typedef struct WinDumpPhyMemDesc64 {
+ uint32_t NumberOfRuns;
+ uint32_t unused;
+ uint64_t NumberOfPages;
+ WinDumpPhyMemRun64 Run[43];
+} QEMU_PACKED WinDumpPhyMemDesc64;
+
+typedef struct WinDumpExceptionRecord {
+ uint32_t ExceptionCode;
+ uint32_t ExceptionFlags;
+ uint64_t ExceptionRecord;
+ uint64_t ExceptionAddress;
+ uint32_t NumberParameters;
+ uint32_t unused;
+ uint64_t ExceptionInformation[15];
+} QEMU_PACKED WinDumpExceptionRecord;
+
+typedef struct WinDumpHeader64 {
+ char Signature[4];
+ char ValidDump[4];
+ uint32_t MajorVersion;
+ uint32_t MinorVersion;
+ uint64_t DirectoryTableBase;
+ uint64_t PfnDatabase;
+ uint64_t PsLoadedModuleList;
+ uint64_t PsActiveProcessHead;
+ uint32_t MachineImageType;
+ uint32_t NumberProcessors;
+ union {
+ struct {
+ uint32_t BugcheckCode;
+ uint32_t unused0;
+ uint64_t BugcheckParameter1;
+ uint64_t BugcheckParameter2;
+ uint64_t BugcheckParameter3;
+ uint64_t BugcheckParameter4;
+ };
+ uint8_t BugcheckData[40];
+ };
+ uint8_t VersionUser[32];
+ uint64_t KdDebuggerDataBlock;
+ union {
+ WinDumpPhyMemDesc64 PhysicalMemoryBlock;
+ uint8_t PhysicalMemoryBlockBuffer[704];
+ };
+ union {
+ uint8_t ContextBuffer[3000];
+ };
+ WinDumpExceptionRecord Exception;
+ uint32_t DumpType;
+ uint32_t unused1;
+ uint64_t RequiredDumpSpace;
+ uint64_t SystemTime;
+ char Comment[128];
+ uint64_t SystemUpTime;
+ uint32_t MiniDumpFields;
+ uint32_t SecondaryDataState;
+ uint32_t ProductType;
+ uint32_t SuiteMask;
+ uint32_t WriterStatus;
+ uint8_t unused2;
+ uint8_t KdSecondaryVersion;
+ uint8_t reserved[4018];
+} QEMU_PACKED WinDumpHeader64;
+
+#define KDBG_OWNER_TAG_OFFSET64 0x10
+#define KDBG_MM_PFN_DATABASE_OFFSET64 0xC0
+#define KDBG_KI_BUGCHECK_DATA_OFFSET64 0x88
+#define KDBG_KI_PROCESSOR_BLOCK_OFFSET64 0x218
+#define KDBG_OFFSET_PRCB_CONTEXT_OFFSET64 0x338
+
+#define VMCOREINFO_ELF_NOTE_HDR_SIZE 24
+
+#define WIN_CTX_X64 0x00100000L
+
+#define WIN_CTX_CTL 0x00000001L
+#define WIN_CTX_INT 0x00000002L
+#define WIN_CTX_SEG 0x00000004L
+#define WIN_CTX_FP 0x00000008L
+#define WIN_CTX_DBG 0x00000010L
+
+#define WIN_CTX_FULL (WIN_CTX_X64 | WIN_CTX_CTL | WIN_CTX_INT | WIN_CTX_FP)
+#define WIN_CTX_ALL (WIN_CTX_FULL | WIN_CTX_SEG | WIN_CTX_DBG)
+
+#define LIVE_SYSTEM_DUMP 0x00000161
+
+typedef struct WinM128A {
+ uint64_t low;
+ int64_t high;
+} QEMU_ALIGNED(16) WinM128A;
+
+typedef struct WinContext {
+ uint64_t PHome[6];
+
+ uint32_t ContextFlags;
+ uint32_t MxCsr;
+
+ uint16_t SegCs;
+ uint16_t SegDs;
+ uint16_t SegEs;
+ uint16_t SegFs;
+ uint16_t SegGs;
+ uint16_t SegSs;
+ uint32_t EFlags;
+
+ uint64_t Dr0;
+ uint64_t Dr1;
+ uint64_t Dr2;
+ uint64_t Dr3;
+ uint64_t Dr6;
+ uint64_t Dr7;
+
+ uint64_t Rax;
+ uint64_t Rcx;
+ uint64_t Rdx;
+ uint64_t Rbx;
+ uint64_t Rsp;
+ uint64_t Rbp;
+ uint64_t Rsi;
+ uint64_t Rdi;
+ uint64_t R8;
+ uint64_t R9;
+ uint64_t R10;
+ uint64_t R11;
+ uint64_t R12;
+ uint64_t R13;
+ uint64_t R14;
+ uint64_t R15;
+
+ uint64_t Rip;
+
+ struct {
+ uint16_t ControlWord;
+ uint16_t StatusWord;
+ uint8_t TagWord;
+ uint8_t Reserved1;
+ uint16_t ErrorOpcode;
+ uint32_t ErrorOffset;
+ uint16_t ErrorSelector;
+ uint16_t Reserved2;
+ uint32_t DataOffset;
+ uint16_t DataSelector;
+ uint16_t Reserved3;
+ uint32_t MxCsr;
+ uint32_t MxCsr_Mask;
+ WinM128A FloatRegisters[8];
+ WinM128A XmmRegisters[16];
+ uint8_t Reserved4[96];
+ } FltSave;
+
+ WinM128A VectorRegister[26];
+ uint64_t VectorControl;
+
+ uint64_t DebugControl;
+ uint64_t LastBranchToRip;
+ uint64_t LastBranchFromRip;
+ uint64_t LastExceptionToRip;
+ uint64_t LastExceptionFromRip;
+} QEMU_ALIGNED(16) WinContext;
+
+#endif /* QEMU_WIN_DUMP_DEFS_H */
diff --git a/win_dump.h b/win_dump.h
index f9e1faf..b8c2534 100644
--- a/win_dump.h
+++ b/win_dump.h
@@ -8,169 +8,11 @@
*
*/
-typedef struct WinDumpPhyMemRun64 {
- uint64_t BasePage;
- uint64_t PageCount;
-} QEMU_PACKED WinDumpPhyMemRun64;
+#ifndef WIN_DUMP_H
+#define WIN_DUMP_H
-typedef struct WinDumpPhyMemDesc64 {
- uint32_t NumberOfRuns;
- uint32_t unused;
- uint64_t NumberOfPages;
- WinDumpPhyMemRun64 Run[43];
-} QEMU_PACKED WinDumpPhyMemDesc64;
-
-typedef struct WinDumpExceptionRecord {
- uint32_t ExceptionCode;
- uint32_t ExceptionFlags;
- uint64_t ExceptionRecord;
- uint64_t ExceptionAddress;
- uint32_t NumberParameters;
- uint32_t unused;
- uint64_t ExceptionInformation[15];
-} QEMU_PACKED WinDumpExceptionRecord;
-
-typedef struct WinDumpHeader64 {
- char Signature[4];
- char ValidDump[4];
- uint32_t MajorVersion;
- uint32_t MinorVersion;
- uint64_t DirectoryTableBase;
- uint64_t PfnDatabase;
- uint64_t PsLoadedModuleList;
- uint64_t PsActiveProcessHead;
- uint32_t MachineImageType;
- uint32_t NumberProcessors;
- union {
- struct {
- uint32_t BugcheckCode;
- uint32_t unused0;
- uint64_t BugcheckParameter1;
- uint64_t BugcheckParameter2;
- uint64_t BugcheckParameter3;
- uint64_t BugcheckParameter4;
- };
- uint8_t BugcheckData[40];
- };
- uint8_t VersionUser[32];
- uint64_t KdDebuggerDataBlock;
- union {
- WinDumpPhyMemDesc64 PhysicalMemoryBlock;
- uint8_t PhysicalMemoryBlockBuffer[704];
- };
- union {
- uint8_t ContextBuffer[3000];
- };
- WinDumpExceptionRecord Exception;
- uint32_t DumpType;
- uint32_t unused1;
- uint64_t RequiredDumpSpace;
- uint64_t SystemTime;
- char Comment[128];
- uint64_t SystemUpTime;
- uint32_t MiniDumpFields;
- uint32_t SecondaryDataState;
- uint32_t ProductType;
- uint32_t SuiteMask;
- uint32_t WriterStatus;
- uint8_t unused2;
- uint8_t KdSecondaryVersion;
- uint8_t reserved[4018];
-} QEMU_PACKED WinDumpHeader64;
+#include "qemu/win_dump_defs.h"
void create_win_dump(DumpState *s, Error **errp);
-#define KDBG_OWNER_TAG_OFFSET64 0x10
-#define KDBG_MM_PFN_DATABASE_OFFSET64 0xC0
-#define KDBG_KI_BUGCHECK_DATA_OFFSET64 0x88
-#define KDBG_KI_PROCESSOR_BLOCK_OFFSET64 0x218
-#define KDBG_OFFSET_PRCB_CONTEXT_OFFSET64 0x338
-
-#define VMCOREINFO_ELF_NOTE_HDR_SIZE 24
-
-#define WIN_CTX_X64 0x00100000L
-
-#define WIN_CTX_CTL 0x00000001L
-#define WIN_CTX_INT 0x00000002L
-#define WIN_CTX_SEG 0x00000004L
-#define WIN_CTX_FP 0x00000008L
-#define WIN_CTX_DBG 0x00000010L
-
-#define WIN_CTX_FULL (WIN_CTX_X64 | WIN_CTX_CTL | WIN_CTX_INT | WIN_CTX_FP)
-#define WIN_CTX_ALL (WIN_CTX_FULL | WIN_CTX_SEG | WIN_CTX_DBG)
-
-#define LIVE_SYSTEM_DUMP 0x00000161
-
-typedef struct WinM128A {
- uint64_t low;
- int64_t high;
-} QEMU_ALIGNED(16) WinM128A;
-
-typedef struct WinContext {
- uint64_t PHome[6];
-
- uint32_t ContextFlags;
- uint32_t MxCsr;
-
- uint16_t SegCs;
- uint16_t SegDs;
- uint16_t SegEs;
- uint16_t SegFs;
- uint16_t SegGs;
- uint16_t SegSs;
- uint32_t EFlags;
-
- uint64_t Dr0;
- uint64_t Dr1;
- uint64_t Dr2;
- uint64_t Dr3;
- uint64_t Dr6;
- uint64_t Dr7;
-
- uint64_t Rax;
- uint64_t Rcx;
- uint64_t Rdx;
- uint64_t Rbx;
- uint64_t Rsp;
- uint64_t Rbp;
- uint64_t Rsi;
- uint64_t Rdi;
- uint64_t R8;
- uint64_t R9;
- uint64_t R10;
- uint64_t R11;
- uint64_t R12;
- uint64_t R13;
- uint64_t R14;
- uint64_t R15;
-
- uint64_t Rip;
-
- struct {
- uint16_t ControlWord;
- uint16_t StatusWord;
- uint8_t TagWord;
- uint8_t Reserved1;
- uint16_t ErrorOpcode;
- uint32_t ErrorOffset;
- uint16_t ErrorSelector;
- uint16_t Reserved2;
- uint32_t DataOffset;
- uint16_t DataSelector;
- uint16_t Reserved3;
- uint32_t MxCsr;
- uint32_t MxCsr_Mask;
- WinM128A FloatRegisters[8];
- WinM128A XmmRegisters[16];
- uint8_t Reserved4[96];
- } FltSave;
-
- WinM128A VectorRegister[26];
- uint64_t VectorControl;
-
- uint64_t DebugControl;
- uint64_t LastBranchToRip;
- uint64_t LastBranchFromRip;
- uint64_t LastExceptionToRip;
- uint64_t LastExceptionFromRip;
-} QEMU_ALIGNED(16) WinContext;
+#endif /* WIN_DUMP_H */
--
2.7.4
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [Qemu-devel] [PATCH 3/5] contrib/elf2dmp: improve paging root selection
2018-08-29 12:41 [Qemu-devel] [PATCH 0/5] contrib: add elf2dmp tool Viktor Prutyanov
2018-08-29 12:41 ` [Qemu-devel] [PATCH 1/5] dump: move Windows dump structures definitions Viktor Prutyanov
@ 2018-08-29 12:41 ` Viktor Prutyanov
2018-08-29 12:41 ` [Qemu-devel] [PATCH 4/5] contrib/elf2dmp: add DMP file name as 2nd argument Viktor Prutyanov
` (3 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Viktor Prutyanov @ 2018-08-29 12:41 UTC (permalink / raw)
To: qemu-devel
Cc: marcandre.lureau, pbonzini, armbru, dgilbert, rkagan,
viktor.prutyanov, Viktor Prutyanov
Even if KERNEL_GS_BASEs are absent in QEMU CPU states, there
is a chance to find suitable CR3 value from CPU which runs kernel task.
Signed-off-by: Viktor Prutyanov <viktor.prutyanov@virtuozzo.com>
---
contrib/elf2dmp/main.c | 56 +++++++++++++++++++++++++++++++++++++++-------
contrib/elf2dmp/qemu_elf.c | 16 +++++++++++--
contrib/elf2dmp/qemu_elf.h | 3 +++
3 files changed, 65 insertions(+), 10 deletions(-)
diff --git a/contrib/elf2dmp/main.c b/contrib/elf2dmp/main.c
index eb11e66..62f08e0 100644
--- a/contrib/elf2dmp/main.c
+++ b/contrib/elf2dmp/main.c
@@ -188,17 +188,53 @@ static void win_context_init_from_qemu_cpu_state(WinContext *ctx,
*ctx = win_ctx;
}
-static void fix_dtb(struct va_space *vs, QEMUCPUState *s)
+/*
+ * Finds paging-structure hierarchy base,
+ * if previously set doesn't give access to kernel structures
+ */
+static int fix_dtb(struct va_space *vs, QEMU_Elf *qe)
{
- uint64_t Prcb = (s->gs.base >> 63) ? s->gs.base : s->kernel_gs_base;
- void *prcb = va_space_resolve(vs, Prcb);
+ /*
+ * Firstly, test previously set DTB.
+ */
+ if (va_space_resolve(vs, SharedUserData)) {
+ return 0;
+ }
+
+ /*
+ * Secondly, find CPU which run system task.
+ */
+ for (size_t i = 0; i < qe->state_nr; i++) {
+ QEMUCPUState *s = qe->state[i];
- if (!prcb) {
- va_space_set_dtb(vs, *(uint64_t *)va_space_resolve(vs, Prcb + 0x7000));
+ if (is_system(s)) {
+ va_space_set_dtb(vs, s->cr[3]);
+ printf("DTB 0x%016lx has been found from CPU #%zu"
+ " as system task CR3\n", vs->dtb, i);
+ return !(va_space_resolve(vs, SharedUserData));
+ }
}
- assert(va_space_resolve(vs, Prcb));
- printf("DTB is 0x%016lx\n", vs->dtb);
+ /*
+ * Thirdly, use KERNEL_GS_BASE from CPU #0 as PRCB address and
+ * CR3 as [Prcb+0x7000]
+ */
+ if (qe->has_kernel_gs_base) {
+ QEMUCPUState *s = qe->state[0];
+ uint64_t Prcb = s->kernel_gs_base;
+ uint64_t *cr3 = va_space_resolve(vs, Prcb + 0x7000);
+
+ if (!cr3) {
+ return 1;
+ }
+
+ va_space_set_dtb(vs, *cr3);
+ printf("DirectoryTableBase = 0x%016lx has been found from CPU #0"
+ " as interrupt handling CR3\n", vs->dtb);
+ return !(va_space_resolve(vs, SharedUserData));
+ }
+
+ return 1;
}
static int fill_header(WinDumpHeader64 *hdr, struct pa_space *ps,
@@ -448,7 +484,11 @@ int main(int argc, char *argv[])
printf("CPU #0 CR3 is 0x%016lx\n", state->cr[3]);
va_space_create(&vs, &ps, state->cr[3]);
- fix_dtb(&vs, state);
+ if (fix_dtb(&vs, &qemu_elf)) {
+ eprintf("Failed to find paging base\n");
+ err = 1;
+ goto out_elf;
+ }
printf("CPU #0 IDT is at 0x%016lx\n", state->idt.base);
diff --git a/contrib/elf2dmp/qemu_elf.c b/contrib/elf2dmp/qemu_elf.c
index f7b5ebd..d139db2 100644
--- a/contrib/elf2dmp/qemu_elf.c
+++ b/contrib/elf2dmp/qemu_elf.c
@@ -33,6 +33,11 @@
DIV_ROUND_UP((name_size), 4) + \
DIV_ROUND_UP((desc_size), 4)) * 4)
+int is_system(QEMUCPUState *s)
+{
+ return s->gs.base >> 63;
+}
+
static char *nhdr_get_name(Elf64_Nhdr *nhdr)
{
return (char *)nhdr + ROUND_UP(sizeof(*nhdr), 4);
@@ -76,13 +81,20 @@ static int init_states(QEMU_Elf *qe)
return 1;
}
+ qe->has_kernel_gs_base = 1;
+
for (Elf64_Nhdr *nhdr = start; nhdr < end; nhdr = nhdr_get_next(nhdr)) {
if (!strcmp(nhdr_get_name(nhdr), QEMU_NOTE_NAME)) {
QEMUCPUState *state = nhdr_get_desc(nhdr);
if (state->size < sizeof(*state)) {
- eprintf("QEMU CPU state size %d doesn't match\n", state->size);
- return 1;
+ eprintf("CPU #%zu: QEMU CPU state size %u doesn't match\n",
+ cpu_nr, state->size);
+ /*
+ * We assume either every QEMU CPU state has KERNEL_GS_BASE or
+ * no one has.
+ */
+ qe->has_kernel_gs_base = 0;
}
cpu_nr++;
}
diff --git a/contrib/elf2dmp/qemu_elf.h b/contrib/elf2dmp/qemu_elf.h
index 2a28bb0..d85d655 100644
--- a/contrib/elf2dmp/qemu_elf.h
+++ b/contrib/elf2dmp/qemu_elf.h
@@ -31,12 +31,15 @@ typedef struct QEMUCPUState {
uint64_t kernel_gs_base;
} QEMUCPUState;
+int is_system(QEMUCPUState *s);
+
typedef struct QEMU_Elf {
int fd;
size_t size;
void *map;
QEMUCPUState **state;
size_t state_nr;
+ int has_kernel_gs_base;
} QEMU_Elf;
int QEMU_Elf_init(QEMU_Elf *qe, const char *filename);
--
2.7.4
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [Qemu-devel] [PATCH 4/5] contrib/elf2dmp: add DMP file name as 2nd argument
2018-08-29 12:41 [Qemu-devel] [PATCH 0/5] contrib: add elf2dmp tool Viktor Prutyanov
2018-08-29 12:41 ` [Qemu-devel] [PATCH 1/5] dump: move Windows dump structures definitions Viktor Prutyanov
2018-08-29 12:41 ` [Qemu-devel] [PATCH 3/5] contrib/elf2dmp: improve paging root selection Viktor Prutyanov
@ 2018-08-29 12:41 ` Viktor Prutyanov
2018-08-29 12:41 ` [Qemu-devel] [PATCH 5/5] contrib/elf2dmp: add 1GB and 2MB pages support Viktor Prutyanov
` (2 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Viktor Prutyanov @ 2018-08-29 12:41 UTC (permalink / raw)
To: qemu-devel
Cc: marcandre.lureau, pbonzini, armbru, dgilbert, rkagan,
viktor.prutyanov, Viktor Prutyanov
Before this patch output DMP file name was strictly 'memory.dmp'.
Signed-off-by: Viktor Prutyanov <viktor.prutyanov@virtuozzo.com>
---
contrib/elf2dmp/main.c | 34 +++++++++++++++++++++++-----------
1 file changed, 23 insertions(+), 11 deletions(-)
diff --git a/contrib/elf2dmp/main.c b/contrib/elf2dmp/main.c
index 62f08e0..64782fc 100644
--- a/contrib/elf2dmp/main.c
+++ b/contrib/elf2dmp/main.c
@@ -334,24 +334,36 @@ static int fill_context(KDDEBUGGER_DATA64 *kdbg,
return 0;
}
-static int write_dump(struct pa_space *ps, WinDumpHeader64 *hdr)
+static int write_dump(struct pa_space *ps,
+ WinDumpHeader64 *hdr, const char *name)
{
- FILE *dmp_file = fopen("memory.dmp", "wb");
+ FILE *dmp_file = fopen(name, "wb");
if (!dmp_file) {
+ eprintf("Failed to open output file \'%s\'\n", name);
return 1;
}
- printf("Writing down to file...\n");
- fwrite(hdr, sizeof(*hdr), 1, dmp_file);
+ printf("Writing header to file...\n");
- for (size_t i = 0; i < ps->block_nr; i++) {
- fwrite(ps->block[i].addr, ps->block[i].size, 1, dmp_file);
+ if (fwrite(hdr, sizeof(*hdr), 1, dmp_file) != 1) {
+ eprintf("Failed to write dump header\n");
+ fclose(dmp_file);
+ return 1;
}
- fclose(dmp_file);
+ for (size_t i = 0; i < ps->block_nr; i++) {
+ struct pa_block *b = &ps->block[i];
- return 0;
+ printf("Writing block #%zu/%zu to file...\n", i, ps->block_nr);
+ if (fwrite(b->addr, b->size, 1, dmp_file) != 1) {
+ eprintf("Failed to write dump header\n");
+ fclose(dmp_file);
+ return 1;
+ }
+ }
+
+ return fclose(dmp_file);
}
static int pe_get_pdb_symstore_hash(uint64_t base, void *start_addr,
@@ -464,8 +476,8 @@ int main(int argc, char *argv[])
KDDEBUGGER_DATA64 *kdbg;
uint64_t KdVersionBlock;
- if (argc != 2) {
- eprintf("usage:\n\t%s elf_dump\n", argv[0]);
+ if (argc != 3) {
+ eprintf("usage:\n\t%s elf_file dmp_file\n", argv[0]);
return 1;
}
@@ -561,7 +573,7 @@ int main(int argc, char *argv[])
goto out_pdb;
}
- if (write_dump(&ps, &header)) {
+ if (write_dump(&ps, &header, argv[2])) {
eprintf("Failed to save dump\n");
err = 1;
goto out_kdbg;
--
2.7.4
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [Qemu-devel] [PATCH 5/5] contrib/elf2dmp: add 1GB and 2MB pages support
2018-08-29 12:41 [Qemu-devel] [PATCH 0/5] contrib: add elf2dmp tool Viktor Prutyanov
` (2 preceding siblings ...)
2018-08-29 12:41 ` [Qemu-devel] [PATCH 4/5] contrib/elf2dmp: add DMP file name as 2nd argument Viktor Prutyanov
@ 2018-08-29 12:41 ` Viktor Prutyanov
2018-09-14 3:39 ` [Qemu-devel] [PATCH 0/5] contrib: add elf2dmp tool Viktor Prutyanov
2018-09-14 15:22 ` Paolo Bonzini
5 siblings, 0 replies; 7+ messages in thread
From: Viktor Prutyanov @ 2018-08-29 12:41 UTC (permalink / raw)
To: qemu-devel
Cc: marcandre.lureau, pbonzini, armbru, dgilbert, rkagan,
viktor.prutyanov, Viktor Prutyanov
After this patch 1GB and 2MB pages are being correctly processed during
virtual address resolving.
Signed-off-by: Viktor Prutyanov <viktor.prutyanov@virtuozzo.com>
---
contrib/elf2dmp/addrspace.c | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/contrib/elf2dmp/addrspace.c b/contrib/elf2dmp/addrspace.c
index 70f4271..f36e749 100644
--- a/contrib/elf2dmp/addrspace.c
+++ b/contrib/elf2dmp/addrspace.c
@@ -145,6 +145,21 @@ static bool is_present(uint64_t entry)
return entry & 0x1;
}
+static bool page_size_flag(uint64_t entry)
+{
+ return entry & (1 << 7);
+}
+
+static uint64_t get_1GB_paddr(uint64_t va, uint64_t pdpte)
+{
+ return (pdpte & 0xfffffc0000000) | (va & 0x3fffffff);
+}
+
+static uint64_t get_2MB_paddr(uint64_t va, uint64_t pgd_entry)
+{
+ return (pgd_entry & 0xfffffffe00000) | (va & 0x00000001fffff);
+}
+
static uint64_t va_space_va2pa(struct va_space *vs, uint64_t va)
{
uint64_t pml4e, pdpe, pgd, pte;
@@ -159,11 +174,19 @@ static uint64_t va_space_va2pa(struct va_space *vs, uint64_t va)
return INVALID_PA;
}
+ if (page_size_flag(pdpe)) {
+ return get_1GB_paddr(va, pdpe);
+ }
+
pgd = get_pgd(vs, va, pdpe);
if (!is_present(pgd)) {
return INVALID_PA;
}
+ if (page_size_flag(pgd)) {
+ return get_2MB_paddr(va, pgd);
+ }
+
pte = get_pte(vs, va, pgd);
if (!is_present(pte)) {
return INVALID_PA;
--
2.7.4
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [Qemu-devel] [PATCH 0/5] contrib: add elf2dmp tool
2018-08-29 12:41 [Qemu-devel] [PATCH 0/5] contrib: add elf2dmp tool Viktor Prutyanov
` (3 preceding siblings ...)
2018-08-29 12:41 ` [Qemu-devel] [PATCH 5/5] contrib/elf2dmp: add 1GB and 2MB pages support Viktor Prutyanov
@ 2018-09-14 3:39 ` Viktor Prutyanov
2018-09-14 15:22 ` Paolo Bonzini
5 siblings, 0 replies; 7+ messages in thread
From: Viktor Prutyanov @ 2018-09-14 3:39 UTC (permalink / raw)
To: qemu-devel; +Cc: marcandre.lureau, pbonzini, armbru, dgilbert, rkagan
В Wed, 29 Aug 2018 15:41:23 +0300
Viktor Prutyanov <viktor.prutyanov@virtuozzo.com> пишет:
> elf2dmp is a converter from ELF dump (produced by
> 'dump-guest-memory') to Windows MEMORY.DMP format (also know as
> 'Complete Memory Dump') which can be opened in WinDbg.
>
> This tool can help if VMCoreInfo device/driver is absent in Windows
> VM and 'dump-guest-memory -w' is not available but dump can be
> created in ELF format.
>
> elf2dmp differs from other universal converters in method of
> determining of virtual memory layout. The tool uses register values
> from QEMU ELF dump file to do it. In particular, it uses
> KERNEL_GS_BASE value added to dump format in QEMU 3.0.
>
> Even if KERNEL_GS_BASEs are absent in ELF dump file, at least 1 vCPU
> with kernel task can be found quite often and virtual memory layout
> can be determined.
>
> Viktor Prutyanov (5):
> dump: move Windows dump structures definitions
> contrib: add elf2dmp tool
> contrib/elf2dmp: improve paging root selection
> contrib/elf2dmp: add DMP file name as 2nd argument
> contrib/elf2dmp: add 1GB and 2MB pages support
>
> Makefile | 5 +
> Makefile.objs | 1 +
> configure | 3 +
> contrib/elf2dmp/Makefile.objs | 1 +
> contrib/elf2dmp/addrspace.c | 236 +++++++++++++++++
> contrib/elf2dmp/addrspace.h | 44 ++++
> contrib/elf2dmp/download.c | 50 ++++
> contrib/elf2dmp/download.h | 13 +
> contrib/elf2dmp/err.h | 13 +
> contrib/elf2dmp/kdbg.h | 194 ++++++++++++++
> contrib/elf2dmp/main.c | 594
> ++++++++++++++++++++++++++++++++++++++++++
> contrib/elf2dmp/pdb.c | 331 +++++++++++++++++++++++
> contrib/elf2dmp/pdb.h | 241 +++++++++++++++++
> contrib/elf2dmp/pe.h | 121 +++++++++
> contrib/elf2dmp/qemu_elf.c | 172 ++++++++++++
> contrib/elf2dmp/qemu_elf.h | 51 ++++
> include/qemu/win_dump_defs.h | 179 +++++++++++++
> win_dump.h | 166 +----------- 18 files changed,
> 2253 insertions(+), 162 deletions(-) create mode 100644
> contrib/elf2dmp/Makefile.objs create mode 100644
> contrib/elf2dmp/addrspace.c create mode 100644
> contrib/elf2dmp/addrspace.h create mode 100644
> contrib/elf2dmp/download.c create mode 100644
> contrib/elf2dmp/download.h create mode 100644 contrib/elf2dmp/err.h
> create mode 100644 contrib/elf2dmp/kdbg.h
> create mode 100644 contrib/elf2dmp/main.c
> create mode 100644 contrib/elf2dmp/pdb.c
> create mode 100644 contrib/elf2dmp/pdb.h
> create mode 100644 contrib/elf2dmp/pe.h
> create mode 100644 contrib/elf2dmp/qemu_elf.c
> create mode 100644 contrib/elf2dmp/qemu_elf.h
> create mode 100644 include/qemu/win_dump_defs.h
>
ping
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Qemu-devel] [PATCH 0/5] contrib: add elf2dmp tool
2018-08-29 12:41 [Qemu-devel] [PATCH 0/5] contrib: add elf2dmp tool Viktor Prutyanov
` (4 preceding siblings ...)
2018-09-14 3:39 ` [Qemu-devel] [PATCH 0/5] contrib: add elf2dmp tool Viktor Prutyanov
@ 2018-09-14 15:22 ` Paolo Bonzini
5 siblings, 0 replies; 7+ messages in thread
From: Paolo Bonzini @ 2018-09-14 15:22 UTC (permalink / raw)
To: Viktor Prutyanov, qemu-devel
Cc: marcandre.lureau, armbru, dgilbert, rkagan, viktor.prutyanov
On 29/08/2018 14:41, Viktor Prutyanov wrote:
> elf2dmp is a converter from ELF dump (produced by 'dump-guest-memory') to
> Windows MEMORY.DMP format (also know as 'Complete Memory Dump') which can be
> opened in WinDbg.
>
> This tool can help if VMCoreInfo device/driver is absent in Windows VM and
> 'dump-guest-memory -w' is not available but dump can be created in ELF format.
>
> elf2dmp differs from other universal converters in method of determining of
> virtual memory layout. The tool uses register values from QEMU ELF dump file
> to do it. In particular, it uses KERNEL_GS_BASE value added to dump format in
> QEMU 3.0.
>
> Even if KERNEL_GS_BASEs are absent in ELF dump file, at least 1 vCPU with
> kernel task can be found quite often and virtual memory layout can be
> determined.
>
> Viktor Prutyanov (5):
> dump: move Windows dump structures definitions
> contrib: add elf2dmp tool
> contrib/elf2dmp: improve paging root selection
> contrib/elf2dmp: add DMP file name as 2nd argument
> contrib/elf2dmp: add 1GB and 2MB pages support
>
> Makefile | 5 +
> Makefile.objs | 1 +
> configure | 3 +
> contrib/elf2dmp/Makefile.objs | 1 +
> contrib/elf2dmp/addrspace.c | 236 +++++++++++++++++
> contrib/elf2dmp/addrspace.h | 44 ++++
> contrib/elf2dmp/download.c | 50 ++++
> contrib/elf2dmp/download.h | 13 +
> contrib/elf2dmp/err.h | 13 +
> contrib/elf2dmp/kdbg.h | 194 ++++++++++++++
> contrib/elf2dmp/main.c | 594 ++++++++++++++++++++++++++++++++++++++++++
> contrib/elf2dmp/pdb.c | 331 +++++++++++++++++++++++
> contrib/elf2dmp/pdb.h | 241 +++++++++++++++++
> contrib/elf2dmp/pe.h | 121 +++++++++
> contrib/elf2dmp/qemu_elf.c | 172 ++++++++++++
> contrib/elf2dmp/qemu_elf.h | 51 ++++
> include/qemu/win_dump_defs.h | 179 +++++++++++++
> win_dump.h | 166 +-----------
> 18 files changed, 2253 insertions(+), 162 deletions(-)
> create mode 100644 contrib/elf2dmp/Makefile.objs
> create mode 100644 contrib/elf2dmp/addrspace.c
> create mode 100644 contrib/elf2dmp/addrspace.h
> create mode 100644 contrib/elf2dmp/download.c
> create mode 100644 contrib/elf2dmp/download.h
> create mode 100644 contrib/elf2dmp/err.h
> create mode 100644 contrib/elf2dmp/kdbg.h
> create mode 100644 contrib/elf2dmp/main.c
> create mode 100644 contrib/elf2dmp/pdb.c
> create mode 100644 contrib/elf2dmp/pdb.h
> create mode 100644 contrib/elf2dmp/pe.h
> create mode 100644 contrib/elf2dmp/qemu_elf.c
> create mode 100644 contrib/elf2dmp/qemu_elf.h
> create mode 100644 include/qemu/win_dump_defs.h
>
Queued, squashing patches 2-5. Would you like to send a patch for
MAINTAINERS, adding yourself for elf2dmp?
Paolo
^ permalink raw reply [flat|nested] 7+ messages in thread