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 *
9fc0608acSStefan Weil * This work is licensed under the terms of the GNU GPL, version 2 or later.
10fc0608acSStefan Weil * See the COPYING file in the top-level directory.
119fecbed0SWen Congyang *
129fecbed0SWen Congyang */
139fecbed0SWen Congyang
14b6a0aa05SPeter Maydell #include "qemu/osdep.h"
159fecbed0SWen Congyang #include "cpu.h"
16*32cad1ffSPhilippe Mathieu-Daudé #include "system/dump.h"
179fecbed0SWen Congyang #include "elf.h"
18*32cad1ffSPhilippe Mathieu-Daudé #include "system/memory_mapping.h"
199fecbed0SWen Congyang
2018a1f0d7SMarc-André Lureau #define ELF_NOTE_SIZE(hdr_size, name_size, desc_size) \
2118a1f0d7SMarc-André Lureau ((DIV_ROUND_UP((hdr_size), 4) \
2218a1f0d7SMarc-André Lureau + DIV_ROUND_UP((name_size), 4) \
2318a1f0d7SMarc-André Lureau + DIV_ROUND_UP((desc_size), 4)) * 4)
2418a1f0d7SMarc-André Lureau
259fecbed0SWen Congyang #ifdef TARGET_X86_64
269fecbed0SWen Congyang typedef struct {
279fecbed0SWen Congyang target_ulong r15, r14, r13, r12, rbp, rbx, r11, r10;
289fecbed0SWen Congyang target_ulong r9, r8, rax, rcx, rdx, rsi, rdi, orig_rax;
299fecbed0SWen Congyang target_ulong rip, cs, eflags;
309fecbed0SWen Congyang target_ulong rsp, ss;
319fecbed0SWen Congyang target_ulong fs_base, gs_base;
329fecbed0SWen Congyang target_ulong ds, es, fs, gs;
339fecbed0SWen Congyang } x86_64_user_regs_struct;
349fecbed0SWen Congyang
359fecbed0SWen Congyang typedef struct {
369fecbed0SWen Congyang char pad1[32];
379fecbed0SWen Congyang uint32_t pid;
389fecbed0SWen Congyang char pad2[76];
399fecbed0SWen Congyang x86_64_user_regs_struct regs;
409fecbed0SWen Congyang char pad3[8];
419fecbed0SWen Congyang } x86_64_elf_prstatus;
429fecbed0SWen Congyang
x86_64_write_elf64_note(WriteCoreDumpFunction f,CPUX86State * env,int id,DumpState * s)43c72bf468SJens Freimann static int x86_64_write_elf64_note(WriteCoreDumpFunction f,
44369ff018SAndreas Färber CPUX86State *env, int id,
451af0006aSJanosch Frank DumpState *s)
469fecbed0SWen Congyang {
479fecbed0SWen Congyang x86_64_user_regs_struct regs;
489fecbed0SWen Congyang Elf64_Nhdr *note;
499fecbed0SWen Congyang char *buf;
509fecbed0SWen Congyang int descsz, note_size, name_size = 5;
519fecbed0SWen Congyang const char *name = "CORE";
529fecbed0SWen Congyang int ret;
539fecbed0SWen Congyang
549fecbed0SWen Congyang regs.r15 = env->regs[15];
559fecbed0SWen Congyang regs.r14 = env->regs[14];
569fecbed0SWen Congyang regs.r13 = env->regs[13];
579fecbed0SWen Congyang regs.r12 = env->regs[12];
589fecbed0SWen Congyang regs.r11 = env->regs[11];
599fecbed0SWen Congyang regs.r10 = env->regs[10];
609fecbed0SWen Congyang regs.r9 = env->regs[9];
619fecbed0SWen Congyang regs.r8 = env->regs[8];
629fecbed0SWen Congyang regs.rbp = env->regs[R_EBP];
639fecbed0SWen Congyang regs.rsp = env->regs[R_ESP];
649fecbed0SWen Congyang regs.rdi = env->regs[R_EDI];
659fecbed0SWen Congyang regs.rsi = env->regs[R_ESI];
669fecbed0SWen Congyang regs.rdx = env->regs[R_EDX];
679fecbed0SWen Congyang regs.rcx = env->regs[R_ECX];
689fecbed0SWen Congyang regs.rbx = env->regs[R_EBX];
699fecbed0SWen Congyang regs.rax = env->regs[R_EAX];
709fecbed0SWen Congyang regs.rip = env->eip;
719fecbed0SWen Congyang regs.eflags = env->eflags;
729fecbed0SWen Congyang
739fecbed0SWen Congyang regs.orig_rax = 0; /* FIXME */
749fecbed0SWen Congyang regs.cs = env->segs[R_CS].selector;
759fecbed0SWen Congyang regs.ss = env->segs[R_SS].selector;
769fecbed0SWen Congyang regs.fs_base = env->segs[R_FS].base;
779fecbed0SWen Congyang regs.gs_base = env->segs[R_GS].base;
789fecbed0SWen Congyang regs.ds = env->segs[R_DS].selector;
799fecbed0SWen Congyang regs.es = env->segs[R_ES].selector;
809fecbed0SWen Congyang regs.fs = env->segs[R_FS].selector;
819fecbed0SWen Congyang regs.gs = env->segs[R_GS].selector;
829fecbed0SWen Congyang
839fecbed0SWen Congyang descsz = sizeof(x86_64_elf_prstatus);
8418a1f0d7SMarc-André Lureau note_size = ELF_NOTE_SIZE(sizeof(Elf64_Nhdr), name_size, descsz);
854be34d1eSMarkus Armbruster note = g_malloc0(note_size);
869fecbed0SWen Congyang note->n_namesz = cpu_to_le32(name_size);
879fecbed0SWen Congyang note->n_descsz = cpu_to_le32(descsz);
889fecbed0SWen Congyang note->n_type = cpu_to_le32(NT_PRSTATUS);
899fecbed0SWen Congyang buf = (char *)note;
9017fc7e93SMarc-André Lureau buf += ROUND_UP(sizeof(Elf64_Nhdr), 4);
919fecbed0SWen Congyang memcpy(buf, name, name_size);
9217fc7e93SMarc-André Lureau buf += ROUND_UP(name_size, 4);
939fecbed0SWen Congyang memcpy(buf + 32, &id, 4); /* pr_pid */
949fecbed0SWen Congyang buf += descsz - sizeof(x86_64_user_regs_struct)-sizeof(target_ulong);
959fecbed0SWen Congyang memcpy(buf, ®s, sizeof(x86_64_user_regs_struct));
969fecbed0SWen Congyang
971af0006aSJanosch Frank ret = f(note, note_size, s);
989fecbed0SWen Congyang g_free(note);
999fecbed0SWen Congyang if (ret < 0) {
1009fecbed0SWen Congyang return -1;
1019fecbed0SWen Congyang }
1029fecbed0SWen Congyang
1039fecbed0SWen Congyang return 0;
1049fecbed0SWen Congyang }
1059fecbed0SWen Congyang #endif
1069fecbed0SWen Congyang
1079fecbed0SWen Congyang typedef struct {
1089fecbed0SWen Congyang uint32_t ebx, ecx, edx, esi, edi, ebp, eax;
1099fecbed0SWen Congyang unsigned short ds, __ds, es, __es;
1109fecbed0SWen Congyang unsigned short fs, __fs, gs, __gs;
1119fecbed0SWen Congyang uint32_t orig_eax, eip;
1129fecbed0SWen Congyang unsigned short cs, __cs;
1139fecbed0SWen Congyang uint32_t eflags, esp;
1149fecbed0SWen Congyang unsigned short ss, __ss;
1159fecbed0SWen Congyang } x86_user_regs_struct;
1169fecbed0SWen Congyang
1179fecbed0SWen Congyang typedef struct {
1189fecbed0SWen Congyang char pad1[24];
1199fecbed0SWen Congyang uint32_t pid;
1209fecbed0SWen Congyang char pad2[44];
1219fecbed0SWen Congyang x86_user_regs_struct regs;
1229fecbed0SWen Congyang char pad3[4];
1239fecbed0SWen Congyang } x86_elf_prstatus;
1249fecbed0SWen Congyang
x86_fill_elf_prstatus(x86_elf_prstatus * prstatus,CPUX86State * env,int id)125369ff018SAndreas Färber static void x86_fill_elf_prstatus(x86_elf_prstatus *prstatus, CPUX86State *env,
1269fecbed0SWen Congyang int id)
1279fecbed0SWen Congyang {
1289fecbed0SWen Congyang memset(prstatus, 0, sizeof(x86_elf_prstatus));
1299fecbed0SWen Congyang prstatus->regs.ebp = env->regs[R_EBP] & 0xffffffff;
1309fecbed0SWen Congyang prstatus->regs.esp = env->regs[R_ESP] & 0xffffffff;
1319fecbed0SWen Congyang prstatus->regs.edi = env->regs[R_EDI] & 0xffffffff;
1329fecbed0SWen Congyang prstatus->regs.esi = env->regs[R_ESI] & 0xffffffff;
1339fecbed0SWen Congyang prstatus->regs.edx = env->regs[R_EDX] & 0xffffffff;
1349fecbed0SWen Congyang prstatus->regs.ecx = env->regs[R_ECX] & 0xffffffff;
1359fecbed0SWen Congyang prstatus->regs.ebx = env->regs[R_EBX] & 0xffffffff;
1369fecbed0SWen Congyang prstatus->regs.eax = env->regs[R_EAX] & 0xffffffff;
1379fecbed0SWen Congyang prstatus->regs.eip = env->eip & 0xffffffff;
1389fecbed0SWen Congyang prstatus->regs.eflags = env->eflags & 0xffffffff;
1399fecbed0SWen Congyang
1409fecbed0SWen Congyang prstatus->regs.cs = env->segs[R_CS].selector;
1419fecbed0SWen Congyang prstatus->regs.ss = env->segs[R_SS].selector;
1429fecbed0SWen Congyang prstatus->regs.ds = env->segs[R_DS].selector;
1439fecbed0SWen Congyang prstatus->regs.es = env->segs[R_ES].selector;
1449fecbed0SWen Congyang prstatus->regs.fs = env->segs[R_FS].selector;
1459fecbed0SWen Congyang prstatus->regs.gs = env->segs[R_GS].selector;
1469fecbed0SWen Congyang
1479fecbed0SWen Congyang prstatus->pid = id;
1489fecbed0SWen Congyang }
1499fecbed0SWen Congyang
x86_write_elf64_note(WriteCoreDumpFunction f,CPUX86State * env,int id,DumpState * s)150369ff018SAndreas Färber static int x86_write_elf64_note(WriteCoreDumpFunction f, CPUX86State *env,
1511af0006aSJanosch Frank int id, DumpState *s)
1529fecbed0SWen Congyang {
1539fecbed0SWen Congyang x86_elf_prstatus prstatus;
1549fecbed0SWen Congyang Elf64_Nhdr *note;
1559fecbed0SWen Congyang char *buf;
1569fecbed0SWen Congyang int descsz, note_size, name_size = 5;
1579fecbed0SWen Congyang const char *name = "CORE";
1589fecbed0SWen Congyang int ret;
1599fecbed0SWen Congyang
1609fecbed0SWen Congyang x86_fill_elf_prstatus(&prstatus, env, id);
1619fecbed0SWen Congyang descsz = sizeof(x86_elf_prstatus);
16218a1f0d7SMarc-André Lureau note_size = ELF_NOTE_SIZE(sizeof(Elf64_Nhdr), name_size, descsz);
1634be34d1eSMarkus Armbruster note = g_malloc0(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;
16817fc7e93SMarc-André Lureau buf += ROUND_UP(sizeof(Elf64_Nhdr), 4);
1699fecbed0SWen Congyang memcpy(buf, name, name_size);
17017fc7e93SMarc-André Lureau buf += ROUND_UP(name_size, 4);
1719fecbed0SWen Congyang memcpy(buf, &prstatus, sizeof(prstatus));
1729fecbed0SWen Congyang
1731af0006aSJanosch Frank ret = f(note, note_size, s);
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
x86_cpu_write_elf64_note(WriteCoreDumpFunction f,CPUState * cs,int cpuid,DumpState * s)182c72bf468SJens Freimann int x86_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs,
1831af0006aSJanosch Frank int cpuid, DumpState *s)
1849fecbed0SWen Congyang {
185c72bf468SJens Freimann X86CPU *cpu = X86_CPU(cs);
1869fecbed0SWen Congyang int ret;
1879fecbed0SWen Congyang #ifdef TARGET_X86_64
188182735efSAndreas Färber X86CPU *first_x86_cpu = X86_CPU(first_cpu);
189182735efSAndreas Färber bool lma = !!(first_x86_cpu->env.hflags & HF_LMA_MASK);
1909fecbed0SWen Congyang
1919fecbed0SWen Congyang if (lma) {
1921af0006aSJanosch Frank ret = x86_64_write_elf64_note(f, &cpu->env, cpuid, s);
1939fecbed0SWen Congyang } else {
1949fecbed0SWen Congyang #endif
1951af0006aSJanosch Frank ret = x86_write_elf64_note(f, &cpu->env, cpuid, s);
1969fecbed0SWen Congyang #ifdef TARGET_X86_64
1979fecbed0SWen Congyang }
1989fecbed0SWen Congyang #endif
1999fecbed0SWen Congyang
2009fecbed0SWen Congyang return ret;
2019fecbed0SWen Congyang }
2029fecbed0SWen Congyang
x86_cpu_write_elf32_note(WriteCoreDumpFunction f,CPUState * cs,int cpuid,DumpState * s)203c72bf468SJens Freimann int x86_cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cs,
2041af0006aSJanosch Frank int cpuid, DumpState *s)
2059fecbed0SWen Congyang {
206c72bf468SJens Freimann X86CPU *cpu = X86_CPU(cs);
2079fecbed0SWen Congyang x86_elf_prstatus prstatus;
2089fecbed0SWen Congyang Elf32_Nhdr *note;
2099fecbed0SWen Congyang char *buf;
2109fecbed0SWen Congyang int descsz, note_size, name_size = 5;
2119fecbed0SWen Congyang const char *name = "CORE";
2129fecbed0SWen Congyang int ret;
2139fecbed0SWen Congyang
214c72bf468SJens Freimann x86_fill_elf_prstatus(&prstatus, &cpu->env, cpuid);
2159fecbed0SWen Congyang descsz = sizeof(x86_elf_prstatus);
21618a1f0d7SMarc-André Lureau note_size = ELF_NOTE_SIZE(sizeof(Elf32_Nhdr), name_size, descsz);
2174be34d1eSMarkus Armbruster note = g_malloc0(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;
22217fc7e93SMarc-André Lureau buf += ROUND_UP(sizeof(Elf32_Nhdr), 4);
2239fecbed0SWen Congyang memcpy(buf, name, name_size);
22417fc7e93SMarc-André Lureau buf += ROUND_UP(name_size, 4);
2259fecbed0SWen Congyang memcpy(buf, &prstatus, sizeof(prstatus));
2269fecbed0SWen Congyang
2271af0006aSJanosch Frank ret = f(note, note_size, s);
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];
26146fac17dSViktor Prutyanov /*
26246fac17dSViktor Prutyanov * Fields below are optional and are being added at the end without
26346fac17dSViktor Prutyanov * changing the version. External tools may identify their presence
26446fac17dSViktor Prutyanov * by checking 'size' field.
26546fac17dSViktor Prutyanov */
26646fac17dSViktor Prutyanov uint64_t kernel_gs_base;
26790166b71SWen Congyang };
26890166b71SWen Congyang
26990166b71SWen Congyang typedef struct QEMUCPUState QEMUCPUState;
27090166b71SWen Congyang
copy_segment(QEMUCPUSegment * d,SegmentCache * s)27190166b71SWen Congyang static void copy_segment(QEMUCPUSegment *d, SegmentCache *s)
27290166b71SWen Congyang {
27390166b71SWen Congyang d->pad = 0;
27490166b71SWen Congyang d->selector = s->selector;
27590166b71SWen Congyang d->limit = s->limit;
27690166b71SWen Congyang d->flags = s->flags;
27790166b71SWen Congyang d->base = s->base;
27890166b71SWen Congyang }
27990166b71SWen Congyang
qemu_get_cpustate(QEMUCPUState * s,CPUX86State * env)280369ff018SAndreas Färber static void qemu_get_cpustate(QEMUCPUState *s, CPUX86State *env)
28190166b71SWen Congyang {
28290166b71SWen Congyang memset(s, 0, sizeof(QEMUCPUState));
28390166b71SWen Congyang
28490166b71SWen Congyang s->version = QEMUCPUSTATE_VERSION;
28590166b71SWen Congyang s->size = sizeof(QEMUCPUState);
28690166b71SWen Congyang
28790166b71SWen Congyang s->rax = env->regs[R_EAX];
28890166b71SWen Congyang s->rbx = env->regs[R_EBX];
28990166b71SWen Congyang s->rcx = env->regs[R_ECX];
29090166b71SWen Congyang s->rdx = env->regs[R_EDX];
29190166b71SWen Congyang s->rsi = env->regs[R_ESI];
29290166b71SWen Congyang s->rdi = env->regs[R_EDI];
29390166b71SWen Congyang s->rsp = env->regs[R_ESP];
29490166b71SWen Congyang s->rbp = env->regs[R_EBP];
29590166b71SWen Congyang #ifdef TARGET_X86_64
29690166b71SWen Congyang s->r8 = env->regs[8];
29790166b71SWen Congyang s->r9 = env->regs[9];
29890166b71SWen Congyang s->r10 = env->regs[10];
29990166b71SWen Congyang s->r11 = env->regs[11];
30090166b71SWen Congyang s->r12 = env->regs[12];
30190166b71SWen Congyang s->r13 = env->regs[13];
30290166b71SWen Congyang s->r14 = env->regs[14];
30390166b71SWen Congyang s->r15 = env->regs[15];
30490166b71SWen Congyang #endif
30590166b71SWen Congyang s->rip = env->eip;
30690166b71SWen Congyang s->rflags = env->eflags;
30790166b71SWen Congyang
30890166b71SWen Congyang copy_segment(&s->cs, &env->segs[R_CS]);
30990166b71SWen Congyang copy_segment(&s->ds, &env->segs[R_DS]);
31090166b71SWen Congyang copy_segment(&s->es, &env->segs[R_ES]);
31190166b71SWen Congyang copy_segment(&s->fs, &env->segs[R_FS]);
31290166b71SWen Congyang copy_segment(&s->gs, &env->segs[R_GS]);
31390166b71SWen Congyang copy_segment(&s->ss, &env->segs[R_SS]);
31490166b71SWen Congyang copy_segment(&s->ldt, &env->ldt);
31590166b71SWen Congyang copy_segment(&s->tr, &env->tr);
31690166b71SWen Congyang copy_segment(&s->gdt, &env->gdt);
31790166b71SWen Congyang copy_segment(&s->idt, &env->idt);
31890166b71SWen Congyang
31990166b71SWen Congyang s->cr[0] = env->cr[0];
32090166b71SWen Congyang s->cr[1] = env->cr[1];
32190166b71SWen Congyang s->cr[2] = env->cr[2];
32290166b71SWen Congyang s->cr[3] = env->cr[3];
32390166b71SWen Congyang s->cr[4] = env->cr[4];
32446fac17dSViktor Prutyanov
32546fac17dSViktor Prutyanov #ifdef TARGET_X86_64
32646fac17dSViktor Prutyanov s->kernel_gs_base = env->kernelgsbase;
32746fac17dSViktor Prutyanov #endif
32890166b71SWen Congyang }
32990166b71SWen Congyang
cpu_write_qemu_note(WriteCoreDumpFunction f,CPUX86State * env,DumpState * s,int type)330c72bf468SJens Freimann static inline int cpu_write_qemu_note(WriteCoreDumpFunction f,
331369ff018SAndreas Färber CPUX86State *env,
3321af0006aSJanosch Frank DumpState *s,
33390166b71SWen Congyang int type)
33490166b71SWen Congyang {
33590166b71SWen Congyang QEMUCPUState state;
33690166b71SWen Congyang Elf64_Nhdr *note64;
33790166b71SWen Congyang Elf32_Nhdr *note32;
33890166b71SWen Congyang void *note;
33990166b71SWen Congyang char *buf;
34090166b71SWen Congyang int descsz, note_size, name_size = 5, note_head_size;
34190166b71SWen Congyang const char *name = "QEMU";
34290166b71SWen Congyang int ret;
34390166b71SWen Congyang
34490166b71SWen Congyang qemu_get_cpustate(&state, env);
34590166b71SWen Congyang
34690166b71SWen Congyang descsz = sizeof(state);
34790166b71SWen Congyang if (type == 0) {
34890166b71SWen Congyang note_head_size = sizeof(Elf32_Nhdr);
34990166b71SWen Congyang } else {
35090166b71SWen Congyang note_head_size = sizeof(Elf64_Nhdr);
35190166b71SWen Congyang }
352074d5afeSMarc-André Lureau note_size = (DIV_ROUND_UP(note_head_size, 4) + DIV_ROUND_UP(name_size, 4) +
353074d5afeSMarc-André Lureau DIV_ROUND_UP(descsz, 4)) * 4;
3544be34d1eSMarkus Armbruster note = g_malloc0(note_size);
35590166b71SWen Congyang if (type == 0) {
35690166b71SWen Congyang note32 = note;
35790166b71SWen Congyang note32->n_namesz = cpu_to_le32(name_size);
35890166b71SWen Congyang note32->n_descsz = cpu_to_le32(descsz);
35990166b71SWen Congyang note32->n_type = 0;
36090166b71SWen Congyang } else {
36190166b71SWen Congyang note64 = note;
36290166b71SWen Congyang note64->n_namesz = cpu_to_le32(name_size);
36390166b71SWen Congyang note64->n_descsz = cpu_to_le32(descsz);
36490166b71SWen Congyang note64->n_type = 0;
36590166b71SWen Congyang }
36690166b71SWen Congyang buf = note;
36717fc7e93SMarc-André Lureau buf += ROUND_UP(note_head_size, 4);
36890166b71SWen Congyang memcpy(buf, name, name_size);
36917fc7e93SMarc-André Lureau buf += ROUND_UP(name_size, 4);
37090166b71SWen Congyang memcpy(buf, &state, sizeof(state));
37190166b71SWen Congyang
3721af0006aSJanosch Frank ret = f(note, note_size, s);
37390166b71SWen Congyang g_free(note);
37490166b71SWen Congyang if (ret < 0) {
37590166b71SWen Congyang return -1;
37690166b71SWen Congyang }
37790166b71SWen Congyang
37890166b71SWen Congyang return 0;
37990166b71SWen Congyang }
38090166b71SWen Congyang
x86_cpu_write_elf64_qemunote(WriteCoreDumpFunction f,CPUState * cs,DumpState * s)381c72bf468SJens Freimann int x86_cpu_write_elf64_qemunote(WriteCoreDumpFunction f, CPUState *cs,
3821af0006aSJanosch Frank DumpState *s)
38390166b71SWen Congyang {
384c72bf468SJens Freimann X86CPU *cpu = X86_CPU(cs);
385c72bf468SJens Freimann
3861af0006aSJanosch Frank return cpu_write_qemu_note(f, &cpu->env, s, 1);
38790166b71SWen Congyang }
38890166b71SWen Congyang
x86_cpu_write_elf32_qemunote(WriteCoreDumpFunction f,CPUState * cs,DumpState * s)389c72bf468SJens Freimann int x86_cpu_write_elf32_qemunote(WriteCoreDumpFunction f, CPUState *cs,
3901af0006aSJanosch Frank DumpState *s)
39190166b71SWen Congyang {
392c72bf468SJens Freimann X86CPU *cpu = X86_CPU(cs);
393c72bf468SJens Freimann
3941af0006aSJanosch Frank return cpu_write_qemu_note(f, &cpu->env, s, 0);
39590166b71SWen Congyang }
39625ae9c1dSWen Congyang
cpu_get_dump_info(ArchDumpInfo * info,const GuestPhysBlockList * guest_phys_blocks)39756c4bfb3SLaszlo Ersek int cpu_get_dump_info(ArchDumpInfo *info,
39856c4bfb3SLaszlo Ersek const GuestPhysBlockList *guest_phys_blocks)
39925ae9c1dSWen Congyang {
40025ae9c1dSWen Congyang bool lma = false;
40156c4bfb3SLaszlo Ersek GuestPhysBlock *block;
40225ae9c1dSWen Congyang
40325ae9c1dSWen Congyang #ifdef TARGET_X86_64
404182735efSAndreas Färber X86CPU *first_x86_cpu = X86_CPU(first_cpu);
405fd5d23baSIwona Kotlarska lma = first_cpu && (first_x86_cpu->env.hflags & HF_LMA_MASK);
40625ae9c1dSWen Congyang #endif
40725ae9c1dSWen Congyang
40825ae9c1dSWen Congyang if (lma) {
40925ae9c1dSWen Congyang info->d_machine = EM_X86_64;
41025ae9c1dSWen Congyang } else {
41125ae9c1dSWen Congyang info->d_machine = EM_386;
41225ae9c1dSWen Congyang }
41325ae9c1dSWen Congyang info->d_endian = ELFDATA2LSB;
41425ae9c1dSWen Congyang
41525ae9c1dSWen Congyang if (lma) {
41625ae9c1dSWen Congyang info->d_class = ELFCLASS64;
41725ae9c1dSWen Congyang } else {
41825ae9c1dSWen Congyang info->d_class = ELFCLASS32;
41925ae9c1dSWen Congyang
42056c4bfb3SLaszlo Ersek QTAILQ_FOREACH(block, &guest_phys_blocks->head, next) {
42156c4bfb3SLaszlo Ersek if (block->target_end > UINT_MAX) {
42225ae9c1dSWen Congyang /* The memory size is greater than 4G */
42325ae9c1dSWen Congyang info->d_class = ELFCLASS64;
42425ae9c1dSWen Congyang break;
42525ae9c1dSWen Congyang }
42625ae9c1dSWen Congyang }
42725ae9c1dSWen Congyang }
42825ae9c1dSWen Congyang
42925ae9c1dSWen Congyang return 0;
43025ae9c1dSWen Congyang }
4310038ffb0SWen Congyang
cpu_get_note_size(int class,int machine,int nr_cpus)4324720bd05SPaolo Bonzini ssize_t cpu_get_note_size(int class, int machine, int nr_cpus)
4330038ffb0SWen Congyang {
4340038ffb0SWen Congyang int name_size = 5; /* "CORE" or "QEMU" */
4350038ffb0SWen Congyang size_t elf_note_size = 0;
4360038ffb0SWen Congyang size_t qemu_note_size = 0;
4370038ffb0SWen Congyang int elf_desc_size = 0;
4380038ffb0SWen Congyang int qemu_desc_size = 0;
4390038ffb0SWen Congyang int note_head_size;
4400038ffb0SWen Congyang
4410038ffb0SWen Congyang if (class == ELFCLASS32) {
4420038ffb0SWen Congyang note_head_size = sizeof(Elf32_Nhdr);
4430038ffb0SWen Congyang } else {
4440038ffb0SWen Congyang note_head_size = sizeof(Elf64_Nhdr);
4450038ffb0SWen Congyang }
4460038ffb0SWen Congyang
4470038ffb0SWen Congyang if (machine == EM_386) {
4480038ffb0SWen Congyang elf_desc_size = sizeof(x86_elf_prstatus);
4490038ffb0SWen Congyang }
4500038ffb0SWen Congyang #ifdef TARGET_X86_64
4510038ffb0SWen Congyang else {
4520038ffb0SWen Congyang elf_desc_size = sizeof(x86_64_elf_prstatus);
4530038ffb0SWen Congyang }
4540038ffb0SWen Congyang #endif
4550038ffb0SWen Congyang qemu_desc_size = sizeof(QEMUCPUState);
4560038ffb0SWen Congyang
45718a1f0d7SMarc-André Lureau elf_note_size = ELF_NOTE_SIZE(note_head_size, name_size, elf_desc_size);
45818a1f0d7SMarc-André Lureau qemu_note_size = ELF_NOTE_SIZE(note_head_size, name_size, qemu_desc_size);
4590038ffb0SWen Congyang
4600038ffb0SWen Congyang return (elf_note_size + qemu_note_size) * nr_cpus;
4610038ffb0SWen Congyang }
462