14fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org// Copyright (c) 2012, Google Inc. 24fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org// All rights reserved. 34fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org// 44fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org// Redistribution and use in source and binary forms, with or without 54fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org// modification, are permitted provided that the following conditions are 64fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org// met: 74fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org// 84fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org// * Redistributions of source code must retain the above copyright 94fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org// notice, this list of conditions and the following disclaimer. 104fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org// * Redistributions in binary form must reproduce the above 114fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org// copyright notice, this list of conditions and the following disclaimer 124fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org// in the documentation and/or other materials provided with the 134fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org// distribution. 144fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org// * Neither the name of Google Inc. nor the names of its 154fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org// contributors may be used to endorse or promote products derived from 164fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org// this software without specific prior written permission. 174fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org// 184fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 194fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 204fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 214fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 224fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 234fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 244fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 254fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 264fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 274fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 284fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 294fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org 304fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org// linux_core_dumper.cc: Implement google_breakpad::LinuxCoreDumper. 314fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org// See linux_core_dumper.h for details. 324fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org 334fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org#include "client/linux/minidump_writer/linux_core_dumper.h" 344fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org 354fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org#include <asm/ptrace.h> 364fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org#include <assert.h> 374fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org#include <elf.h> 384fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org#include <stdio.h> 394fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org#include <string.h> 404fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org#include <sys/procfs.h> 414fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org 424fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org#include "common/linux/linux_libc_support.h" 434fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org 444fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.orgnamespace google_breakpad { 454fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org 464fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.orgLinuxCoreDumper::LinuxCoreDumper(pid_t pid, 474fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org const char* core_path, 484fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org const char* procfs_path) 494fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org : LinuxDumper(pid), 504fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org core_path_(core_path), 514fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org procfs_path_(procfs_path), 524fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org thread_infos_(&allocator_, 8) { 534fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org assert(core_path_); 544fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org} 554fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org 564fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.orgbool LinuxCoreDumper::BuildProcPath(char* path, pid_t pid, 574fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org const char* node) const { 584fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org if (!path || !node) 594fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org return false; 604fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org 614fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org size_t node_len = my_strlen(node); 624fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org if (node_len == 0) 634fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org return false; 644fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org 654fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org size_t procfs_path_len = my_strlen(procfs_path_); 664fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org size_t total_length = procfs_path_len + 1 + node_len; 674fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org if (total_length >= NAME_MAX) 684fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org return false; 694fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org 704fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org memcpy(path, procfs_path_, procfs_path_len); 714fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org path[procfs_path_len] = '/'; 724fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org memcpy(path + procfs_path_len + 1, node, node_len); 734fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org path[total_length] = '\0'; 744fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org return true; 754fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org} 764fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org 77e0aa94bfb6682a04f824b64d064fbb58ac5343c7benchan@chromium.orgbool LinuxCoreDumper::CopyFromProcess(void* dest, pid_t child, 784fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org const void* src, size_t length) { 794fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org ElfCoreDump::Addr virtual_address = reinterpret_cast<ElfCoreDump::Addr>(src); 804fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org // TODO(benchan): Investigate whether the data to be copied could span 814fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org // across multiple segments in the core dump file. ElfCoreDump::CopyData 824fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org // and this method do not handle that case yet. 834fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org if (!core_.CopyData(dest, virtual_address, length)) { 844fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org // If the data segment is not found in the core dump, fill the result 854fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org // with marker characters. 864fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org memset(dest, 0xab, length); 87e0aa94bfb6682a04f824b64d064fbb58ac5343c7benchan@chromium.org return false; 884fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org } 89e0aa94bfb6682a04f824b64d064fbb58ac5343c7benchan@chromium.org return true; 904fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org} 914fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org 924fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.orgbool LinuxCoreDumper::GetThreadInfoByIndex(size_t index, ThreadInfo* info) { 934fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org if (index >= thread_infos_.size()) 944fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org return false; 954fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org 964fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org *info = thread_infos_[index]; 974fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org const uint8_t* stack_pointer; 984fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org#if defined(__i386) 994fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org memcpy(&stack_pointer, &info->regs.esp, sizeof(info->regs.esp)); 1004fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org#elif defined(__x86_64) 1014fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org memcpy(&stack_pointer, &info->regs.rsp, sizeof(info->regs.rsp)); 1024fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org#elif defined(__ARM_EABI__) 1034fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org memcpy(&stack_pointer, &info->regs.ARM_sp, sizeof(info->regs.ARM_sp)); 1042eedc625759a8943d72711769a84fce05a23ecd0rmcilroy@chromium.org#elif defined(__aarch64__) 1052eedc625759a8943d72711769a84fce05a23ecd0rmcilroy@chromium.org memcpy(&stack_pointer, &info->regs.sp, sizeof(info->regs.sp)); 1065f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com#elif defined(__mips__) 1072eedc625759a8943d72711769a84fce05a23ecd0rmcilroy@chromium.org stack_pointer = 1085f22d6a7f471f2352d394c188560fd06830e14f3gordana.cmiljanovic@imgtec.com reinterpret_cast<uint8_t*>(info->regs.regs[MD_CONTEXT_MIPS_REG_SP]); 1094fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org#else 1104fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org#error "This code hasn't been ported to your platform yet." 1114fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org#endif 112a576a63122315d8675b8ef6b43c848e627354afbmkrebs@chromium.org info->stack_pointer = reinterpret_cast<uintptr_t>(stack_pointer); 113a576a63122315d8675b8ef6b43c848e627354afbmkrebs@chromium.org return true; 1144fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org} 1154fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org 1164fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.orgbool LinuxCoreDumper::IsPostMortem() const { 1174fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org return true; 1184fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org} 1194fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org 1204fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.orgbool LinuxCoreDumper::ThreadsSuspend() { 1214fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org return true; 1224fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org} 1234fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org 1244fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.orgbool LinuxCoreDumper::ThreadsResume() { 1254fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org return true; 1264fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org} 1274fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org 1284fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.orgbool LinuxCoreDumper::EnumerateThreads() { 129dd5dd85f3795609723082a2b34f81e19b4f1679frmcilroy@chromium.org if (!mapped_core_file_.Map(core_path_, 0)) { 1304fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org fprintf(stderr, "Could not map core dump file into memory\n"); 1314fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org return false; 1324fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org } 1334fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org 1344fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org core_.SetContent(mapped_core_file_.content()); 1354fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org if (!core_.IsValid()) { 1364fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org fprintf(stderr, "Invalid core dump file\n"); 1374fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org return false; 1384fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org } 1394fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org 1404fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org ElfCoreDump::Note note = core_.GetFirstNote(); 1414fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org if (!note.IsValid()) { 1424fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org fprintf(stderr, "PT_NOTE section not found\n"); 1434fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org return false; 1444fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org } 1454fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org 1464fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org bool first_thread = true; 1474fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org do { 1484fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org ElfCoreDump::Word type = note.GetType(); 1494fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org MemoryRange name = note.GetName(); 1504fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org MemoryRange description = note.GetDescription(); 1514fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org 1524fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org if (type == 0 || name.IsEmpty() || description.IsEmpty()) { 1534fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org fprintf(stderr, "Could not found a valid PT_NOTE.\n"); 1544fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org return false; 1554fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org } 1564fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org 1574fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org // Based on write_note_info() in linux/kernel/fs/binfmt_elf.c, notes are 1584fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org // ordered as follows (NT_PRXFPREG and NT_386_TLS are i386 specific): 1594fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org // Thread Name Type 1604fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org // ------------------------------------------------------------------- 1614fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org // 1st thread CORE NT_PRSTATUS 1624fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org // process-wide CORE NT_PRPSINFO 1634fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org // process-wide CORE NT_AUXV 1644fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org // 1st thread CORE NT_FPREGSET 1654fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org // 1st thread LINUX NT_PRXFPREG 1664fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org // 1st thread LINUX NT_386_TLS 1674fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org // 1684fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org // 2nd thread CORE NT_PRSTATUS 1694fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org // 2nd thread CORE NT_FPREGSET 1704fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org // 2nd thread LINUX NT_PRXFPREG 1714fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org // 2nd thread LINUX NT_386_TLS 1724fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org // 1734fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org // 3rd thread CORE NT_PRSTATUS 1744fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org // 3rd thread CORE NT_FPREGSET 1754fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org // 3rd thread LINUX NT_PRXFPREG 1764fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org // 3rd thread LINUX NT_386_TLS 1774fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org // 1784fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org // The following code only works if notes are ordered as expected. 1794fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org switch (type) { 1804fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org case NT_PRSTATUS: { 1814fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org if (description.length() != sizeof(elf_prstatus)) { 1824fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org fprintf(stderr, "Found NT_PRSTATUS descriptor of unexpected size\n"); 1834fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org return false; 1844fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org } 1854fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org 1864fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org const elf_prstatus* status = 1874fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org reinterpret_cast<const elf_prstatus*>(description.data()); 1884fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org pid_t pid = status->pr_pid; 1894fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org ThreadInfo info; 1904fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org memset(&info, 0, sizeof(ThreadInfo)); 1914fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org info.tgid = status->pr_pgrp; 1924fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org info.ppid = status->pr_ppid; 193032cbb80abf2e8adce5c8cc906a3fde0e20a23c6gordana.cmiljanovic@imgtec.com#if defined(__mips__) 194032cbb80abf2e8adce5c8cc906a3fde0e20a23c6gordana.cmiljanovic@imgtec.com for (int i = EF_REG0; i <= EF_REG31; i++) 195032cbb80abf2e8adce5c8cc906a3fde0e20a23c6gordana.cmiljanovic@imgtec.com info.regs.regs[i - EF_REG0] = status->pr_reg[i]; 196032cbb80abf2e8adce5c8cc906a3fde0e20a23c6gordana.cmiljanovic@imgtec.com 197032cbb80abf2e8adce5c8cc906a3fde0e20a23c6gordana.cmiljanovic@imgtec.com info.regs.lo = status->pr_reg[EF_LO]; 198032cbb80abf2e8adce5c8cc906a3fde0e20a23c6gordana.cmiljanovic@imgtec.com info.regs.hi = status->pr_reg[EF_HI]; 199032cbb80abf2e8adce5c8cc906a3fde0e20a23c6gordana.cmiljanovic@imgtec.com info.regs.epc = status->pr_reg[EF_CP0_EPC]; 200032cbb80abf2e8adce5c8cc906a3fde0e20a23c6gordana.cmiljanovic@imgtec.com info.regs.badvaddr = status->pr_reg[EF_CP0_BADVADDR]; 201032cbb80abf2e8adce5c8cc906a3fde0e20a23c6gordana.cmiljanovic@imgtec.com info.regs.status = status->pr_reg[EF_CP0_STATUS]; 202032cbb80abf2e8adce5c8cc906a3fde0e20a23c6gordana.cmiljanovic@imgtec.com info.regs.cause = status->pr_reg[EF_CP0_CAUSE]; 203032cbb80abf2e8adce5c8cc906a3fde0e20a23c6gordana.cmiljanovic@imgtec.com#else 2044fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org memcpy(&info.regs, status->pr_reg, sizeof(info.regs)); 205032cbb80abf2e8adce5c8cc906a3fde0e20a23c6gordana.cmiljanovic@imgtec.com#endif 2064fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org if (first_thread) { 2074fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org crash_thread_ = pid; 2084fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org crash_signal_ = status->pr_info.si_signo; 2094fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org } 2104fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org first_thread = false; 2114fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org threads_.push_back(pid); 2124fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org thread_infos_.push_back(info); 2134fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org break; 2144fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org } 2154fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org#if defined(__i386) || defined(__x86_64) 2164fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org case NT_FPREGSET: { 2174fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org if (thread_infos_.empty()) 2184fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org return false; 2194fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org 2204fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org ThreadInfo* info = &thread_infos_.back(); 2214fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org if (description.length() != sizeof(info->fpregs)) { 2224fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org fprintf(stderr, "Found NT_FPREGSET descriptor of unexpected size\n"); 2234fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org return false; 2244fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org } 2254fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org 2264fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org memcpy(&info->fpregs, description.data(), sizeof(info->fpregs)); 2274fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org break; 2284fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org } 2294fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org#endif 2304fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org#if defined(__i386) 2314fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org case NT_PRXFPREG: { 2324fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org if (thread_infos_.empty()) 2334fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org return false; 2344fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org 2354fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org ThreadInfo* info = &thread_infos_.back(); 2364fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org if (description.length() != sizeof(info->fpxregs)) { 2374fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org fprintf(stderr, "Found NT_PRXFPREG descriptor of unexpected size\n"); 2384fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org return false; 2394fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org } 2404fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org 2414fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org memcpy(&info->fpxregs, description.data(), sizeof(info->fpxregs)); 2424fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org break; 2434fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org } 2444fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org#endif 2454fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org } 2464fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org note = note.GetNextNote(); 2474fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org } while (note.IsValid()); 2484fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org 2494fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org return true; 2504fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org} 2514fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org 2524fa638a7ecb6ab042664300767614308dbc147bbbenchan@chromium.org} // namespace google_breakpad 253