vgdb: Handle EAGAIN in read_buf
[valgrind.git] / coregrind / m_coredump / coredump-elf.c
blob4a8c29c529a75900680260a49da99a9d2cf9671f
2 /*--------------------------------------------------------------------*/
3 /*--- Dumping core. coredump-elf.c ---*/
4 /*--------------------------------------------------------------------*/
6 /*
7 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
10 Copyright (C) 2000-2017 Julian Seward
11 jseward@acm.org
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, see <http://www.gnu.org/licenses/>.
26 The GNU General Public License is contained in the file COPYING.
29 #if defined(VGO_linux) || defined(VGO_freebsd)
31 #include "pub_core_basics.h"
32 #include "pub_core_vki.h"
33 #include "pub_core_aspacehl.h"
34 #include "pub_core_aspacemgr.h"
35 #include "pub_core_libcbase.h"
36 #include "pub_core_machine.h"
37 #include "pub_core_coredump.h"
38 #include "pub_core_libcprint.h"
39 #include "pub_core_libcfile.h" // VG_(close) et al
40 #include "pub_core_libcproc.h" // VG_(geteuid), VG_(getegid)
41 #include "pub_core_libcassert.h" // VG_(exit), vg_assert
42 #include "pub_core_mallocfree.h" // VG_(malloc), VG_(free)
43 #include "pub_core_threadstate.h"
44 #include "pub_core_xarray.h"
45 #include "pub_core_clientstate.h"
46 #include "pub_core_options.h"
49 Dump core
51 Generate a standard ELF core file corresponding to the client state
52 at the time of a crash.
54 #include <elf.h>
55 #ifndef NT_PRXFPREG
56 #define NT_PRXFPREG 0x46e62b7f /* copied from gdb5.1/include/elf/common.h */
57 #endif /* NT_PRXFPREG */
59 #if VG_WORDSIZE == 8
60 #define ESZ(x) Elf64_##x
61 #elif VG_WORDSIZE == 4
62 #define ESZ(x) Elf32_##x
63 #else
64 #error VG_WORDSIZE needs to ==4 or ==8
65 #endif
67 /* If true, then this Segment may be mentioned in the core */
68 static Bool may_dump(const NSegment *seg)
70 if (seg->kind == SkAnonC ||
71 seg->kind == SkShmC ||
72 (seg->kind == SkFileC &&
73 !VKI_S_ISCHR(seg->mode) && !VKI_S_ISBLK(seg->mode)))
74 return True;
76 return False;
79 /* If true, then this Segment's contents will be in the core */
80 static Bool should_dump(const NSegment *seg)
82 return may_dump(seg); // && seg->hasW;
85 static void fill_ehdr(ESZ(Ehdr) *ehdr, Int num_phdrs)
87 VG_(memset)(ehdr, 0, sizeof(*ehdr));
89 VG_(memcpy)(ehdr->e_ident, ELFMAG, SELFMAG);
90 ehdr->e_ident[EI_CLASS] = VG_ELF_CLASS;
91 ehdr->e_ident[EI_DATA] = VG_ELF_DATA2XXX;
92 ehdr->e_ident[EI_VERSION] = EV_CURRENT;
93 #if defined(VGO_freebsd)
94 ehdr->e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
95 #endif
97 ehdr->e_type = ET_CORE;
98 ehdr->e_machine = VG_ELF_MACHINE;
99 ehdr->e_version = EV_CURRENT;
100 ehdr->e_entry = 0;
101 ehdr->e_phoff = sizeof(ESZ(Ehdr));
102 ehdr->e_shoff = 0;
103 #if defined(VGP_nanomips_linux)
104 ehdr->e_flags = VKI_EF_NANOMIPS_ABI_P32;
105 #else
106 ehdr->e_flags = 0;
107 #endif
108 ehdr->e_ehsize = sizeof(ESZ(Ehdr));
109 ehdr->e_phentsize = sizeof(ESZ(Phdr));
110 ehdr->e_phnum = num_phdrs;
111 ehdr->e_shentsize = 0;
112 ehdr->e_shnum = 0;
113 ehdr->e_shstrndx = 0;
117 static void fill_phdr(ESZ(Phdr) *phdr, const NSegment *seg, UInt off, Bool write)
119 SizeT len = seg->end - seg->start + 1;
121 write = write && should_dump(seg);
123 VG_(memset)(phdr, 0, sizeof(*phdr));
125 phdr->p_type = PT_LOAD;
126 phdr->p_offset = off;
127 phdr->p_vaddr = seg->start;
128 phdr->p_paddr = 0;
129 phdr->p_filesz = write ? len : 0;
130 phdr->p_memsz = len;
131 phdr->p_flags = 0;
133 if (seg->hasR)
134 phdr->p_flags |= PF_R;
135 if (seg->hasW)
136 phdr->p_flags |= PF_W;
137 if (seg->hasX)
138 phdr->p_flags |= PF_X;
140 phdr->p_align = VKI_PAGE_SIZE;
143 #if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
144 || defined(VGPV_mips32_linux_android)
145 /* Android's libc doesn't provide a definition for this. Hence: */
146 typedef
147 struct {
148 Elf32_Word n_namesz;
149 Elf32_Word n_descsz;
150 Elf32_Word n_type;
152 Elf32_Nhdr;
153 #endif
155 struct note {
156 struct note *next;
157 ESZ(Nhdr) note;
158 HChar name[0];
161 static UInt note_size(const struct note *n)
163 return sizeof(ESZ(Nhdr)) + VG_ROUNDUP(VG_(strlen)(n->name)+1, 4)
164 + VG_ROUNDUP(n->note.n_descsz, 4);
167 #if !defined(VGPV_arm_linux_android) \
168 && !defined(VGPV_x86_linux_android) \
169 && !defined(VGPV_mips32_linux_android) \
170 && !defined(VGPV_arm64_linux_android)
171 static void add_note(struct note **list, const HChar *name, UInt type,
172 const void *data, UInt datasz)
174 Int namelen = VG_(strlen)(name)+1;
175 Int notelen = sizeof(struct note) +
176 VG_ROUNDUP(namelen, 4) +
177 VG_ROUNDUP(datasz, 4);
178 struct note *n = VG_(malloc)("coredump-elf.an.1", notelen);
180 VG_(memset)(n, 0, notelen);
182 n->next = *list;
183 *list = n;
185 n->note.n_type = type;
186 n->note.n_namesz = namelen;
187 n->note.n_descsz = datasz;
189 VG_(memcpy)(n->name, name, namelen);
190 VG_(memcpy)(n->name+VG_ROUNDUP(namelen,4), data, datasz);
192 #endif /* !defined(VGPV_*_linux_android) */
194 static void write_note(Int fd, const struct note *n)
196 VG_(write)(fd, &n->note, note_size(n));
199 #if defined(VGO_freebsd)
200 static void fill_prpsinfo(const ThreadState *tst,
201 struct vki_elf_prpsinfo *prpsinfo)
203 VG_(memset)(prpsinfo, 0, sizeof(*prpsinfo));
205 prpsinfo->pr_version = VKI_PRPSINFO_VERSION;
206 prpsinfo->pr_psinfosz = sizeof(struct vki_elf_prpsinfo);
207 VG_(client_fname)(prpsinfo->pr_fname, sizeof(prpsinfo->pr_fname), False);
208 // why?
209 VG_(strncpy)(prpsinfo->pr_psargs, prpsinfo->pr_fname, sizeof(prpsinfo->pr_psargs) - 1);
211 #else
212 static void fill_prpsinfo(const ThreadState *tst,
213 struct vki_elf_prpsinfo *prpsinfo)
215 VG_(memset)(prpsinfo, 0, sizeof(*prpsinfo));
217 switch(tst->status) {
218 case VgTs_Runnable:
219 case VgTs_Yielding:
220 prpsinfo->pr_sname = 'R';
221 break;
223 case VgTs_WaitSys:
224 prpsinfo->pr_sname = 'S';
225 break;
227 case VgTs_Zombie:
228 prpsinfo->pr_sname = 'Z';
229 break;
231 case VgTs_Empty:
232 case VgTs_Init:
233 prpsinfo->pr_sname = '?';
234 break;
237 prpsinfo->pr_uid = 0;
238 prpsinfo->pr_gid = 0;
240 VG_(client_fname)(prpsinfo->pr_fname, sizeof(prpsinfo->pr_fname), False);
242 #endif
244 static void fill_prstatus(const ThreadState *tst,
245 /*OUT*/struct vki_elf_prstatus *prs,
246 const vki_siginfo_t *si)
248 #if defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \
249 || defined(VGP_nanomips_linux)
250 vki_elf_greg_t *regs;
251 #else
252 struct vki_user_regs_struct *regs;
253 #endif
254 const ThreadArchState* arch = &tst->arch;
256 VG_(memset)(prs, 0, sizeof(*prs));
258 #if defined(VGO_freebsd)
259 prs->pr_version = VKI_PRSTATUS_VERSION;
260 prs->pr_statussz = sizeof(struct vki_elf_prstatus);
261 prs->pr_gregsetsz = sizeof(vki_elf_gregset_t);
262 prs->pr_fpregsetsz = sizeof(vki_elf_fpregset_t);
263 prs->pr_osreldate = VG_(getosreldate)();
265 prs->pr_cursig = si->si_signo;
266 prs->pr_pid = tst->os_state.lwpid;
267 #else
268 prs->pr_info.si_signo = si->si_signo;
269 prs->pr_info.si_code = si->si_code;
270 prs->pr_info.si_errno = 0;
272 prs->pr_cursig = si->si_signo;
274 prs->pr_pid = tst->os_state.lwpid;
275 prs->pr_ppid = 0;
276 prs->pr_pgrp = VG_(getpgrp)();
277 prs->pr_sid = VG_(getpgrp)();
278 #endif
280 #if defined(VGP_s390x_linux)
281 /* prs->pr_reg has struct type. Need to take address. */
282 regs = (struct vki_user_regs_struct *)&(prs->pr_reg);
283 #elif defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \
284 || defined(VGP_nanomips_linux)
285 regs = (vki_elf_greg_t *)prs->pr_reg;
286 #else
287 regs = (struct vki_user_regs_struct *)prs->pr_reg;
288 vg_assert(sizeof(*regs) == sizeof(prs->pr_reg));
289 #endif
291 #if defined(VGP_x86_linux)
292 regs->eflags = LibVEX_GuestX86_get_eflags( &arch->vex );
293 regs->esp = arch->vex.guest_ESP;
294 regs->eip = arch->vex.guest_EIP;
296 regs->ebx = arch->vex.guest_EBX;
297 regs->ecx = arch->vex.guest_ECX;
298 regs->edx = arch->vex.guest_EDX;
299 regs->esi = arch->vex.guest_ESI;
300 regs->edi = arch->vex.guest_EDI;
301 regs->ebp = arch->vex.guest_EBP;
302 regs->eax = arch->vex.guest_EAX;
304 regs->cs = arch->vex.guest_CS;
305 regs->ds = arch->vex.guest_DS;
306 regs->ss = arch->vex.guest_SS;
307 regs->es = arch->vex.guest_ES;
308 regs->fs = arch->vex.guest_FS;
309 regs->gs = arch->vex.guest_GS;
311 #elif defined(VGP_amd64_linux)
312 regs->eflags = LibVEX_GuestAMD64_get_rflags( &arch->vex );
313 regs->rsp = arch->vex.guest_RSP;
314 regs->rip = arch->vex.guest_RIP;
316 regs->rbx = arch->vex.guest_RBX;
317 regs->rcx = arch->vex.guest_RCX;
318 regs->rdx = arch->vex.guest_RDX;
319 regs->rsi = arch->vex.guest_RSI;
320 regs->rdi = arch->vex.guest_RDI;
321 regs->rbp = arch->vex.guest_RBP;
322 regs->rax = arch->vex.guest_RAX;
323 regs->r8 = arch->vex.guest_R8;
324 regs->r9 = arch->vex.guest_R9;
325 regs->r10 = arch->vex.guest_R10;
326 regs->r11 = arch->vex.guest_R11;
327 regs->r12 = arch->vex.guest_R12;
328 regs->r13 = arch->vex.guest_R13;
329 regs->r14 = arch->vex.guest_R14;
330 regs->r15 = arch->vex.guest_R15;
332 #elif defined(VGP_ppc32_linux)
333 # define DO(n) regs->gpr[n] = arch->vex.guest_GPR##n
334 DO(0); DO(1); DO(2); DO(3); DO(4); DO(5); DO(6); DO(7);
335 DO(8); DO(9); DO(10); DO(11); DO(12); DO(13); DO(14); DO(15);
336 DO(16); DO(17); DO(18); DO(19); DO(20); DO(21); DO(22); DO(23);
337 DO(24); DO(25); DO(26); DO(27); DO(28); DO(29); DO(30); DO(31);
338 # undef DO
340 regs->nip = arch->vex.guest_CIA;
341 regs->msr = 0xf032; /* pretty arbitrary */
342 regs->orig_gpr3 = arch->vex.guest_GPR3;
343 regs->ctr = arch->vex.guest_CTR;
344 regs->link = arch->vex.guest_LR;
345 regs->xer = LibVEX_GuestPPC32_get_XER( &arch->vex );
346 regs->ccr = LibVEX_GuestPPC32_get_CR( &arch->vex );
347 regs->mq = 0;
348 regs->trap = 0;
349 regs->dar = 0; /* should be fault address? */
350 regs->dsisr = 0;
351 regs->result = 0;
353 #elif defined(VGP_ppc64be_linux)
354 # define DO(n) regs->gpr[n] = arch->vex.guest_GPR##n
355 DO(0); DO(1); DO(2); DO(3); DO(4); DO(5); DO(6); DO(7);
356 DO(8); DO(9); DO(10); DO(11); DO(12); DO(13); DO(14); DO(15);
357 DO(16); DO(17); DO(18); DO(19); DO(20); DO(21); DO(22); DO(23);
358 DO(24); DO(25); DO(26); DO(27); DO(28); DO(29); DO(30); DO(31);
359 # undef DO
361 regs->nip = arch->vex.guest_CIA;
362 regs->msr = 0xf032; /* pretty arbitrary */
363 regs->orig_gpr3 = arch->vex.guest_GPR3;
364 regs->ctr = arch->vex.guest_CTR;
365 regs->link = arch->vex.guest_LR;
366 regs->xer = LibVEX_GuestPPC64_get_XER( &arch->vex );
367 regs->ccr = LibVEX_GuestPPC64_get_CR( &arch->vex );
368 /* regs->mq = 0; */
369 regs->trap = 0;
370 regs->dar = 0; /* should be fault address? */
371 regs->dsisr = 0;
372 regs->result = 0;
374 #elif defined(VGP_ppc64le_linux)
375 # define DO(n) regs->gpr[n] = arch->vex.guest_GPR##n
376 DO(0); DO(1); DO(2); DO(3); DO(4); DO(5); DO(6); DO(7);
377 DO(8); DO(9); DO(10); DO(11); DO(12); DO(13); DO(14); DO(15);
378 DO(16); DO(17); DO(18); DO(19); DO(20); DO(21); DO(22); DO(23);
379 DO(24); DO(25); DO(26); DO(27); DO(28); DO(29); DO(30); DO(31);
380 # undef DO
382 regs->nip = arch->vex.guest_CIA;
383 regs->msr = 0xf033; /* pretty arbitrary */
384 regs->orig_gpr3 = arch->vex.guest_GPR3;
385 regs->ctr = arch->vex.guest_CTR;
386 regs->link = arch->vex.guest_LR;
387 regs->xer = LibVEX_GuestPPC64_get_XER( &(arch->vex) );
388 regs->ccr = LibVEX_GuestPPC64_get_CR( &(arch->vex) );
389 /* regs->mq = 0; */
390 regs->trap = 0;
391 regs->dar = 0; /* should be fault address? */
392 regs->dsisr = 0;
393 regs->result = 0;
395 #elif defined(VGP_arm_linux)
396 regs->ARM_r0 = arch->vex.guest_R0;
397 regs->ARM_r1 = arch->vex.guest_R1;
398 regs->ARM_r2 = arch->vex.guest_R2;
399 regs->ARM_r3 = arch->vex.guest_R3;
400 regs->ARM_r4 = arch->vex.guest_R4;
401 regs->ARM_r5 = arch->vex.guest_R5;
402 regs->ARM_r6 = arch->vex.guest_R6;
403 regs->ARM_r7 = arch->vex.guest_R7;
404 regs->ARM_r8 = arch->vex.guest_R8;
405 regs->ARM_r9 = arch->vex.guest_R9;
406 regs->ARM_r10 = arch->vex.guest_R10;
407 regs->ARM_fp = arch->vex.guest_R11;
408 regs->ARM_ip = arch->vex.guest_R12;
409 regs->ARM_sp = arch->vex.guest_R13;
410 regs->ARM_lr = arch->vex.guest_R14;
411 regs->ARM_pc = arch->vex.guest_R15T;
412 regs->ARM_cpsr = LibVEX_GuestARM_get_cpsr( &arch->vex );
414 #elif defined(VGP_arm64_linux)
415 regs->regs[0] = arch->vex.guest_X0;
416 regs->regs[1] = arch->vex.guest_X1;
417 regs->regs[2] = arch->vex.guest_X2;
418 regs->regs[3] = arch->vex.guest_X3;
419 regs->regs[4] = arch->vex.guest_X4;
420 regs->regs[5] = arch->vex.guest_X5;
421 regs->regs[6] = arch->vex.guest_X6;
422 regs->regs[7] = arch->vex.guest_X7;
423 regs->regs[8] = arch->vex.guest_X8;
424 regs->regs[9] = arch->vex.guest_X9;
425 regs->regs[10] = arch->vex.guest_X10;
426 regs->regs[11] = arch->vex.guest_X11;
427 regs->regs[12] = arch->vex.guest_X12;
428 regs->regs[13] = arch->vex.guest_X13;
429 regs->regs[14] = arch->vex.guest_X14;
430 regs->regs[15] = arch->vex.guest_X15;
431 regs->regs[16] = arch->vex.guest_X16;
432 regs->regs[17] = arch->vex.guest_X17;
433 regs->regs[18] = arch->vex.guest_X18;
434 regs->regs[19] = arch->vex.guest_X19;
435 regs->regs[20] = arch->vex.guest_X20;
436 regs->regs[21] = arch->vex.guest_X21;
437 regs->regs[22] = arch->vex.guest_X22;
438 regs->regs[23] = arch->vex.guest_X23;
439 regs->regs[24] = arch->vex.guest_X24;
440 regs->regs[25] = arch->vex.guest_X25;
441 regs->regs[26] = arch->vex.guest_X26;
442 regs->regs[27] = arch->vex.guest_X27;
443 regs->regs[28] = arch->vex.guest_X28;
444 regs->regs[29] = arch->vex.guest_X29;
445 regs->regs[30] = arch->vex.guest_X30;
446 regs->sp = arch->vex.guest_XSP;
447 regs->pc = arch->vex.guest_PC;
448 regs->pstate = LibVEX_GuestARM64_get_nzcv( &arch->vex ); /* is this correct? */
450 #elif defined(VGP_s390x_linux)
451 # define DO(n) regs->gprs[n] = arch->vex.guest_r##n
452 DO(0); DO(1); DO(2); DO(3); DO(4); DO(5); DO(6); DO(7);
453 DO(8); DO(9); DO(10); DO(11); DO(12); DO(13); DO(14); DO(15);
454 # undef DO
455 # define DO(n) regs->acrs[n] = arch->vex.guest_a##n
456 DO(0); DO(1); DO(2); DO(3); DO(4); DO(5); DO(6); DO(7);
457 DO(8); DO(9); DO(10); DO(11); DO(12); DO(13); DO(14); DO(15);
458 # undef DO
459 regs->orig_gpr2 = arch->vex.guest_r2;
461 #elif defined(VGP_mips32_linux)
462 # define DO(n) regs[VKI_MIPS32_EF_R##n] = arch->vex.guest_r##n
463 DO(1); DO(2); DO(3); DO(4); DO(5); DO(6); DO(7); DO(8);
464 DO(9); DO(10); DO(11); DO(12); DO(13); DO(14); DO(15); DO(16);
465 DO(17); DO(18); DO(19); DO(20); DO(21); DO(22); DO(23); DO(24);
466 DO(25); DO(28); DO(29); DO(30); DO(31);
467 # undef DO
468 regs[VKI_MIPS32_EF_LO] = arch->vex.guest_LO;
469 regs[VKI_MIPS32_EF_HI] = arch->vex.guest_HI;
470 regs[VKI_MIPS32_EF_CP0_STATUS] = arch->vex.guest_CP0_status;
471 regs[VKI_MIPS32_EF_CP0_EPC] = arch->vex.guest_PC;
472 #elif defined(VGP_mips64_linux)
473 # define DO(n) regs[VKI_MIPS64_EF_R##n] = arch->vex.guest_r##n
474 DO(1); DO(2); DO(3); DO(4); DO(5); DO(6); DO(7); DO(8);
475 DO(9); DO(10); DO(11); DO(12); DO(13); DO(14); DO(15); DO(16);
476 DO(17); DO(18); DO(19); DO(20); DO(21); DO(22); DO(23); DO(24);
477 DO(25); DO(28); DO(29); DO(30); DO(31);
478 # undef DO
479 regs[VKI_MIPS64_EF_LO] = arch->vex.guest_LO;
480 regs[VKI_MIPS64_EF_HI] = arch->vex.guest_HI;
481 regs[VKI_MIPS64_EF_CP0_STATUS] = arch->vex.guest_CP0_status;
482 regs[VKI_MIPS64_EF_CP0_EPC] = arch->vex.guest_PC;
483 #elif defined(VGP_nanomips_linux)
484 # define DO(n) regs[VKI_MIPS32_EF_R##n] = arch->vex.guest_r##n
485 DO(1); DO(2); DO(3); DO(4); DO(5); DO(6); DO(7); DO(8);
486 DO(9); DO(10); DO(11); DO(12); DO(13); DO(14); DO(15); DO(16);
487 DO(17); DO(18); DO(19); DO(20); DO(21); DO(22); DO(23); DO(24);
488 DO(25); DO(28); DO(29); DO(30); DO(31);
489 regs[VKI_MIPS32_EF_CP0_STATUS] = arch->vex.guest_CP0_status;
490 regs[VKI_MIPS32_EF_CP0_EPC] = arch->vex.guest_PC;
491 # undef DO
492 #elif defined(VGP_amd64_freebsd)
493 regs->rflags = LibVEX_GuestAMD64_get_rflags( &arch->vex );
494 regs->rsp = arch->vex.guest_RSP;
495 regs->rip = arch->vex.guest_RIP;
496 regs->rbx = arch->vex.guest_RBX;
497 regs->rcx = arch->vex.guest_RCX;
498 regs->rdx = arch->vex.guest_RDX;
499 regs->rsi = arch->vex.guest_RSI;
500 regs->rdi = arch->vex.guest_RDI;
501 regs->rbp = arch->vex.guest_RBP;
502 regs->rax = arch->vex.guest_RAX;
503 regs->r8 = arch->vex.guest_R8;
504 regs->r9 = arch->vex.guest_R9;
505 regs->r10 = arch->vex.guest_R10;
506 regs->r11 = arch->vex.guest_R11;
507 regs->r12 = arch->vex.guest_R12;
508 regs->r13 = arch->vex.guest_R13;
509 regs->r14 = arch->vex.guest_R14;
510 regs->r15 = arch->vex.guest_R15;
511 #elif defined(VGP_x86_freebsd)
512 regs->eflags = LibVEX_GuestX86_get_eflags( &arch->vex );
513 regs->esp = arch->vex.guest_ESP;
514 regs->eip = arch->vex.guest_EIP;
516 regs->ebx = arch->vex.guest_EBX;
517 regs->ecx = arch->vex.guest_ECX;
518 regs->edx = arch->vex.guest_EDX;
519 regs->esi = arch->vex.guest_ESI;
520 regs->edi = arch->vex.guest_EDI;
521 regs->ebp = arch->vex.guest_EBP;
522 regs->eax = arch->vex.guest_EAX;
524 regs->cs = arch->vex.guest_CS;
525 regs->ds = arch->vex.guest_DS;
526 regs->ss = arch->vex.guest_SS;
527 regs->es = arch->vex.guest_ES;
528 regs->fs = arch->vex.guest_FS;
529 regs->gs = arch->vex.guest_GS;
531 #else
532 # error Unknown ELF platform
533 #endif
536 static void fill_fpu(const ThreadState *tst, vki_elf_fpregset_t *fpu)
538 __attribute__((unused))
539 const ThreadArchState* arch = &tst->arch;
541 #if defined(VGP_x86_linux)
542 //:: static void fill_fpu(vki_elf_fpregset_t *fpu, const HChar *from)
543 //:: {
544 //:: if (VG_(have_ssestate)) {
545 //:: UShort *to;
546 //:: Int i;
547 //::
548 //:: /* This is what the kernel does */
549 //:: VG_(memcpy)(fpu, from, 7*sizeof(long));
550 //::
551 //:: to = (UShort *)&fpu->st_space[0];
552 //:: from += 18 * sizeof(UShort);
553 //::
554 //:: for (i = 0; i < 8; i++, to += 5, from += 8)
555 //:: VG_(memcpy)(to, from, 5*sizeof(UShort));
556 //:: } else
557 //:: VG_(memcpy)(fpu, from, sizeof(*fpu));
558 //:: }
560 //:: fill_fpu(fpu, (const HChar *)&arch->m_sse);
562 #elif defined(VGP_amd64_linux)
563 //:: fpu->cwd = ?;
564 //:: fpu->swd = ?;
565 //:: fpu->twd = ?;
566 //:: fpu->fop = ?;
567 //:: fpu->rip = ?;
568 //:: fpu->rdp = ?;
569 //:: fpu->mxcsr = ?;
570 //:: fpu->mxcsr_mask = ?;
571 //:: fpu->st_space = ?;
573 # define DO(n) VG_(memcpy)(fpu->xmm_space + n * 4, \
574 &arch->vex.guest_YMM##n[0], 16)
575 DO(0); DO(1); DO(2); DO(3); DO(4); DO(5); DO(6); DO(7);
576 DO(8); DO(9); DO(10); DO(11); DO(12); DO(13); DO(14); DO(15);
577 # undef DO
579 VG_(memset)(fpu->padding, 0, sizeof(fpu->padding));
581 #elif defined(VGP_ppc32_linux)
582 /* The guest state has the FPR fields declared as ULongs, so need
583 to fish out the values without converting them.
584 NOTE: The 32 FP registers map to the first 32 VSX registers.*/
585 # define DO(n) (*fpu)[n] = *(double*)(&arch->vex.guest_VSR##n)
586 DO(0); DO(1); DO(2); DO(3); DO(4); DO(5); DO(6); DO(7);
587 DO(8); DO(9); DO(10); DO(11); DO(12); DO(13); DO(14); DO(15);
588 DO(16); DO(17); DO(18); DO(19); DO(20); DO(21); DO(22); DO(23);
589 DO(24); DO(25); DO(26); DO(27); DO(28); DO(29); DO(30); DO(31);
590 # undef DO
592 #elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)
593 /* The guest state has the FPR fields declared as ULongs, so need
594 to fish out the values without converting them.
595 NOTE: The 32 FP registers map to the first 32 VSX registers.*/
596 # define DO(n) (*fpu)[n] = *(double*)(&arch->vex.guest_VSR##n)
597 DO(0); DO(1); DO(2); DO(3); DO(4); DO(5); DO(6); DO(7);
598 DO(8); DO(9); DO(10); DO(11); DO(12); DO(13); DO(14); DO(15);
599 DO(16); DO(17); DO(18); DO(19); DO(20); DO(21); DO(22); DO(23);
600 DO(24); DO(25); DO(26); DO(27); DO(28); DO(29); DO(30); DO(31);
601 # undef DO
603 #elif defined(VGP_arm_linux)
604 // umm ...
606 #elif defined(VGP_arm64_linux)
607 fpu->vregs[0] = *(const __uint128_t*)arch->vex.guest_Q0;
608 fpu->vregs[1] = *(const __uint128_t*)arch->vex.guest_Q1;
609 fpu->vregs[2] = *(const __uint128_t*)arch->vex.guest_Q2;
610 fpu->vregs[3] = *(const __uint128_t*)arch->vex.guest_Q3;
611 fpu->vregs[4] = *(const __uint128_t*)arch->vex.guest_Q4;
612 fpu->vregs[5] = *(const __uint128_t*)arch->vex.guest_Q5;
613 fpu->vregs[6] = *(const __uint128_t*)arch->vex.guest_Q6;
614 fpu->vregs[7] = *(const __uint128_t*)arch->vex.guest_Q7;
615 fpu->vregs[8] = *(const __uint128_t*)arch->vex.guest_Q8;
616 fpu->vregs[9] = *(const __uint128_t*)arch->vex.guest_Q9;
617 fpu->vregs[10] = *(const __uint128_t*)arch->vex.guest_Q10;
618 fpu->vregs[11] = *(const __uint128_t*)arch->vex.guest_Q11;
619 fpu->vregs[12] = *(const __uint128_t*)arch->vex.guest_Q12;
620 fpu->vregs[13] = *(const __uint128_t*)arch->vex.guest_Q13;
621 fpu->vregs[14] = *(const __uint128_t*)arch->vex.guest_Q14;
622 fpu->vregs[15] = *(const __uint128_t*)arch->vex.guest_Q15;
623 fpu->vregs[16] = *(const __uint128_t*)arch->vex.guest_Q16;
624 fpu->vregs[17] = *(const __uint128_t*)arch->vex.guest_Q17;
625 fpu->vregs[18] = *(const __uint128_t*)arch->vex.guest_Q18;
626 fpu->vregs[19] = *(const __uint128_t*)arch->vex.guest_Q19;
627 fpu->vregs[20] = *(const __uint128_t*)arch->vex.guest_Q20;
628 fpu->vregs[21] = *(const __uint128_t*)arch->vex.guest_Q21;
629 fpu->vregs[22] = *(const __uint128_t*)arch->vex.guest_Q22;
630 fpu->vregs[23] = *(const __uint128_t*)arch->vex.guest_Q23;
631 fpu->vregs[24] = *(const __uint128_t*)arch->vex.guest_Q24;
632 fpu->vregs[25] = *(const __uint128_t*)arch->vex.guest_Q25;
633 fpu->vregs[26] = *(const __uint128_t*)arch->vex.guest_Q26;
634 fpu->vregs[27] = *(const __uint128_t*)arch->vex.guest_Q27;
635 fpu->vregs[28] = *(const __uint128_t*)arch->vex.guest_Q28;
636 fpu->vregs[29] = *(const __uint128_t*)arch->vex.guest_Q29;
637 fpu->vregs[30] = *(const __uint128_t*)arch->vex.guest_Q30;
638 fpu->vregs[31] = *(const __uint128_t*)arch->vex.guest_Q31;
639 fpu->fpsr = *(const __vki_u32*)arch->vex.guest_QCFLAG;
640 fpu->fpcr = arch->vex.guest_FPCR;
642 #elif defined(VGP_s390x_linux)
643 /* NOTE: The 16 FP registers map to the first 16 VSX registers. */
644 # define DO(n) fpu->fprs[n].ui = *(const Double*)(&arch->vex.guest_v##n.w64[0])
645 DO(0); DO(1); DO(2); DO(3); DO(4); DO(5); DO(6); DO(7);
646 DO(8); DO(9); DO(10); DO(11); DO(12); DO(13); DO(14); DO(15);
647 # undef DO
648 #elif defined(VGP_mips32_linux) || defined(VGP_mips64_linux)
649 # define DO(n) (*fpu)[n] = *(const double*)(&arch->vex.guest_f##n)
650 DO(0); DO(1); DO(2); DO(3); DO(4); DO(5); DO(6); DO(7);
651 DO(8); DO(9); DO(10); DO(11); DO(12); DO(13); DO(14); DO(15);
652 DO(16); DO(17); DO(18); DO(19); DO(20); DO(21); DO(22); DO(23);
653 DO(24); DO(25); DO(26); DO(27); DO(28); DO(29); DO(30); DO(31);
654 # undef DO
655 #elif defined(VGP_nanomips_linux)
657 #elif defined(VGP_x86_freebsd)
659 #elif defined(VGP_amd64_freebsd)
661 # define DO(n) VG_(memcpy)(fpu->xmm_space + n * 4, \
662 &arch->vex.guest_YMM##n[0], 16)
663 DO(0); DO(1); DO(2); DO(3); DO(4); DO(5); DO(6); DO(7);
664 DO(8); DO(9); DO(10); DO(11); DO(12); DO(13); DO(14); DO(15);
665 # undef DO
667 #else
668 # error Unknown ELF platform
669 #endif
672 #if defined(VGP_x86_linux) && !defined(VGPV_x86_linux_android)
673 static void fill_xfpu(const ThreadState *tst, vki_elf_fpxregset_t *xfpu)
675 const ThreadArchState* arch = &tst->arch;
677 //:: xfpu->cwd = ?;
678 //:: xfpu->swd = ?;
679 //:: xfpu->twd = ?;
680 //:: xfpu->fop = ?;
681 //:: xfpu->fip = ?;
682 //:: xfpu->fcs = ?;
683 //:: xfpu->foo = ?;
684 //:: xfpu->fos = ?;
685 //:: xfpu->mxcsr = ?;
686 xfpu->reserved = 0;
687 //:: xfpu->st_space = ?;
689 # define DO(n) VG_(memcpy)(xfpu->xmm_space + n * 4, &arch->vex.guest_XMM##n, sizeof(arch->vex.guest_XMM##n))
690 DO(0); DO(1); DO(2); DO(3); DO(4); DO(5); DO(6); DO(7);
691 # undef DO
693 VG_(memset)(xfpu->padding, 0, sizeof(xfpu->padding));
695 #endif
697 static
698 void dump_one_thread(struct note **notelist, const vki_siginfo_t *si, ThreadId tid)
700 vki_elf_fpregset_t fpu;
701 struct vki_elf_prstatus prstatus;
702 const HChar* name;
703 # if !defined(VGO_freebsd)
704 name = "CORE";
705 # else
706 /* lldb on FreeBSD expects a prstatus with name "FreeBSD"
707 * see llvm::Error ProcessElfCore::parseFreeBSDNotes(llvm::ArrayRef<CoreNote> notes) in ProcessElfCore.cpp
708 * Otherwise it exits with "Could not find NT_PRSTATUS note in core file." */
709 name = "FreeBSD";
710 # endif
711 VG_(memset)(&fpu, 0, sizeof(fpu));
712 VG_(memset)(&prstatus, 0, sizeof(prstatus));
713 # if defined(VGP_x86_linux) && !defined(VGPV_x86_linux_android)
715 vki_elf_fpxregset_t xfpu;
716 VG_(memset)(&xfpu, 0, sizeof(xfpu));
717 fill_xfpu(&VG_(threads)[tid], &xfpu);
718 add_note(notelist, "LINUX", NT_PRXFPREG, &xfpu, sizeof(xfpu));
720 # endif
722 fill_fpu(&VG_(threads)[tid], &fpu);
723 # if !defined(VGPV_arm_linux_android) \
724 && !defined(VGPV_x86_linux_android) \
725 && !defined(VGPV_mips32_linux_android) \
726 && !defined(VGPV_arm64_linux_android) \
727 && !defined(VGP_nanomips_linux)
728 add_note(notelist, name, NT_FPREGSET, &fpu, sizeof(fpu));
729 # endif
731 fill_prstatus(&VG_(threads)[tid], &prstatus, si);
732 # if !defined(VGPV_arm_linux_android) \
733 && !defined(VGPV_x86_linux_android) \
734 && !defined(VGPV_mips32_linux_android) \
735 && !defined(VGPV_arm64_linux_android)
736 add_note(notelist, name, NT_PRSTATUS, &prstatus, sizeof(prstatus));
737 # endif
740 static
741 void make_elf_coredump(ThreadId tid, const vki_siginfo_t *si, ULong max_size)
743 HChar* buf = NULL;
744 HChar *basename;
745 const HChar *coreext = "";
746 Int seq = 0;
747 Int core_fd;
748 NSegment const * seg;
749 ESZ(Ehdr) ehdr;
750 ESZ(Phdr) *phdrs = NULL;
751 Int num_phdrs;
752 Int i, idx;
753 UInt off;
754 struct note *notelist, *note;
755 UInt notesz;
756 struct vki_elf_prpsinfo prpsinfo;
757 Addr *seg_starts = NULL;
758 Int n_seg_starts;
760 if (VG_(clo_log_fname_unexpanded) != NULL) {
761 coreext = ".core";
762 basename = VG_(expand_file_name)("--log-file",
763 VG_(clo_log_fname_unexpanded));
764 } else
765 basename = VG_(strdup)("coredump-elf.mec.1", "vgcore");
767 vg_assert(coreext);
768 vg_assert(basename);
769 buf = VG_(malloc)( "coredump-elf.mec.1",
770 VG_(strlen)(coreext) + VG_(strlen)(basename)
771 + 100/*for the two %ds. */ );
773 for(;;) {
774 Int oflags = VKI_O_CREAT|VKI_O_WRONLY|VKI_O_EXCL|VKI_O_TRUNC;
775 SysRes sres;
777 if (seq == 0)
778 VG_(sprintf)(buf, "%s%s.%d",
779 basename, coreext, VG_(getpid)());
780 else
781 VG_(sprintf)(buf, "%s%s.%d.%d",
782 basename, coreext, VG_(getpid)(), seq);
783 seq++;
785 # if defined(VKI_O_LARGEFILE)
786 oflags |= VKI_O_LARGEFILE;
787 # endif
789 sres = VG_(open)(buf, oflags, VKI_S_IRUSR|VKI_S_IWUSR);
790 if (!sr_isError(sres)) {
791 core_fd = sr_Res(sres);
792 break;
795 if (sr_isError(sres) && sr_Err(sres) != VKI_EEXIST)
796 goto cleanup; /* can't create file */
799 /* Get the client segments */
800 seg_starts = VG_(get_segment_starts)(SkFileC | SkAnonC | SkShmC,
801 &n_seg_starts);
803 /* First, count how many memory segments to dump */
804 num_phdrs = 1; /* start with notes */
805 for(i = 0; i < n_seg_starts; i++) {
806 if (!may_dump(VG_(am_find_nsegment)(seg_starts[i])))
807 continue;
809 num_phdrs++;
812 fill_ehdr(&ehdr, num_phdrs);
814 notelist = NULL;
816 /* Second, work out their layout */
817 phdrs = VG_(malloc)("coredump-elf.mec.1", sizeof(*phdrs) * num_phdrs);
819 /* Add details for all threads except the one that faulted */
820 for(i = 1; i < VG_N_THREADS; i++) {
822 if (VG_(threads)[i].status == VgTs_Empty)
823 continue;
825 if (i == tid)
826 continue;
828 dump_one_thread(&notelist, si, i);
831 /* Add details for the faulting thread. Note that because we are
832 adding to the head of a linked list this thread will actually
833 come out first in the core file, which seems to be how
834 debuggers determine that it is the faulting thread. */
835 dump_one_thread(&notelist, si, tid);
837 fill_prpsinfo(&VG_(threads)[tid], &prpsinfo);
838 # if !defined(VGPV_arm_linux_android) \
839 && !defined(VGPV_x86_linux_android) \
840 && !defined(VGPV_mips32_linux_android) \
841 && !defined(VGPV_arm64_linux_android)
842 add_note(&notelist, "CORE", NT_PRPSINFO, &prpsinfo, sizeof(prpsinfo));
843 # endif
845 for (note = notelist, notesz = 0; note != NULL; note = note->next)
846 notesz += note_size(note);
848 off = sizeof(ehdr) + sizeof(*phdrs) * num_phdrs;
850 phdrs[0].p_type = PT_NOTE;
851 phdrs[0].p_offset = off;
852 phdrs[0].p_vaddr = 0;
853 phdrs[0].p_paddr = 0;
854 phdrs[0].p_filesz = notesz;
855 phdrs[0].p_memsz = 0;
856 phdrs[0].p_flags = 0;
857 phdrs[0].p_align = 0;
859 off += notesz;
861 off = VG_PGROUNDUP(off);
863 for(i = 0, idx = 1; i < n_seg_starts; i++) {
864 seg = VG_(am_find_nsegment)(seg_starts[i]);
866 if (!may_dump(seg))
867 continue;
869 fill_phdr(&phdrs[idx], seg, off,
870 (seg->end - seg->start + 1 + off) < max_size);
872 off += phdrs[idx].p_filesz;
874 idx++;
877 /* write everything out */
878 VG_(write)(core_fd, &ehdr, sizeof(ehdr));
879 VG_(write)(core_fd, phdrs, sizeof(*phdrs) * num_phdrs);
881 for(note = notelist; note != NULL; note = note->next)
882 write_note(core_fd, note);
884 VG_(lseek)(core_fd, phdrs[1].p_offset, VKI_SEEK_SET);
886 for(i = 0, idx = 1; i < n_seg_starts; i++) {
887 seg = VG_(am_find_nsegment)(seg_starts[i]);
889 if (!should_dump(seg))
890 continue;
892 if (phdrs[idx].p_filesz > 0) {
893 vg_assert(VG_(lseek)(core_fd, phdrs[idx].p_offset, VKI_SEEK_SET)
894 == phdrs[idx].p_offset);
895 vg_assert(seg->end - seg->start + 1 >= phdrs[idx].p_filesz);
897 (void)VG_(write)(core_fd, (void *)seg->start, phdrs[idx].p_filesz);
899 idx++;
902 VG_(close)(core_fd);
904 cleanup:
905 VG_(free)(basename);
906 VG_(free)(buf);
907 VG_(free)(seg_starts);
908 VG_(free)(phdrs);
911 void VG_(make_coredump)(ThreadId tid, const vki_siginfo_t *si, ULong max_size)
913 make_elf_coredump(tid, si, max_size);
916 #endif // defined(VGO_linux)
918 /*--------------------------------------------------------------------*/
919 /*--- end ---*/
920 /*--------------------------------------------------------------------*/