// Copyright 2014 The Crashpad Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #include "snapshot/mac/thread_snapshot_mac.h" #include "base/check_op.h" #include "snapshot/mac/cpu_context_mac.h" #include "snapshot/mac/process_reader_mac.h" namespace crashpad { namespace internal { ThreadSnapshotMac::ThreadSnapshotMac() : ThreadSnapshot(), context_union_(), context_(), stack_(), thread_id_(0), thread_specific_data_address_(0), thread_(MACH_PORT_NULL), suspend_count_(0), priority_(0), initialized_() { } ThreadSnapshotMac::~ThreadSnapshotMac() { } bool ThreadSnapshotMac::Initialize( ProcessReaderMac* process_reader, const ProcessReaderMac::Thread& process_reader_thread) { INITIALIZATION_STATE_SET_INITIALIZING(initialized_); thread_ = process_reader_thread.port; thread_id_ = process_reader_thread.id; suspend_count_ = process_reader_thread.suspend_count; priority_ = process_reader_thread.priority; thread_specific_data_address_ = process_reader_thread.thread_specific_data_address; stack_.Initialize(process_reader->Memory(), process_reader_thread.stack_region_address, process_reader_thread.stack_region_size); #if defined(ARCH_CPU_X86_FAMILY) if (process_reader->Is64Bit()) { context_.architecture = kCPUArchitectureX86_64; context_.x86_64 = &context_union_.x86_64; InitializeCPUContextX86_64(context_.x86_64, THREAD_STATE_NONE, nullptr, 0, &process_reader_thread.thread_context.t64, &process_reader_thread.float_context.f64, &process_reader_thread.debug_context.d64); } else { context_.architecture = kCPUArchitectureX86; context_.x86 = &context_union_.x86; InitializeCPUContextX86(context_.x86, THREAD_STATE_NONE, nullptr, 0, &process_reader_thread.thread_context.t32, &process_reader_thread.float_context.f32, &process_reader_thread.debug_context.d32); } #elif defined(ARCH_CPU_ARM64) context_.architecture = kCPUArchitectureARM64; context_.arm64 = &context_union_.arm64; InitializeCPUContextARM64(context_.arm64, THREAD_STATE_NONE, nullptr, 0, &process_reader_thread.thread_context, &process_reader_thread.float_context, &process_reader_thread.debug_context); #else #error Port to your CPU architecture #endif INITIALIZATION_STATE_SET_VALID(initialized_); return true; } const CPUContext* ThreadSnapshotMac::Context() const { INITIALIZATION_STATE_DCHECK_VALID(initialized_); return &context_; } const MemorySnapshot* ThreadSnapshotMac::Stack() const { INITIALIZATION_STATE_DCHECK_VALID(initialized_); return &stack_; } uint64_t ThreadSnapshotMac::ThreadID() const { INITIALIZATION_STATE_DCHECK_VALID(initialized_); return thread_id_; } int ThreadSnapshotMac::SuspendCount() const { INITIALIZATION_STATE_DCHECK_VALID(initialized_); return suspend_count_; } int ThreadSnapshotMac::Priority() const { INITIALIZATION_STATE_DCHECK_VALID(initialized_); return priority_; } uint64_t ThreadSnapshotMac::ThreadSpecificDataAddress() const { INITIALIZATION_STATE_DCHECK_VALID(initialized_); return thread_specific_data_address_; } std::vector ThreadSnapshotMac::ExtraMemory() const { return std::vector(); } } // namespace internal } // namespace crashpad