[Tizen] Unify dnetmemoryenumlib terms to match the codebase (#291)
[platform/upstream/coreclr.git] / src / utilcode / dacutil.cpp
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 //
6 // Internal data access functionality.
7 //
8
9 //*****************************************************************************
10
11 #include "stdafx.h"
12
13 #include <winwrap.h>
14 #include <utilcode.h>
15 #include <dacprivate.h>
16
17 //----------------------------------------------------------------------------
18 //
19 // LiveProcDataTarget.
20 //
21 //----------------------------------------------------------------------------
22
23 LiveProcDataTarget::LiveProcDataTarget(HANDLE process,
24                                        DWORD processId,
25                                        CLRDATA_ADDRESS baseAddressOfEngine)
26 {
27     m_process = process;
28     m_processId = processId;
29     m_baseAddressOfEngine = baseAddressOfEngine;
30 }
31
32 STDMETHODIMP
33 LiveProcDataTarget::QueryInterface(
34     THIS_
35     IN REFIID InterfaceId,
36     OUT PVOID* Interface
37     )
38 {
39     if (InterfaceId == IID_IUnknown ||
40         InterfaceId == IID_ICLRDataTarget)
41     {
42         *Interface = (ICLRDataTarget*)this;
43         // No need to refcount as this class is contained.
44         return S_OK;
45     }
46     else
47     {
48         *Interface = NULL;
49         return E_NOINTERFACE;
50     }
51 }
52
53 STDMETHODIMP_(ULONG)
54 LiveProcDataTarget::AddRef(
55     THIS
56     )
57 {
58     // No need to refcount as this class is contained.
59     return 1;
60 }
61
62 STDMETHODIMP_(ULONG)
63 LiveProcDataTarget::Release(
64     THIS
65     )
66 {
67     SUPPORTS_DAC_HOST_ONLY;
68     // No need to refcount as this class is contained.
69     return 0;
70 }
71
72 HRESULT STDMETHODCALLTYPE
73 LiveProcDataTarget::GetMachineType( 
74     /* [out] */ ULONG32 *machine)
75 {
76     LIMITED_METHOD_CONTRACT;
77
78 #if defined(_TARGET_X86_)
79     *machine = IMAGE_FILE_MACHINE_I386;
80 #elif defined(_TARGET_AMD64_)
81     *machine = IMAGE_FILE_MACHINE_AMD64;
82 #elif defined(_TARGET_ARM_)
83     *machine = IMAGE_FILE_MACHINE_ARMNT;
84 #else
85     PORTABILITY_ASSERT("Unknown Processor");
86 #endif
87     return S_OK;
88 }
89
90 HRESULT STDMETHODCALLTYPE
91 LiveProcDataTarget::GetPointerSize( 
92     /* [out] */ ULONG32 *size)
93 {
94     LIMITED_METHOD_CONTRACT;
95
96     *size = sizeof(void*);
97     return S_OK;
98 }
99
100 HRESULT STDMETHODCALLTYPE
101 LiveProcDataTarget::GetImageBase( 
102     /* [string][in] */ LPCWSTR name,
103     /* [out] */ CLRDATA_ADDRESS *base)
104 {
105     //
106     // The only image base that the access code cares
107     // about right now is the base of mscorwks.  
108     //
109     
110     if (wcscmp(name, MAIN_CLR_DLL_NAME_W))
111     {
112         return E_NOINTERFACE;
113     }
114
115     // 
116     // If a base address was specified, use that
117     //
118     if (NULL != m_baseAddressOfEngine)
119     {
120         *base = m_baseAddressOfEngine;
121         return S_OK;
122     }
123
124     // 
125     // Our creator must have told us WHICH clr to work with.
126     //
127     return E_FAIL;
128 }
129
130 HRESULT STDMETHODCALLTYPE
131 LiveProcDataTarget::ReadVirtual( 
132     /* [in] */ CLRDATA_ADDRESS address,
133     /* [length_is][size_is][out] */ PBYTE buffer,
134     /* [in] */ ULONG32 request,
135     /* [optional][out] */ ULONG32 *done)
136 {
137     // ReadProcessMemory will fail if any part of the
138     // region to read does not have read access.  This
139     // routine attempts to read the largest valid prefix
140     // so it has to break up reads on page boundaries.
141
142     HRESULT status = S_OK;
143     ULONG32 totalDone = 0;
144     SIZE_T read;
145     ULONG32 readSize;
146
147     while (request > 0)
148     {
149         // Calculate bytes to read and don't let read cross
150         // a page boundary.
151         readSize = GetOsPageSize() - (ULONG32)(address & (GetOsPageSize() - 1));
152         readSize = min(request, readSize);
153
154         if (!ReadProcessMemory(m_process, (PVOID)(ULONG_PTR)address,
155                                buffer, readSize, &read))
156         {
157             if (totalDone == 0)
158             {
159                 // If we haven't read anything indicate failure.
160                 status = E_FAIL;
161             }
162             break;
163         }
164
165         totalDone += (ULONG32)read;
166         address += read;
167         buffer += read;
168         request -= (ULONG32)read;
169     }
170
171     *done = totalDone;
172     return status;
173 }
174
175 HRESULT STDMETHODCALLTYPE
176 LiveProcDataTarget::WriteVirtual( 
177     /* [in] */ CLRDATA_ADDRESS address,
178     /* [size_is][in] */ PBYTE buffer,
179     /* [in] */ ULONG32 request,
180     /* [optional][out] */ ULONG32 *done)
181 {
182     // Not necessary yet.
183     return E_NOTIMPL;
184 }
185
186 HRESULT STDMETHODCALLTYPE
187 LiveProcDataTarget::GetTLSValue(
188     /* [in] */ ULONG32 threadID,
189     /* [in] */ ULONG32 index,
190     /* [out] */ CLRDATA_ADDRESS* value)
191 {
192     SUPPORTS_DAC;
193     // Not necessary yet.
194     return E_NOTIMPL;
195 }
196
197 HRESULT STDMETHODCALLTYPE
198 LiveProcDataTarget::SetTLSValue(
199     /* [in] */ ULONG32 threadID,
200     /* [in] */ ULONG32 index,
201     /* [in] */ CLRDATA_ADDRESS value)
202 {
203     // Not necessary yet.
204     return E_NOTIMPL;
205 }
206
207 HRESULT STDMETHODCALLTYPE
208 LiveProcDataTarget::GetCurrentThreadID(
209     /* [out] */ ULONG32* threadID)
210 {
211     SUPPORTS_DAC;
212     // Not necessary yet.
213     return E_NOTIMPL;
214 }
215
216 HRESULT STDMETHODCALLTYPE
217 LiveProcDataTarget::GetThreadContext(
218     /* [in] */ ULONG32 threadID,
219     /* [in] */ ULONG32 contextFlags,
220     /* [in] */ ULONG32 contextSize,
221     /* [out, size_is(contextSize)] */ PBYTE context)
222 {
223     // Not necessary yet.
224     return E_NOTIMPL;
225 }
226
227 HRESULT STDMETHODCALLTYPE
228 LiveProcDataTarget::SetThreadContext(
229     /* [in] */ ULONG32 threadID,
230     /* [in] */ ULONG32 contextSize,
231     /* [out, size_is(contextSize)] */ PBYTE context)
232 {
233     // Not necessary yet.
234     return E_NOTIMPL;
235 }
236
237 HRESULT STDMETHODCALLTYPE
238 LiveProcDataTarget::Request( 
239     /* [in] */ ULONG32 reqCode,
240     /* [in] */ ULONG32 inBufferSize,
241     /* [size_is][in] */ BYTE *inBuffer,
242     /* [in] */ ULONG32 outBufferSize,
243     /* [size_is][out] */ BYTE *outBuffer)
244 {
245     // None supported.
246     return E_INVALIDARG;
247 }