xref: /qemu/target/i386/arch_dump.c (revision 25ae9c1d8bbfeb6c00eccb4297a5937d8375a44a)
19fecbed0SWen Congyang /*
29fecbed0SWen Congyang  * i386 memory mapping
39fecbed0SWen Congyang  *
49fecbed0SWen Congyang  * Copyright Fujitsu, Corp. 2011, 2012
59fecbed0SWen Congyang  *
69fecbed0SWen Congyang  * Authors:
79fecbed0SWen Congyang  *     Wen Congyang <wency@cn.fujitsu.com>
89fecbed0SWen Congyang  *
99fecbed0SWen Congyang  * This work is licensed under the terms of the GNU GPL, version 2.  See
109fecbed0SWen Congyang  * the COPYING file in the top-level directory.
119fecbed0SWen Congyang  *
129fecbed0SWen Congyang  */
139fecbed0SWen Congyang 
149fecbed0SWen Congyang #include "cpu.h"
159fecbed0SWen Congyang #include "cpu-all.h"
1625ae9c1dSWen Congyang #include "dump.h"
179fecbed0SWen Congyang #include "elf.h"
189fecbed0SWen Congyang 
199fecbed0SWen Congyang #ifdef TARGET_X86_64
209fecbed0SWen Congyang typedef struct {
219fecbed0SWen Congyang     target_ulong r15, r14, r13, r12, rbp, rbx, r11, r10;
229fecbed0SWen Congyang     target_ulong r9, r8, rax, rcx, rdx, rsi, rdi, orig_rax;
239fecbed0SWen Congyang     target_ulong rip, cs, eflags;
249fecbed0SWen Congyang     target_ulong rsp, ss;
259fecbed0SWen Congyang     target_ulong fs_base, gs_base;
269fecbed0SWen Congyang     target_ulong ds, es, fs, gs;
279fecbed0SWen Congyang } x86_64_user_regs_struct;
289fecbed0SWen Congyang 
299fecbed0SWen Congyang typedef struct {
309fecbed0SWen Congyang     char pad1[32];
319fecbed0SWen Congyang     uint32_t pid;
329fecbed0SWen Congyang     char pad2[76];
339fecbed0SWen Congyang     x86_64_user_regs_struct regs;
349fecbed0SWen Congyang     char pad3[8];
359fecbed0SWen Congyang } x86_64_elf_prstatus;
369fecbed0SWen Congyang 
379fecbed0SWen Congyang static int x86_64_write_elf64_note(write_core_dump_function f,
389fecbed0SWen Congyang                                    CPUArchState *env, int id,
399fecbed0SWen Congyang                                    void *opaque)
409fecbed0SWen Congyang {
419fecbed0SWen Congyang     x86_64_user_regs_struct regs;
429fecbed0SWen Congyang     Elf64_Nhdr *note;
439fecbed0SWen Congyang     char *buf;
449fecbed0SWen Congyang     int descsz, note_size, name_size = 5;
459fecbed0SWen Congyang     const char *name = "CORE";
469fecbed0SWen Congyang     int ret;
479fecbed0SWen Congyang 
489fecbed0SWen Congyang     regs.r15 = env->regs[15];
499fecbed0SWen Congyang     regs.r14 = env->regs[14];
509fecbed0SWen Congyang     regs.r13 = env->regs[13];
519fecbed0SWen Congyang     regs.r12 = env->regs[12];
529fecbed0SWen Congyang     regs.r11 = env->regs[11];
539fecbed0SWen Congyang     regs.r10 = env->regs[10];
549fecbed0SWen Congyang     regs.r9  = env->regs[9];
559fecbed0SWen Congyang     regs.r8  = env->regs[8];
569fecbed0SWen Congyang     regs.rbp = env->regs[R_EBP];
579fecbed0SWen Congyang     regs.rsp = env->regs[R_ESP];
589fecbed0SWen Congyang     regs.rdi = env->regs[R_EDI];
599fecbed0SWen Congyang     regs.rsi = env->regs[R_ESI];
609fecbed0SWen Congyang     regs.rdx = env->regs[R_EDX];
619fecbed0SWen Congyang     regs.rcx = env->regs[R_ECX];
629fecbed0SWen Congyang     regs.rbx = env->regs[R_EBX];
639fecbed0SWen Congyang     regs.rax = env->regs[R_EAX];
649fecbed0SWen Congyang     regs.rip = env->eip;
659fecbed0SWen Congyang     regs.eflags = env->eflags;
669fecbed0SWen Congyang 
679fecbed0SWen Congyang     regs.orig_rax = 0; /* FIXME */
689fecbed0SWen Congyang     regs.cs = env->segs[R_CS].selector;
699fecbed0SWen Congyang     regs.ss = env->segs[R_SS].selector;
709fecbed0SWen Congyang     regs.fs_base = env->segs[R_FS].base;
719fecbed0SWen Congyang     regs.gs_base = env->segs[R_GS].base;
729fecbed0SWen Congyang     regs.ds = env->segs[R_DS].selector;
739fecbed0SWen Congyang     regs.es = env->segs[R_ES].selector;
749fecbed0SWen Congyang     regs.fs = env->segs[R_FS].selector;
759fecbed0SWen Congyang     regs.gs = env->segs[R_GS].selector;
769fecbed0SWen Congyang 
779fecbed0SWen Congyang     descsz = sizeof(x86_64_elf_prstatus);
789fecbed0SWen Congyang     note_size = ((sizeof(Elf64_Nhdr) + 3) / 4 + (name_size + 3) / 4 +
799fecbed0SWen Congyang                 (descsz + 3) / 4) * 4;
809fecbed0SWen Congyang     note = g_malloc(note_size);
819fecbed0SWen Congyang 
829fecbed0SWen Congyang     memset(note, 0, note_size);
839fecbed0SWen Congyang     note->n_namesz = cpu_to_le32(name_size);
849fecbed0SWen Congyang     note->n_descsz = cpu_to_le32(descsz);
859fecbed0SWen Congyang     note->n_type = cpu_to_le32(NT_PRSTATUS);
869fecbed0SWen Congyang     buf = (char *)note;
879fecbed0SWen Congyang     buf += ((sizeof(Elf64_Nhdr) + 3) / 4) * 4;
889fecbed0SWen Congyang     memcpy(buf, name, name_size);
899fecbed0SWen Congyang     buf += ((name_size + 3) / 4) * 4;
909fecbed0SWen Congyang     memcpy(buf + 32, &id, 4); /* pr_pid */
919fecbed0SWen Congyang     buf += descsz - sizeof(x86_64_user_regs_struct)-sizeof(target_ulong);
929fecbed0SWen Congyang     memcpy(buf, &regs, sizeof(x86_64_user_regs_struct));
939fecbed0SWen Congyang 
949fecbed0SWen Congyang     ret = f(note, note_size, opaque);
959fecbed0SWen Congyang     g_free(note);
969fecbed0SWen Congyang     if (ret < 0) {
979fecbed0SWen Congyang         return -1;
989fecbed0SWen Congyang     }
999fecbed0SWen Congyang 
1009fecbed0SWen Congyang     return 0;
1019fecbed0SWen Congyang }
1029fecbed0SWen Congyang #endif
1039fecbed0SWen Congyang 
1049fecbed0SWen Congyang typedef struct {
1059fecbed0SWen Congyang     uint32_t ebx, ecx, edx, esi, edi, ebp, eax;
1069fecbed0SWen Congyang     unsigned short ds, __ds, es, __es;
1079fecbed0SWen Congyang     unsigned short fs, __fs, gs, __gs;
1089fecbed0SWen Congyang     uint32_t orig_eax, eip;
1099fecbed0SWen Congyang     unsigned short cs, __cs;
1109fecbed0SWen Congyang     uint32_t eflags, esp;
1119fecbed0SWen Congyang     unsigned short ss, __ss;
1129fecbed0SWen Congyang } x86_user_regs_struct;
1139fecbed0SWen Congyang 
1149fecbed0SWen Congyang typedef struct {
1159fecbed0SWen Congyang     char pad1[24];
1169fecbed0SWen Congyang     uint32_t pid;
1179fecbed0SWen Congyang     char pad2[44];
1189fecbed0SWen Congyang     x86_user_regs_struct regs;
1199fecbed0SWen Congyang     char pad3[4];
1209fecbed0SWen Congyang } x86_elf_prstatus;
1219fecbed0SWen Congyang 
1229fecbed0SWen Congyang static void x86_fill_elf_prstatus(x86_elf_prstatus *prstatus, CPUArchState *env,
1239fecbed0SWen Congyang                                   int id)
1249fecbed0SWen Congyang {
1259fecbed0SWen Congyang     memset(prstatus, 0, sizeof(x86_elf_prstatus));
1269fecbed0SWen Congyang     prstatus->regs.ebp = env->regs[R_EBP] & 0xffffffff;
1279fecbed0SWen Congyang     prstatus->regs.esp = env->regs[R_ESP] & 0xffffffff;
1289fecbed0SWen Congyang     prstatus->regs.edi = env->regs[R_EDI] & 0xffffffff;
1299fecbed0SWen Congyang     prstatus->regs.esi = env->regs[R_ESI] & 0xffffffff;
1309fecbed0SWen Congyang     prstatus->regs.edx = env->regs[R_EDX] & 0xffffffff;
1319fecbed0SWen Congyang     prstatus->regs.ecx = env->regs[R_ECX] & 0xffffffff;
1329fecbed0SWen Congyang     prstatus->regs.ebx = env->regs[R_EBX] & 0xffffffff;
1339fecbed0SWen Congyang     prstatus->regs.eax = env->regs[R_EAX] & 0xffffffff;
1349fecbed0SWen Congyang     prstatus->regs.eip = env->eip & 0xffffffff;
1359fecbed0SWen Congyang     prstatus->regs.eflags = env->eflags & 0xffffffff;
1369fecbed0SWen Congyang 
1379fecbed0SWen Congyang     prstatus->regs.cs = env->segs[R_CS].selector;
1389fecbed0SWen Congyang     prstatus->regs.ss = env->segs[R_SS].selector;
1399fecbed0SWen Congyang     prstatus->regs.ds = env->segs[R_DS].selector;
1409fecbed0SWen Congyang     prstatus->regs.es = env->segs[R_ES].selector;
1419fecbed0SWen Congyang     prstatus->regs.fs = env->segs[R_FS].selector;
1429fecbed0SWen Congyang     prstatus->regs.gs = env->segs[R_GS].selector;
1439fecbed0SWen Congyang 
1449fecbed0SWen Congyang     prstatus->pid = id;
1459fecbed0SWen Congyang }
1469fecbed0SWen Congyang 
1479fecbed0SWen Congyang static int x86_write_elf64_note(write_core_dump_function f, CPUArchState *env,
1489fecbed0SWen Congyang                                 int id, void *opaque)
1499fecbed0SWen Congyang {
1509fecbed0SWen Congyang     x86_elf_prstatus prstatus;
1519fecbed0SWen Congyang     Elf64_Nhdr *note;
1529fecbed0SWen Congyang     char *buf;
1539fecbed0SWen Congyang     int descsz, note_size, name_size = 5;
1549fecbed0SWen Congyang     const char *name = "CORE";
1559fecbed0SWen Congyang     int ret;
1569fecbed0SWen Congyang 
1579fecbed0SWen Congyang     x86_fill_elf_prstatus(&prstatus, env, id);
1589fecbed0SWen Congyang     descsz = sizeof(x86_elf_prstatus);
1599fecbed0SWen Congyang     note_size = ((sizeof(Elf64_Nhdr) + 3) / 4 + (name_size + 3) / 4 +
1609fecbed0SWen Congyang                 (descsz + 3) / 4) * 4;
1619fecbed0SWen Congyang     note = g_malloc(note_size);
1629fecbed0SWen Congyang 
1639fecbed0SWen Congyang     memset(note, 0, note_size);
1649fecbed0SWen Congyang     note->n_namesz = cpu_to_le32(name_size);
1659fecbed0SWen Congyang     note->n_descsz = cpu_to_le32(descsz);
1669fecbed0SWen Congyang     note->n_type = cpu_to_le32(NT_PRSTATUS);
1679fecbed0SWen Congyang     buf = (char *)note;
1689fecbed0SWen Congyang     buf += ((sizeof(Elf64_Nhdr) + 3) / 4) * 4;
1699fecbed0SWen Congyang     memcpy(buf, name, name_size);
1709fecbed0SWen Congyang     buf += ((name_size + 3) / 4) * 4;
1719fecbed0SWen Congyang     memcpy(buf, &prstatus, sizeof(prstatus));
1729fecbed0SWen Congyang 
1739fecbed0SWen Congyang     ret = f(note, note_size, opaque);
1749fecbed0SWen Congyang     g_free(note);
1759fecbed0SWen Congyang     if (ret < 0) {
1769fecbed0SWen Congyang         return -1;
1779fecbed0SWen Congyang     }
1789fecbed0SWen Congyang 
1799fecbed0SWen Congyang     return 0;
1809fecbed0SWen Congyang }
1819fecbed0SWen Congyang 
1829fecbed0SWen Congyang int cpu_write_elf64_note(write_core_dump_function f, CPUArchState *env,
1839fecbed0SWen Congyang                          int cpuid, void *opaque)
1849fecbed0SWen Congyang {
1859fecbed0SWen Congyang     int ret;
1869fecbed0SWen Congyang #ifdef TARGET_X86_64
1879fecbed0SWen Congyang     bool lma = !!(first_cpu->hflags & HF_LMA_MASK);
1889fecbed0SWen Congyang 
1899fecbed0SWen Congyang     if (lma) {
1909fecbed0SWen Congyang         ret = x86_64_write_elf64_note(f, env, cpuid, opaque);
1919fecbed0SWen Congyang     } else {
1929fecbed0SWen Congyang #endif
1939fecbed0SWen Congyang         ret = x86_write_elf64_note(f, env, cpuid, opaque);
1949fecbed0SWen Congyang #ifdef TARGET_X86_64
1959fecbed0SWen Congyang     }
1969fecbed0SWen Congyang #endif
1979fecbed0SWen Congyang 
1989fecbed0SWen Congyang     return ret;
1999fecbed0SWen Congyang }
2009fecbed0SWen Congyang 
2019fecbed0SWen Congyang int cpu_write_elf32_note(write_core_dump_function f, CPUArchState *env,
2029fecbed0SWen Congyang                          int cpuid, void *opaque)
2039fecbed0SWen Congyang {
2049fecbed0SWen Congyang     x86_elf_prstatus prstatus;
2059fecbed0SWen Congyang     Elf32_Nhdr *note;
2069fecbed0SWen Congyang     char *buf;
2079fecbed0SWen Congyang     int descsz, note_size, name_size = 5;
2089fecbed0SWen Congyang     const char *name = "CORE";
2099fecbed0SWen Congyang     int ret;
2109fecbed0SWen Congyang 
2119fecbed0SWen Congyang     x86_fill_elf_prstatus(&prstatus, env, cpuid);
2129fecbed0SWen Congyang     descsz = sizeof(x86_elf_prstatus);
2139fecbed0SWen Congyang     note_size = ((sizeof(Elf32_Nhdr) + 3) / 4 + (name_size + 3) / 4 +
2149fecbed0SWen Congyang                 (descsz + 3) / 4) * 4;
2159fecbed0SWen Congyang     note = g_malloc(note_size);
2169fecbed0SWen Congyang 
2179fecbed0SWen Congyang     memset(note, 0, note_size);
2189fecbed0SWen Congyang     note->n_namesz = cpu_to_le32(name_size);
2199fecbed0SWen Congyang     note->n_descsz = cpu_to_le32(descsz);
2209fecbed0SWen Congyang     note->n_type = cpu_to_le32(NT_PRSTATUS);
2219fecbed0SWen Congyang     buf = (char *)note;
2229fecbed0SWen Congyang     buf += ((sizeof(Elf32_Nhdr) + 3) / 4) * 4;
2239fecbed0SWen Congyang     memcpy(buf, name, name_size);
2249fecbed0SWen Congyang     buf += ((name_size + 3) / 4) * 4;
2259fecbed0SWen Congyang     memcpy(buf, &prstatus, sizeof(prstatus));
2269fecbed0SWen Congyang 
2279fecbed0SWen Congyang     ret = f(note, note_size, opaque);
2289fecbed0SWen Congyang     g_free(note);
2299fecbed0SWen Congyang     if (ret < 0) {
2309fecbed0SWen Congyang         return -1;
2319fecbed0SWen Congyang     }
2329fecbed0SWen Congyang 
2339fecbed0SWen Congyang     return 0;
2349fecbed0SWen Congyang }
23590166b71SWen Congyang 
23690166b71SWen Congyang /*
23790166b71SWen Congyang  * please count up QEMUCPUSTATE_VERSION if you have changed definition of
23890166b71SWen Congyang  * QEMUCPUState, and modify the tools using this information accordingly.
23990166b71SWen Congyang  */
24090166b71SWen Congyang #define QEMUCPUSTATE_VERSION (1)
24190166b71SWen Congyang 
24290166b71SWen Congyang struct QEMUCPUSegment {
24390166b71SWen Congyang     uint32_t selector;
24490166b71SWen Congyang     uint32_t limit;
24590166b71SWen Congyang     uint32_t flags;
24690166b71SWen Congyang     uint32_t pad;
24790166b71SWen Congyang     uint64_t base;
24890166b71SWen Congyang };
24990166b71SWen Congyang 
25090166b71SWen Congyang typedef struct QEMUCPUSegment QEMUCPUSegment;
25190166b71SWen Congyang 
25290166b71SWen Congyang struct QEMUCPUState {
25390166b71SWen Congyang     uint32_t version;
25490166b71SWen Congyang     uint32_t size;
25590166b71SWen Congyang     uint64_t rax, rbx, rcx, rdx, rsi, rdi, rsp, rbp;
25690166b71SWen Congyang     uint64_t r8, r9, r10, r11, r12, r13, r14, r15;
25790166b71SWen Congyang     uint64_t rip, rflags;
25890166b71SWen Congyang     QEMUCPUSegment cs, ds, es, fs, gs, ss;
25990166b71SWen Congyang     QEMUCPUSegment ldt, tr, gdt, idt;
26090166b71SWen Congyang     uint64_t cr[5];
26190166b71SWen Congyang };
26290166b71SWen Congyang 
26390166b71SWen Congyang typedef struct QEMUCPUState QEMUCPUState;
26490166b71SWen Congyang 
26590166b71SWen Congyang static void copy_segment(QEMUCPUSegment *d, SegmentCache *s)
26690166b71SWen Congyang {
26790166b71SWen Congyang     d->pad = 0;
26890166b71SWen Congyang     d->selector = s->selector;
26990166b71SWen Congyang     d->limit = s->limit;
27090166b71SWen Congyang     d->flags = s->flags;
27190166b71SWen Congyang     d->base = s->base;
27290166b71SWen Congyang }
27390166b71SWen Congyang 
27490166b71SWen Congyang static void qemu_get_cpustate(QEMUCPUState *s, CPUArchState *env)
27590166b71SWen Congyang {
27690166b71SWen Congyang     memset(s, 0, sizeof(QEMUCPUState));
27790166b71SWen Congyang 
27890166b71SWen Congyang     s->version = QEMUCPUSTATE_VERSION;
27990166b71SWen Congyang     s->size = sizeof(QEMUCPUState);
28090166b71SWen Congyang 
28190166b71SWen Congyang     s->rax = env->regs[R_EAX];
28290166b71SWen Congyang     s->rbx = env->regs[R_EBX];
28390166b71SWen Congyang     s->rcx = env->regs[R_ECX];
28490166b71SWen Congyang     s->rdx = env->regs[R_EDX];
28590166b71SWen Congyang     s->rsi = env->regs[R_ESI];
28690166b71SWen Congyang     s->rdi = env->regs[R_EDI];
28790166b71SWen Congyang     s->rsp = env->regs[R_ESP];
28890166b71SWen Congyang     s->rbp = env->regs[R_EBP];
28990166b71SWen Congyang #ifdef TARGET_X86_64
29090166b71SWen Congyang     s->r8  = env->regs[8];
29190166b71SWen Congyang     s->r9  = env->regs[9];
29290166b71SWen Congyang     s->r10 = env->regs[10];
29390166b71SWen Congyang     s->r11 = env->regs[11];
29490166b71SWen Congyang     s->r12 = env->regs[12];
29590166b71SWen Congyang     s->r13 = env->regs[13];
29690166b71SWen Congyang     s->r14 = env->regs[14];
29790166b71SWen Congyang     s->r15 = env->regs[15];
29890166b71SWen Congyang #endif
29990166b71SWen Congyang     s->rip = env->eip;
30090166b71SWen Congyang     s->rflags = env->eflags;
30190166b71SWen Congyang 
30290166b71SWen Congyang     copy_segment(&s->cs, &env->segs[R_CS]);
30390166b71SWen Congyang     copy_segment(&s->ds, &env->segs[R_DS]);
30490166b71SWen Congyang     copy_segment(&s->es, &env->segs[R_ES]);
30590166b71SWen Congyang     copy_segment(&s->fs, &env->segs[R_FS]);
30690166b71SWen Congyang     copy_segment(&s->gs, &env->segs[R_GS]);
30790166b71SWen Congyang     copy_segment(&s->ss, &env->segs[R_SS]);
30890166b71SWen Congyang     copy_segment(&s->ldt, &env->ldt);
30990166b71SWen Congyang     copy_segment(&s->tr, &env->tr);
31090166b71SWen Congyang     copy_segment(&s->gdt, &env->gdt);
31190166b71SWen Congyang     copy_segment(&s->idt, &env->idt);
31290166b71SWen Congyang 
31390166b71SWen Congyang     s->cr[0] = env->cr[0];
31490166b71SWen Congyang     s->cr[1] = env->cr[1];
31590166b71SWen Congyang     s->cr[2] = env->cr[2];
31690166b71SWen Congyang     s->cr[3] = env->cr[3];
31790166b71SWen Congyang     s->cr[4] = env->cr[4];
31890166b71SWen Congyang }
31990166b71SWen Congyang 
32090166b71SWen Congyang static inline int cpu_write_qemu_note(write_core_dump_function f,
32190166b71SWen Congyang                                       CPUArchState *env,
32290166b71SWen Congyang                                       void *opaque,
32390166b71SWen Congyang                                       int type)
32490166b71SWen Congyang {
32590166b71SWen Congyang     QEMUCPUState state;
32690166b71SWen Congyang     Elf64_Nhdr *note64;
32790166b71SWen Congyang     Elf32_Nhdr *note32;
32890166b71SWen Congyang     void *note;
32990166b71SWen Congyang     char *buf;
33090166b71SWen Congyang     int descsz, note_size, name_size = 5, note_head_size;
33190166b71SWen Congyang     const char *name = "QEMU";
33290166b71SWen Congyang     int ret;
33390166b71SWen Congyang 
33490166b71SWen Congyang     qemu_get_cpustate(&state, env);
33590166b71SWen Congyang 
33690166b71SWen Congyang     descsz = sizeof(state);
33790166b71SWen Congyang     if (type == 0) {
33890166b71SWen Congyang         note_head_size = sizeof(Elf32_Nhdr);
33990166b71SWen Congyang     } else {
34090166b71SWen Congyang         note_head_size = sizeof(Elf64_Nhdr);
34190166b71SWen Congyang     }
34290166b71SWen Congyang     note_size = ((note_head_size + 3) / 4 + (name_size + 3) / 4 +
34390166b71SWen Congyang                 (descsz + 3) / 4) * 4;
34490166b71SWen Congyang     note = g_malloc(note_size);
34590166b71SWen Congyang 
34690166b71SWen Congyang     memset(note, 0, note_size);
34790166b71SWen Congyang     if (type == 0) {
34890166b71SWen Congyang         note32 = note;
34990166b71SWen Congyang         note32->n_namesz = cpu_to_le32(name_size);
35090166b71SWen Congyang         note32->n_descsz = cpu_to_le32(descsz);
35190166b71SWen Congyang         note32->n_type = 0;
35290166b71SWen Congyang     } else {
35390166b71SWen Congyang         note64 = note;
35490166b71SWen Congyang         note64->n_namesz = cpu_to_le32(name_size);
35590166b71SWen Congyang         note64->n_descsz = cpu_to_le32(descsz);
35690166b71SWen Congyang         note64->n_type = 0;
35790166b71SWen Congyang     }
35890166b71SWen Congyang     buf = note;
35990166b71SWen Congyang     buf += ((note_head_size + 3) / 4) * 4;
36090166b71SWen Congyang     memcpy(buf, name, name_size);
36190166b71SWen Congyang     buf += ((name_size + 3) / 4) * 4;
36290166b71SWen Congyang     memcpy(buf, &state, sizeof(state));
36390166b71SWen Congyang 
36490166b71SWen Congyang     ret = f(note, note_size, opaque);
36590166b71SWen Congyang     g_free(note);
36690166b71SWen Congyang     if (ret < 0) {
36790166b71SWen Congyang         return -1;
36890166b71SWen Congyang     }
36990166b71SWen Congyang 
37090166b71SWen Congyang     return 0;
37190166b71SWen Congyang }
37290166b71SWen Congyang 
37390166b71SWen Congyang int cpu_write_elf64_qemunote(write_core_dump_function f, CPUArchState *env,
37490166b71SWen Congyang                              void *opaque)
37590166b71SWen Congyang {
37690166b71SWen Congyang     return cpu_write_qemu_note(f, env, opaque, 1);
37790166b71SWen Congyang }
37890166b71SWen Congyang 
37990166b71SWen Congyang int cpu_write_elf32_qemunote(write_core_dump_function f, CPUArchState *env,
38090166b71SWen Congyang                              void *opaque)
38190166b71SWen Congyang {
38290166b71SWen Congyang     return cpu_write_qemu_note(f, env, opaque, 0);
38390166b71SWen Congyang }
38425ae9c1dSWen Congyang 
38525ae9c1dSWen Congyang int cpu_get_dump_info(ArchDumpInfo *info)
38625ae9c1dSWen Congyang {
38725ae9c1dSWen Congyang     bool lma = false;
38825ae9c1dSWen Congyang     RAMBlock *block;
38925ae9c1dSWen Congyang 
39025ae9c1dSWen Congyang #ifdef TARGET_X86_64
39125ae9c1dSWen Congyang     lma = !!(first_cpu->hflags & HF_LMA_MASK);
39225ae9c1dSWen Congyang #endif
39325ae9c1dSWen Congyang 
39425ae9c1dSWen Congyang     if (lma) {
39525ae9c1dSWen Congyang         info->d_machine = EM_X86_64;
39625ae9c1dSWen Congyang     } else {
39725ae9c1dSWen Congyang         info->d_machine = EM_386;
39825ae9c1dSWen Congyang     }
39925ae9c1dSWen Congyang     info->d_endian = ELFDATA2LSB;
40025ae9c1dSWen Congyang 
40125ae9c1dSWen Congyang     if (lma) {
40225ae9c1dSWen Congyang         info->d_class = ELFCLASS64;
40325ae9c1dSWen Congyang     } else {
40425ae9c1dSWen Congyang         info->d_class = ELFCLASS32;
40525ae9c1dSWen Congyang 
40625ae9c1dSWen Congyang         QLIST_FOREACH(block, &ram_list.blocks, next) {
40725ae9c1dSWen Congyang             if (block->offset + block->length > UINT_MAX) {
40825ae9c1dSWen Congyang                 /* The memory size is greater than 4G */
40925ae9c1dSWen Congyang                 info->d_class = ELFCLASS64;
41025ae9c1dSWen Congyang                 break;
41125ae9c1dSWen Congyang             }
41225ae9c1dSWen Congyang         }
41325ae9c1dSWen Congyang     }
41425ae9c1dSWen Congyang 
41525ae9c1dSWen Congyang     return 0;
41625ae9c1dSWen Congyang }
417