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, ®s, 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