1 // Copyright 2014 The Crashpad Authors. All rights reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "snapshot/mac/thread_snapshot_mac.h"
16 
17 #include "base/logging.h"
18 #include "snapshot/mac/cpu_context_mac.h"
19 #include "snapshot/mac/process_reader_mac.h"
20 
21 namespace crashpad {
22 namespace internal {
23 
ThreadSnapshotMac()24 ThreadSnapshotMac::ThreadSnapshotMac()
25     : ThreadSnapshot(),
26       context_union_(),
27       context_(),
28       stack_(),
29       thread_id_(0),
30       thread_specific_data_address_(0),
31       thread_(MACH_PORT_NULL),
32       suspend_count_(0),
33       priority_(0),
34       initialized_() {
35 }
36 
~ThreadSnapshotMac()37 ThreadSnapshotMac::~ThreadSnapshotMac() {
38 }
39 
Initialize(ProcessReaderMac * process_reader,const ProcessReaderMac::Thread & process_reader_thread)40 bool ThreadSnapshotMac::Initialize(
41     ProcessReaderMac* process_reader,
42     const ProcessReaderMac::Thread& process_reader_thread) {
43   INITIALIZATION_STATE_SET_INITIALIZING(initialized_);
44 
45   thread_ = process_reader_thread.port;
46   thread_id_ = process_reader_thread.id;
47   suspend_count_ = process_reader_thread.suspend_count;
48   priority_ = process_reader_thread.priority;
49   thread_specific_data_address_ =
50       process_reader_thread.thread_specific_data_address;
51 
52   stack_.Initialize(process_reader->Memory(),
53                     process_reader_thread.stack_region_address,
54                     process_reader_thread.stack_region_size);
55 
56 #if defined(ARCH_CPU_X86_FAMILY)
57   if (process_reader->Is64Bit()) {
58     context_.architecture = kCPUArchitectureX86_64;
59     context_.x86_64 = &context_union_.x86_64;
60     InitializeCPUContextX86_64(context_.x86_64,
61                                THREAD_STATE_NONE,
62                                nullptr,
63                                0,
64                                &process_reader_thread.thread_context.t64,
65                                &process_reader_thread.float_context.f64,
66                                &process_reader_thread.debug_context.d64);
67   } else {
68     context_.architecture = kCPUArchitectureX86;
69     context_.x86 = &context_union_.x86;
70     InitializeCPUContextX86(context_.x86,
71                             THREAD_STATE_NONE,
72                             nullptr,
73                             0,
74                             &process_reader_thread.thread_context.t32,
75                             &process_reader_thread.float_context.f32,
76                             &process_reader_thread.debug_context.d32);
77   }
78 #endif
79 
80   INITIALIZATION_STATE_SET_VALID(initialized_);
81   return true;
82 }
83 
Context() const84 const CPUContext* ThreadSnapshotMac::Context() const {
85   INITIALIZATION_STATE_DCHECK_VALID(initialized_);
86   return &context_;
87 }
88 
Stack() const89 const MemorySnapshot* ThreadSnapshotMac::Stack() const {
90   INITIALIZATION_STATE_DCHECK_VALID(initialized_);
91   return &stack_;
92 }
93 
ThreadID() const94 uint64_t ThreadSnapshotMac::ThreadID() const {
95   INITIALIZATION_STATE_DCHECK_VALID(initialized_);
96   return thread_id_;
97 }
98 
SuspendCount() const99 int ThreadSnapshotMac::SuspendCount() const {
100   INITIALIZATION_STATE_DCHECK_VALID(initialized_);
101   return suspend_count_;
102 }
103 
Priority() const104 int ThreadSnapshotMac::Priority() const {
105   INITIALIZATION_STATE_DCHECK_VALID(initialized_);
106   return priority_;
107 }
108 
ThreadSpecificDataAddress() const109 uint64_t ThreadSnapshotMac::ThreadSpecificDataAddress() const {
110   INITIALIZATION_STATE_DCHECK_VALID(initialized_);
111   return thread_specific_data_address_;
112 }
113 
ExtraMemory() const114 std::vector<const MemorySnapshot*> ThreadSnapshotMac::ExtraMemory() const {
115   return std::vector<const MemorySnapshot*>();
116 }
117 
118 }  // namespace internal
119 }  // namespace crashpad
120