1 /* 2 * i386 memory mapping 3 * 4 * Copyright Fujitsu, Corp. 2011, 2012 5 * 6 * Authors: 7 * Wen Congyang <wency@cn.fujitsu.com> 8 * 9 * This work is licensed under the terms of the GNU GPL, version 2 or later. 10 * See the COPYING file in the top-level directory. 11 * 12 */ 13 14 #include "qemu/osdep.h" 15 #include "cpu.h" 16 #include "exec/cpu-all.h" 17 #include "sysemu/dump.h" 18 #include "elf.h" 19 #include "sysemu/memory_mapping.h" 20 21 #define ELF_NOTE_SIZE(hdr_size, name_size, desc_size) \ 22 ((DIV_ROUND_UP((hdr_size), 4) \ 23 + DIV_ROUND_UP((name_size), 4) \ 24 + DIV_ROUND_UP((desc_size), 4)) * 4) 25 26 #ifdef TARGET_X86_64 27 typedef struct { 28 target_ulong r15, r14, r13, r12, rbp, rbx, r11, r10; 29 target_ulong r9, r8, rax, rcx, rdx, rsi, rdi, orig_rax; 30 target_ulong rip, cs, eflags; 31 target_ulong rsp, ss; 32 target_ulong fs_base, gs_base; 33 target_ulong ds, es, fs, gs; 34 } x86_64_user_regs_struct; 35 36 typedef struct { 37 char pad1[32]; 38 uint32_t pid; 39 char pad2[76]; 40 x86_64_user_regs_struct regs; 41 char pad3[8]; 42 } x86_64_elf_prstatus; 43 44 static int x86_64_write_elf64_note(WriteCoreDumpFunction f, 45 CPUX86State *env, int id, 46 void *opaque) 47 { 48 x86_64_user_regs_struct regs; 49 Elf64_Nhdr *note; 50 char *buf; 51 int descsz, note_size, name_size = 5; 52 const char *name = "CORE"; 53 int ret; 54 55 regs.r15 = env->regs[15]; 56 regs.r14 = env->regs[14]; 57 regs.r13 = env->regs[13]; 58 regs.r12 = env->regs[12]; 59 regs.r11 = env->regs[11]; 60 regs.r10 = env->regs[10]; 61 regs.r9 = env->regs[9]; 62 regs.r8 = env->regs[8]; 63 regs.rbp = env->regs[R_EBP]; 64 regs.rsp = env->regs[R_ESP]; 65 regs.rdi = env->regs[R_EDI]; 66 regs.rsi = env->regs[R_ESI]; 67 regs.rdx = env->regs[R_EDX]; 68 regs.rcx = env->regs[R_ECX]; 69 regs.rbx = env->regs[R_EBX]; 70 regs.rax = env->regs[R_EAX]; 71 regs.rip = env->eip; 72 regs.eflags = env->eflags; 73 74 regs.orig_rax = 0; /* FIXME */ 75 regs.cs = env->segs[R_CS].selector; 76 regs.ss = env->segs[R_SS].selector; 77 regs.fs_base = env->segs[R_FS].base; 78 regs.gs_base = env->segs[R_GS].base; 79 regs.ds = env->segs[R_DS].selector; 80 regs.es = env->segs[R_ES].selector; 81 regs.fs = env->segs[R_FS].selector; 82 regs.gs = env->segs[R_GS].selector; 83 84 descsz = sizeof(x86_64_elf_prstatus); 85 note_size = ELF_NOTE_SIZE(sizeof(Elf64_Nhdr), name_size, descsz); 86 note = g_malloc0(note_size); 87 note->n_namesz = cpu_to_le32(name_size); 88 note->n_descsz = cpu_to_le32(descsz); 89 note->n_type = cpu_to_le32(NT_PRSTATUS); 90 buf = (char *)note; 91 buf += ROUND_UP(sizeof(Elf64_Nhdr), 4); 92 memcpy(buf, name, name_size); 93 buf += ROUND_UP(name_size, 4); 94 memcpy(buf + 32, &id, 4); /* pr_pid */ 95 buf += descsz - sizeof(x86_64_user_regs_struct)-sizeof(target_ulong); 96 memcpy(buf, ®s, sizeof(x86_64_user_regs_struct)); 97 98 ret = f(note, note_size, opaque); 99 g_free(note); 100 if (ret < 0) { 101 return -1; 102 } 103 104 return 0; 105 } 106 #endif 107 108 typedef struct { 109 uint32_t ebx, ecx, edx, esi, edi, ebp, eax; 110 unsigned short ds, __ds, es, __es; 111 unsigned short fs, __fs, gs, __gs; 112 uint32_t orig_eax, eip; 113 unsigned short cs, __cs; 114 uint32_t eflags, esp; 115 unsigned short ss, __ss; 116 } x86_user_regs_struct; 117 118 typedef struct { 119 char pad1[24]; 120 uint32_t pid; 121 char pad2[44]; 122 x86_user_regs_struct regs; 123 char pad3[4]; 124 } x86_elf_prstatus; 125 126 static void x86_fill_elf_prstatus(x86_elf_prstatus *prstatus, CPUX86State *env, 127 int id) 128 { 129 memset(prstatus, 0, sizeof(x86_elf_prstatus)); 130 prstatus->regs.ebp = env->regs[R_EBP] & 0xffffffff; 131 prstatus->regs.esp = env->regs[R_ESP] & 0xffffffff; 132 prstatus->regs.edi = env->regs[R_EDI] & 0xffffffff; 133 prstatus->regs.esi = env->regs[R_ESI] & 0xffffffff; 134 prstatus->regs.edx = env->regs[R_EDX] & 0xffffffff; 135 prstatus->regs.ecx = env->regs[R_ECX] & 0xffffffff; 136 prstatus->regs.ebx = env->regs[R_EBX] & 0xffffffff; 137 prstatus->regs.eax = env->regs[R_EAX] & 0xffffffff; 138 prstatus->regs.eip = env->eip & 0xffffffff; 139 prstatus->regs.eflags = env->eflags & 0xffffffff; 140 141 prstatus->regs.cs = env->segs[R_CS].selector; 142 prstatus->regs.ss = env->segs[R_SS].selector; 143 prstatus->regs.ds = env->segs[R_DS].selector; 144 prstatus->regs.es = env->segs[R_ES].selector; 145 prstatus->regs.fs = env->segs[R_FS].selector; 146 prstatus->regs.gs = env->segs[R_GS].selector; 147 148 prstatus->pid = id; 149 } 150 151 static int x86_write_elf64_note(WriteCoreDumpFunction f, CPUX86State *env, 152 int id, void *opaque) 153 { 154 x86_elf_prstatus prstatus; 155 Elf64_Nhdr *note; 156 char *buf; 157 int descsz, note_size, name_size = 5; 158 const char *name = "CORE"; 159 int ret; 160 161 x86_fill_elf_prstatus(&prstatus, env, id); 162 descsz = sizeof(x86_elf_prstatus); 163 note_size = ELF_NOTE_SIZE(sizeof(Elf64_Nhdr), name_size, descsz); 164 note = g_malloc0(note_size); 165 note->n_namesz = cpu_to_le32(name_size); 166 note->n_descsz = cpu_to_le32(descsz); 167 note->n_type = cpu_to_le32(NT_PRSTATUS); 168 buf = (char *)note; 169 buf += ROUND_UP(sizeof(Elf64_Nhdr), 4); 170 memcpy(buf, name, name_size); 171 buf += ROUND_UP(name_size, 4); 172 memcpy(buf, &prstatus, sizeof(prstatus)); 173 174 ret = f(note, note_size, opaque); 175 g_free(note); 176 if (ret < 0) { 177 return -1; 178 } 179 180 return 0; 181 } 182 183 int x86_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs, 184 int cpuid, void *opaque) 185 { 186 X86CPU *cpu = X86_CPU(cs); 187 int ret; 188 #ifdef TARGET_X86_64 189 X86CPU *first_x86_cpu = X86_CPU(first_cpu); 190 bool lma = !!(first_x86_cpu->env.hflags & HF_LMA_MASK); 191 192 if (lma) { 193 ret = x86_64_write_elf64_note(f, &cpu->env, cpuid, opaque); 194 } else { 195 #endif 196 ret = x86_write_elf64_note(f, &cpu->env, cpuid, opaque); 197 #ifdef TARGET_X86_64 198 } 199 #endif 200 201 return ret; 202 } 203 204 int x86_cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cs, 205 int cpuid, void *opaque) 206 { 207 X86CPU *cpu = X86_CPU(cs); 208 x86_elf_prstatus prstatus; 209 Elf32_Nhdr *note; 210 char *buf; 211 int descsz, note_size, name_size = 5; 212 const char *name = "CORE"; 213 int ret; 214 215 x86_fill_elf_prstatus(&prstatus, &cpu->env, cpuid); 216 descsz = sizeof(x86_elf_prstatus); 217 note_size = ELF_NOTE_SIZE(sizeof(Elf32_Nhdr), name_size, descsz); 218 note = g_malloc0(note_size); 219 note->n_namesz = cpu_to_le32(name_size); 220 note->n_descsz = cpu_to_le32(descsz); 221 note->n_type = cpu_to_le32(NT_PRSTATUS); 222 buf = (char *)note; 223 buf += ROUND_UP(sizeof(Elf32_Nhdr), 4); 224 memcpy(buf, name, name_size); 225 buf += ROUND_UP(name_size, 4); 226 memcpy(buf, &prstatus, sizeof(prstatus)); 227 228 ret = f(note, note_size, opaque); 229 g_free(note); 230 if (ret < 0) { 231 return -1; 232 } 233 234 return 0; 235 } 236 237 /* 238 * please count up QEMUCPUSTATE_VERSION if you have changed definition of 239 * QEMUCPUState, and modify the tools using this information accordingly. 240 */ 241 #define QEMUCPUSTATE_VERSION (1) 242 243 struct QEMUCPUSegment { 244 uint32_t selector; 245 uint32_t limit; 246 uint32_t flags; 247 uint32_t pad; 248 uint64_t base; 249 }; 250 251 typedef struct QEMUCPUSegment QEMUCPUSegment; 252 253 struct QEMUCPUState { 254 uint32_t version; 255 uint32_t size; 256 uint64_t rax, rbx, rcx, rdx, rsi, rdi, rsp, rbp; 257 uint64_t r8, r9, r10, r11, r12, r13, r14, r15; 258 uint64_t rip, rflags; 259 QEMUCPUSegment cs, ds, es, fs, gs, ss; 260 QEMUCPUSegment ldt, tr, gdt, idt; 261 uint64_t cr[5]; 262 }; 263 264 typedef struct QEMUCPUState QEMUCPUState; 265 266 static void copy_segment(QEMUCPUSegment *d, SegmentCache *s) 267 { 268 d->pad = 0; 269 d->selector = s->selector; 270 d->limit = s->limit; 271 d->flags = s->flags; 272 d->base = s->base; 273 } 274 275 static void qemu_get_cpustate(QEMUCPUState *s, CPUX86State *env) 276 { 277 memset(s, 0, sizeof(QEMUCPUState)); 278 279 s->version = QEMUCPUSTATE_VERSION; 280 s->size = sizeof(QEMUCPUState); 281 282 s->rax = env->regs[R_EAX]; 283 s->rbx = env->regs[R_EBX]; 284 s->rcx = env->regs[R_ECX]; 285 s->rdx = env->regs[R_EDX]; 286 s->rsi = env->regs[R_ESI]; 287 s->rdi = env->regs[R_EDI]; 288 s->rsp = env->regs[R_ESP]; 289 s->rbp = env->regs[R_EBP]; 290 #ifdef TARGET_X86_64 291 s->r8 = env->regs[8]; 292 s->r9 = env->regs[9]; 293 s->r10 = env->regs[10]; 294 s->r11 = env->regs[11]; 295 s->r12 = env->regs[12]; 296 s->r13 = env->regs[13]; 297 s->r14 = env->regs[14]; 298 s->r15 = env->regs[15]; 299 #endif 300 s->rip = env->eip; 301 s->rflags = env->eflags; 302 303 copy_segment(&s->cs, &env->segs[R_CS]); 304 copy_segment(&s->ds, &env->segs[R_DS]); 305 copy_segment(&s->es, &env->segs[R_ES]); 306 copy_segment(&s->fs, &env->segs[R_FS]); 307 copy_segment(&s->gs, &env->segs[R_GS]); 308 copy_segment(&s->ss, &env->segs[R_SS]); 309 copy_segment(&s->ldt, &env->ldt); 310 copy_segment(&s->tr, &env->tr); 311 copy_segment(&s->gdt, &env->gdt); 312 copy_segment(&s->idt, &env->idt); 313 314 s->cr[0] = env->cr[0]; 315 s->cr[1] = env->cr[1]; 316 s->cr[2] = env->cr[2]; 317 s->cr[3] = env->cr[3]; 318 s->cr[4] = env->cr[4]; 319 } 320 321 static inline int cpu_write_qemu_note(WriteCoreDumpFunction f, 322 CPUX86State *env, 323 void *opaque, 324 int type) 325 { 326 QEMUCPUState state; 327 Elf64_Nhdr *note64; 328 Elf32_Nhdr *note32; 329 void *note; 330 char *buf; 331 int descsz, note_size, name_size = 5, note_head_size; 332 const char *name = "QEMU"; 333 int ret; 334 335 qemu_get_cpustate(&state, env); 336 337 descsz = sizeof(state); 338 if (type == 0) { 339 note_head_size = sizeof(Elf32_Nhdr); 340 } else { 341 note_head_size = sizeof(Elf64_Nhdr); 342 } 343 note_size = (DIV_ROUND_UP(note_head_size, 4) + DIV_ROUND_UP(name_size, 4) + 344 DIV_ROUND_UP(descsz, 4)) * 4; 345 note = g_malloc0(note_size); 346 if (type == 0) { 347 note32 = note; 348 note32->n_namesz = cpu_to_le32(name_size); 349 note32->n_descsz = cpu_to_le32(descsz); 350 note32->n_type = 0; 351 } else { 352 note64 = note; 353 note64->n_namesz = cpu_to_le32(name_size); 354 note64->n_descsz = cpu_to_le32(descsz); 355 note64->n_type = 0; 356 } 357 buf = note; 358 buf += ROUND_UP(note_head_size, 4); 359 memcpy(buf, name, name_size); 360 buf += ROUND_UP(name_size, 4); 361 memcpy(buf, &state, sizeof(state)); 362 363 ret = f(note, note_size, opaque); 364 g_free(note); 365 if (ret < 0) { 366 return -1; 367 } 368 369 return 0; 370 } 371 372 int x86_cpu_write_elf64_qemunote(WriteCoreDumpFunction f, CPUState *cs, 373 void *opaque) 374 { 375 X86CPU *cpu = X86_CPU(cs); 376 377 return cpu_write_qemu_note(f, &cpu->env, opaque, 1); 378 } 379 380 int x86_cpu_write_elf32_qemunote(WriteCoreDumpFunction f, CPUState *cs, 381 void *opaque) 382 { 383 X86CPU *cpu = X86_CPU(cs); 384 385 return cpu_write_qemu_note(f, &cpu->env, opaque, 0); 386 } 387 388 int cpu_get_dump_info(ArchDumpInfo *info, 389 const GuestPhysBlockList *guest_phys_blocks) 390 { 391 bool lma = false; 392 GuestPhysBlock *block; 393 394 #ifdef TARGET_X86_64 395 X86CPU *first_x86_cpu = X86_CPU(first_cpu); 396 lma = first_cpu && (first_x86_cpu->env.hflags & HF_LMA_MASK); 397 #endif 398 399 if (lma) { 400 info->d_machine = EM_X86_64; 401 } else { 402 info->d_machine = EM_386; 403 } 404 info->d_endian = ELFDATA2LSB; 405 406 if (lma) { 407 info->d_class = ELFCLASS64; 408 } else { 409 info->d_class = ELFCLASS32; 410 411 QTAILQ_FOREACH(block, &guest_phys_blocks->head, next) { 412 if (block->target_end > UINT_MAX) { 413 /* The memory size is greater than 4G */ 414 info->d_class = ELFCLASS64; 415 break; 416 } 417 } 418 } 419 420 return 0; 421 } 422 423 ssize_t cpu_get_note_size(int class, int machine, int nr_cpus) 424 { 425 int name_size = 5; /* "CORE" or "QEMU" */ 426 size_t elf_note_size = 0; 427 size_t qemu_note_size = 0; 428 int elf_desc_size = 0; 429 int qemu_desc_size = 0; 430 int note_head_size; 431 432 if (class == ELFCLASS32) { 433 note_head_size = sizeof(Elf32_Nhdr); 434 } else { 435 note_head_size = sizeof(Elf64_Nhdr); 436 } 437 438 if (machine == EM_386) { 439 elf_desc_size = sizeof(x86_elf_prstatus); 440 } 441 #ifdef TARGET_X86_64 442 else { 443 elf_desc_size = sizeof(x86_64_elf_prstatus); 444 } 445 #endif 446 qemu_desc_size = sizeof(QEMUCPUState); 447 448 elf_note_size = ELF_NOTE_SIZE(note_head_size, name_size, elf_desc_size); 449 qemu_note_size = ELF_NOTE_SIZE(note_head_size, name_size, qemu_desc_size); 450 451 return (elf_note_size + qemu_note_size) * nr_cpus; 452 } 453