LCOV - code coverage report
Current view: top level - toolkit/crashreporter/breakpad-client/linux/dump_writer_common - thread_info.cc (source / functions) Hit Total Coverage
Test: output.info Lines: 0 61 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 4 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // Copyright (c) 2014, Google Inc.
       2             : // All rights reserved.
       3             : //
       4             : // Redistribution and use in source and binary forms, with or without
       5             : // modification, are permitted provided that the following conditions are
       6             : // met:
       7             : //
       8             : //     * Redistributions of source code must retain the above copyright
       9             : // notice, this list of conditions and the following disclaimer.
      10             : //     * Redistributions in binary form must reproduce the above
      11             : // copyright notice, this list of conditions and the following disclaimer
      12             : // in the documentation and/or other materials provided with the
      13             : // distribution.
      14             : //     * Neither the name of Google Inc. nor the names of its
      15             : // contributors may be used to endorse or promote products derived from
      16             : // this software without specific prior written permission.
      17             : //
      18             : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
      19             : // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
      20             : // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
      21             : // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
      22             : // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
      23             : // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
      24             : // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
      25             : // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      26             : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      27             : // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
      28             : // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      29             : 
      30             : #include "linux/dump_writer_common/thread_info.h"
      31             : 
      32             : #include <string.h>
      33             : #include <assert.h>
      34             : 
      35             : #include "common/linux/linux_libc_support.h"
      36             : #include "google_breakpad/common/minidump_format.h"
      37             : 
      38             : namespace {
      39             : 
      40             : #if defined(__i386__)
      41             : // Write a uint16_t to memory
      42             : //   out: memory location to write to
      43             : //   v: value to write.
      44             : void U16(void* out, uint16_t v) {
      45             :   my_memcpy(out, &v, sizeof(v));
      46             : }
      47             : 
      48             : // Write a uint32_t to memory
      49             : //   out: memory location to write to
      50             : //   v: value to write.
      51             : void U32(void* out, uint32_t v) {
      52             :   my_memcpy(out, &v, sizeof(v));
      53             : }
      54             : #endif
      55             : 
      56             : }
      57             : 
      58             : namespace google_breakpad {
      59             : 
      60             : #if defined(__i386__)
      61             : 
      62             : uintptr_t ThreadInfo::GetInstructionPointer() const {
      63             :   return regs.eip;
      64             : }
      65             : 
      66             : void ThreadInfo::FillCPUContext(RawContextCPU* out) const {
      67             :   out->context_flags = MD_CONTEXT_X86_ALL;
      68             : 
      69             :   out->dr0 = dregs[0];
      70             :   out->dr1 = dregs[1];
      71             :   out->dr2 = dregs[2];
      72             :   out->dr3 = dregs[3];
      73             :   // 4 and 5 deliberatly omitted because they aren't included in the minidump
      74             :   // format.
      75             :   out->dr6 = dregs[6];
      76             :   out->dr7 = dregs[7];
      77             : 
      78             :   out->gs = regs.xgs;
      79             :   out->fs = regs.xfs;
      80             :   out->es = regs.xes;
      81             :   out->ds = regs.xds;
      82             : 
      83             :   out->edi = regs.edi;
      84             :   out->esi = regs.esi;
      85             :   out->ebx = regs.ebx;
      86             :   out->edx = regs.edx;
      87             :   out->ecx = regs.ecx;
      88             :   out->eax = regs.eax;
      89             : 
      90             :   out->ebp = regs.ebp;
      91             :   out->eip = regs.eip;
      92             :   out->cs = regs.xcs;
      93             :   out->eflags = regs.eflags;
      94             :   out->esp = regs.esp;
      95             :   out->ss = regs.xss;
      96             : 
      97             :   out->float_save.control_word = fpregs.cwd;
      98             :   out->float_save.status_word = fpregs.swd;
      99             :   out->float_save.tag_word = fpregs.twd;
     100             :   out->float_save.error_offset = fpregs.fip;
     101             :   out->float_save.error_selector = fpregs.fcs;
     102             :   out->float_save.data_offset = fpregs.foo;
     103             :   out->float_save.data_selector = fpregs.fos;
     104             : 
     105             :   // 8 registers * 10 bytes per register.
     106             :   my_memcpy(out->float_save.register_area, fpregs.st_space, 10 * 8);
     107             : 
     108             :   // This matches the Intel fpsave format.
     109             :   U16(out->extended_registers + 0, fpregs.cwd);
     110             :   U16(out->extended_registers + 2, fpregs.swd);
     111             :   U16(out->extended_registers + 4, fpregs.twd);
     112             :   U16(out->extended_registers + 6, fpxregs.fop);
     113             :   U32(out->extended_registers + 8, fpxregs.fip);
     114             :   U16(out->extended_registers + 12, fpxregs.fcs);
     115             :   U32(out->extended_registers + 16, fpregs.foo);
     116             :   U16(out->extended_registers + 20, fpregs.fos);
     117             :   U32(out->extended_registers + 24, fpxregs.mxcsr);
     118             : 
     119             :   my_memcpy(out->extended_registers + 32, &fpxregs.st_space, 128);
     120             :   my_memcpy(out->extended_registers + 160, &fpxregs.xmm_space, 128);
     121             : }
     122             : 
     123             : #elif defined(__x86_64)
     124             : 
     125           0 : uintptr_t ThreadInfo::GetInstructionPointer() const {
     126           0 :   return regs.rip;
     127             : }
     128             : 
     129           0 : void ThreadInfo::FillCPUContext(RawContextCPU* out) const {
     130           0 :   out->context_flags = MD_CONTEXT_AMD64_FULL |
     131             :                        MD_CONTEXT_AMD64_SEGMENTS;
     132             : 
     133           0 :   out->cs = regs.cs;
     134             : 
     135           0 :   out->ds = regs.ds;
     136           0 :   out->es = regs.es;
     137           0 :   out->fs = regs.fs;
     138           0 :   out->gs = regs.gs;
     139             : 
     140           0 :   out->ss = regs.ss;
     141           0 :   out->eflags = regs.eflags;
     142             : 
     143           0 :   out->dr0 = dregs[0];
     144           0 :   out->dr1 = dregs[1];
     145           0 :   out->dr2 = dregs[2];
     146           0 :   out->dr3 = dregs[3];
     147             :   // 4 and 5 deliberatly omitted because they aren't included in the minidump
     148             :   // format.
     149           0 :   out->dr6 = dregs[6];
     150           0 :   out->dr7 = dregs[7];
     151             : 
     152           0 :   out->rax = regs.rax;
     153           0 :   out->rcx = regs.rcx;
     154           0 :   out->rdx = regs.rdx;
     155           0 :   out->rbx = regs.rbx;
     156             : 
     157           0 :   out->rsp = regs.rsp;
     158             : 
     159           0 :   out->rbp = regs.rbp;
     160           0 :   out->rsi = regs.rsi;
     161           0 :   out->rdi = regs.rdi;
     162           0 :   out->r8 = regs.r8;
     163           0 :   out->r9 = regs.r9;
     164           0 :   out->r10 = regs.r10;
     165           0 :   out->r11 = regs.r11;
     166           0 :   out->r12 = regs.r12;
     167           0 :   out->r13 = regs.r13;
     168           0 :   out->r14 = regs.r14;
     169           0 :   out->r15 = regs.r15;
     170             : 
     171           0 :   out->rip = regs.rip;
     172             : 
     173           0 :   out->flt_save.control_word = fpregs.cwd;
     174           0 :   out->flt_save.status_word = fpregs.swd;
     175           0 :   out->flt_save.tag_word = fpregs.ftw;
     176           0 :   out->flt_save.error_opcode = fpregs.fop;
     177           0 :   out->flt_save.error_offset = fpregs.rip;
     178           0 :   out->flt_save.error_selector = 0;  // We don't have this.
     179           0 :   out->flt_save.data_offset = fpregs.rdp;
     180           0 :   out->flt_save.data_selector = 0;   // We don't have this.
     181           0 :   out->flt_save.mx_csr = fpregs.mxcsr;
     182           0 :   out->flt_save.mx_csr_mask = fpregs.mxcr_mask;
     183             : 
     184           0 :   my_memcpy(&out->flt_save.float_registers, &fpregs.st_space, 8 * 16);
     185           0 :   my_memcpy(&out->flt_save.xmm_registers, &fpregs.xmm_space, 16 * 16);
     186           0 : }
     187             : 
     188             : #elif defined(__ARM_EABI__)
     189             : 
     190             : uintptr_t ThreadInfo::GetInstructionPointer() const {
     191             :   return regs.uregs[15];
     192             : }
     193             : 
     194             : void ThreadInfo::FillCPUContext(RawContextCPU* out) const {
     195             :   out->context_flags = MD_CONTEXT_ARM_FULL;
     196             : 
     197             :   for (int i = 0; i < MD_CONTEXT_ARM_GPR_COUNT; ++i)
     198             :     out->iregs[i] = regs.uregs[i];
     199             :   // No CPSR register in ThreadInfo(it's not accessible via ptrace)
     200             :   out->cpsr = 0;
     201             : #if !defined(__ANDROID__)
     202             :   out->float_save.fpscr = fpregs.fpsr |
     203             :     (static_cast<uint64_t>(fpregs.fpcr) << 32);
     204             :   // TODO: sort this out, actually collect floating point registers
     205             :   my_memset(&out->float_save.regs, 0, sizeof(out->float_save.regs));
     206             :   my_memset(&out->float_save.extra, 0, sizeof(out->float_save.extra));
     207             : #endif
     208             : }
     209             : 
     210             : #elif defined(__aarch64__)
     211             : 
     212             : uintptr_t ThreadInfo::GetInstructionPointer() const {
     213             :   return regs.pc;
     214             : }
     215             : 
     216             : void ThreadInfo::FillCPUContext(RawContextCPU* out) const {
     217             :   out->context_flags = MD_CONTEXT_ARM64_FULL;
     218             : 
     219             :   out->cpsr = static_cast<uint32_t>(regs.pstate);
     220             :   for (int i = 0; i < MD_CONTEXT_ARM64_REG_SP; ++i)
     221             :     out->iregs[i] = regs.regs[i];
     222             :   out->iregs[MD_CONTEXT_ARM64_REG_SP] = regs.sp;
     223             :   out->iregs[MD_CONTEXT_ARM64_REG_PC] = regs.pc;
     224             : 
     225             :   out->float_save.fpsr = fpregs.fpsr;
     226             :   out->float_save.fpcr = fpregs.fpcr;
     227             :   my_memcpy(&out->float_save.regs, &fpregs.vregs,
     228             :       MD_FLOATINGSAVEAREA_ARM64_FPR_COUNT * 16);
     229             : }
     230             : 
     231             : #elif defined(__mips__)
     232             : 
     233             : uintptr_t ThreadInfo::GetInstructionPointer() const {
     234             :   return mcontext.pc;
     235             : }
     236             : 
     237             : void ThreadInfo::FillCPUContext(RawContextCPU* out) const {
     238             : #if _MIPS_SIM == _ABI64
     239             :   out->context_flags = MD_CONTEXT_MIPS64_FULL;
     240             : #elif _MIPS_SIM == _ABIO32
     241             :   out->context_flags = MD_CONTEXT_MIPS_FULL;
     242             : #else
     243             : # error "This mips ABI is currently not supported (n32)"
     244             : #endif
     245             : 
     246             :   for (int i = 0; i < MD_CONTEXT_MIPS_GPR_COUNT; ++i)
     247             :     out->iregs[i] = mcontext.gregs[i];
     248             : 
     249             :   out->mdhi = mcontext.mdhi;
     250             :   out->mdlo = mcontext.mdlo;
     251             :   out->dsp_control = mcontext.dsp;
     252             : 
     253             :   out->hi[0] = mcontext.hi1;
     254             :   out->lo[0] = mcontext.lo1;
     255             :   out->hi[1] = mcontext.hi2;
     256             :   out->lo[1] = mcontext.lo2;
     257             :   out->hi[2] = mcontext.hi3;
     258             :   out->lo[2] = mcontext.lo3;
     259             : 
     260             :   out->epc = mcontext.pc;
     261             :   out->badvaddr = 0; // Not stored in mcontext
     262             :   out->status = 0; // Not stored in mcontext
     263             :   out->cause = 0; // Not stored in mcontext
     264             : 
     265             :   for (int i = 0; i < MD_FLOATINGSAVEAREA_MIPS_FPR_COUNT; ++i)
     266             :     out->float_save.regs[i] = mcontext.fpregs.fp_r.fp_fregs[i]._fp_fregs;
     267             : 
     268             :   out->float_save.fpcsr = mcontext.fpc_csr;
     269             : #if _MIPS_SIM == _ABIO32
     270             :   out->float_save.fir = mcontext.fpc_eir;
     271             : #endif
     272             : }
     273             : #endif  // __mips__
     274             : 
     275           0 : void ThreadInfo::GetGeneralPurposeRegisters(void** gp_regs, size_t* size) {
     276           0 :   assert(gp_regs || size);
     277             : #if defined(__mips__)
     278             :   if (gp_regs)
     279             :     *gp_regs = mcontext.gregs;
     280             :   if (size)
     281             :     *size = sizeof(mcontext.gregs);
     282             : #else
     283           0 :   if (gp_regs)
     284           0 :     *gp_regs = &regs;
     285           0 :   if (size)
     286           0 :     *size = sizeof(regs);
     287             : #endif
     288           0 : }
     289             : 
     290           0 : void ThreadInfo::GetFloatingPointRegisters(void** fp_regs, size_t* size) {
     291           0 :   assert(fp_regs || size);
     292             : #if defined(__mips__)
     293             :   if (fp_regs)
     294             :     *fp_regs = &mcontext.fpregs;
     295             :   if (size)
     296             :     *size = sizeof(mcontext.fpregs);
     297             : #else
     298           0 :   if (fp_regs)
     299           0 :     *fp_regs = &fpregs;
     300           0 :   if (size)
     301           0 :     *size = sizeof(fpregs);
     302             : #endif
     303           0 : }
     304             : 
     305             : }  // namespace google_breakpad

Generated by: LCOV version 1.13