xref: /qemu/target/i386/arch_dump.c (revision 9fecbed0c03ddad63c27f1622e2002fdfc2f45e4)
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"
169fecbed0SWen Congyang #include "elf.h"
179fecbed0SWen Congyang 
189fecbed0SWen Congyang #ifdef TARGET_X86_64
199fecbed0SWen Congyang typedef struct {
209fecbed0SWen Congyang     target_ulong r15, r14, r13, r12, rbp, rbx, r11, r10;
219fecbed0SWen Congyang     target_ulong r9, r8, rax, rcx, rdx, rsi, rdi, orig_rax;
229fecbed0SWen Congyang     target_ulong rip, cs, eflags;
239fecbed0SWen Congyang     target_ulong rsp, ss;
249fecbed0SWen Congyang     target_ulong fs_base, gs_base;
259fecbed0SWen Congyang     target_ulong ds, es, fs, gs;
269fecbed0SWen Congyang } x86_64_user_regs_struct;
279fecbed0SWen Congyang 
289fecbed0SWen Congyang typedef struct {
299fecbed0SWen Congyang     char pad1[32];
309fecbed0SWen Congyang     uint32_t pid;
319fecbed0SWen Congyang     char pad2[76];
329fecbed0SWen Congyang     x86_64_user_regs_struct regs;
339fecbed0SWen Congyang     char pad3[8];
349fecbed0SWen Congyang } x86_64_elf_prstatus;
359fecbed0SWen Congyang 
369fecbed0SWen Congyang static int x86_64_write_elf64_note(write_core_dump_function f,
379fecbed0SWen Congyang                                    CPUArchState *env, int id,
389fecbed0SWen Congyang                                    void *opaque)
399fecbed0SWen Congyang {
409fecbed0SWen Congyang     x86_64_user_regs_struct regs;
419fecbed0SWen Congyang     Elf64_Nhdr *note;
429fecbed0SWen Congyang     char *buf;
439fecbed0SWen Congyang     int descsz, note_size, name_size = 5;
449fecbed0SWen Congyang     const char *name = "CORE";
459fecbed0SWen Congyang     int ret;
469fecbed0SWen Congyang 
479fecbed0SWen Congyang     regs.r15 = env->regs[15];
489fecbed0SWen Congyang     regs.r14 = env->regs[14];
499fecbed0SWen Congyang     regs.r13 = env->regs[13];
509fecbed0SWen Congyang     regs.r12 = env->regs[12];
519fecbed0SWen Congyang     regs.r11 = env->regs[11];
529fecbed0SWen Congyang     regs.r10 = env->regs[10];
539fecbed0SWen Congyang     regs.r9  = env->regs[9];
549fecbed0SWen Congyang     regs.r8  = env->regs[8];
559fecbed0SWen Congyang     regs.rbp = env->regs[R_EBP];
569fecbed0SWen Congyang     regs.rsp = env->regs[R_ESP];
579fecbed0SWen Congyang     regs.rdi = env->regs[R_EDI];
589fecbed0SWen Congyang     regs.rsi = env->regs[R_ESI];
599fecbed0SWen Congyang     regs.rdx = env->regs[R_EDX];
609fecbed0SWen Congyang     regs.rcx = env->regs[R_ECX];
619fecbed0SWen Congyang     regs.rbx = env->regs[R_EBX];
629fecbed0SWen Congyang     regs.rax = env->regs[R_EAX];
639fecbed0SWen Congyang     regs.rip = env->eip;
649fecbed0SWen Congyang     regs.eflags = env->eflags;
659fecbed0SWen Congyang 
669fecbed0SWen Congyang     regs.orig_rax = 0; /* FIXME */
679fecbed0SWen Congyang     regs.cs = env->segs[R_CS].selector;
689fecbed0SWen Congyang     regs.ss = env->segs[R_SS].selector;
699fecbed0SWen Congyang     regs.fs_base = env->segs[R_FS].base;
709fecbed0SWen Congyang     regs.gs_base = env->segs[R_GS].base;
719fecbed0SWen Congyang     regs.ds = env->segs[R_DS].selector;
729fecbed0SWen Congyang     regs.es = env->segs[R_ES].selector;
739fecbed0SWen Congyang     regs.fs = env->segs[R_FS].selector;
749fecbed0SWen Congyang     regs.gs = env->segs[R_GS].selector;
759fecbed0SWen Congyang 
769fecbed0SWen Congyang     descsz = sizeof(x86_64_elf_prstatus);
779fecbed0SWen Congyang     note_size = ((sizeof(Elf64_Nhdr) + 3) / 4 + (name_size + 3) / 4 +
789fecbed0SWen Congyang                 (descsz + 3) / 4) * 4;
799fecbed0SWen Congyang     note = g_malloc(note_size);
809fecbed0SWen Congyang 
819fecbed0SWen Congyang     memset(note, 0, note_size);
829fecbed0SWen Congyang     note->n_namesz = cpu_to_le32(name_size);
839fecbed0SWen Congyang     note->n_descsz = cpu_to_le32(descsz);
849fecbed0SWen Congyang     note->n_type = cpu_to_le32(NT_PRSTATUS);
859fecbed0SWen Congyang     buf = (char *)note;
869fecbed0SWen Congyang     buf += ((sizeof(Elf64_Nhdr) + 3) / 4) * 4;
879fecbed0SWen Congyang     memcpy(buf, name, name_size);
889fecbed0SWen Congyang     buf += ((name_size + 3) / 4) * 4;
899fecbed0SWen Congyang     memcpy(buf + 32, &id, 4); /* pr_pid */
909fecbed0SWen Congyang     buf += descsz - sizeof(x86_64_user_regs_struct)-sizeof(target_ulong);
919fecbed0SWen Congyang     memcpy(buf, &regs, sizeof(x86_64_user_regs_struct));
929fecbed0SWen Congyang 
939fecbed0SWen Congyang     ret = f(note, note_size, opaque);
949fecbed0SWen Congyang     g_free(note);
959fecbed0SWen Congyang     if (ret < 0) {
969fecbed0SWen Congyang         return -1;
979fecbed0SWen Congyang     }
989fecbed0SWen Congyang 
999fecbed0SWen Congyang     return 0;
1009fecbed0SWen Congyang }
1019fecbed0SWen Congyang #endif
1029fecbed0SWen Congyang 
1039fecbed0SWen Congyang typedef struct {
1049fecbed0SWen Congyang     uint32_t ebx, ecx, edx, esi, edi, ebp, eax;
1059fecbed0SWen Congyang     unsigned short ds, __ds, es, __es;
1069fecbed0SWen Congyang     unsigned short fs, __fs, gs, __gs;
1079fecbed0SWen Congyang     uint32_t orig_eax, eip;
1089fecbed0SWen Congyang     unsigned short cs, __cs;
1099fecbed0SWen Congyang     uint32_t eflags, esp;
1109fecbed0SWen Congyang     unsigned short ss, __ss;
1119fecbed0SWen Congyang } x86_user_regs_struct;
1129fecbed0SWen Congyang 
1139fecbed0SWen Congyang typedef struct {
1149fecbed0SWen Congyang     char pad1[24];
1159fecbed0SWen Congyang     uint32_t pid;
1169fecbed0SWen Congyang     char pad2[44];
1179fecbed0SWen Congyang     x86_user_regs_struct regs;
1189fecbed0SWen Congyang     char pad3[4];
1199fecbed0SWen Congyang } x86_elf_prstatus;
1209fecbed0SWen Congyang 
1219fecbed0SWen Congyang static void x86_fill_elf_prstatus(x86_elf_prstatus *prstatus, CPUArchState *env,
1229fecbed0SWen Congyang                                   int id)
1239fecbed0SWen Congyang {
1249fecbed0SWen Congyang     memset(prstatus, 0, sizeof(x86_elf_prstatus));
1259fecbed0SWen Congyang     prstatus->regs.ebp = env->regs[R_EBP] & 0xffffffff;
1269fecbed0SWen Congyang     prstatus->regs.esp = env->regs[R_ESP] & 0xffffffff;
1279fecbed0SWen Congyang     prstatus->regs.edi = env->regs[R_EDI] & 0xffffffff;
1289fecbed0SWen Congyang     prstatus->regs.esi = env->regs[R_ESI] & 0xffffffff;
1299fecbed0SWen Congyang     prstatus->regs.edx = env->regs[R_EDX] & 0xffffffff;
1309fecbed0SWen Congyang     prstatus->regs.ecx = env->regs[R_ECX] & 0xffffffff;
1319fecbed0SWen Congyang     prstatus->regs.ebx = env->regs[R_EBX] & 0xffffffff;
1329fecbed0SWen Congyang     prstatus->regs.eax = env->regs[R_EAX] & 0xffffffff;
1339fecbed0SWen Congyang     prstatus->regs.eip = env->eip & 0xffffffff;
1349fecbed0SWen Congyang     prstatus->regs.eflags = env->eflags & 0xffffffff;
1359fecbed0SWen Congyang 
1369fecbed0SWen Congyang     prstatus->regs.cs = env->segs[R_CS].selector;
1379fecbed0SWen Congyang     prstatus->regs.ss = env->segs[R_SS].selector;
1389fecbed0SWen Congyang     prstatus->regs.ds = env->segs[R_DS].selector;
1399fecbed0SWen Congyang     prstatus->regs.es = env->segs[R_ES].selector;
1409fecbed0SWen Congyang     prstatus->regs.fs = env->segs[R_FS].selector;
1419fecbed0SWen Congyang     prstatus->regs.gs = env->segs[R_GS].selector;
1429fecbed0SWen Congyang 
1439fecbed0SWen Congyang     prstatus->pid = id;
1449fecbed0SWen Congyang }
1459fecbed0SWen Congyang 
1469fecbed0SWen Congyang static int x86_write_elf64_note(write_core_dump_function f, CPUArchState *env,
1479fecbed0SWen Congyang                                 int id, void *opaque)
1489fecbed0SWen Congyang {
1499fecbed0SWen Congyang     x86_elf_prstatus prstatus;
1509fecbed0SWen Congyang     Elf64_Nhdr *note;
1519fecbed0SWen Congyang     char *buf;
1529fecbed0SWen Congyang     int descsz, note_size, name_size = 5;
1539fecbed0SWen Congyang     const char *name = "CORE";
1549fecbed0SWen Congyang     int ret;
1559fecbed0SWen Congyang 
1569fecbed0SWen Congyang     x86_fill_elf_prstatus(&prstatus, env, id);
1579fecbed0SWen Congyang     descsz = sizeof(x86_elf_prstatus);
1589fecbed0SWen Congyang     note_size = ((sizeof(Elf64_Nhdr) + 3) / 4 + (name_size + 3) / 4 +
1599fecbed0SWen Congyang                 (descsz + 3) / 4) * 4;
1609fecbed0SWen Congyang     note = g_malloc(note_size);
1619fecbed0SWen Congyang 
1629fecbed0SWen Congyang     memset(note, 0, note_size);
1639fecbed0SWen Congyang     note->n_namesz = cpu_to_le32(name_size);
1649fecbed0SWen Congyang     note->n_descsz = cpu_to_le32(descsz);
1659fecbed0SWen Congyang     note->n_type = cpu_to_le32(NT_PRSTATUS);
1669fecbed0SWen Congyang     buf = (char *)note;
1679fecbed0SWen Congyang     buf += ((sizeof(Elf64_Nhdr) + 3) / 4) * 4;
1689fecbed0SWen Congyang     memcpy(buf, name, name_size);
1699fecbed0SWen Congyang     buf += ((name_size + 3) / 4) * 4;
1709fecbed0SWen Congyang     memcpy(buf, &prstatus, sizeof(prstatus));
1719fecbed0SWen Congyang 
1729fecbed0SWen Congyang     ret = f(note, note_size, opaque);
1739fecbed0SWen Congyang     g_free(note);
1749fecbed0SWen Congyang     if (ret < 0) {
1759fecbed0SWen Congyang         return -1;
1769fecbed0SWen Congyang     }
1779fecbed0SWen Congyang 
1789fecbed0SWen Congyang     return 0;
1799fecbed0SWen Congyang }
1809fecbed0SWen Congyang 
1819fecbed0SWen Congyang int cpu_write_elf64_note(write_core_dump_function f, CPUArchState *env,
1829fecbed0SWen Congyang                          int cpuid, void *opaque)
1839fecbed0SWen Congyang {
1849fecbed0SWen Congyang     int ret;
1859fecbed0SWen Congyang #ifdef TARGET_X86_64
1869fecbed0SWen Congyang     bool lma = !!(first_cpu->hflags & HF_LMA_MASK);
1879fecbed0SWen Congyang 
1889fecbed0SWen Congyang     if (lma) {
1899fecbed0SWen Congyang         ret = x86_64_write_elf64_note(f, env, cpuid, opaque);
1909fecbed0SWen Congyang     } else {
1919fecbed0SWen Congyang #endif
1929fecbed0SWen Congyang         ret = x86_write_elf64_note(f, env, cpuid, opaque);
1939fecbed0SWen Congyang #ifdef TARGET_X86_64
1949fecbed0SWen Congyang     }
1959fecbed0SWen Congyang #endif
1969fecbed0SWen Congyang 
1979fecbed0SWen Congyang     return ret;
1989fecbed0SWen Congyang }
1999fecbed0SWen Congyang 
2009fecbed0SWen Congyang int cpu_write_elf32_note(write_core_dump_function f, CPUArchState *env,
2019fecbed0SWen Congyang                          int cpuid, void *opaque)
2029fecbed0SWen Congyang {
2039fecbed0SWen Congyang     x86_elf_prstatus prstatus;
2049fecbed0SWen Congyang     Elf32_Nhdr *note;
2059fecbed0SWen Congyang     char *buf;
2069fecbed0SWen Congyang     int descsz, note_size, name_size = 5;
2079fecbed0SWen Congyang     const char *name = "CORE";
2089fecbed0SWen Congyang     int ret;
2099fecbed0SWen Congyang 
2109fecbed0SWen Congyang     x86_fill_elf_prstatus(&prstatus, env, cpuid);
2119fecbed0SWen Congyang     descsz = sizeof(x86_elf_prstatus);
2129fecbed0SWen Congyang     note_size = ((sizeof(Elf32_Nhdr) + 3) / 4 + (name_size + 3) / 4 +
2139fecbed0SWen Congyang                 (descsz + 3) / 4) * 4;
2149fecbed0SWen Congyang     note = g_malloc(note_size);
2159fecbed0SWen Congyang 
2169fecbed0SWen Congyang     memset(note, 0, note_size);
2179fecbed0SWen Congyang     note->n_namesz = cpu_to_le32(name_size);
2189fecbed0SWen Congyang     note->n_descsz = cpu_to_le32(descsz);
2199fecbed0SWen Congyang     note->n_type = cpu_to_le32(NT_PRSTATUS);
2209fecbed0SWen Congyang     buf = (char *)note;
2219fecbed0SWen Congyang     buf += ((sizeof(Elf32_Nhdr) + 3) / 4) * 4;
2229fecbed0SWen Congyang     memcpy(buf, name, name_size);
2239fecbed0SWen Congyang     buf += ((name_size + 3) / 4) * 4;
2249fecbed0SWen Congyang     memcpy(buf, &prstatus, sizeof(prstatus));
2259fecbed0SWen Congyang 
2269fecbed0SWen Congyang     ret = f(note, note_size, opaque);
2279fecbed0SWen Congyang     g_free(note);
2289fecbed0SWen Congyang     if (ret < 0) {
2299fecbed0SWen Congyang         return -1;
2309fecbed0SWen Congyang     }
2319fecbed0SWen Congyang 
2329fecbed0SWen Congyang     return 0;
2339fecbed0SWen Congyang }
234