LCOV - code coverage report
Current view: top level - toolkit/crashreporter/breakpad-client/linux/dump_writer_common - ucontext_reader.cc (source / functions) Hit Total Coverage
Test: output.info Lines: 0 41 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 3 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/ucontext_reader.h"
      31             : 
      32             : #include "common/linux/linux_libc_support.h"
      33             : #include "google_breakpad/common/minidump_format.h"
      34             : 
      35             : namespace google_breakpad {
      36             : 
      37             : // Minidump defines register structures which are different from the raw
      38             : // structures which we get from the kernel. These are platform specific
      39             : // functions to juggle the ucontext and user structures into minidump format.
      40             : 
      41             : #if defined(__i386__)
      42             : 
      43             : uintptr_t UContextReader::GetStackPointer(const struct ucontext* uc) {
      44             :   return uc->uc_mcontext.gregs[REG_ESP];
      45             : }
      46             : 
      47             : uintptr_t UContextReader::GetInstructionPointer(const struct ucontext* uc) {
      48             :   return uc->uc_mcontext.gregs[REG_EIP];
      49             : }
      50             : 
      51             : void UContextReader::FillCPUContext(RawContextCPU *out, const ucontext *uc,
      52             :                                     const struct _libc_fpstate* fp) {
      53             :   const greg_t* regs = uc->uc_mcontext.gregs;
      54             : 
      55             :   out->context_flags = MD_CONTEXT_X86_FULL |
      56             :                        MD_CONTEXT_X86_FLOATING_POINT;
      57             : 
      58             :   out->gs = regs[REG_GS];
      59             :   out->fs = regs[REG_FS];
      60             :   out->es = regs[REG_ES];
      61             :   out->ds = regs[REG_DS];
      62             : 
      63             :   out->edi = regs[REG_EDI];
      64             :   out->esi = regs[REG_ESI];
      65             :   out->ebx = regs[REG_EBX];
      66             :   out->edx = regs[REG_EDX];
      67             :   out->ecx = regs[REG_ECX];
      68             :   out->eax = regs[REG_EAX];
      69             : 
      70             :   out->ebp = regs[REG_EBP];
      71             :   out->eip = regs[REG_EIP];
      72             :   out->cs = regs[REG_CS];
      73             :   out->eflags = regs[REG_EFL];
      74             :   out->esp = regs[REG_UESP];
      75             :   out->ss = regs[REG_SS];
      76             : 
      77             :   out->float_save.control_word = fp->cw;
      78             :   out->float_save.status_word = fp->sw;
      79             :   out->float_save.tag_word = fp->tag;
      80             :   out->float_save.error_offset = fp->ipoff;
      81             :   out->float_save.error_selector = fp->cssel;
      82             :   out->float_save.data_offset = fp->dataoff;
      83             :   out->float_save.data_selector = fp->datasel;
      84             : 
      85             :   // 8 registers * 10 bytes per register.
      86             :   my_memcpy(out->float_save.register_area, fp->_st, 10 * 8);
      87             : }
      88             : 
      89             : #elif defined(__x86_64)
      90             : 
      91           0 : uintptr_t UContextReader::GetStackPointer(const struct ucontext* uc) {
      92           0 :   return uc->uc_mcontext.gregs[REG_RSP];
      93             : }
      94             : 
      95           0 : uintptr_t UContextReader::GetInstructionPointer(const struct ucontext* uc) {
      96           0 :   return uc->uc_mcontext.gregs[REG_RIP];
      97             : }
      98             : 
      99           0 : void UContextReader::FillCPUContext(RawContextCPU *out, const ucontext *uc,
     100             :                                     const struct _libc_fpstate* fpregs) {
     101           0 :   const greg_t* regs = uc->uc_mcontext.gregs;
     102             : 
     103           0 :   out->context_flags = MD_CONTEXT_AMD64_FULL;
     104             : 
     105           0 :   out->cs = regs[REG_CSGSFS] & 0xffff;
     106             : 
     107           0 :   out->fs = (regs[REG_CSGSFS] >> 32) & 0xffff;
     108           0 :   out->gs = (regs[REG_CSGSFS] >> 16) & 0xffff;
     109             : 
     110           0 :   out->eflags = regs[REG_EFL];
     111             : 
     112           0 :   out->rax = regs[REG_RAX];
     113           0 :   out->rcx = regs[REG_RCX];
     114           0 :   out->rdx = regs[REG_RDX];
     115           0 :   out->rbx = regs[REG_RBX];
     116             : 
     117           0 :   out->rsp = regs[REG_RSP];
     118           0 :   out->rbp = regs[REG_RBP];
     119           0 :   out->rsi = regs[REG_RSI];
     120           0 :   out->rdi = regs[REG_RDI];
     121           0 :   out->r8 = regs[REG_R8];
     122           0 :   out->r9 = regs[REG_R9];
     123           0 :   out->r10 = regs[REG_R10];
     124           0 :   out->r11 = regs[REG_R11];
     125           0 :   out->r12 = regs[REG_R12];
     126           0 :   out->r13 = regs[REG_R13];
     127           0 :   out->r14 = regs[REG_R14];
     128           0 :   out->r15 = regs[REG_R15];
     129             : 
     130           0 :   out->rip = regs[REG_RIP];
     131             : 
     132           0 :   out->flt_save.control_word = fpregs->cwd;
     133           0 :   out->flt_save.status_word = fpregs->swd;
     134           0 :   out->flt_save.tag_word = fpregs->ftw;
     135           0 :   out->flt_save.error_opcode = fpregs->fop;
     136           0 :   out->flt_save.error_offset = fpregs->rip;
     137           0 :   out->flt_save.data_offset = fpregs->rdp;
     138           0 :   out->flt_save.error_selector = 0;  // We don't have this.
     139           0 :   out->flt_save.data_selector = 0;  // We don't have this.
     140           0 :   out->flt_save.mx_csr = fpregs->mxcsr;
     141           0 :   out->flt_save.mx_csr_mask = fpregs->mxcr_mask;
     142           0 :   my_memcpy(&out->flt_save.float_registers, &fpregs->_st, 8 * 16);
     143           0 :   my_memcpy(&out->flt_save.xmm_registers, &fpregs->_xmm, 16 * 16);
     144           0 : }
     145             : 
     146             : #elif defined(__ARM_EABI__)
     147             : 
     148             : uintptr_t UContextReader::GetStackPointer(const struct ucontext* uc) {
     149             :   return uc->uc_mcontext.arm_sp;
     150             : }
     151             : 
     152             : uintptr_t UContextReader::GetInstructionPointer(const struct ucontext* uc) {
     153             :   return uc->uc_mcontext.arm_pc;
     154             : }
     155             : 
     156             : void UContextReader::FillCPUContext(RawContextCPU *out, const ucontext *uc) {
     157             :   out->context_flags = MD_CONTEXT_ARM_FULL;
     158             : 
     159             :   out->iregs[0] = uc->uc_mcontext.arm_r0;
     160             :   out->iregs[1] = uc->uc_mcontext.arm_r1;
     161             :   out->iregs[2] = uc->uc_mcontext.arm_r2;
     162             :   out->iregs[3] = uc->uc_mcontext.arm_r3;
     163             :   out->iregs[4] = uc->uc_mcontext.arm_r4;
     164             :   out->iregs[5] = uc->uc_mcontext.arm_r5;
     165             :   out->iregs[6] = uc->uc_mcontext.arm_r6;
     166             :   out->iregs[7] = uc->uc_mcontext.arm_r7;
     167             :   out->iregs[8] = uc->uc_mcontext.arm_r8;
     168             :   out->iregs[9] = uc->uc_mcontext.arm_r9;
     169             :   out->iregs[10] = uc->uc_mcontext.arm_r10;
     170             : 
     171             :   out->iregs[11] = uc->uc_mcontext.arm_fp;
     172             :   out->iregs[12] = uc->uc_mcontext.arm_ip;
     173             :   out->iregs[13] = uc->uc_mcontext.arm_sp;
     174             :   out->iregs[14] = uc->uc_mcontext.arm_lr;
     175             :   out->iregs[15] = uc->uc_mcontext.arm_pc;
     176             : 
     177             :   out->cpsr = uc->uc_mcontext.arm_cpsr;
     178             : 
     179             :   // TODO: fix this after fixing ExceptionHandler
     180             :   out->float_save.fpscr = 0;
     181             :   my_memset(&out->float_save.regs, 0, sizeof(out->float_save.regs));
     182             :   my_memset(&out->float_save.extra, 0, sizeof(out->float_save.extra));
     183             : }
     184             : 
     185             : #elif defined(__aarch64__)
     186             : 
     187             : uintptr_t UContextReader::GetStackPointer(const struct ucontext* uc) {
     188             :   return uc->uc_mcontext.sp;
     189             : }
     190             : 
     191             : uintptr_t UContextReader::GetInstructionPointer(const struct ucontext* uc) {
     192             :   return uc->uc_mcontext.pc;
     193             : }
     194             : 
     195             : void UContextReader::FillCPUContext(RawContextCPU *out, const ucontext *uc,
     196             :                                     const struct fpsimd_context* fpregs) {
     197             :   out->context_flags = MD_CONTEXT_ARM64_FULL;
     198             : 
     199             :   out->cpsr = static_cast<uint32_t>(uc->uc_mcontext.pstate);
     200             :   for (int i = 0; i < MD_CONTEXT_ARM64_REG_SP; ++i)
     201             :     out->iregs[i] = uc->uc_mcontext.regs[i];
     202             :   out->iregs[MD_CONTEXT_ARM64_REG_SP] = uc->uc_mcontext.sp;
     203             :   out->iregs[MD_CONTEXT_ARM64_REG_PC] = uc->uc_mcontext.pc;
     204             : 
     205             :   out->float_save.fpsr = fpregs->fpsr;
     206             :   out->float_save.fpcr = fpregs->fpcr;
     207             :   my_memcpy(&out->float_save.regs, &fpregs->vregs,
     208             :       MD_FLOATINGSAVEAREA_ARM64_FPR_COUNT * 16);
     209             : }
     210             : 
     211             : #elif defined(__mips__)
     212             : 
     213             : uintptr_t UContextReader::GetStackPointer(const struct ucontext* uc) {
     214             :   return uc->uc_mcontext.gregs[MD_CONTEXT_MIPS_REG_SP];
     215             : }
     216             : 
     217             : uintptr_t UContextReader::GetInstructionPointer(const struct ucontext* uc) {
     218             :   return uc->uc_mcontext.pc;
     219             : }
     220             : 
     221             : void UContextReader::FillCPUContext(RawContextCPU *out, const ucontext *uc) {
     222             : #if _MIPS_SIM == _ABI64
     223             :   out->context_flags = MD_CONTEXT_MIPS64_FULL;
     224             : #elif _MIPS_SIM == _ABIO32
     225             :   out->context_flags = MD_CONTEXT_MIPS_FULL;
     226             : #else
     227             : #error "This mips ABI is currently not supported (n32)"
     228             : #endif
     229             : 
     230             :   for (int i = 0; i < MD_CONTEXT_MIPS_GPR_COUNT; ++i)
     231             :     out->iregs[i] = uc->uc_mcontext.gregs[i];
     232             : 
     233             :   out->mdhi = uc->uc_mcontext.mdhi;
     234             :   out->mdlo = uc->uc_mcontext.mdlo;
     235             : 
     236             :   out->hi[0] = uc->uc_mcontext.hi1;
     237             :   out->hi[1] = uc->uc_mcontext.hi2;
     238             :   out->hi[2] = uc->uc_mcontext.hi3;
     239             :   out->lo[0] = uc->uc_mcontext.lo1;
     240             :   out->lo[1] = uc->uc_mcontext.lo2;
     241             :   out->lo[2] = uc->uc_mcontext.lo3;
     242             :   out->dsp_control = uc->uc_mcontext.dsp;
     243             : 
     244             :   out->epc = uc->uc_mcontext.pc;
     245             :   out->badvaddr = 0;  // Not reported in signal context.
     246             :   out->status = 0;  // Not reported in signal context.
     247             :   out->cause = 0;  // Not reported in signal context.
     248             : 
     249             :   for (int i = 0; i < MD_FLOATINGSAVEAREA_MIPS_FPR_COUNT; ++i)
     250             :     out->float_save.regs[i] = uc->uc_mcontext.fpregs.fp_r.fp_dregs[i];
     251             : 
     252             :   out->float_save.fpcsr = uc->uc_mcontext.fpc_csr;
     253             : #if _MIPS_SIM == _ABIO32
     254             :   out->float_save.fir = uc->uc_mcontext.fpc_eir;  // Unused.
     255             : #endif
     256             : }
     257             : #endif
     258             : 
     259             : }  // namespace google_breakpad

Generated by: LCOV version 1.13