>From a11545d9d273e115bdf257bb9e94709146b99727 Mon Sep 17 00:00:00 2001
From: qiaonuohan <qiaonuohan@cn.fujitsu.com>
Date: Sun, 22 Jul 2012 10:24:58 +0800
Subject: [PATCH 3/3] display registers stored in qemu note section

---
 netdump.c |  210 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 netdump.h |   22 +++++++
 2 files changed, 232 insertions(+), 0 deletions(-)

diff --git a/netdump.c b/netdump.c
index e3cc1ce..235bced 100644
--- a/netdump.c
+++ b/netdump.c
@@ -1690,12 +1690,14 @@ dump_Elf32_Nhdr(Elf32_Off offset, int store)
 	char *ptr;
 	ulong *uptr;
 	int xen_core, vmcoreinfo, eraseinfo;
+	int qemu_info;
 	uint64_t remaining, notesize;
 
 	note = (Elf32_Nhdr *)((char *)nd->elf32 + offset);
 
         BZERO(buf, BUFSIZE);
 	xen_core = vmcoreinfo = eraseinfo = FALSE;
+	qemu_info = FALSE;
         ptr = (char *)note + sizeof(Elf32_Nhdr);
 
 	if (ptr > (nd->elf_header + nd->header_size)) {
@@ -1786,6 +1788,7 @@ dump_Elf32_Nhdr(Elf32_Off offset, int store)
 		xen_core = STRNEQ(buf, "XEN CORE") || STRNEQ(buf, "Xen");
 		vmcoreinfo = STRNEQ(buf, "VMCOREINFO");
 		eraseinfo = STRNEQ(buf, "ERASEINFO");
+		qemu_info = STRNEQ(buf, "QEMU");
 		if (xen_core) {
 			netdump_print("(unknown Xen n_type)\n"); 
 			if (store)
@@ -1876,6 +1879,103 @@ dump_Elf32_Nhdr(Elf32_Off offset, int store)
 	if (xen_core)
 		uptr = (ulong *)roundup((ulong)uptr, 4);
 
+	if (CRASHDEBUG(1) & qemu_info) {
+		netdump_print("version:%08lx      size:%08lx\n",
+				((QEMUCPUState *)uptr)->version,
+				((QEMUCPUState *)uptr)->size);
+		netdump_print("rax:%016llx  rbx:%016llx  rcx:%016llx\n",
+				((QEMUCPUState *)uptr)->rax,
+				((QEMUCPUState *)uptr)->rbx,
+				((QEMUCPUState *)uptr)->rcx);
+		netdump_print("rdx:%016llx  rsi:%016llx  rdi:%016llx\n",
+				((QEMUCPUState *)uptr)->rdx,
+				((QEMUCPUState *)uptr)->rsi,
+				((QEMUCPUState *)uptr)->rdi);
+		netdump_print("rsp:%016llx  rbp:%016llx\n",
+				((QEMUCPUState *)uptr)->rsp,
+				((QEMUCPUState *)uptr)->rbp);
+		netdump_print("rip:%016llx  rflags:%016llx\n",
+				((QEMUCPUState *)uptr)->rip,
+				((QEMUCPUState *)uptr)->rflags);
+		netdump_print("cs:\n  selector:%08lx  limit:%08lx  flags:%08lx\n\
+  pad:%08lx  base:%016llx\n",
+				((QEMUCPUState *)uptr)->cs.selector,
+				((QEMUCPUState *)uptr)->cs.limit,
+				((QEMUCPUState *)uptr)->cs.flags,
+				((QEMUCPUState *)uptr)->cs.pad,
+				((QEMUCPUState *)uptr)->cs.base);
+		netdump_print("ds:\n  selector:%08lx  limit:%08lx  flags:%08lx\n\
+  pad:%08lx  base:%016llx\n",
+				((QEMUCPUState *)uptr)->ds.selector,
+				((QEMUCPUState *)uptr)->ds.limit,
+				((QEMUCPUState *)uptr)->ds.flags,
+				((QEMUCPUState *)uptr)->ds.pad,
+				((QEMUCPUState *)uptr)->ds.base);
+		netdump_print("es:\n  selector:%08lx  limit:%08lx  flags:%08lx\n\
+  pad:%08lx  base:%016llx\n",
+				((QEMUCPUState *)uptr)->es.selector,
+				((QEMUCPUState *)uptr)->es.limit,
+				((QEMUCPUState *)uptr)->es.flags,
+				((QEMUCPUState *)uptr)->es.pad,
+				((QEMUCPUState *)uptr)->es.base);
+		netdump_print("fs:\n  selector:%08lx  limit:%08lx  flags:%08lx\n\
+  pad:%08lx  base:%016llx\n",
+				((QEMUCPUState *)uptr)->fs.selector,
+				((QEMUCPUState *)uptr)->fs.limit,
+				((QEMUCPUState *)uptr)->fs.flags,
+				((QEMUCPUState *)uptr)->fs.pad,
+				((QEMUCPUState *)uptr)->fs.base);
+		netdump_print("gs:\n  selector:%08lx  limit:%08lx  flags:%08lx\n\
+  pad:%08lx  base:%016llx\n",
+				((QEMUCPUState *)uptr)->gs.selector,
+				((QEMUCPUState *)uptr)->gs.limit,
+				((QEMUCPUState *)uptr)->gs.flags,
+				((QEMUCPUState *)uptr)->gs.pad,
+				((QEMUCPUState *)uptr)->gs.base);
+		netdump_print("ss:\n  selector:%08lx  limit:%08lx  flags:%08lx\n\
+  pad:%08lx  base:%016llx\n",
+				((QEMUCPUState *)uptr)->ss.selector,
+				((QEMUCPUState *)uptr)->ss.limit,
+				((QEMUCPUState *)uptr)->ss.flags,
+				((QEMUCPUState *)uptr)->ss.pad,
+				((QEMUCPUState *)uptr)->ss.base);
+		netdump_print("ldt:\n  selector:%08lx  limit:%08lx  flags:%08lx\n\
+  pad:%08lx  base:%016llx\n",
+				((QEMUCPUState *)uptr)->ldt.selector,
+				((QEMUCPUState *)uptr)->ldt.limit,
+				((QEMUCPUState *)uptr)->ldt.flags,
+				((QEMUCPUState *)uptr)->ldt.pad,
+				((QEMUCPUState *)uptr)->ldt.base);
+		netdump_print("tr:\n  selector:%08lx  limit:%08lx  flags:%08lx\n\
+  pad:%08lx  base:%016llx\n",
+				((QEMUCPUState *)uptr)->tr.selector,
+				((QEMUCPUState *)uptr)->tr.limit,
+				((QEMUCPUState *)uptr)->tr.flags,
+				((QEMUCPUState *)uptr)->tr.pad,
+				((QEMUCPUState *)uptr)->tr.base);
+		netdump_print("gdt:\n  selector:%08lx  limit:%08lx  flags:%08lx\n\
+  pad:%08lx  base:%016llx\n",
+				((QEMUCPUState *)uptr)->gdt.selector,
+				((QEMUCPUState *)uptr)->gdt.limit,
+				((QEMUCPUState *)uptr)->gdt.flags,
+				((QEMUCPUState *)uptr)->gdt.pad,
+				((QEMUCPUState *)uptr)->gdt.base);
+		netdump_print("idt:\n  selector:%08lx  limit:%08lx  flags:%08lx\n\
+  pad:%08lx  base:%016llx\n",
+				((QEMUCPUState *)uptr)->idt.selector,
+				((QEMUCPUState *)uptr)->idt.limit,
+				((QEMUCPUState *)uptr)->idt.flags,
+				((QEMUCPUState *)uptr)->idt.pad,
+				((QEMUCPUState *)uptr)->idt.base);
+		netdump_print("cr[0]:%016llx  cr[1]:%016llx  cr[2]:%016llx\n",
+				((QEMUCPUState *)uptr)->cr[0],
+				((QEMUCPUState *)uptr)->cr[1],
+				((QEMUCPUState *)uptr)->cr[2]);
+		netdump_print("cr[3]:%016llx  cr[4]:%016llx\n",
+				((QEMUCPUState *)uptr)->cr[3],
+				((QEMUCPUState *)uptr)->cr[4]);
+	}
+
 	if (vmcoreinfo || eraseinfo) {
                 netdump_print("                         ");
                 ptr += note->n_namesz + 1;
@@ -1920,6 +2020,7 @@ dump_Elf64_Nhdr(Elf64_Off offset, int store)
 	int *iptr;
 	ulong *up;
 	int xen_core, vmcoreinfo, eraseinfo;
+	int qemu_info;
 	uint64_t remaining, notesize;
 
 	note = (Elf64_Nhdr *)((char *)nd->elf64 + offset);
@@ -1927,6 +2028,7 @@ dump_Elf64_Nhdr(Elf64_Off offset, int store)
         BZERO(buf, BUFSIZE);
         ptr = (char *)note + sizeof(Elf64_Nhdr);
 	xen_core = vmcoreinfo = eraseinfo = FALSE;
+	qemu_info = FALSE;
 
 	if (ptr > (nd->elf_header + nd->header_size)) {
 		error(WARNING, 
@@ -2047,6 +2149,7 @@ dump_Elf64_Nhdr(Elf64_Off offset, int store)
 		xen_core = STRNEQ(buf, "XEN CORE") || STRNEQ(buf, "Xen");
 		vmcoreinfo = STRNEQ(buf, "VMCOREINFO");
 		eraseinfo = STRNEQ(buf, "ERASEINFO");
+		qemu_info = STRNEQ(buf, "QEMU");
                 if (xen_core) {
                         netdump_print("(unknown Xen n_type)\n");
 			if (store)
@@ -2149,6 +2252,113 @@ dump_Elf64_Nhdr(Elf64_Off offset, int store)
 			uptr = (ulonglong *)roundup((ulong)uptr, 4);
 	}
 
+	if (CRASHDEBUG(1) & qemu_info) {
+		netdump_print("version:%08lx      size:%08lx\n",
+				((QEMUCPUState *)uptr)->version,
+				((QEMUCPUState *)uptr)->size);
+		netdump_print("rax:%016llx  rbx:%016llx  rcx:%016llx\n",
+				((QEMUCPUState *)uptr)->rax,
+				((QEMUCPUState *)uptr)->rbx,
+				((QEMUCPUState *)uptr)->rcx);
+		netdump_print("rdx:%016llx  rsi:%016llx  rdi:%016llx\n",
+				((QEMUCPUState *)uptr)->rdx,
+				((QEMUCPUState *)uptr)->rsi,
+				((QEMUCPUState *)uptr)->rdi);
+		netdump_print("rsp:%016llx  rbp:%016llx  r8:%016llx\n",
+				((QEMUCPUState *)uptr)->rsp,
+				((QEMUCPUState *)uptr)->rbp,
+				((QEMUCPUState *)uptr)->r8);
+		netdump_print("r9:%016llx   r10:%016llx  r11:%016llx\n",
+				((QEMUCPUState *)uptr)->r9,
+				((QEMUCPUState *)uptr)->r10,
+				((QEMUCPUState *)uptr)->r11);
+		netdump_print("r12:%016llx  r13:%016llx  r14:%016llx\n",
+				((QEMUCPUState *)uptr)->r12,
+				((QEMUCPUState *)uptr)->r13,
+				((QEMUCPUState *)uptr)->r14);
+		netdump_print("r15:%016llx  rip:%016llx  rflags:%016llx\n",
+				((QEMUCPUState *)uptr)->r15,
+				((QEMUCPUState *)uptr)->rip,
+				((QEMUCPUState *)uptr)->rflags);
+		netdump_print("cs:\n  selector:%08lx  limit:%08lx  flags:%08lx\n\
+  pad:%08lx  base:%016llx\n",
+				((QEMUCPUState *)uptr)->cs.selector,
+				((QEMUCPUState *)uptr)->cs.limit,
+				((QEMUCPUState *)uptr)->cs.flags,
+				((QEMUCPUState *)uptr)->cs.pad,
+				((QEMUCPUState *)uptr)->cs.base);
+		netdump_print("ds:\n  selector:%08lx  limit:%08lx  flags:%08lx\n\
+  pad:%08lx  base:%016llx\n",
+				((QEMUCPUState *)uptr)->ds.selector,
+				((QEMUCPUState *)uptr)->ds.limit,
+				((QEMUCPUState *)uptr)->ds.flags,
+				((QEMUCPUState *)uptr)->ds.pad,
+				((QEMUCPUState *)uptr)->ds.base);
+		netdump_print("es:\n  selector:%08lx  limit:%08lx  flags:%08lx\n\
+  pad:%08lx  base:%016llx\n",
+				((QEMUCPUState *)uptr)->es.selector,
+				((QEMUCPUState *)uptr)->es.limit,
+				((QEMUCPUState *)uptr)->es.flags,
+				((QEMUCPUState *)uptr)->es.pad,
+				((QEMUCPUState *)uptr)->es.base);
+		netdump_print("fs:\n  selector:%08lx  limit:%08lx  flags:%08lx\n\
+  pad:%08lx  base:%016llx\n",
+				((QEMUCPUState *)uptr)->fs.selector,
+				((QEMUCPUState *)uptr)->fs.limit,
+				((QEMUCPUState *)uptr)->fs.flags,
+				((QEMUCPUState *)uptr)->fs.pad,
+				((QEMUCPUState *)uptr)->fs.base);
+		netdump_print("gs:\n  selector:%08lx  limit:%08lx  flags:%08lx\n\
+  pad:%08lx  base:%016llx\n",
+				((QEMUCPUState *)uptr)->gs.selector,
+				((QEMUCPUState *)uptr)->gs.limit,
+				((QEMUCPUState *)uptr)->gs.flags,
+				((QEMUCPUState *)uptr)->gs.pad,
+				((QEMUCPUState *)uptr)->gs.base);
+		netdump_print("ss:\n  selector:%08lx  limit:%08lx  flags:%08lx\n\
+  pad:%08lx  base:%016llx\n",
+				((QEMUCPUState *)uptr)->ss.selector,
+				((QEMUCPUState *)uptr)->ss.limit,
+				((QEMUCPUState *)uptr)->ss.flags,
+				((QEMUCPUState *)uptr)->ss.pad,
+				((QEMUCPUState *)uptr)->ss.base);
+		netdump_print("ldt:\n  selector:%08lx  limit:%08lx  flags:%08lx\n\
+  pad:%08lx  base:%016llx\n",
+				((QEMUCPUState *)uptr)->ldt.selector,
+				((QEMUCPUState *)uptr)->ldt.limit,
+				((QEMUCPUState *)uptr)->ldt.flags,
+				((QEMUCPUState *)uptr)->ldt.pad,
+				((QEMUCPUState *)uptr)->ldt.base);
+		netdump_print("tr:\n  selector:%08lx  limit:%08lx  flags:%08lx\n\
+  pad:%08lx  base:%016llx\n",
+				((QEMUCPUState *)uptr)->tr.selector,
+				((QEMUCPUState *)uptr)->tr.limit,
+				((QEMUCPUState *)uptr)->tr.flags,
+				((QEMUCPUState *)uptr)->tr.pad,
+				((QEMUCPUState *)uptr)->tr.base);
+		netdump_print("gdt:\n  selector:%08lx  limit:%08lx  flags:%08lx\n\
+  pad:%08lx  base:%016llx\n",
+				((QEMUCPUState *)uptr)->gdt.selector,
+				((QEMUCPUState *)uptr)->gdt.limit,
+				((QEMUCPUState *)uptr)->gdt.flags,
+				((QEMUCPUState *)uptr)->gdt.pad,
+				((QEMUCPUState *)uptr)->gdt.base);
+		netdump_print("idt:\n  selector:%08lx  limit:%08lx  flags:%08lx\n\
+  pad:%08lx  base:%016llx\n",
+				((QEMUCPUState *)uptr)->idt.selector,
+				((QEMUCPUState *)uptr)->idt.limit,
+				((QEMUCPUState *)uptr)->idt.flags,
+				((QEMUCPUState *)uptr)->idt.pad,
+				((QEMUCPUState *)uptr)->idt.base);
+		netdump_print("cr[0]:%016llx  cr[1]:%016llx  cr[2]:%016llx\n",
+				((QEMUCPUState *)uptr)->cr[0],
+				((QEMUCPUState *)uptr)->cr[1],
+				((QEMUCPUState *)uptr)->cr[2]);
+		netdump_print("cr[3]:%016llx  cr[4]:%016llx\n",
+				((QEMUCPUState *)uptr)->cr[3],
+				((QEMUCPUState *)uptr)->cr[4]);
+	}
+
 	if (BITS32() && (xen_core || (note->n_type == NT_PRSTATUS))) {
 		iptr = (int *)uptr;
 		for (i = lf = 0; i < note->n_descsz/sizeof(ulong); i++) {
diff --git a/netdump.h b/netdump.h
index 4a6d661..ba6fde6 100644
--- a/netdump.h
+++ b/netdump.h
@@ -177,3 +177,25 @@ struct proc_kcore_data {
 	Elf32_Phdr *load32;
 };
 
+struct QEMUCPUSegment {
+    uint32_t selector;
+    uint32_t limit;
+    uint32_t flags;
+    uint32_t pad;
+    uint64_t base;
+};
+
+typedef struct QEMUCPUSegment QEMUCPUSegment;
+
+struct QEMUCPUState {
+    uint32_t version;
+    uint32_t size;
+    uint64_t rax, rbx, rcx, rdx, rsi, rdi, rsp, rbp;
+    uint64_t r8, r9, r10, r11, r12, r13, r14, r15;
+    uint64_t rip, rflags;
+    QEMUCPUSegment cs, ds, es, fs, gs, ss;
+    QEMUCPUSegment ldt, tr, gdt, idt;
+    uint64_t cr[5];
+};
+
+typedef struct QEMUCPUState QEMUCPUState;
-- 
1.7.1

