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 149fecbed0SWen Congyang #include "cpu.h" 15022c62cbSPaolo Bonzini #include "exec/cpu-all.h" 169c17d615SPaolo Bonzini #include "sysemu/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 37c72bf468SJens Freimann static int x86_64_write_elf64_note(WriteCoreDumpFunction f, 38369ff018SAndreas Färber CPUX86State *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, ®s, 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 122369ff018SAndreas Färber static void x86_fill_elf_prstatus(x86_elf_prstatus *prstatus, CPUX86State *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 147369ff018SAndreas Färber static int x86_write_elf64_note(WriteCoreDumpFunction f, CPUX86State *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 182c72bf468SJens Freimann int x86_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs, 1839fecbed0SWen Congyang int cpuid, void *opaque) 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) { 192c72bf468SJens Freimann ret = x86_64_write_elf64_note(f, &cpu->env, cpuid, opaque); 1939fecbed0SWen Congyang } else { 1949fecbed0SWen Congyang #endif 195c72bf468SJens Freimann ret = x86_write_elf64_note(f, &cpu->env, cpuid, opaque); 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, 2049fecbed0SWen Congyang int cpuid, void *opaque) 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); 2169fecbed0SWen Congyang note_size = ((sizeof(Elf32_Nhdr) + 3) / 4 + (name_size + 3) / 4 + 2179fecbed0SWen Congyang (descsz + 3) / 4) * 4; 2189fecbed0SWen Congyang note = g_malloc(note_size); 2199fecbed0SWen Congyang 2209fecbed0SWen Congyang memset(note, 0, note_size); 2219fecbed0SWen Congyang note->n_namesz = cpu_to_le32(name_size); 2229fecbed0SWen Congyang note->n_descsz = cpu_to_le32(descsz); 2239fecbed0SWen Congyang note->n_type = cpu_to_le32(NT_PRSTATUS); 2249fecbed0SWen Congyang buf = (char *)note; 2259fecbed0SWen Congyang buf += ((sizeof(Elf32_Nhdr) + 3) / 4) * 4; 2269fecbed0SWen Congyang memcpy(buf, name, name_size); 2279fecbed0SWen Congyang buf += ((name_size + 3) / 4) * 4; 2289fecbed0SWen Congyang memcpy(buf, &prstatus, sizeof(prstatus)); 2299fecbed0SWen Congyang 2309fecbed0SWen Congyang ret = f(note, note_size, opaque); 2319fecbed0SWen Congyang g_free(note); 2329fecbed0SWen Congyang if (ret < 0) { 2339fecbed0SWen Congyang return -1; 2349fecbed0SWen Congyang } 2359fecbed0SWen Congyang 2369fecbed0SWen Congyang return 0; 2379fecbed0SWen Congyang } 23890166b71SWen Congyang 23990166b71SWen Congyang /* 24090166b71SWen Congyang * please count up QEMUCPUSTATE_VERSION if you have changed definition of 24190166b71SWen Congyang * QEMUCPUState, and modify the tools using this information accordingly. 24290166b71SWen Congyang */ 24390166b71SWen Congyang #define QEMUCPUSTATE_VERSION (1) 24490166b71SWen Congyang 24590166b71SWen Congyang struct QEMUCPUSegment { 24690166b71SWen Congyang uint32_t selector; 24790166b71SWen Congyang uint32_t limit; 24890166b71SWen Congyang uint32_t flags; 24990166b71SWen Congyang uint32_t pad; 25090166b71SWen Congyang uint64_t base; 25190166b71SWen Congyang }; 25290166b71SWen Congyang 25390166b71SWen Congyang typedef struct QEMUCPUSegment QEMUCPUSegment; 25490166b71SWen Congyang 25590166b71SWen Congyang struct QEMUCPUState { 25690166b71SWen Congyang uint32_t version; 25790166b71SWen Congyang uint32_t size; 25890166b71SWen Congyang uint64_t rax, rbx, rcx, rdx, rsi, rdi, rsp, rbp; 25990166b71SWen Congyang uint64_t r8, r9, r10, r11, r12, r13, r14, r15; 26090166b71SWen Congyang uint64_t rip, rflags; 26190166b71SWen Congyang QEMUCPUSegment cs, ds, es, fs, gs, ss; 26290166b71SWen Congyang QEMUCPUSegment ldt, tr, gdt, idt; 26390166b71SWen Congyang uint64_t cr[5]; 26490166b71SWen Congyang }; 26590166b71SWen Congyang 26690166b71SWen Congyang typedef struct QEMUCPUState QEMUCPUState; 26790166b71SWen Congyang 26890166b71SWen Congyang static void copy_segment(QEMUCPUSegment *d, SegmentCache *s) 26990166b71SWen Congyang { 27090166b71SWen Congyang d->pad = 0; 27190166b71SWen Congyang d->selector = s->selector; 27290166b71SWen Congyang d->limit = s->limit; 27390166b71SWen Congyang d->flags = s->flags; 27490166b71SWen Congyang d->base = s->base; 27590166b71SWen Congyang } 27690166b71SWen Congyang 277369ff018SAndreas Färber static void qemu_get_cpustate(QEMUCPUState *s, CPUX86State *env) 27890166b71SWen Congyang { 27990166b71SWen Congyang memset(s, 0, sizeof(QEMUCPUState)); 28090166b71SWen Congyang 28190166b71SWen Congyang s->version = QEMUCPUSTATE_VERSION; 28290166b71SWen Congyang s->size = sizeof(QEMUCPUState); 28390166b71SWen Congyang 28490166b71SWen Congyang s->rax = env->regs[R_EAX]; 28590166b71SWen Congyang s->rbx = env->regs[R_EBX]; 28690166b71SWen Congyang s->rcx = env->regs[R_ECX]; 28790166b71SWen Congyang s->rdx = env->regs[R_EDX]; 28890166b71SWen Congyang s->rsi = env->regs[R_ESI]; 28990166b71SWen Congyang s->rdi = env->regs[R_EDI]; 29090166b71SWen Congyang s->rsp = env->regs[R_ESP]; 29190166b71SWen Congyang s->rbp = env->regs[R_EBP]; 29290166b71SWen Congyang #ifdef TARGET_X86_64 29390166b71SWen Congyang s->r8 = env->regs[8]; 29490166b71SWen Congyang s->r9 = env->regs[9]; 29590166b71SWen Congyang s->r10 = env->regs[10]; 29690166b71SWen Congyang s->r11 = env->regs[11]; 29790166b71SWen Congyang s->r12 = env->regs[12]; 29890166b71SWen Congyang s->r13 = env->regs[13]; 29990166b71SWen Congyang s->r14 = env->regs[14]; 30090166b71SWen Congyang s->r15 = env->regs[15]; 30190166b71SWen Congyang #endif 30290166b71SWen Congyang s->rip = env->eip; 30390166b71SWen Congyang s->rflags = env->eflags; 30490166b71SWen Congyang 30590166b71SWen Congyang copy_segment(&s->cs, &env->segs[R_CS]); 30690166b71SWen Congyang copy_segment(&s->ds, &env->segs[R_DS]); 30790166b71SWen Congyang copy_segment(&s->es, &env->segs[R_ES]); 30890166b71SWen Congyang copy_segment(&s->fs, &env->segs[R_FS]); 30990166b71SWen Congyang copy_segment(&s->gs, &env->segs[R_GS]); 31090166b71SWen Congyang copy_segment(&s->ss, &env->segs[R_SS]); 31190166b71SWen Congyang copy_segment(&s->ldt, &env->ldt); 31290166b71SWen Congyang copy_segment(&s->tr, &env->tr); 31390166b71SWen Congyang copy_segment(&s->gdt, &env->gdt); 31490166b71SWen Congyang copy_segment(&s->idt, &env->idt); 31590166b71SWen Congyang 31690166b71SWen Congyang s->cr[0] = env->cr[0]; 31790166b71SWen Congyang s->cr[1] = env->cr[1]; 31890166b71SWen Congyang s->cr[2] = env->cr[2]; 31990166b71SWen Congyang s->cr[3] = env->cr[3]; 32090166b71SWen Congyang s->cr[4] = env->cr[4]; 32190166b71SWen Congyang } 32290166b71SWen Congyang 323c72bf468SJens Freimann static inline int cpu_write_qemu_note(WriteCoreDumpFunction f, 324369ff018SAndreas Färber CPUX86State *env, 32590166b71SWen Congyang void *opaque, 32690166b71SWen Congyang int type) 32790166b71SWen Congyang { 32890166b71SWen Congyang QEMUCPUState state; 32990166b71SWen Congyang Elf64_Nhdr *note64; 33090166b71SWen Congyang Elf32_Nhdr *note32; 33190166b71SWen Congyang void *note; 33290166b71SWen Congyang char *buf; 33390166b71SWen Congyang int descsz, note_size, name_size = 5, note_head_size; 33490166b71SWen Congyang const char *name = "QEMU"; 33590166b71SWen Congyang int ret; 33690166b71SWen Congyang 33790166b71SWen Congyang qemu_get_cpustate(&state, env); 33890166b71SWen Congyang 33990166b71SWen Congyang descsz = sizeof(state); 34090166b71SWen Congyang if (type == 0) { 34190166b71SWen Congyang note_head_size = sizeof(Elf32_Nhdr); 34290166b71SWen Congyang } else { 34390166b71SWen Congyang note_head_size = sizeof(Elf64_Nhdr); 34490166b71SWen Congyang } 34590166b71SWen Congyang note_size = ((note_head_size + 3) / 4 + (name_size + 3) / 4 + 34690166b71SWen Congyang (descsz + 3) / 4) * 4; 34790166b71SWen Congyang note = g_malloc(note_size); 34890166b71SWen Congyang 34990166b71SWen Congyang memset(note, 0, note_size); 35090166b71SWen Congyang if (type == 0) { 35190166b71SWen Congyang note32 = note; 35290166b71SWen Congyang note32->n_namesz = cpu_to_le32(name_size); 35390166b71SWen Congyang note32->n_descsz = cpu_to_le32(descsz); 35490166b71SWen Congyang note32->n_type = 0; 35590166b71SWen Congyang } else { 35690166b71SWen Congyang note64 = note; 35790166b71SWen Congyang note64->n_namesz = cpu_to_le32(name_size); 35890166b71SWen Congyang note64->n_descsz = cpu_to_le32(descsz); 35990166b71SWen Congyang note64->n_type = 0; 36090166b71SWen Congyang } 36190166b71SWen Congyang buf = note; 36290166b71SWen Congyang buf += ((note_head_size + 3) / 4) * 4; 36390166b71SWen Congyang memcpy(buf, name, name_size); 36490166b71SWen Congyang buf += ((name_size + 3) / 4) * 4; 36590166b71SWen Congyang memcpy(buf, &state, sizeof(state)); 36690166b71SWen Congyang 36790166b71SWen Congyang ret = f(note, note_size, opaque); 36890166b71SWen Congyang g_free(note); 36990166b71SWen Congyang if (ret < 0) { 37090166b71SWen Congyang return -1; 37190166b71SWen Congyang } 37290166b71SWen Congyang 37390166b71SWen Congyang return 0; 37490166b71SWen Congyang } 37590166b71SWen Congyang 376c72bf468SJens Freimann int x86_cpu_write_elf64_qemunote(WriteCoreDumpFunction f, CPUState *cs, 37790166b71SWen Congyang void *opaque) 37890166b71SWen Congyang { 379c72bf468SJens Freimann X86CPU *cpu = X86_CPU(cs); 380c72bf468SJens Freimann 381c72bf468SJens Freimann return cpu_write_qemu_note(f, &cpu->env, opaque, 1); 38290166b71SWen Congyang } 38390166b71SWen Congyang 384c72bf468SJens Freimann int x86_cpu_write_elf32_qemunote(WriteCoreDumpFunction f, CPUState *cs, 38590166b71SWen Congyang void *opaque) 38690166b71SWen Congyang { 387c72bf468SJens Freimann X86CPU *cpu = X86_CPU(cs); 388c72bf468SJens Freimann 389c72bf468SJens Freimann return cpu_write_qemu_note(f, &cpu->env, opaque, 0); 39090166b71SWen Congyang } 39125ae9c1dSWen Congyang 39225ae9c1dSWen Congyang int cpu_get_dump_info(ArchDumpInfo *info) 39325ae9c1dSWen Congyang { 39425ae9c1dSWen Congyang bool lma = false; 39525ae9c1dSWen Congyang RAMBlock *block; 39625ae9c1dSWen Congyang 39725ae9c1dSWen Congyang #ifdef TARGET_X86_64 398182735efSAndreas Färber X86CPU *first_x86_cpu = X86_CPU(first_cpu); 399182735efSAndreas Färber 400182735efSAndreas Färber lma = !!(first_x86_cpu->env.hflags & HF_LMA_MASK); 40125ae9c1dSWen Congyang #endif 40225ae9c1dSWen Congyang 40325ae9c1dSWen Congyang if (lma) { 40425ae9c1dSWen Congyang info->d_machine = EM_X86_64; 40525ae9c1dSWen Congyang } else { 40625ae9c1dSWen Congyang info->d_machine = EM_386; 40725ae9c1dSWen Congyang } 40825ae9c1dSWen Congyang info->d_endian = ELFDATA2LSB; 40925ae9c1dSWen Congyang 41025ae9c1dSWen Congyang if (lma) { 41125ae9c1dSWen Congyang info->d_class = ELFCLASS64; 41225ae9c1dSWen Congyang } else { 41325ae9c1dSWen Congyang info->d_class = ELFCLASS32; 41425ae9c1dSWen Congyang 415a3161038SPaolo Bonzini QTAILQ_FOREACH(block, &ram_list.blocks, next) { 41625ae9c1dSWen Congyang if (block->offset + block->length > UINT_MAX) { 41725ae9c1dSWen Congyang /* The memory size is greater than 4G */ 41825ae9c1dSWen Congyang info->d_class = ELFCLASS64; 41925ae9c1dSWen Congyang break; 42025ae9c1dSWen Congyang } 42125ae9c1dSWen Congyang } 42225ae9c1dSWen Congyang } 42325ae9c1dSWen Congyang 42425ae9c1dSWen Congyang return 0; 42525ae9c1dSWen Congyang } 4260038ffb0SWen Congyang 4274720bd05SPaolo Bonzini ssize_t cpu_get_note_size(int class, int machine, int nr_cpus) 4280038ffb0SWen Congyang { 4290038ffb0SWen Congyang int name_size = 5; /* "CORE" or "QEMU" */ 4300038ffb0SWen Congyang size_t elf_note_size = 0; 4310038ffb0SWen Congyang size_t qemu_note_size = 0; 4320038ffb0SWen Congyang int elf_desc_size = 0; 4330038ffb0SWen Congyang int qemu_desc_size = 0; 4340038ffb0SWen Congyang int note_head_size; 4350038ffb0SWen Congyang 4360038ffb0SWen Congyang if (class == ELFCLASS32) { 4370038ffb0SWen Congyang note_head_size = sizeof(Elf32_Nhdr); 4380038ffb0SWen Congyang } else { 4390038ffb0SWen Congyang note_head_size = sizeof(Elf64_Nhdr); 4400038ffb0SWen Congyang } 4410038ffb0SWen Congyang 4420038ffb0SWen Congyang if (machine == EM_386) { 4430038ffb0SWen Congyang elf_desc_size = sizeof(x86_elf_prstatus); 4440038ffb0SWen Congyang } 4450038ffb0SWen Congyang #ifdef TARGET_X86_64 4460038ffb0SWen Congyang else { 4470038ffb0SWen Congyang elf_desc_size = sizeof(x86_64_elf_prstatus); 4480038ffb0SWen Congyang } 4490038ffb0SWen Congyang #endif 4500038ffb0SWen Congyang qemu_desc_size = sizeof(QEMUCPUState); 4510038ffb0SWen Congyang 4520038ffb0SWen Congyang elf_note_size = ((note_head_size + 3) / 4 + (name_size + 3) / 4 + 4530038ffb0SWen Congyang (elf_desc_size + 3) / 4) * 4; 4540038ffb0SWen Congyang qemu_note_size = ((note_head_size + 3) / 4 + (name_size + 3) / 4 + 4550038ffb0SWen Congyang (qemu_desc_size + 3) / 4) * 4; 4560038ffb0SWen Congyang 4570038ffb0SWen Congyang return (elf_note_size + qemu_note_size) * nr_cpus; 4580038ffb0SWen Congyang } 459