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
15DataTarget::DataTarget(void) :
16 m_ref(0)
17{
18}
19
20STDMETHODIMP
21DataTarget::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
47STDMETHODIMP_(ULONG)
48DataTarget::AddRef(
49 THIS
50 )
51{
52 LONG ref = InterlockedIncrement(&m_ref);
53 return ref;
54}
55
56STDMETHODIMP_(ULONG)
57DataTarget::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
69HRESULT STDMETHODCALLTYPE
70DataTarget::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
80HRESULT STDMETHODCALLTYPE
81DataTarget::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
95HRESULT STDMETHODCALLTYPE
96DataTarget::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
113HRESULT STDMETHODCALLTYPE
114DataTarget::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
127HRESULT STDMETHODCALLTYPE
128DataTarget::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
141HRESULT STDMETHODCALLTYPE
142DataTarget::GetTLSValue(
143 /* [in] */ ULONG32 threadID,
144 /* [in] */ ULONG32 index,
145 /* [out] */ CLRDATA_ADDRESS* value)
146{
147 return E_NOTIMPL;
148}
149
150HRESULT STDMETHODCALLTYPE
151DataTarget::SetTLSValue(
152 /* [in] */ ULONG32 threadID,
153 /* [in] */ ULONG32 index,
154 /* [in] */ CLRDATA_ADDRESS value)
155{
156 return E_NOTIMPL;
157}
158
159HRESULT STDMETHODCALLTYPE
160DataTarget::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
170HRESULT STDMETHODCALLTYPE
171DataTarget::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
184HRESULT STDMETHODCALLTYPE
185DataTarget::SetThreadContext(
186 /* [in] */ ULONG32 threadID,
187 /* [in] */ ULONG32 contextSize,
188 /* [out, size_is(contextSize)] */ PBYTE context)
189{
190 return E_NOTIMPL;
191}
192
193HRESULT STDMETHODCALLTYPE
194DataTarget::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
204HRESULT STDMETHODCALLTYPE
205DataTarget::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