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