qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 0/5] contrib: add elf2dmp tool
@ 2018-08-29 12:41 Viktor Prutyanov
  2018-08-29 12:41 ` [Qemu-devel] [PATCH 1/5] dump: move Windows dump structures definitions Viktor Prutyanov
                   ` (5 more replies)
  0 siblings, 6 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

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

-- 
2.7.4

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [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

end of thread, other threads:[~2018-09-14 15:22 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
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 ` [Qemu-devel] [PATCH 4/5] contrib/elf2dmp: add DMP file name as 2nd argument Viktor Prutyanov
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 ` [Qemu-devel] [PATCH 0/5] contrib: add elf2dmp tool Viktor Prutyanov
2018-09-14 15:22 ` Paolo Bonzini

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).