1ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/ 3ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Dumping core. coredump-elf.c ---*/ 4ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/ 5ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 6ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* 7ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown This file is part of Valgrind, a dynamic binary instrumentation 8ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown framework. 9ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 10436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Copyright (C) 2000-2013 Julian Seward 11ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown jseward@acm.org 12ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 13ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown This program is free software; you can redistribute it and/or 14ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown modify it under the terms of the GNU General Public License as 15ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown published by the Free Software Foundation; either version 2 of the 16ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown License, or (at your option) any later version. 17ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 18ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown This program is distributed in the hope that it will be useful, but 19ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown WITHOUT ANY WARRANTY; without even the implied warranty of 20ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown General Public License for more details. 22ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 23ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown You should have received a copy of the GNU General Public License 24ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown along with this program; if not, write to the Free Software 25ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 26ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 02111-1307, USA. 27ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 28ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown The GNU General Public License is contained in the file COPYING. 29ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 30ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 31ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(VGO_linux) 32ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 33ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_basics.h" 34ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_vki.h" 35ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_aspacehl.h" 36ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_aspacemgr.h" 37ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_libcbase.h" 38ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_machine.h" 39ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_coredump.h" 40ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_libcprint.h" 41ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_libcfile.h" // VG_(close) et al 42ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_libcproc.h" // VG_(geteuid), VG_(getegid) 43ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_libcassert.h" // VG_(exit), vg_assert 44ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_mallocfree.h" // VG_(malloc), VG_(free) 45b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "pub_core_libcsetjmp.h" // to keep _threadstate.h happy 46ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_threadstate.h" 47ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_xarray.h" 48ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_clientstate.h" 49ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_options.h" 50ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 51ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* 52ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Dump core 53ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 54ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Generate a standard ELF core file corresponding to the client state 55ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown at the time of a crash. 56ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 57ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <elf.h> 58ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#ifndef NT_PRXFPREG 59b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define NT_PRXFPREG 0x46e62b7f /* copied from gdb5.1/include/elf/common.h */ 60ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif /* NT_PRXFPREG */ 61ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 62ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if VG_WORDSIZE == 8 63ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define ESZ(x) Elf64_##x 64ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#elif VG_WORDSIZE == 4 65ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define ESZ(x) Elf32_##x 66ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else 67ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#error VG_WORDSIZE needs to ==4 or ==8 68ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif 69ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 70ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* If true, then this Segment may be mentioned in the core */ 71ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic Bool may_dump(const NSegment *seg) 72ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 73ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (seg->kind == SkAnonC || 74ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown seg->kind == SkShmC || 75ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (seg->kind == SkFileC && 76ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown !VKI_S_ISCHR(seg->mode) && !VKI_S_ISBLK(seg->mode))) 77ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return True; 78ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 79ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return False; 80ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 81ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 82ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* If true, then this Segment's contents will be in the core */ 83ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic Bool should_dump(const NSegment *seg) 84ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 85ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return may_dump(seg); // && seg->hasW; 86ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 87ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 88ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void fill_ehdr(ESZ(Ehdr) *ehdr, Int num_phdrs) 89ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 90ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(memset)(ehdr, 0, sizeof(*ehdr)); 91ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 92ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(memcpy)(ehdr->e_ident, ELFMAG, SELFMAG); 93ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ehdr->e_ident[EI_CLASS] = VG_ELF_CLASS; 94ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ehdr->e_ident[EI_DATA] = VG_ELF_DATA2XXX; 95ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ehdr->e_ident[EI_VERSION] = EV_CURRENT; 96ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 97ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ehdr->e_type = ET_CORE; 98ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ehdr->e_machine = VG_ELF_MACHINE; 99ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ehdr->e_version = EV_CURRENT; 100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ehdr->e_entry = 0; 101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ehdr->e_phoff = sizeof(ESZ(Ehdr)); 102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ehdr->e_shoff = 0; 103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ehdr->e_flags = 0; 104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ehdr->e_ehsize = sizeof(ESZ(Ehdr)); 105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ehdr->e_phentsize = sizeof(ESZ(Phdr)); 106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ehdr->e_phnum = num_phdrs; 107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ehdr->e_shentsize = 0; 108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ehdr->e_shnum = 0; 109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ehdr->e_shstrndx = 0; 110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void fill_phdr(ESZ(Phdr) *phdr, const NSegment *seg, UInt off, Bool write) 114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SizeT len = seg->end - seg->start; 116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown write = write && should_dump(seg); 118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(memset)(phdr, 0, sizeof(*phdr)); 120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown phdr->p_type = PT_LOAD; 122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown phdr->p_offset = off; 123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown phdr->p_vaddr = seg->start; 124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown phdr->p_paddr = 0; 125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown phdr->p_filesz = write ? len : 0; 126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown phdr->p_memsz = len; 127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown phdr->p_flags = 0; 128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (seg->hasR) 130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown phdr->p_flags |= PF_R; 131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (seg->hasW) 132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown phdr->p_flags |= PF_W; 133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (seg->hasX) 134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown phdr->p_flags |= PF_X; 135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown phdr->p_align = VKI_PAGE_SIZE; 137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstruct note { 140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct note *next; 141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ESZ(Nhdr) note; 142436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HChar name[0]; 143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}; 144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic UInt note_size(const struct note *n) 146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 147b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return sizeof(ESZ(Nhdr)) + VG_ROUNDUP(VG_(strlen)(n->name)+1, 4) 148b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov + VG_ROUNDUP(n->note.n_descsz, 4); 149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 151436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#if !defined(VGPV_arm_linux_android) && !defined(VGPV_x86_linux_android) \ 152436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov && !defined(VGPV_mips32_linux_android) 153436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic void add_note(struct note **list, const HChar *name, UInt type, 154b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov const void *data, UInt datasz) 155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int namelen = VG_(strlen)(name)+1; 157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int notelen = sizeof(struct note) + 158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_ROUNDUP(namelen, 4) + 159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_ROUNDUP(datasz, 4); 160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct note *n = VG_(arena_malloc)(VG_AR_CORE, "coredump-elf.an.1", notelen); 161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(memset)(n, 0, notelen); 163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown n->next = *list; 165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *list = n; 166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown n->note.n_type = type; 168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown n->note.n_namesz = namelen; 169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown n->note.n_descsz = datasz; 170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(memcpy)(n->name, name, namelen); 172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(memcpy)(n->name+VG_ROUNDUP(namelen,4), data, datasz); 173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 174663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#endif /* !defined(VGPV_*_linux_android) */ 175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void write_note(Int fd, const struct note *n) 177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(write)(fd, &n->note, note_size(n)); 179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 181b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic void fill_prpsinfo(const ThreadState *tst, 182b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov struct vki_elf_prpsinfo *prpsinfo) 183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 184436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov static HChar name[VKI_PATH_MAX]; 185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(memset)(prpsinfo, 0, sizeof(*prpsinfo)); 187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch(tst->status) { 189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case VgTs_Runnable: 190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case VgTs_Yielding: 191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown prpsinfo->pr_sname = 'R'; 192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case VgTs_WaitSys: 195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown prpsinfo->pr_sname = 'S'; 196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case VgTs_Zombie: 199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown prpsinfo->pr_sname = 'Z'; 200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case VgTs_Empty: 203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case VgTs_Init: 204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown prpsinfo->pr_sname = '?'; 205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown prpsinfo->pr_uid = 0; 209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown prpsinfo->pr_gid = 0; 210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (VG_(resolve_filename)(VG_(cl_exec_fd), name, VKI_PATH_MAX)) { 212436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HChar *n = name+VG_(strlen)(name)-1; 213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (n > name && *n != '/') 215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown n--; 216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (n != name) 217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown n++; 218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(strncpy)(prpsinfo->pr_fname, n, sizeof(prpsinfo->pr_fname)); 220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void fill_prstatus(const ThreadState *tst, 224436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /*OUT*/struct vki_elf_prstatus *prs, 225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown const vki_siginfo_t *si) 226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct vki_user_regs_struct *regs; 228436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov const ThreadArchState* arch = &tst->arch; 229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(memset)(prs, 0, sizeof(*prs)); 231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown prs->pr_info.si_signo = si->si_signo; 233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown prs->pr_info.si_code = si->si_code; 234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown prs->pr_info.si_errno = 0; 235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown prs->pr_cursig = si->si_signo; 237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown prs->pr_pid = tst->os_state.lwpid; 239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown prs->pr_ppid = 0; 240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown prs->pr_pgrp = VG_(getpgrp)(); 241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown prs->pr_sid = VG_(getpgrp)(); 242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 243436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#if defined(VGP_s390x_linux) 244b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* prs->pr_reg has struct type. Need to take address. */ 245b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov regs = (struct vki_user_regs_struct *)&(prs->pr_reg); 246b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#else 247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown regs = (struct vki_user_regs_struct *)prs->pr_reg; 248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(sizeof(*regs) == sizeof(prs->pr_reg)); 249b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif 250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(VGP_x86_linux) 252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown regs->eflags = LibVEX_GuestX86_get_eflags( &arch->vex ); 253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown regs->esp = arch->vex.guest_ESP; 254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown regs->eip = arch->vex.guest_EIP; 255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown regs->ebx = arch->vex.guest_EBX; 257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown regs->ecx = arch->vex.guest_ECX; 258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown regs->edx = arch->vex.guest_EDX; 259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown regs->esi = arch->vex.guest_ESI; 260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown regs->edi = arch->vex.guest_EDI; 261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown regs->ebp = arch->vex.guest_EBP; 262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown regs->eax = arch->vex.guest_EAX; 263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown regs->cs = arch->vex.guest_CS; 265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown regs->ds = arch->vex.guest_DS; 266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown regs->ss = arch->vex.guest_SS; 267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown regs->es = arch->vex.guest_ES; 268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown regs->fs = arch->vex.guest_FS; 269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown regs->gs = arch->vex.guest_GS; 270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#elif defined(VGP_amd64_linux) 272436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov regs->eflags = LibVEX_GuestAMD64_get_rflags( &arch->vex ); 273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown regs->rsp = arch->vex.guest_RSP; 274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown regs->rip = arch->vex.guest_RIP; 275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown regs->rbx = arch->vex.guest_RBX; 277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown regs->rcx = arch->vex.guest_RCX; 278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown regs->rdx = arch->vex.guest_RDX; 279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown regs->rsi = arch->vex.guest_RSI; 280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown regs->rdi = arch->vex.guest_RDI; 281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown regs->rbp = arch->vex.guest_RBP; 282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown regs->rax = arch->vex.guest_RAX; 283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown regs->r8 = arch->vex.guest_R8; 284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown regs->r9 = arch->vex.guest_R9; 285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown regs->r10 = arch->vex.guest_R10; 286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown regs->r11 = arch->vex.guest_R11; 287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown regs->r12 = arch->vex.guest_R12; 288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown regs->r13 = arch->vex.guest_R13; 289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown regs->r14 = arch->vex.guest_R14; 290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown regs->r15 = arch->vex.guest_R15; 291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#elif defined(VGP_ppc32_linux) 293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# define DO(n) regs->gpr[n] = arch->vex.guest_GPR##n 294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DO(0); DO(1); DO(2); DO(3); DO(4); DO(5); DO(6); DO(7); 295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DO(8); DO(9); DO(10); DO(11); DO(12); DO(13); DO(14); DO(15); 296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DO(16); DO(17); DO(18); DO(19); DO(20); DO(21); DO(22); DO(23); 297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DO(24); DO(25); DO(26); DO(27); DO(28); DO(29); DO(30); DO(31); 298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# undef DO 299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown regs->nip = arch->vex.guest_CIA; 301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown regs->msr = 0xf032; /* pretty arbitrary */ 302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown regs->orig_gpr3 = arch->vex.guest_GPR3; 303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown regs->ctr = arch->vex.guest_CTR; 304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown regs->link = arch->vex.guest_LR; 305436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov regs->xer = LibVEX_GuestPPC32_get_XER( &arch->vex ); 306436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov regs->ccr = LibVEX_GuestPPC32_get_CR( &arch->vex ); 307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown regs->mq = 0; 308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown regs->trap = 0; 309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown regs->dar = 0; /* should be fault address? */ 310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown regs->dsisr = 0; 311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown regs->result = 0; 312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#elif defined(VGP_ppc64_linux) 314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# define DO(n) regs->gpr[n] = arch->vex.guest_GPR##n 315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DO(0); DO(1); DO(2); DO(3); DO(4); DO(5); DO(6); DO(7); 316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DO(8); DO(9); DO(10); DO(11); DO(12); DO(13); DO(14); DO(15); 317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DO(16); DO(17); DO(18); DO(19); DO(20); DO(21); DO(22); DO(23); 318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DO(24); DO(25); DO(26); DO(27); DO(28); DO(29); DO(30); DO(31); 319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# undef DO 320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown regs->nip = arch->vex.guest_CIA; 322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown regs->msr = 0xf032; /* pretty arbitrary */ 323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown regs->orig_gpr3 = arch->vex.guest_GPR3; 324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown regs->ctr = arch->vex.guest_CTR; 325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown regs->link = arch->vex.guest_LR; 326436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov regs->xer = LibVEX_GuestPPC64_get_XER( &arch->vex ); 327436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov regs->ccr = LibVEX_GuestPPC64_get_CR( &arch->vex ); 328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* regs->mq = 0; */ 329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown regs->trap = 0; 330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown regs->dar = 0; /* should be fault address? */ 331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown regs->dsisr = 0; 332ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown regs->result = 0; 333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#elif defined(VGP_arm_linux) 335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown regs->ARM_r0 = arch->vex.guest_R0; 336ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown regs->ARM_r1 = arch->vex.guest_R1; 337ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown regs->ARM_r2 = arch->vex.guest_R2; 338ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown regs->ARM_r3 = arch->vex.guest_R3; 339ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown regs->ARM_r4 = arch->vex.guest_R4; 340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown regs->ARM_r5 = arch->vex.guest_R5; 341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown regs->ARM_r6 = arch->vex.guest_R6; 342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown regs->ARM_r7 = arch->vex.guest_R7; 343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown regs->ARM_r8 = arch->vex.guest_R8; 344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown regs->ARM_r9 = arch->vex.guest_R9; 345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown regs->ARM_r10 = arch->vex.guest_R10; 346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown regs->ARM_fp = arch->vex.guest_R11; 347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown regs->ARM_ip = arch->vex.guest_R12; 348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown regs->ARM_sp = arch->vex.guest_R13; 349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown regs->ARM_lr = arch->vex.guest_R14; 350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown regs->ARM_pc = arch->vex.guest_R15T; 351436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov regs->ARM_cpsr = LibVEX_GuestARM_get_cpsr( &arch->vex ); 352436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 353436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#elif defined(VGP_arm64_linux) 354436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov (void)arch; 355436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov I_die_here; 356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 357b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#elif defined(VGP_s390x_linux) 358b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# define DO(n) regs->gprs[n] = arch->vex.guest_r##n 359b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov DO(0); DO(1); DO(2); DO(3); DO(4); DO(5); DO(6); DO(7); 360b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov DO(8); DO(9); DO(10); DO(11); DO(12); DO(13); DO(14); DO(15); 361b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# undef DO 362b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# define DO(n) regs->acrs[n] = arch->vex.guest_a##n 363b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov DO(0); DO(1); DO(2); DO(3); DO(4); DO(5); DO(6); DO(7); 364b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov DO(8); DO(9); DO(10); DO(11); DO(12); DO(13); DO(14); DO(15); 365b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# undef DO 366b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov regs->orig_gpr2 = arch->vex.guest_r2; 367436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 368663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#elif defined(VGP_mips32_linux) 369663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng# define DO(n) regs->MIPS_r##n = arch->vex.guest_r##n 370663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng DO(0); DO(1); DO(2); DO(3); DO(4); DO(5); DO(6); DO(7); 371663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng DO(8); DO(9); DO(10); DO(11); DO(12); DO(13); DO(14); DO(15); 372663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng DO(16); DO(17); DO(18); DO(19); DO(20); DO(21); DO(22); DO(23); 373663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng DO(24); DO(25); DO(26); DO(27); DO(28); DO(29); DO(30); DO(31); 374663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng# undef DO 375663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng regs->MIPS_hi = arch->vex.guest_HI; 376663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng regs->MIPS_lo = arch->vex.guest_LO; 377436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 378436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#elif defined(VGP_mips64_linux) 379436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# define DO(n) regs->MIPS_r##n = arch->vex.guest_r##n 380436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov DO(0); DO(1); DO(2); DO(3); DO(4); DO(5); DO(6); DO(7); 381436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov DO(8); DO(9); DO(10); DO(11); DO(12); DO(13); DO(14); DO(15); 382436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov DO(16); DO(17); DO(18); DO(19); DO(20); DO(21); DO(22); DO(23); 383436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov DO(24); DO(25); DO(26); DO(27); DO(28); DO(29); DO(30); DO(31); 384436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# undef DO 385436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov regs->MIPS_hi = arch->vex.guest_HI; 386436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov regs->MIPS_lo = arch->vex.guest_LO; 387436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else 389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# error Unknown ELF platform 390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif 391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void fill_fpu(const ThreadState *tst, vki_elf_fpregset_t *fpu) 394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __attribute__((unused)) 396436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov const ThreadArchState* arch = &tst->arch; 397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(VGP_x86_linux) 399436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//:: static void fill_fpu(vki_elf_fpregset_t *fpu, const HChar *from) 400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//:: { 401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//:: if (VG_(have_ssestate)) { 402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//:: UShort *to; 403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//:: Int i; 404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//:: 405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//:: /* This is what the kernel does */ 406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//:: VG_(memcpy)(fpu, from, 7*sizeof(long)); 407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//:: 408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//:: to = (UShort *)&fpu->st_space[0]; 409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//:: from += 18 * sizeof(UShort); 410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//:: 411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//:: for (i = 0; i < 8; i++, to += 5, from += 8) 412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//:: VG_(memcpy)(to, from, 5*sizeof(UShort)); 413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//:: } else 414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//:: VG_(memcpy)(fpu, from, sizeof(*fpu)); 415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//:: } 416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 417436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//:: fill_fpu(fpu, (const HChar *)&arch->m_sse); 418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#elif defined(VGP_amd64_linux) 420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//:: fpu->cwd = ?; 421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//:: fpu->swd = ?; 422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//:: fpu->twd = ?; 423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//:: fpu->fop = ?; 424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//:: fpu->rip = ?; 425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//:: fpu->rdp = ?; 426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//:: fpu->mxcsr = ?; 427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//:: fpu->mxcsr_mask = ?; 428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//:: fpu->st_space = ?; 429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 430663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng# define DO(n) VG_(memcpy)(fpu->xmm_space + n * 4, \ 431663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng &arch->vex.guest_YMM##n[0], 16) 432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DO(0); DO(1); DO(2); DO(3); DO(4); DO(5); DO(6); DO(7); 433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DO(8); DO(9); DO(10); DO(11); DO(12); DO(13); DO(14); DO(15); 434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# undef DO 435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(memset)(fpu->padding, 0, sizeof(fpu->padding)); 437ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 438ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#elif defined(VGP_ppc32_linux) 439ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* The guest state has the FPR fields declared as ULongs, so need 440b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov to fish out the values without converting them. 441b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov NOTE: The 32 FP registers map to the first 32 VSX registers.*/ 442b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# define DO(n) (*fpu)[n] = *(double*)(&arch->vex.guest_VSR##n) 443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DO(0); DO(1); DO(2); DO(3); DO(4); DO(5); DO(6); DO(7); 444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DO(8); DO(9); DO(10); DO(11); DO(12); DO(13); DO(14); DO(15); 445ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DO(16); DO(17); DO(18); DO(19); DO(20); DO(21); DO(22); DO(23); 446ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DO(24); DO(25); DO(26); DO(27); DO(28); DO(29); DO(30); DO(31); 447ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# undef DO 448ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 449ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#elif defined(VGP_ppc64_linux) 450ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* The guest state has the FPR fields declared as ULongs, so need 451b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov to fish out the values without converting them. 452b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov NOTE: The 32 FP registers map to the first 32 VSX registers.*/ 453b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# define DO(n) (*fpu)[n] = *(double*)(&arch->vex.guest_VSR##n) 454ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DO(0); DO(1); DO(2); DO(3); DO(4); DO(5); DO(6); DO(7); 455ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DO(8); DO(9); DO(10); DO(11); DO(12); DO(13); DO(14); DO(15); 456ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DO(16); DO(17); DO(18); DO(19); DO(20); DO(21); DO(22); DO(23); 457ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DO(24); DO(25); DO(26); DO(27); DO(28); DO(29); DO(30); DO(31); 458ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# undef DO 459ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 460ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#elif defined(VGP_arm_linux) 461ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // umm ... 462ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 463436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#elif defined(VGP_arm64_linux) 464436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov I_die_here; 465436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 466b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#elif defined(VGP_s390x_linux) 467b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# define DO(n) fpu->fprs[n].ui = arch->vex.guest_f##n 468b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov DO(0); DO(1); DO(2); DO(3); DO(4); DO(5); DO(6); DO(7); 469b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov DO(8); DO(9); DO(10); DO(11); DO(12); DO(13); DO(14); DO(15); 470b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# undef DO 471663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#elif defined(VGP_mips32_linux) 472663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng# define DO(n) (*fpu)[n] = *(double*)(&arch->vex.guest_f##n) 473663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng DO(0); DO(1); DO(2); DO(3); DO(4); DO(5); DO(6); DO(7); 474663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng DO(8); DO(9); DO(10); DO(11); DO(12); DO(13); DO(14); DO(15); 475663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng DO(16); DO(17); DO(18); DO(19); DO(20); DO(21); DO(22); DO(23); 476663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng DO(24); DO(25); DO(26); DO(27); DO(28); DO(29); DO(30); DO(31); 477663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng# undef DO 478436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#elif defined(VGP_mips32_linux) || defined(VGP_mips64_linux) 479436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# define DO(n) (*fpu)[n] = *(double*)(&arch->vex.guest_f##n) 480436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov DO(0); DO(1); DO(2); DO(3); DO(4); DO(5); DO(6); DO(7); 481436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov DO(8); DO(9); DO(10); DO(11); DO(12); DO(13); DO(14); DO(15); 482436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov DO(16); DO(17); DO(18); DO(19); DO(20); DO(21); DO(22); DO(23); 483436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov DO(24); DO(25); DO(26); DO(27); DO(28); DO(29); DO(30); DO(31); 484436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# undef DO 485ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else 486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# error Unknown ELF platform 487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif 488ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 489ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 490663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#if defined(VGP_x86_linux) && !defined(VGPV_x86_linux_android) 491ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void fill_xfpu(const ThreadState *tst, vki_elf_fpxregset_t *xfpu) 492ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 493436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov const ThreadArchState* arch = &tst->arch; 494ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 495ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//:: xfpu->cwd = ?; 496ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//:: xfpu->swd = ?; 497ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//:: xfpu->twd = ?; 498ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//:: xfpu->fop = ?; 499ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//:: xfpu->fip = ?; 500ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//:: xfpu->fcs = ?; 501ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//:: xfpu->foo = ?; 502ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//:: xfpu->fos = ?; 503ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//:: xfpu->mxcsr = ?; 504ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown xfpu->reserved = 0; 505ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//:: xfpu->st_space = ?; 506ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 507ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# define DO(n) VG_(memcpy)(xfpu->xmm_space + n * 4, &arch->vex.guest_XMM##n, sizeof(arch->vex.guest_XMM##n)) 508ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DO(0); DO(1); DO(2); DO(3); DO(4); DO(5); DO(6); DO(7); 509ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# undef DO 510ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 511ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(memset)(xfpu->padding, 0, sizeof(xfpu->padding)); 512ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 513ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif 514ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 515ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic 516436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovvoid make_elf_coredump(ThreadId tid, const vki_siginfo_t *si, ULong max_size) 517ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 518436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HChar* buf = NULL; 519436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov const HChar *basename = "vgcore"; 520436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov const HChar *coreext = ""; 521ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int seq = 0; 522ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int core_fd; 523ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown NSegment const * seg; 524ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ESZ(Ehdr) ehdr; 525ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ESZ(Phdr) *phdrs; 526ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int num_phdrs; 527ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int i, idx; 528ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt off; 529ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct note *notelist, *note; 530ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt notesz; 531ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct vki_elf_prpsinfo prpsinfo; 532ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct vki_elf_prstatus prstatus; 533ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Addr *seg_starts; 534ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int n_seg_starts; 535ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 536ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (VG_(clo_log_fname_expanded) != NULL) { 537ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown coreext = ".core"; 538ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown basename = VG_(expand_file_name)( 539ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "--log-file (while creating core filename)", 540ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(clo_log_fname_expanded)); 541ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 542ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 543ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(coreext); 544ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(basename); 545ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown buf = VG_(malloc)( "coredump-elf.mec.1", 546ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(strlen)(coreext) + VG_(strlen)(basename) 547ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown + 100/*for the two %ds. */ ); 548ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(buf); 549ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 550ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for(;;) { 551b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Int oflags = VKI_O_CREAT|VKI_O_WRONLY|VKI_O_EXCL|VKI_O_TRUNC; 552ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SysRes sres; 553ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 554ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (seq == 0) 555ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(sprintf)(buf, "%s%s.%d", 556ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown basename, coreext, VG_(getpid)()); 557ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else 558ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(sprintf)(buf, "%s%s.%d.%d", 559ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown basename, coreext, VG_(getpid)(), seq); 560ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown seq++; 561ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 562b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# if defined(VKI_O_LARGEFILE) 563b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov oflags |= VKI_O_LARGEFILE; 564b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# endif 565b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 566b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov sres = VG_(open)(buf, oflags, VKI_S_IRUSR|VKI_S_IWUSR); 567ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (!sr_isError(sres)) { 568ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown core_fd = sr_Res(sres); 569ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 570ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 571ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 572ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (sr_isError(sres) && sr_Err(sres) != VKI_EEXIST) 573ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; /* can't create file */ 574ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 575ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 576ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Get the segments */ 577ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown seg_starts = VG_(get_segment_starts)(&n_seg_starts); 578ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 579ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* First, count how many memory segments to dump */ 580ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown num_phdrs = 1; /* start with notes */ 581ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for(i = 0; i < n_seg_starts; i++) { 582ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (!may_dump(VG_(am_find_nsegment(seg_starts[i])))) 583ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown continue; 584ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 585ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown num_phdrs++; 586ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 587ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 588ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown fill_ehdr(&ehdr, num_phdrs); 589ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 590ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown notelist = NULL; 591ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 592ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Second, work out their layout */ 593ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown phdrs = VG_(arena_malloc)(VG_AR_CORE, "coredump-elf.mec.1", 594ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sizeof(*phdrs) * num_phdrs); 595ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 596ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for(i = 1; i < VG_N_THREADS; i++) { 597ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vki_elf_fpregset_t fpu; 598ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 599ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (VG_(threads)[i].status == VgTs_Empty) 600ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown continue; 601ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 602436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# if defined(VGP_x86_linux) && !defined(VGPV_x86_linux_android) 603ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { 604ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vki_elf_fpxregset_t xfpu; 605ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown fill_xfpu(&VG_(threads)[i], &xfpu); 606ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown add_note(¬elist, "LINUX", NT_PRXFPREG, &xfpu, sizeof(xfpu)); 607ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 608b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# endif 609ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 610ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown fill_fpu(&VG_(threads)[i], &fpu); 611436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# if !defined(VGPV_arm_linux_android) && !defined(VGPV_x86_linux_android) \ 61278c715b24ad43c879a589fb02c7c4f94304425c5Dmitriy Ivanov && !defined(VGPV_mips32_linux_android) && !defined(VGPV_arm64_linux_android) 613ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown add_note(¬elist, "CORE", NT_FPREGSET, &fpu, sizeof(fpu)); 614b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# endif 615ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 616ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown fill_prstatus(&VG_(threads)[i], &prstatus, si); 617436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# if !defined(VGPV_arm_linux_android) && !defined(VGPV_x86_linux_android) \ 618436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov && !defined(VGPV_mips32_linux_android) 619ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown add_note(¬elist, "CORE", NT_PRSTATUS, &prstatus, sizeof(prstatus)); 620b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# endif 621ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 622ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 623ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown fill_prpsinfo(&VG_(threads)[tid], &prpsinfo); 624436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# if !defined(VGPV_arm_linux_android) && !defined(VGPV_x86_linux_android) \ 625436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov && !defined(VGPV_mips32_linux_android) 626ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown add_note(¬elist, "CORE", NT_PRPSINFO, &prpsinfo, sizeof(prpsinfo)); 627b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# endif 628ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 629b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov for (note = notelist, notesz = 0; note != NULL; note = note->next) 630ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown notesz += note_size(note); 631ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 632ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown off = sizeof(ehdr) + sizeof(*phdrs) * num_phdrs; 633ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 634ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown phdrs[0].p_type = PT_NOTE; 635ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown phdrs[0].p_offset = off; 636ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown phdrs[0].p_vaddr = 0; 637ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown phdrs[0].p_paddr = 0; 638ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown phdrs[0].p_filesz = notesz; 639ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown phdrs[0].p_memsz = 0; 640ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown phdrs[0].p_flags = 0; 641ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown phdrs[0].p_align = 0; 642ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 643ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown off += notesz; 644ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 645ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown off = VG_PGROUNDUP(off); 646ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 647ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for(i = 0, idx = 1; i < n_seg_starts; i++) { 648ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown seg = VG_(am_find_nsegment(seg_starts[i])); 649ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 650ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (!may_dump(seg)) 651ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown continue; 652ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 653b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov fill_phdr(&phdrs[idx], seg, off, 654b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov (seg->end - seg->start + off) < max_size); 655ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 656ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown off += phdrs[idx].p_filesz; 657ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 658ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown idx++; 659ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 660ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 661ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* write everything out */ 662ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(write)(core_fd, &ehdr, sizeof(ehdr)); 663ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(write)(core_fd, phdrs, sizeof(*phdrs) * num_phdrs); 664ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 665ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for(note = notelist; note != NULL; note = note->next) 666ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown write_note(core_fd, note); 667ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 668ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(lseek)(core_fd, phdrs[1].p_offset, VKI_SEEK_SET); 669ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 670ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for(i = 0, idx = 1; i < n_seg_starts; i++) { 671ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown seg = VG_(am_find_nsegment(seg_starts[i])); 672ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 673ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (!should_dump(seg)) 674ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown continue; 675ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 676ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (phdrs[idx].p_filesz > 0) { 677b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov vg_assert(VG_(lseek)(core_fd, phdrs[idx].p_offset, VKI_SEEK_SET) 678b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov == phdrs[idx].p_offset); 679ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(seg->end - seg->start >= phdrs[idx].p_filesz); 680ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 681ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (void)VG_(write)(core_fd, (void *)seg->start, phdrs[idx].p_filesz); 682ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 683ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown idx++; 684ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 685ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 686ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(free)(seg_starts); 687ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 688ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(close)(core_fd); 689ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 690ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 691436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovvoid VG_(make_coredump)(ThreadId tid, const vki_siginfo_t *si, ULong max_size) 692ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 693ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown make_elf_coredump(tid, si, max_size); 694ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 695ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 696ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif // defined(VGO_linux) 697ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 698ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/ 699ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- end ---*/ 700ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/ 701