1 | // Licensed to the .NET Foundation under one or more agreements. |
2 | // The .NET Foundation licenses this file to you under the MIT license. |
3 | // See the LICENSE file in the project root for more information. |
4 | |
5 | #include "sos.h" |
6 | #include "datatarget.h" |
7 | #include "corhdr.h" |
8 | #include "cor.h" |
9 | #include "dacprivate.h" |
10 | #include "sospriv.h" |
11 | #include "corerror.h" |
12 | |
13 | #define IMAGE_FILE_MACHINE_AMD64 0x8664 // AMD64 (K8) |
14 | |
15 | DataTarget::DataTarget(void) : |
16 | m_ref(0) |
17 | { |
18 | } |
19 | |
20 | STDMETHODIMP |
21 | DataTarget::QueryInterface( |
22 | THIS_ |
23 | ___in REFIID InterfaceId, |
24 | ___out PVOID* Interface |
25 | ) |
26 | { |
27 | if (InterfaceId == IID_IUnknown || |
28 | InterfaceId == IID_ICLRDataTarget) |
29 | { |
30 | *Interface = (ICLRDataTarget*)this; |
31 | AddRef(); |
32 | return S_OK; |
33 | } |
34 | else if (InterfaceId == IID_ICorDebugDataTarget4) |
35 | { |
36 | *Interface = (ICorDebugDataTarget4*)this; |
37 | AddRef(); |
38 | return S_OK; |
39 | } |
40 | else |
41 | { |
42 | *Interface = NULL; |
43 | return E_NOINTERFACE; |
44 | } |
45 | } |
46 | |
47 | STDMETHODIMP_(ULONG) |
48 | DataTarget::AddRef( |
49 | THIS |
50 | ) |
51 | { |
52 | LONG ref = InterlockedIncrement(&m_ref); |
53 | return ref; |
54 | } |
55 | |
56 | STDMETHODIMP_(ULONG) |
57 | DataTarget::Release( |
58 | THIS |
59 | ) |
60 | { |
61 | LONG ref = InterlockedDecrement(&m_ref); |
62 | if (ref == 0) |
63 | { |
64 | delete this; |
65 | } |
66 | return ref; |
67 | } |
68 | |
69 | HRESULT STDMETHODCALLTYPE |
70 | DataTarget::GetMachineType( |
71 | /* [out] */ ULONG32 *machine) |
72 | { |
73 | if (g_ExtControl == NULL) |
74 | { |
75 | return E_UNEXPECTED; |
76 | } |
77 | return g_ExtControl->GetExecutingProcessorType(machine); |
78 | } |
79 | |
80 | HRESULT STDMETHODCALLTYPE |
81 | DataTarget::GetPointerSize( |
82 | /* [out] */ ULONG32 *size) |
83 | { |
84 | #if defined(SOS_TARGET_AMD64) || defined(SOS_TARGET_ARM64) |
85 | *size = 8; |
86 | #elif defined(SOS_TARGET_ARM) || defined(SOS_TARGET_X86) |
87 | *size = 4; |
88 | #else |
89 | #error Unsupported architecture |
90 | #endif |
91 | |
92 | return S_OK; |
93 | } |
94 | |
95 | HRESULT STDMETHODCALLTYPE |
96 | DataTarget::GetImageBase( |
97 | /* [string][in] */ LPCWSTR name, |
98 | /* [out] */ CLRDATA_ADDRESS *base) |
99 | { |
100 | if (g_ExtSymbols == NULL) |
101 | { |
102 | return E_UNEXPECTED; |
103 | } |
104 | CHAR lpstr[MAX_LONGPATH]; |
105 | int name_length = WideCharToMultiByte(CP_ACP, 0, name, -1, lpstr, MAX_LONGPATH, NULL, NULL); |
106 | if (name_length == 0) |
107 | { |
108 | return E_FAIL; |
109 | } |
110 | return g_ExtSymbols->GetModuleByModuleName(lpstr, 0, NULL, base); |
111 | } |
112 | |
113 | HRESULT STDMETHODCALLTYPE |
114 | DataTarget::ReadVirtual( |
115 | /* [in] */ CLRDATA_ADDRESS address, |
116 | /* [length_is][size_is][out] */ PBYTE buffer, |
117 | /* [in] */ ULONG32 request, |
118 | /* [optional][out] */ ULONG32 *done) |
119 | { |
120 | if (g_ExtData == NULL) |
121 | { |
122 | return E_UNEXPECTED; |
123 | } |
124 | return g_ExtData->ReadVirtual(address, (PVOID)buffer, request, done); |
125 | } |
126 | |
127 | HRESULT STDMETHODCALLTYPE |
128 | DataTarget::WriteVirtual( |
129 | /* [in] */ CLRDATA_ADDRESS address, |
130 | /* [size_is][in] */ PBYTE buffer, |
131 | /* [in] */ ULONG32 request, |
132 | /* [optional][out] */ ULONG32 *done) |
133 | { |
134 | if (g_ExtData == NULL) |
135 | { |
136 | return E_UNEXPECTED; |
137 | } |
138 | return g_ExtData->WriteVirtual(address, (PVOID)buffer, request, done); |
139 | } |
140 | |
141 | HRESULT STDMETHODCALLTYPE |
142 | DataTarget::GetTLSValue( |
143 | /* [in] */ ULONG32 threadID, |
144 | /* [in] */ ULONG32 index, |
145 | /* [out] */ CLRDATA_ADDRESS* value) |
146 | { |
147 | return E_NOTIMPL; |
148 | } |
149 | |
150 | HRESULT STDMETHODCALLTYPE |
151 | DataTarget::SetTLSValue( |
152 | /* [in] */ ULONG32 threadID, |
153 | /* [in] */ ULONG32 index, |
154 | /* [in] */ CLRDATA_ADDRESS value) |
155 | { |
156 | return E_NOTIMPL; |
157 | } |
158 | |
159 | HRESULT STDMETHODCALLTYPE |
160 | DataTarget::GetCurrentThreadID( |
161 | /* [out] */ ULONG32* threadID) |
162 | { |
163 | if (g_ExtSystem == NULL) |
164 | { |
165 | return E_UNEXPECTED; |
166 | } |
167 | return g_ExtSystem->GetCurrentThreadSystemId(threadID); |
168 | } |
169 | |
170 | HRESULT STDMETHODCALLTYPE |
171 | DataTarget::GetThreadContext( |
172 | /* [in] */ ULONG32 threadID, |
173 | /* [in] */ ULONG32 contextFlags, |
174 | /* [in] */ ULONG32 contextSize, |
175 | /* [out, size_is(contextSize)] */ PBYTE context) |
176 | { |
177 | if (g_ExtSystem == NULL) |
178 | { |
179 | return E_UNEXPECTED; |
180 | } |
181 | return g_ExtSystem->GetThreadContextById(threadID, contextFlags, contextSize, context); |
182 | } |
183 | |
184 | HRESULT STDMETHODCALLTYPE |
185 | DataTarget::SetThreadContext( |
186 | /* [in] */ ULONG32 threadID, |
187 | /* [in] */ ULONG32 contextSize, |
188 | /* [out, size_is(contextSize)] */ PBYTE context) |
189 | { |
190 | return E_NOTIMPL; |
191 | } |
192 | |
193 | HRESULT STDMETHODCALLTYPE |
194 | DataTarget::Request( |
195 | /* [in] */ ULONG32 reqCode, |
196 | /* [in] */ ULONG32 inBufferSize, |
197 | /* [size_is][in] */ BYTE *inBuffer, |
198 | /* [in] */ ULONG32 outBufferSize, |
199 | /* [size_is][out] */ BYTE *outBuffer) |
200 | { |
201 | return E_NOTIMPL; |
202 | } |
203 | |
204 | HRESULT STDMETHODCALLTYPE |
205 | DataTarget::VirtualUnwind( |
206 | /* [in] */ DWORD threadId, |
207 | /* [in] */ ULONG32 contextSize, |
208 | /* [in, out, size_is(contextSize)] */ PBYTE context) |
209 | { |
210 | if (g_ExtServices == NULL) |
211 | { |
212 | return E_UNEXPECTED; |
213 | } |
214 | return g_ExtServices->VirtualUnwind(threadId, contextSize, context); |
215 | } |
216 | |