]> git.proxmox.com Git - qemu.git/blobdiff - target-i386/arch_dump.c
qdev-properties-system.c: Allow vlan or netdev for -device, not both
[qemu.git] / target-i386 / arch_dump.c
index ddbe20c32a4ab6a46d3f488cb682f4f8ccb0794d..0bbed239f81da74ecace4daebd5cfdcc180c29c4 100644 (file)
@@ -6,14 +6,16 @@
  * Authors:
  *     Wen Congyang <wency@cn.fujitsu.com>
  *
- * This work is licensed under the terms of the GNU GPL, version 2.  See
- * the COPYING file in the top-level directory.
+ * 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 "cpu.h"
-#include "cpu-all.h"
+#include "exec/cpu-all.h"
+#include "sysemu/dump.h"
 #include "elf.h"
+#include "sysemu/memory_mapping.h"
 
 #ifdef TARGET_X86_64
 typedef struct {
@@ -33,8 +35,8 @@ typedef struct {
     char pad3[8];
 } x86_64_elf_prstatus;
 
-static int x86_64_write_elf64_note(write_core_dump_function f,
-                                   CPUArchState *env, int id,
+static int x86_64_write_elf64_note(WriteCoreDumpFunction f,
+                                   CPUX86State *env, int id,
                                    void *opaque)
 {
     x86_64_user_regs_struct regs;
@@ -118,7 +120,7 @@ typedef struct {
     char pad3[4];
 } x86_elf_prstatus;
 
-static void x86_fill_elf_prstatus(x86_elf_prstatus *prstatus, CPUArchState *env,
+static void x86_fill_elf_prstatus(x86_elf_prstatus *prstatus, CPUX86State *env,
                                   int id)
 {
     memset(prstatus, 0, sizeof(x86_elf_prstatus));
@@ -143,7 +145,7 @@ static void x86_fill_elf_prstatus(x86_elf_prstatus *prstatus, CPUArchState *env,
     prstatus->pid = id;
 }
 
-static int x86_write_elf64_note(write_core_dump_function f, CPUArchState *env,
+static int x86_write_elf64_note(WriteCoreDumpFunction f, CPUX86State *env,
                                 int id, void *opaque)
 {
     x86_elf_prstatus prstatus;
@@ -178,18 +180,20 @@ static int x86_write_elf64_note(write_core_dump_function f, CPUArchState *env,
     return 0;
 }
 
-int cpu_write_elf64_note(write_core_dump_function f, CPUArchState *env,
-                         int cpuid, void *opaque)
+int x86_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs,
+                             int cpuid, void *opaque)
 {
+    X86CPU *cpu = X86_CPU(cs);
     int ret;
 #ifdef TARGET_X86_64
-    bool lma = !!(first_cpu->hflags & HF_LMA_MASK);
+    X86CPU *first_x86_cpu = X86_CPU(first_cpu);
+    bool lma = !!(first_x86_cpu->env.hflags & HF_LMA_MASK);
 
     if (lma) {
-        ret = x86_64_write_elf64_note(f, env, cpuid, opaque);
+        ret = x86_64_write_elf64_note(f, &cpu->env, cpuid, opaque);
     } else {
 #endif
-        ret = x86_write_elf64_note(f, env, cpuid, opaque);
+        ret = x86_write_elf64_note(f, &cpu->env, cpuid, opaque);
 #ifdef TARGET_X86_64
     }
 #endif
@@ -197,9 +201,10 @@ int cpu_write_elf64_note(write_core_dump_function f, CPUArchState *env,
     return ret;
 }
 
-int cpu_write_elf32_note(write_core_dump_function f, CPUArchState *env,
-                         int cpuid, void *opaque)
+int x86_cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cs,
+                             int cpuid, void *opaque)
 {
+    X86CPU *cpu = X86_CPU(cs);
     x86_elf_prstatus prstatus;
     Elf32_Nhdr *note;
     char *buf;
@@ -207,7 +212,7 @@ int cpu_write_elf32_note(write_core_dump_function f, CPUArchState *env,
     const char *name = "CORE";
     int ret;
 
-    x86_fill_elf_prstatus(&prstatus, env, cpuid);
+    x86_fill_elf_prstatus(&prstatus, &cpu->env, cpuid);
     descsz = sizeof(x86_elf_prstatus);
     note_size = ((sizeof(Elf32_Nhdr) + 3) / 4 + (name_size + 3) / 4 +
                 (descsz + 3) / 4) * 4;
@@ -270,7 +275,7 @@ static void copy_segment(QEMUCPUSegment *d, SegmentCache *s)
     d->base = s->base;
 }
 
-static void qemu_get_cpustate(QEMUCPUState *s, CPUArchState *env)
+static void qemu_get_cpustate(QEMUCPUState *s, CPUX86State *env)
 {
     memset(s, 0, sizeof(QEMUCPUState));
 
@@ -316,8 +321,8 @@ static void qemu_get_cpustate(QEMUCPUState *s, CPUArchState *env)
     s->cr[4] = env->cr[4];
 }
 
-static inline int cpu_write_qemu_note(write_core_dump_function f,
-                                      CPUArchState *env,
+static inline int cpu_write_qemu_note(WriteCoreDumpFunction f,
+                                      CPUX86State *env,
                                       void *opaque,
                                       int type)
 {
@@ -369,14 +374,87 @@ static inline int cpu_write_qemu_note(write_core_dump_function f,
     return 0;
 }
 
-int cpu_write_elf64_qemunote(write_core_dump_function f, CPUArchState *env,
-                             void *opaque)
+int x86_cpu_write_elf64_qemunote(WriteCoreDumpFunction f, CPUState *cs,
+                                 void *opaque)
 {
-    return cpu_write_qemu_note(f, env, opaque, 1);
+    X86CPU *cpu = X86_CPU(cs);
+
+    return cpu_write_qemu_note(f, &cpu->env, opaque, 1);
+}
+
+int x86_cpu_write_elf32_qemunote(WriteCoreDumpFunction f, CPUState *cs,
+                                 void *opaque)
+{
+    X86CPU *cpu = X86_CPU(cs);
+
+    return cpu_write_qemu_note(f, &cpu->env, opaque, 0);
 }
 
-int cpu_write_elf32_qemunote(write_core_dump_function f, CPUArchState *env,
-                             void *opaque)
+int cpu_get_dump_info(ArchDumpInfo *info,
+                      const GuestPhysBlockList *guest_phys_blocks)
 {
-    return cpu_write_qemu_note(f, env, opaque, 0);
+    bool lma = false;
+    GuestPhysBlock *block;
+
+#ifdef TARGET_X86_64
+    X86CPU *first_x86_cpu = X86_CPU(first_cpu);
+
+    lma = !!(first_x86_cpu->env.hflags & HF_LMA_MASK);
+#endif
+
+    if (lma) {
+        info->d_machine = EM_X86_64;
+    } else {
+        info->d_machine = EM_386;
+    }
+    info->d_endian = ELFDATA2LSB;
+
+    if (lma) {
+        info->d_class = ELFCLASS64;
+    } else {
+        info->d_class = ELFCLASS32;
+
+        QTAILQ_FOREACH(block, &guest_phys_blocks->head, next) {
+            if (block->target_end > UINT_MAX) {
+                /* The memory size is greater than 4G */
+                info->d_class = ELFCLASS64;
+                break;
+            }
+        }
+    }
+
+    return 0;
+}
+
+ssize_t cpu_get_note_size(int class, int machine, int nr_cpus)
+{
+    int name_size = 5; /* "CORE" or "QEMU" */
+    size_t elf_note_size = 0;
+    size_t qemu_note_size = 0;
+    int elf_desc_size = 0;
+    int qemu_desc_size = 0;
+    int note_head_size;
+
+    if (class == ELFCLASS32) {
+        note_head_size = sizeof(Elf32_Nhdr);
+    } else {
+        note_head_size = sizeof(Elf64_Nhdr);
+    }
+
+    if (machine == EM_386) {
+        elf_desc_size = sizeof(x86_elf_prstatus);
+    }
+#ifdef TARGET_X86_64
+    else {
+        elf_desc_size = sizeof(x86_64_elf_prstatus);
+    }
+#endif
+    qemu_desc_size = sizeof(QEMUCPUState);
+
+    elf_note_size = ((note_head_size + 3) / 4 + (name_size + 3) / 4 +
+                     (elf_desc_size + 3) / 4) * 4;
+    qemu_note_size = ((note_head_size + 3) / 4 + (name_size + 3) / 4 +
+                      (qemu_desc_size + 3) / 4) * 4;
+
+    return (elf_note_size + qemu_note_size) * nr_cpus;
 }