summaryrefslogtreecommitdiff
path: root/src/unwinder/unwinder.cpp
blob: 5ab3048905eb0b7210e5ad31c939a1213c461596 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

// 

#include "stdafx.h"
#include "unwinder.h"

EXTERN_C void GetRuntimeStackWalkInfo(IN  ULONG64   ControlPc,
                                      OUT UINT_PTR* pModuleBase,
                                      OUT UINT_PTR* pFuncEntry);

//---------------------------------------------------------------------------------------
//
// Given a control PC, return the base of the module it is in.  For jitted managed code, this is the 
// start of the code heap.
//
// Arguments:
//    address - the specified address
//    pdwBase - out parameter; returns the module base
//
// Return Value:
//    S_OK if we retrieve the module base successfully;
//    E_FAIL otherwise
//

HRESULT OOPStackUnwinder::GetModuleBase(      DWORD64  address,
                                          __out PDWORD64 pdwBase)
{
    GetRuntimeStackWalkInfo(address, reinterpret_cast<UINT_PTR *>(pdwBase), NULL);
    return ((*pdwBase == NULL) ? E_FAIL : S_OK);
}

//---------------------------------------------------------------------------------------
//
// Given a control PC, return the function entry of the functoin it is in.
//
// Arguments:
//    address  - the specified IP
//    pBuffer  - the buffer to store the retrieved function entry
//    cbBuffer - the size of the buffer
//
// Return Value:
//    S_OK          if we retrieve the function entry successfully;
//    E_INVALIDARG  if the buffer is too small;
//    E_FAIL        otherwise
//

HRESULT OOPStackUnwinder::GetFunctionEntry(                       DWORD64 address,
                                           __out_ecount(cbBuffer) PVOID   pBuffer,
                                                                  DWORD   cbBuffer)
{
    if (cbBuffer < sizeof(T_RUNTIME_FUNCTION))
    {
        return E_INVALIDARG;
    }

    PVOID pFuncEntry = NULL;
    GetRuntimeStackWalkInfo(address, NULL, reinterpret_cast<UINT_PTR *>(&pFuncEntry));
    if (pFuncEntry == NULL)
    {
        return E_FAIL;
    }

    memcpy(pBuffer, pFuncEntry, cbBuffer);
    return S_OK;
}