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
7#include "stdafx.h"
8#include "unwinder.h"
9
10EXTERN_C void GetRuntimeStackWalkInfo(IN ULONG64 ControlPc,
11 OUT UINT_PTR* pModuleBase,
12 OUT UINT_PTR* pFuncEntry);
13
14//---------------------------------------------------------------------------------------
15//
16// Given a control PC, return the base of the module it is in. For jitted managed code, this is the
17// start of the code heap.
18//
19// Arguments:
20// address - the specified address
21// pdwBase - out parameter; returns the module base
22//
23// Return Value:
24// S_OK if we retrieve the module base successfully;
25// E_FAIL otherwise
26//
27
28HRESULT OOPStackUnwinder::GetModuleBase( DWORD64 address,
29 __out PDWORD64 pdwBase)
30{
31 GetRuntimeStackWalkInfo(address, reinterpret_cast<UINT_PTR *>(pdwBase), NULL);
32 return ((*pdwBase == NULL) ? E_FAIL : S_OK);
33}
34
35//---------------------------------------------------------------------------------------
36//
37// Given a control PC, return the function entry of the function it is in.
38//
39// Arguments:
40// address - the specified IP
41// pBuffer - the buffer to store the retrieved function entry
42// cbBuffer - the size of the buffer
43//
44// Return Value:
45// S_OK if we retrieve the function entry successfully;
46// E_INVALIDARG if the buffer is too small;
47// E_FAIL otherwise
48//
49
50HRESULT OOPStackUnwinder::GetFunctionEntry( DWORD64 address,
51 __out_ecount(cbBuffer) PVOID pBuffer,
52 DWORD cbBuffer)
53{
54 if (cbBuffer < sizeof(T_RUNTIME_FUNCTION))
55 {
56 return E_INVALIDARG;
57 }
58
59 PVOID pFuncEntry = NULL;
60 GetRuntimeStackWalkInfo(address, NULL, reinterpret_cast<UINT_PTR *>(&pFuncEntry));
61 if (pFuncEntry == NULL)
62 {
63 return E_FAIL;
64 }
65
66 memcpy(pBuffer, pFuncEntry, cbBuffer);
67 return S_OK;
68}
69