130f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org// Copyright (c) 2014, Google Inc.
230f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org// All rights reserved.
330f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org//
430f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org// Redistribution and use in source and binary forms, with or without
530f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org// modification, are permitted provided that the following conditions are
630f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org// met:
730f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org//
830f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org//     * Redistributions of source code must retain the above copyright
930f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org// notice, this list of conditions and the following disclaimer.
1030f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org//     * Redistributions in binary form must reproduce the above
1130f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org// copyright notice, this list of conditions and the following disclaimer
1230f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org// in the documentation and/or other materials provided with the
1330f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org// distribution.
1430f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org//     * Neither the name of Google Inc. nor the names of its
1530f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org// contributors may be used to endorse or promote products derived from
1630f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org// this software without specific prior written permission.
1730f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org//
1830f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1930f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2030f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2130f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2230f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2330f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2430f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2530f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2630f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2730f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2830f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2930f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org
3030f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org#include "client/linux/dump_writer_common/thread_info.h"
3130f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org
3230f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org#include <string.h>
3330f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org
3430f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org#include "common/linux/linux_libc_support.h"
3530f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org#include "google_breakpad/common/minidump_format.h"
3630f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org
3730f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.orgnamespace {
3830f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org
3930f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org#if defined(__i386__)
4030f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org// Write a uint16_t to memory
4130f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org//   out: memory location to write to
4230f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org//   v: value to write.
4330f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.orgvoid U16(void* out, uint16_t v) {
4430f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  my_memcpy(out, &v, sizeof(v));
4530f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org}
4630f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org
4730f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org// Write a uint32_t to memory
4830f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org//   out: memory location to write to
4930f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org//   v: value to write.
5030f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.orgvoid U32(void* out, uint32_t v) {
5130f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  my_memcpy(out, &v, sizeof(v));
5230f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org}
5330f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org#endif
5430f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org
5530f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org}
5630f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org
5730f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.orgnamespace google_breakpad {
5830f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org
5930f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org#if defined(__i386__)
6030f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org
6130f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.orguintptr_t ThreadInfo::GetInstructionPointer() const {
6230f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  return regs.eip;
6330f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org}
6430f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org
6530f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.orgvoid ThreadInfo::FillCPUContext(RawContextCPU* out) const {
6630f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->context_flags = MD_CONTEXT_X86_ALL;
6730f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org
6830f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->dr0 = dregs[0];
6930f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->dr1 = dregs[1];
7030f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->dr2 = dregs[2];
7130f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->dr3 = dregs[3];
7230f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  // 4 and 5 deliberatly omitted because they aren't included in the minidump
7330f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  // format.
7430f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->dr6 = dregs[6];
7530f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->dr7 = dregs[7];
7630f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org
7730f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->gs = regs.xgs;
7830f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->fs = regs.xfs;
7930f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->es = regs.xes;
8030f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->ds = regs.xds;
8130f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org
8230f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->edi = regs.edi;
8330f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->esi = regs.esi;
8430f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->ebx = regs.ebx;
8530f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->edx = regs.edx;
8630f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->ecx = regs.ecx;
8730f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->eax = regs.eax;
8830f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org
8930f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->ebp = regs.ebp;
9030f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->eip = regs.eip;
9130f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->cs = regs.xcs;
9230f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->eflags = regs.eflags;
9330f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->esp = regs.esp;
9430f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->ss = regs.xss;
9530f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org
9630f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->float_save.control_word = fpregs.cwd;
9730f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->float_save.status_word = fpregs.swd;
9830f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->float_save.tag_word = fpregs.twd;
9930f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->float_save.error_offset = fpregs.fip;
10030f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->float_save.error_selector = fpregs.fcs;
10130f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->float_save.data_offset = fpregs.foo;
10230f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->float_save.data_selector = fpregs.fos;
10330f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org
10430f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  // 8 registers * 10 bytes per register.
10530f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  my_memcpy(out->float_save.register_area, fpregs.st_space, 10 * 8);
10630f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org
10730f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  // This matches the Intel fpsave format.
10830f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  U16(out->extended_registers + 0, fpregs.cwd);
10930f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  U16(out->extended_registers + 2, fpregs.swd);
11030f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  U16(out->extended_registers + 4, fpregs.twd);
11130f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  U16(out->extended_registers + 6, fpxregs.fop);
11230f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  U32(out->extended_registers + 8, fpxregs.fip);
11330f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  U16(out->extended_registers + 12, fpxregs.fcs);
11430f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  U32(out->extended_registers + 16, fpregs.foo);
11530f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  U16(out->extended_registers + 20, fpregs.fos);
11630f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  U32(out->extended_registers + 24, fpxregs.mxcsr);
11730f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org
11830f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  my_memcpy(out->extended_registers + 32, &fpxregs.st_space, 128);
11930f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  my_memcpy(out->extended_registers + 160, &fpxregs.xmm_space, 128);
12030f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org}
12130f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org
12230f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org#elif defined(__x86_64)
12330f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org
12430f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.orguintptr_t ThreadInfo::GetInstructionPointer() const {
12530f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  return regs.rip;
12630f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org}
12730f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org
12830f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.orgvoid ThreadInfo::FillCPUContext(RawContextCPU* out) const {
12930f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->context_flags = MD_CONTEXT_AMD64_FULL |
13030f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org                       MD_CONTEXT_AMD64_SEGMENTS;
13130f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org
13230f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->cs = regs.cs;
13330f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org
13430f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->ds = regs.ds;
13530f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->es = regs.es;
13630f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->fs = regs.fs;
13730f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->gs = regs.gs;
13830f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org
13930f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->ss = regs.ss;
14030f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->eflags = regs.eflags;
14130f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org
14230f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->dr0 = dregs[0];
14330f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->dr1 = dregs[1];
14430f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->dr2 = dregs[2];
14530f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->dr3 = dregs[3];
14630f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  // 4 and 5 deliberatly omitted because they aren't included in the minidump
14730f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  // format.
14830f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->dr6 = dregs[6];
14930f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->dr7 = dregs[7];
15030f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org
15130f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->rax = regs.rax;
15230f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->rcx = regs.rcx;
15330f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->rdx = regs.rdx;
15430f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->rbx = regs.rbx;
15530f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org
15630f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->rsp = regs.rsp;
15730f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org
15830f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->rbp = regs.rbp;
15930f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->rsi = regs.rsi;
16030f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->rdi = regs.rdi;
16130f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->r8 = regs.r8;
16230f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->r9 = regs.r9;
16330f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->r10 = regs.r10;
16430f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->r11 = regs.r11;
16530f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->r12 = regs.r12;
16630f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->r13 = regs.r13;
16730f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->r14 = regs.r14;
16830f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->r15 = regs.r15;
16930f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org
17030f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->rip = regs.rip;
17130f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org
17230f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->flt_save.control_word = fpregs.cwd;
17330f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->flt_save.status_word = fpregs.swd;
17430f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->flt_save.tag_word = fpregs.ftw;
17530f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->flt_save.error_opcode = fpregs.fop;
17630f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->flt_save.error_offset = fpregs.rip;
17730f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->flt_save.error_selector = 0;  // We don't have this.
17830f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->flt_save.data_offset = fpregs.rdp;
17930f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->flt_save.data_selector = 0;   // We don't have this.
18030f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->flt_save.mx_csr = fpregs.mxcsr;
18130f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->flt_save.mx_csr_mask = fpregs.mxcr_mask;
1824eb247bbf2fde47d6ecdde8214a35c1a9bb06c49primiano@chromium.org
18330f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  my_memcpy(&out->flt_save.float_registers, &fpregs.st_space, 8 * 16);
18430f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  my_memcpy(&out->flt_save.xmm_registers, &fpregs.xmm_space, 16 * 16);
18530f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org}
18630f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org
18730f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org#elif defined(__ARM_EABI__)
18830f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org
18930f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.orguintptr_t ThreadInfo::GetInstructionPointer() const {
19030f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  return regs.uregs[15];
19130f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org}
19230f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org
19330f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.orgvoid ThreadInfo::FillCPUContext(RawContextCPU* out) const {
19430f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->context_flags = MD_CONTEXT_ARM_FULL;
19530f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org
19630f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  for (int i = 0; i < MD_CONTEXT_ARM_GPR_COUNT; ++i)
19730f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org    out->iregs[i] = regs.uregs[i];
19830f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  // No CPSR register in ThreadInfo(it's not accessible via ptrace)
19930f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->cpsr = 0;
20030f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org#if !defined(__ANDROID__)
20130f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->float_save.fpscr = fpregs.fpsr |
20230f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org    (static_cast<uint64_t>(fpregs.fpcr) << 32);
20330f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  // TODO: sort this out, actually collect floating point registers
20430f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  my_memset(&out->float_save.regs, 0, sizeof(out->float_save.regs));
20530f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  my_memset(&out->float_save.extra, 0, sizeof(out->float_save.extra));
20630f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org#endif
20730f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org}
20830f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org
20930f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org#elif defined(__aarch64__)
21030f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org
21130f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.orguintptr_t ThreadInfo::GetInstructionPointer() const {
21230f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  return regs.pc;
21330f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org}
21430f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org
21530f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.orgvoid ThreadInfo::FillCPUContext(RawContextCPU* out) const {
21630f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->context_flags = MD_CONTEXT_ARM64_FULL;
21730f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org
21830f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->cpsr = static_cast<uint32_t>(regs.pstate);
21930f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  for (int i = 0; i < MD_CONTEXT_ARM64_REG_SP; ++i)
22030f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org    out->iregs[i] = regs.regs[i];
22130f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->iregs[MD_CONTEXT_ARM64_REG_SP] = regs.sp;
22230f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->iregs[MD_CONTEXT_ARM64_REG_PC] = regs.pc;
22330f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org
22430f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->float_save.fpsr = fpregs.fpsr;
22530f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->float_save.fpcr = fpregs.fpcr;
22630f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  my_memcpy(&out->float_save.regs, &fpregs.vregs,
22730f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org      MD_FLOATINGSAVEAREA_ARM64_FPR_COUNT * 16);
22830f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org}
22930f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org
23030f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org#elif defined(__mips__)
23130f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org
23230f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.orguintptr_t ThreadInfo::GetInstructionPointer() const {
23330f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  return regs.epc;
23430f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org}
23530f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org
23630f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.orgvoid ThreadInfo::FillCPUContext(RawContextCPU* out) const {
23730f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->context_flags = MD_CONTEXT_MIPS_FULL;
23830f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org
23930f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  for (int i = 0; i < MD_CONTEXT_MIPS_GPR_COUNT; ++i)
24030f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org    out->iregs[i] = regs.regs[i];
24130f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org
24230f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->mdhi = regs.hi;
24330f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->mdlo = regs.lo;
24430f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org
24530f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  for (int i = 0; i < MD_CONTEXT_MIPS_DSP_COUNT; ++i) {
24630f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org    out->hi[i] = hi[i];
24730f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org    out->lo[i] = lo[i];
24830f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  }
24930f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->dsp_control = dsp_control;
25030f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org
25130f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->epc = regs.epc;
25230f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->badvaddr = regs.badvaddr;
25330f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->status = regs.status;
25430f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->cause = regs.cause;
25530f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org
25630f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  for (int i = 0; i < MD_FLOATINGSAVEAREA_MIPS_FPR_COUNT; ++i)
25730f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org    out->float_save.regs[i] = fpregs.regs[i];
25830f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org
25930f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->float_save.fpcsr = fpregs.fpcsr;
26030f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org  out->float_save.fir = fpregs.fir;
26130f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org}
26230f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org#endif
26330f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org
26430f1b7fb16cdc906078f031bf12c1ffb2cb5ea3eprimiano@chromium.org}  // namespace google_breakpad
265