summaryrefslogtreecommitdiff
path: root/src/inc/gcinfodumper.h
blob: 296dd295435af3589bf8664da16ae2cb5dd96af7 (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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
// 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.

#ifndef __GCINFODUMPER_H__
#define __GCINFODUMPER_H__

#include "gcinfotypes.h"
#include "gcinfodecoder.h"


//
// This class dumps the contents of the gc encodings, providing outputs
// similar to the inputs to GcInfoEncoder.  This uses the same GcInfoDecoder
// functions that the EE uses (vs. decoding the bits directly).
//
class GcInfoDumper
{
public:

    GcInfoDumper (GCInfoToken gcInfoToken);
    ~GcInfoDumper ();

    // Returns TRUE to stop decoding.
    typedef BOOL InterruptibleStateChangeProc (
            UINT32 CodeOffset,
            BOOL fInterruptible,
            PVOID pvData);

    // Returns TRUE to stop decoding.
    typedef BOOL OnSafePointProc (
            UINT32 CodeOffset,
            PVOID pvData);

    // Returns TRUE to stop decoding.
    typedef BOOL RegisterStateChangeProc (
            UINT32 CodeOffset,
            UINT32 RegisterNumber,
            GcSlotFlags Flags,
            GcSlotState NewState,
            PVOID pvData);
    
    // Returns TRUE to stop decoding.
    typedef BOOL StackSlotStateChangeProc (
            UINT32 CodeOffset,
            GcSlotFlags flags,
            GcStackSlotBase BaseRegister,
            SSIZE_T StackOffset,
            GcSlotState NewState,
            PVOID pvData);

    enum EnumerateStateChangesResults
    {
        SUCCESS = 0,
        OUT_OF_MEMORY,
        REPORTED_REGISTER_IN_CALLERS_FRAME,
        REPORTED_FRAME_POINTER,
        REPORTED_INVALID_BASE_REGISTER,
        REPORTED_INVALID_POINTER,
        DECODER_FAILED,
    };

    // Returns TRUE if successful.  FALSE if out of memory, invalid data, etc.
    EnumerateStateChangesResults EnumerateStateChanges (
            InterruptibleStateChangeProc *pfnInterruptibleStateChange,
            RegisterStateChangeProc *pfnRegisterStateChange,
            StackSlotStateChangeProc *pfnStackSlotStateChange,
            OnSafePointProc *pfnSafePointFunc,
            PVOID pvData);

    size_t GetGCInfoSize();

private:

    struct LivePointerRecord
    {
        OBJECTREF *ppObject;
        DWORD flags;
        LivePointerRecord *pNext;
        UINT marked;
    };

    GCInfoToken m_gcTable;
    UINT32 m_StackBaseRegister;
    UINT32 m_SizeOfEditAndContinuePreservedArea;
    LivePointerRecord *m_pRecords;
    RegisterStateChangeProc *m_pfnRegisterStateChange;
    StackSlotStateChangeProc *m_pfnStackSlotStateChange;
    PVOID m_pvCallbackData;
    EnumerateStateChangesResults m_Error;
    size_t m_gcInfoSize;

    static void LivePointerCallback (
            LPVOID          hCallback,      // callback data
            OBJECTREF*      pObject,        // address of obect-reference we are reporting
            uint32_t        flags           // is this a pinned and/or interior pointer
            DAC_ARG(DacSlotLocation loc));  // the location the pointer came from

    static void FreePointerRecords (LivePointerRecord *pRecords);

    // Return TRUE if callback requested to stop decoding.
    BOOL ReportPointerRecord (
            UINT32 CodeOffset,
            BOOL fLive,
            REGDISPLAY *pRD,
            LivePointerRecord *pRecord);

    // Return TRUE if callback requested to stop decoding.
    BOOL ReportPointerDifferences (
            UINT32 offset,
            REGDISPLAY *pRD,
            LivePointerRecord *pPrevState);
};


#endif // !__GCINFODUMPER_H__