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" 1856c4bfb3SLaszlo Ersek #include "sysemu/memory_mapping.h" 199fecbed0SWen Congyang 209fecbed0SWen Congyang #ifdef TARGET_X86_64 219fecbed0SWen Congyang typedef struct { 229fecbed0SWen Congyang target_ulong r15, r14, r13, r12, rbp, rbx, r11, r10; 239fecbed0SWen Congyang target_ulong r9, r8, rax, rcx, rdx, rsi, rdi, orig_rax; 249fecbed0SWen Congyang target_ulong rip, cs, eflags; 259fecbed0SWen Congyang target_ulong rsp, ss; 269fecbed0SWen Congyang target_ulong fs_base, gs_base; 279fecbed0SWen Congyang target_ulong ds, es, fs, gs; 289fecbed0SWen Congyang } x86_64_user_regs_struct; 299fecbed0SWen Congyang 309fecbed0SWen Congyang typedef struct { 319fecbed0SWen Congyang char pad1[32]; 329fecbed0SWen Congyang uint32_t pid; 339fecbed0SWen Congyang char pad2[76]; 349fecbed0SWen Congyang x86_64_user_regs_struct regs; 359fecbed0SWen Congyang char pad3[8]; 369fecbed0SWen Congyang } x86_64_elf_prstatus; 379fecbed0SWen Congyang 38c72bf468SJens Freimann static int x86_64_write_elf64_note(WriteCoreDumpFunction f, 39369ff018SAndreas Färber CPUX86State *env, int id, 409fecbed0SWen Congyang void *opaque) 419fecbed0SWen Congyang { 429fecbed0SWen Congyang x86_64_user_regs_struct regs; 439fecbed0SWen Congyang Elf64_Nhdr *note; 449fecbed0SWen Congyang char *buf; 459fecbed0SWen Congyang int descsz, note_size, name_size = 5; 469fecbed0SWen Congyang const char *name = "CORE"; 479fecbed0SWen Congyang int ret; 489fecbed0SWen Congyang 499fecbed0SWen Congyang regs.r15 = env->regs[15]; 509fecbed0SWen Congyang regs.r14 = env->regs[14]; 519fecbed0SWen Congyang regs.r13 = env->regs[13]; 529fecbed0SWen Congyang regs.r12 = env->regs[12]; 539fecbed0SWen Congyang regs.r11 = env->regs[11]; 549fecbed0SWen Congyang regs.r10 = env->regs[10]; 559fecbed0SWen Congyang regs.r9 = env->regs[9]; 569fecbed0SWen Congyang regs.r8 = env->regs[8]; 579fecbed0SWen Congyang regs.rbp = env->regs[R_EBP]; 589fecbed0SWen Congyang regs.rsp = env->regs[R_ESP]; 599fecbed0SWen Congyang regs.rdi = env->regs[R_EDI]; 609fecbed0SWen Congyang regs.rsi = env->regs[R_ESI]; 619fecbed0SWen Congyang regs.rdx = env->regs[R_EDX]; 629fecbed0SWen Congyang regs.rcx = env->regs[R_ECX]; 639fecbed0SWen Congyang regs.rbx = env->regs[R_EBX]; 649fecbed0SWen Congyang regs.rax = env->regs[R_EAX]; 659fecbed0SWen Congyang regs.rip = env->eip; 669fecbed0SWen Congyang regs.eflags = env->eflags; 679fecbed0SWen Congyang 689fecbed0SWen Congyang regs.orig_rax = 0; /* FIXME */ 699fecbed0SWen Congyang regs.cs = env->segs[R_CS].selector; 709fecbed0SWen Congyang regs.ss = env->segs[R_SS].selector; 719fecbed0SWen Congyang regs.fs_base = env->segs[R_FS].base; 729fecbed0SWen Congyang regs.gs_base = env->segs[R_GS].base; 739fecbed0SWen Congyang regs.ds = env->segs[R_DS].selector; 749fecbed0SWen Congyang regs.es = env->segs[R_ES].selector; 759fecbed0SWen Congyang regs.fs = env->segs[R_FS].selector; 769fecbed0SWen Congyang regs.gs = env->segs[R_GS].selector; 779fecbed0SWen Congyang 789fecbed0SWen Congyang descsz = sizeof(x86_64_elf_prstatus); 799fecbed0SWen Congyang note_size = ((sizeof(Elf64_Nhdr) + 3) / 4 + (name_size + 3) / 4 + 809fecbed0SWen Congyang (descsz + 3) / 4) * 4; 819fecbed0SWen Congyang note = g_malloc(note_size); 829fecbed0SWen Congyang 839fecbed0SWen Congyang memset(note, 0, note_size); 849fecbed0SWen Congyang note->n_namesz = cpu_to_le32(name_size); 859fecbed0SWen Congyang note->n_descsz = cpu_to_le32(descsz); 869fecbed0SWen Congyang note->n_type = cpu_to_le32(NT_PRSTATUS); 879fecbed0SWen Congyang buf = (char *)note; 889fecbed0SWen Congyang buf += ((sizeof(Elf64_Nhdr) + 3) / 4) * 4; 899fecbed0SWen Congyang memcpy(buf, name, name_size); 909fecbed0SWen Congyang buf += ((name_size + 3) / 4) * 4; 919fecbed0SWen Congyang memcpy(buf + 32, &id, 4); /* pr_pid */ 929fecbed0SWen Congyang buf += descsz - sizeof(x86_64_user_regs_struct)-sizeof(target_ulong); 939fecbed0SWen Congyang memcpy(buf, ®s, sizeof(x86_64_user_regs_struct)); 949fecbed0SWen Congyang 959fecbed0SWen Congyang ret = f(note, note_size, opaque); 969fecbed0SWen Congyang g_free(note); 979fecbed0SWen Congyang if (ret < 0) { 989fecbed0SWen Congyang return -1; 999fecbed0SWen Congyang } 1009fecbed0SWen Congyang 1019fecbed0SWen Congyang return 0; 1029fecbed0SWen Congyang } 1039fecbed0SWen Congyang #endif 1049fecbed0SWen Congyang 1059fecbed0SWen Congyang typedef struct { 1069fecbed0SWen Congyang uint32_t ebx, ecx, edx, esi, edi, ebp, eax; 1079fecbed0SWen Congyang unsigned short ds, __ds, es, __es; 1089fecbed0SWen Congyang unsigned short fs, __fs, gs, __gs; 1099fecbed0SWen Congyang uint32_t orig_eax, eip; 1109fecbed0SWen Congyang unsigned short cs, __cs; 1119fecbed0SWen Congyang uint32_t eflags, esp; 1129fecbed0SWen Congyang unsigned short ss, __ss; 1139fecbed0SWen Congyang } x86_user_regs_struct; 1149fecbed0SWen Congyang 1159fecbed0SWen Congyang typedef struct { 1169fecbed0SWen Congyang char pad1[24]; 1179fecbed0SWen Congyang uint32_t pid; 1189fecbed0SWen Congyang char pad2[44]; 1199fecbed0SWen Congyang x86_user_regs_struct regs; 1209fecbed0SWen Congyang char pad3[4]; 1219fecbed0SWen Congyang } x86_elf_prstatus; 1229fecbed0SWen Congyang 123369ff018SAndreas Färber static void x86_fill_elf_prstatus(x86_elf_prstatus *prstatus, CPUX86State *env, 1249fecbed0SWen Congyang int id) 1259fecbed0SWen Congyang { 1269fecbed0SWen Congyang memset(prstatus, 0, sizeof(x86_elf_prstatus)); 1279fecbed0SWen Congyang prstatus->regs.ebp = env->regs[R_EBP] & 0xffffffff; 1289fecbed0SWen Congyang prstatus->regs.esp = env->regs[R_ESP] & 0xffffffff; 1299fecbed0SWen Congyang prstatus->regs.edi = env->regs[R_EDI] & 0xffffffff; 1309fecbed0SWen Congyang prstatus->regs.esi = env->regs[R_ESI] & 0xffffffff; 1319fecbed0SWen Congyang prstatus->regs.edx = env->regs[R_EDX] & 0xffffffff; 1329fecbed0SWen Congyang prstatus->regs.ecx = env->regs[R_ECX] & 0xffffffff; 1339fecbed0SWen Congyang prstatus->regs.ebx = env->regs[R_EBX] & 0xffffffff; 1349fecbed0SWen Congyang prstatus->regs.eax = env->regs[R_EAX] & 0xffffffff; 1359fecbed0SWen Congyang prstatus->regs.eip = env->eip & 0xffffffff; 1369fecbed0SWen Congyang prstatus->regs.eflags = env->eflags & 0xffffffff; 1379fecbed0SWen Congyang 1389fecbed0SWen Congyang prstatus->regs.cs = env->segs[R_CS].selector; 1399fecbed0SWen Congyang prstatus->regs.ss = env->segs[R_SS].selector; 1409fecbed0SWen Congyang prstatus->regs.ds = env->segs[R_DS].selector; 1419fecbed0SWen Congyang prstatus->regs.es = env->segs[R_ES].selector; 1429fecbed0SWen Congyang prstatus->regs.fs = env->segs[R_FS].selector; 1439fecbed0SWen Congyang prstatus->regs.gs = env->segs[R_GS].selector; 1449fecbed0SWen Congyang 1459fecbed0SWen Congyang prstatus->pid = id; 1469fecbed0SWen Congyang } 1479fecbed0SWen Congyang 148369ff018SAndreas Färber static int x86_write_elf64_note(WriteCoreDumpFunction f, CPUX86State *env, 1499fecbed0SWen Congyang int id, void *opaque) 1509fecbed0SWen Congyang { 1519fecbed0SWen Congyang x86_elf_prstatus prstatus; 1529fecbed0SWen Congyang Elf64_Nhdr *note; 1539fecbed0SWen Congyang char *buf; 1549fecbed0SWen Congyang int descsz, note_size, name_size = 5; 1559fecbed0SWen Congyang const char *name = "CORE"; 1569fecbed0SWen Congyang int ret; 1579fecbed0SWen Congyang 1589fecbed0SWen Congyang x86_fill_elf_prstatus(&prstatus, env, id); 1599fecbed0SWen Congyang descsz = sizeof(x86_elf_prstatus); 1609fecbed0SWen Congyang note_size = ((sizeof(Elf64_Nhdr) + 3) / 4 + (name_size + 3) / 4 + 1619fecbed0SWen Congyang (descsz + 3) / 4) * 4; 1629fecbed0SWen Congyang note = g_malloc(note_size); 1639fecbed0SWen Congyang 1649fecbed0SWen Congyang memset(note, 0, note_size); 1659fecbed0SWen Congyang note->n_namesz = cpu_to_le32(name_size); 1669fecbed0SWen Congyang note->n_descsz = cpu_to_le32(descsz); 1679fecbed0SWen Congyang note->n_type = cpu_to_le32(NT_PRSTATUS); 1689fecbed0SWen Congyang buf = (char *)note; 1699fecbed0SWen Congyang buf += ((sizeof(Elf64_Nhdr) + 3) / 4) * 4; 1709fecbed0SWen Congyang memcpy(buf, name, name_size); 1719fecbed0SWen Congyang buf += ((name_size + 3) / 4) * 4; 1729fecbed0SWen Congyang memcpy(buf, &prstatus, sizeof(prstatus)); 1739fecbed0SWen Congyang 1749fecbed0SWen Congyang ret = f(note, note_size, opaque); 1759fecbed0SWen Congyang g_free(note); 1769fecbed0SWen Congyang if (ret < 0) { 1779fecbed0SWen Congyang return -1; 1789fecbed0SWen Congyang } 1799fecbed0SWen Congyang 1809fecbed0SWen Congyang return 0; 1819fecbed0SWen Congyang } 1829fecbed0SWen Congyang 183c72bf468SJens Freimann int x86_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs, 1849fecbed0SWen Congyang int cpuid, void *opaque) 1859fecbed0SWen Congyang { 186c72bf468SJens Freimann X86CPU *cpu = X86_CPU(cs); 1879fecbed0SWen Congyang int ret; 1889fecbed0SWen Congyang #ifdef TARGET_X86_64 189182735efSAndreas Färber X86CPU *first_x86_cpu = X86_CPU(first_cpu); 190182735efSAndreas Färber bool lma = !!(first_x86_cpu->env.hflags & HF_LMA_MASK); 1919fecbed0SWen Congyang 1929fecbed0SWen Congyang if (lma) { 193c72bf468SJens Freimann ret = x86_64_write_elf64_note(f, &cpu->env, cpuid, opaque); 1949fecbed0SWen Congyang } else { 1959fecbed0SWen Congyang #endif 196c72bf468SJens Freimann ret = x86_write_elf64_note(f, &cpu->env, cpuid, opaque); 1979fecbed0SWen Congyang #ifdef TARGET_X86_64 1989fecbed0SWen Congyang } 1999fecbed0SWen Congyang #endif 2009fecbed0SWen Congyang 2019fecbed0SWen Congyang return ret; 2029fecbed0SWen Congyang } 2039fecbed0SWen Congyang 204c72bf468SJens Freimann int x86_cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cs, 2059fecbed0SWen Congyang int cpuid, void *opaque) 2069fecbed0SWen Congyang { 207c72bf468SJens Freimann X86CPU *cpu = X86_CPU(cs); 2089fecbed0SWen Congyang x86_elf_prstatus prstatus; 2099fecbed0SWen Congyang Elf32_Nhdr *note; 2109fecbed0SWen Congyang char *buf; 2119fecbed0SWen Congyang int descsz, note_size, name_size = 5; 2129fecbed0SWen Congyang const char *name = "CORE"; 2139fecbed0SWen Congyang int ret; 2149fecbed0SWen Congyang 215c72bf468SJens Freimann x86_fill_elf_prstatus(&prstatus, &cpu->env, cpuid); 2169fecbed0SWen Congyang descsz = sizeof(x86_elf_prstatus); 2179fecbed0SWen Congyang note_size = ((sizeof(Elf32_Nhdr) + 3) / 4 + (name_size + 3) / 4 + 2189fecbed0SWen Congyang (descsz + 3) / 4) * 4; 2199fecbed0SWen Congyang note = g_malloc(note_size); 2209fecbed0SWen Congyang 2219fecbed0SWen Congyang memset(note, 0, note_size); 2229fecbed0SWen Congyang note->n_namesz = cpu_to_le32(name_size); 2239fecbed0SWen Congyang note->n_descsz = cpu_to_le32(descsz); 2249fecbed0SWen Congyang note->n_type = cpu_to_le32(NT_PRSTATUS); 2259fecbed0SWen Congyang buf = (char *)note; 2269fecbed0SWen Congyang buf += ((sizeof(Elf32_Nhdr) + 3) / 4) * 4; 2279fecbed0SWen Congyang memcpy(buf, name, name_size); 2289fecbed0SWen Congyang buf += ((name_size + 3) / 4) * 4; 2299fecbed0SWen Congyang memcpy(buf, &prstatus, sizeof(prstatus)); 2309fecbed0SWen Congyang 2319fecbed0SWen Congyang ret = f(note, note_size, opaque); 2329fecbed0SWen Congyang g_free(note); 2339fecbed0SWen Congyang if (ret < 0) { 2349fecbed0SWen Congyang return -1; 2359fecbed0SWen Congyang } 2369fecbed0SWen Congyang 2379fecbed0SWen Congyang return 0; 2389fecbed0SWen Congyang } 23990166b71SWen Congyang 24090166b71SWen Congyang /* 24190166b71SWen Congyang * please count up QEMUCPUSTATE_VERSION if you have changed definition of 24290166b71SWen Congyang * QEMUCPUState, and modify the tools using this information accordingly. 24390166b71SWen Congyang */ 24490166b71SWen Congyang #define QEMUCPUSTATE_VERSION (1) 24590166b71SWen Congyang 24690166b71SWen Congyang struct QEMUCPUSegment { 24790166b71SWen Congyang uint32_t selector; 24890166b71SWen Congyang uint32_t limit; 24990166b71SWen Congyang uint32_t flags; 25090166b71SWen Congyang uint32_t pad; 25190166b71SWen Congyang uint64_t base; 25290166b71SWen Congyang }; 25390166b71SWen Congyang 25490166b71SWen Congyang typedef struct QEMUCPUSegment QEMUCPUSegment; 25590166b71SWen Congyang 25690166b71SWen Congyang struct QEMUCPUState { 25790166b71SWen Congyang uint32_t version; 25890166b71SWen Congyang uint32_t size; 25990166b71SWen Congyang uint64_t rax, rbx, rcx, rdx, rsi, rdi, rsp, rbp; 26090166b71SWen Congyang uint64_t r8, r9, r10, r11, r12, r13, r14, r15; 26190166b71SWen Congyang uint64_t rip, rflags; 26290166b71SWen Congyang QEMUCPUSegment cs, ds, es, fs, gs, ss; 26390166b71SWen Congyang QEMUCPUSegment ldt, tr, gdt, idt; 26490166b71SWen Congyang uint64_t cr[5]; 26590166b71SWen Congyang }; 26690166b71SWen Congyang 26790166b71SWen Congyang typedef struct QEMUCPUState QEMUCPUState; 26890166b71SWen Congyang 26990166b71SWen Congyang static void copy_segment(QEMUCPUSegment *d, SegmentCache *s) 27090166b71SWen Congyang { 27190166b71SWen Congyang d->pad = 0; 27290166b71SWen Congyang d->selector = s->selector; 27390166b71SWen Congyang d->limit = s->limit; 27490166b71SWen Congyang d->flags = s->flags; 27590166b71SWen Congyang d->base = s->base; 27690166b71SWen Congyang } 27790166b71SWen Congyang 278369ff018SAndreas Färber static void qemu_get_cpustate(QEMUCPUState *s, CPUX86State *env) 27990166b71SWen Congyang { 28090166b71SWen Congyang memset(s, 0, sizeof(QEMUCPUState)); 28190166b71SWen Congyang 28290166b71SWen Congyang s->version = QEMUCPUSTATE_VERSION; 28390166b71SWen Congyang s->size = sizeof(QEMUCPUState); 28490166b71SWen Congyang 28590166b71SWen Congyang s->rax = env->regs[R_EAX]; 28690166b71SWen Congyang s->rbx = env->regs[R_EBX]; 28790166b71SWen Congyang s->rcx = env->regs[R_ECX]; 28890166b71SWen Congyang s->rdx = env->regs[R_EDX]; 28990166b71SWen Congyang s->rsi = env->regs[R_ESI]; 29090166b71SWen Congyang s->rdi = env->regs[R_EDI]; 29190166b71SWen Congyang s->rsp = env->regs[R_ESP]; 29290166b71SWen Congyang s->rbp = env->regs[R_EBP]; 29390166b71SWen Congyang #ifdef TARGET_X86_64 29490166b71SWen Congyang s->r8 = env->regs[8]; 29590166b71SWen Congyang s->r9 = env->regs[9]; 29690166b71SWen Congyang s->r10 = env->regs[10]; 29790166b71SWen Congyang s->r11 = env->regs[11]; 29890166b71SWen Congyang s->r12 = env->regs[12]; 29990166b71SWen Congyang s->r13 = env->regs[13]; 30090166b71SWen Congyang s->r14 = env->regs[14]; 30190166b71SWen Congyang s->r15 = env->regs[15]; 30290166b71SWen Congyang #endif 30390166b71SWen Congyang s->rip = env->eip; 30490166b71SWen Congyang s->rflags = env->eflags; 30590166b71SWen Congyang 30690166b71SWen Congyang copy_segment(&s->cs, &env->segs[R_CS]); 30790166b71SWen Congyang copy_segment(&s->ds, &env->segs[R_DS]); 30890166b71SWen Congyang copy_segment(&s->es, &env->segs[R_ES]); 30990166b71SWen Congyang copy_segment(&s->fs, &env->segs[R_FS]); 31090166b71SWen Congyang copy_segment(&s->gs, &env->segs[R_GS]); 31190166b71SWen Congyang copy_segment(&s->ss, &env->segs[R_SS]); 31290166b71SWen Congyang copy_segment(&s->ldt, &env->ldt); 31390166b71SWen Congyang copy_segment(&s->tr, &env->tr); 31490166b71SWen Congyang copy_segment(&s->gdt, &env->gdt); 31590166b71SWen Congyang copy_segment(&s->idt, &env->idt); 31690166b71SWen Congyang 31790166b71SWen Congyang s->cr[0] = env->cr[0]; 31890166b71SWen Congyang s->cr[1] = env->cr[1]; 31990166b71SWen Congyang s->cr[2] = env->cr[2]; 32090166b71SWen Congyang s->cr[3] = env->cr[3]; 32190166b71SWen Congyang s->cr[4] = env->cr[4]; 32290166b71SWen Congyang } 32390166b71SWen Congyang 324c72bf468SJens Freimann static inline int cpu_write_qemu_note(WriteCoreDumpFunction f, 325369ff018SAndreas Färber CPUX86State *env, 32690166b71SWen Congyang void *opaque, 32790166b71SWen Congyang int type) 32890166b71SWen Congyang { 32990166b71SWen Congyang QEMUCPUState state; 33090166b71SWen Congyang Elf64_Nhdr *note64; 33190166b71SWen Congyang Elf32_Nhdr *note32; 33290166b71SWen Congyang void *note; 33390166b71SWen Congyang char *buf; 33490166b71SWen Congyang int descsz, note_size, name_size = 5, note_head_size; 33590166b71SWen Congyang const char *name = "QEMU"; 33690166b71SWen Congyang int ret; 33790166b71SWen Congyang 33890166b71SWen Congyang qemu_get_cpustate(&state, env); 33990166b71SWen Congyang 34090166b71SWen Congyang descsz = sizeof(state); 34190166b71SWen Congyang if (type == 0) { 34290166b71SWen Congyang note_head_size = sizeof(Elf32_Nhdr); 34390166b71SWen Congyang } else { 34490166b71SWen Congyang note_head_size = sizeof(Elf64_Nhdr); 34590166b71SWen Congyang } 34690166b71SWen Congyang note_size = ((note_head_size + 3) / 4 + (name_size + 3) / 4 + 34790166b71SWen Congyang (descsz + 3) / 4) * 4; 34890166b71SWen Congyang note = g_malloc(note_size); 34990166b71SWen Congyang 35090166b71SWen Congyang memset(note, 0, note_size); 35190166b71SWen Congyang if (type == 0) { 35290166b71SWen Congyang note32 = note; 35390166b71SWen Congyang note32->n_namesz = cpu_to_le32(name_size); 35490166b71SWen Congyang note32->n_descsz = cpu_to_le32(descsz); 35590166b71SWen Congyang note32->n_type = 0; 35690166b71SWen Congyang } else { 35790166b71SWen Congyang note64 = note; 35890166b71SWen Congyang note64->n_namesz = cpu_to_le32(name_size); 35990166b71SWen Congyang note64->n_descsz = cpu_to_le32(descsz); 36090166b71SWen Congyang note64->n_type = 0; 36190166b71SWen Congyang } 36290166b71SWen Congyang buf = note; 36390166b71SWen Congyang buf += ((note_head_size + 3) / 4) * 4; 36490166b71SWen Congyang memcpy(buf, name, name_size); 36590166b71SWen Congyang buf += ((name_size + 3) / 4) * 4; 36690166b71SWen Congyang memcpy(buf, &state, sizeof(state)); 36790166b71SWen Congyang 36890166b71SWen Congyang ret = f(note, note_size, opaque); 36990166b71SWen Congyang g_free(note); 37090166b71SWen Congyang if (ret < 0) { 37190166b71SWen Congyang return -1; 37290166b71SWen Congyang } 37390166b71SWen Congyang 37490166b71SWen Congyang return 0; 37590166b71SWen Congyang } 37690166b71SWen Congyang 377c72bf468SJens Freimann int x86_cpu_write_elf64_qemunote(WriteCoreDumpFunction f, CPUState *cs, 37890166b71SWen Congyang void *opaque) 37990166b71SWen Congyang { 380c72bf468SJens Freimann X86CPU *cpu = X86_CPU(cs); 381c72bf468SJens Freimann 382c72bf468SJens Freimann return cpu_write_qemu_note(f, &cpu->env, opaque, 1); 38390166b71SWen Congyang } 38490166b71SWen Congyang 385c72bf468SJens Freimann int x86_cpu_write_elf32_qemunote(WriteCoreDumpFunction f, CPUState *cs, 38690166b71SWen Congyang void *opaque) 38790166b71SWen Congyang { 388c72bf468SJens Freimann X86CPU *cpu = X86_CPU(cs); 389c72bf468SJens Freimann 390c72bf468SJens Freimann return cpu_write_qemu_note(f, &cpu->env, opaque, 0); 39190166b71SWen Congyang } 39225ae9c1dSWen Congyang 39356c4bfb3SLaszlo Ersek int cpu_get_dump_info(ArchDumpInfo *info, 39456c4bfb3SLaszlo Ersek const GuestPhysBlockList *guest_phys_blocks) 39525ae9c1dSWen Congyang { 39625ae9c1dSWen Congyang bool lma = false; 39756c4bfb3SLaszlo Ersek GuestPhysBlock *block; 39825ae9c1dSWen Congyang 39925ae9c1dSWen Congyang #ifdef TARGET_X86_64 400182735efSAndreas Färber X86CPU *first_x86_cpu = X86_CPU(first_cpu); 401182735efSAndreas Färber 402182735efSAndreas Färber lma = !!(first_x86_cpu->env.hflags & HF_LMA_MASK); 40325ae9c1dSWen Congyang #endif 40425ae9c1dSWen Congyang 40525ae9c1dSWen Congyang if (lma) { 40625ae9c1dSWen Congyang info->d_machine = EM_X86_64; 40725ae9c1dSWen Congyang } else { 40825ae9c1dSWen Congyang info->d_machine = EM_386; 40925ae9c1dSWen Congyang } 41025ae9c1dSWen Congyang info->d_endian = ELFDATA2LSB; 41125ae9c1dSWen Congyang 41225ae9c1dSWen Congyang if (lma) { 41325ae9c1dSWen Congyang info->d_class = ELFCLASS64; 41425ae9c1dSWen Congyang } else { 41525ae9c1dSWen Congyang info->d_class = ELFCLASS32; 41625ae9c1dSWen Congyang 41756c4bfb3SLaszlo Ersek QTAILQ_FOREACH(block, &guest_phys_blocks->head, next) { 41856c4bfb3SLaszlo Ersek if (block->target_end > UINT_MAX) { 41925ae9c1dSWen Congyang /* The memory size is greater than 4G */ 42025ae9c1dSWen Congyang info->d_class = ELFCLASS64; 42125ae9c1dSWen Congyang break; 42225ae9c1dSWen Congyang } 42325ae9c1dSWen Congyang } 42425ae9c1dSWen Congyang } 42525ae9c1dSWen Congyang 42625ae9c1dSWen Congyang return 0; 42725ae9c1dSWen Congyang } 4280038ffb0SWen Congyang 4294720bd05SPaolo Bonzini ssize_t cpu_get_note_size(int class, int machine, int nr_cpus) 4300038ffb0SWen Congyang { 4310038ffb0SWen Congyang int name_size = 5; /* "CORE" or "QEMU" */ 4320038ffb0SWen Congyang size_t elf_note_size = 0; 4330038ffb0SWen Congyang size_t qemu_note_size = 0; 4340038ffb0SWen Congyang int elf_desc_size = 0; 4350038ffb0SWen Congyang int qemu_desc_size = 0; 4360038ffb0SWen Congyang int note_head_size; 4370038ffb0SWen Congyang 4380038ffb0SWen Congyang if (class == ELFCLASS32) { 4390038ffb0SWen Congyang note_head_size = sizeof(Elf32_Nhdr); 4400038ffb0SWen Congyang } else { 4410038ffb0SWen Congyang note_head_size = sizeof(Elf64_Nhdr); 4420038ffb0SWen Congyang } 4430038ffb0SWen Congyang 4440038ffb0SWen Congyang if (machine == EM_386) { 4450038ffb0SWen Congyang elf_desc_size = sizeof(x86_elf_prstatus); 4460038ffb0SWen Congyang } 4470038ffb0SWen Congyang #ifdef TARGET_X86_64 4480038ffb0SWen Congyang else { 4490038ffb0SWen Congyang elf_desc_size = sizeof(x86_64_elf_prstatus); 4500038ffb0SWen Congyang } 4510038ffb0SWen Congyang #endif 4520038ffb0SWen Congyang qemu_desc_size = sizeof(QEMUCPUState); 4530038ffb0SWen Congyang 4540038ffb0SWen Congyang elf_note_size = ((note_head_size + 3) / 4 + (name_size + 3) / 4 + 4550038ffb0SWen Congyang (elf_desc_size + 3) / 4) * 4; 4560038ffb0SWen Congyang qemu_note_size = ((note_head_size + 3) / 4 + (name_size + 3) / 4 + 4570038ffb0SWen Congyang (qemu_desc_size + 3) / 4) * 4; 4580038ffb0SWen Congyang 4590038ffb0SWen Congyang return (elf_note_size + qemu_note_size) * nr_cpus; 4600038ffb0SWen Congyang } 461