summaryrefslogtreecommitdiff
path: root/src/ToolBox/SOS/Strike/disasm.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/ToolBox/SOS/Strike/disasm.h')
-rw-r--r--src/ToolBox/SOS/Strike/disasm.h453
1 files changed, 453 insertions, 0 deletions
diff --git a/src/ToolBox/SOS/Strike/disasm.h b/src/ToolBox/SOS/Strike/disasm.h
new file mode 100644
index 0000000000..59fc168a6e
--- /dev/null
+++ b/src/ToolBox/SOS/Strike/disasm.h
@@ -0,0 +1,453 @@
+// 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 __disasm_h__
+#define __disasm_h__
+
+#include "sos_stacktrace.h"
+
+struct InfoHdr;
+class GCDump;
+
+
+struct DumpStackFlag
+{
+ BOOL fEEonly;
+ BOOL fSuppressSrcInfo;
+ DWORD_PTR top;
+ DWORD_PTR end;
+};
+
+struct GCEncodingInfo
+{
+ LPVOID pvMainFiber;
+ LPVOID pvGCTableFiber;
+
+ BYTE *table;
+ unsigned int methodSize;
+
+ char buf[1000];
+ int cch;
+
+ SIZE_T ofs;
+
+ // When decoding a cold region, set this to the size of the hot region to keep offset
+ // calculations working.
+ SIZE_T hotSizeToAdd;
+ bool fDoneDecoding;
+};
+
+// Returns:
+// NULL if the EHInfo passed in does not refer to a Typed clause
+// "..." if pEHInfo->isCatchAllHandler is TRUE
+// "TypeName" if pEHInfo is a DACEHInfo* that references type "TypeName".
+// Note:
+// The return is a pointer to a global buffer, therefore this value must
+// be consumed as soon as possible after a call to this function.
+LPCWSTR EHTypedClauseTypeName(const DACEHInfo* pEHInfo);
+
+struct SOSEHInfo
+{
+#ifndef FEATURE_CORECLR
+ __field_ecount(EHCount)
+#endif
+ DACEHInfo *m_pInfos;
+ UINT EHCount;
+ CLRDATA_ADDRESS methodStart;
+
+ SOSEHInfo() { ZeroMemory(this, sizeof(SOSEHInfo)); }
+ ~SOSEHInfo() { if (m_pInfos) { delete [] m_pInfos; } }
+
+ void FormatForDisassembly(CLRDATA_ADDRESS offSet);
+};
+
+BOOL IsClonedFinally(DACEHInfo *pEHInfo);
+
+void DumpStackWorker (DumpStackFlag &DSFlag);
+
+void UnassemblyUnmanaged (DWORD_PTR IP, BOOL bSuppressLines);
+
+HRESULT CheckEEDll ();
+
+BOOL GetCalleeSite (DWORD_PTR IP, DWORD_PTR &IPCallee);
+
+void DisasmAndClean (DWORD_PTR &IP, __out_ecount_opt(length) char *line, ULONG length);
+
+INT_PTR GetValueFromExpr(___in __in_z char *ptr, INT_PTR &value);
+
+void NextTerm (__deref_inout_z char *& ptr);
+
+BOOL IsByRef (__deref_inout_z char *& ptr);
+
+BOOL IsTermSep (char ch);
+
+const char * HelperFuncName (size_t IP);
+
+enum eTargetType { ettUnk = 0, ettNative = 1, ettJitHelp = 2, ettStub = 3, ettMD = 4 };
+
+// GetFinalTarget is based on HandleCall, but avoids printing anything to the output.
+// This is currently only called on x64
+eTargetType GetFinalTarget(DWORD_PTR callee, DWORD_PTR* finalMDorIP);
+
+#ifdef _MSC_VER
+// SOS is essentially single-threaded. ignore "construction of local static object is not thread-safe"
+#pragma warning(push)
+#pragma warning(disable:4640)
+#endif // _MSC_VER
+
+//-----------------------------------------------------------------------------------------
+//
+// Implementations for the supported target platforms
+//
+//-----------------------------------------------------------------------------------------
+
+#ifndef THUMB_CODE
+#define THUMB_CODE 1
+#endif
+#define STACKWALK_CONTROLPC_ADJUST_OFFSET 2
+
+#ifdef SOS_TARGET_X86
+
+/// X86 Machine specific code
+class X86Machine : public IMachine
+{
+public:
+ typedef X86_CONTEXT TGT_CTXT;
+
+ static IMachine* GetInstance()
+ { static X86Machine s_X86MachineInstance; return &s_X86MachineInstance; }
+
+ ULONG GetPlatform() const { return IMAGE_FILE_MACHINE_I386; }
+ ULONG GetContextSize() const { return sizeof(X86_CONTEXT); }
+ virtual void Unassembly(
+ TADDR IPBegin,
+ TADDR IPEnd,
+ TADDR IPAskedFor,
+ TADDR GCStressCodeCopy,
+ GCEncodingInfo * pGCEncodingInfo,
+ SOSEHInfo *pEHInfo,
+ BOOL bSuppressLines,
+ BOOL bDisplayOffsets) const;
+ virtual void IsReturnAddress(
+ TADDR retAddr,
+ TADDR* whereCalled) const;
+ virtual BOOL GetExceptionContext (
+ TADDR stack,
+ TADDR PC,
+ TADDR *cxrAddr,
+ CROSS_PLATFORM_CONTEXT * cxr,
+ TADDR * exrAddr,
+ PEXCEPTION_RECORD exr) const;
+
+ // retrieve stack pointer, frame pointer, and instruction pointer from the target context
+ virtual TADDR GetSP(const CROSS_PLATFORM_CONTEXT & ctx) const { return ctx.X86Context.Esp; }
+ virtual TADDR GetBP(const CROSS_PLATFORM_CONTEXT & ctx) const { return ctx.X86Context.Ebp; }
+ virtual TADDR GetIP(const CROSS_PLATFORM_CONTEXT & ctx) const { return ctx.X86Context.Eip; }
+
+ virtual void FillSimpleContext(StackTrace_SimpleContext * dest, LPVOID srcCtx) const;
+ virtual void FillTargetContext(LPVOID destCtx, LPVOID srcCtx, int idx = 0) const;
+
+ virtual LPCSTR GetDumpStackHeading() const { return s_DumpStackHeading; }
+ virtual LPCSTR GetDumpStackObjectsHeading() const { return s_DSOHeading; }
+ virtual LPCSTR GetSPName() const { return s_SPName; }
+ virtual void GetGCRegisters(LPCSTR** regNames, unsigned int* cntRegs) const
+ { _ASSERTE(cntRegs != NULL); *regNames = s_GCRegs; *cntRegs = _countof(s_GCRegs); }
+
+ virtual void DumpGCInfo(GCInfoToken gcInfoToken, unsigned methodSize, printfFtn gcPrintf, bool encBytes, bool bPrintHeader) const;
+
+private:
+ X86Machine() {}
+ ~X86Machine() {}
+ X86Machine(const X86Machine& machine); // undefined
+ X86Machine & operator=(const X86Machine&); // undefined
+
+private:
+ static LPCSTR s_DumpStackHeading;
+ static LPCSTR s_DSOHeading;
+ static LPCSTR s_GCRegs[7];
+ static LPCSTR s_SPName;
+}; // class X86Machine
+
+#endif // SOS_TARGET_X86
+
+
+#ifdef SOS_TARGET_ARM
+
+/// ARM Machine specific code
+class ARMMachine : public IMachine
+{
+public:
+ typedef ARM_CONTEXT TGT_CTXT;
+
+ static IMachine* GetInstance()
+ { return &s_ARMMachineInstance; }
+
+ ULONG GetPlatform() const { return IMAGE_FILE_MACHINE_ARMNT; }
+ ULONG GetContextSize() const { return sizeof(ARM_CONTEXT); }
+ virtual void Unassembly(
+ TADDR IPBegin,
+ TADDR IPEnd,
+ TADDR IPAskedFor,
+ TADDR GCStressCodeCopy,
+ GCEncodingInfo *pGCEncodingInfo,
+ SOSEHInfo *pEHInfo,
+ BOOL bSuppressLines,
+ BOOL bDisplayOffsets) const;
+ virtual void IsReturnAddress(
+ TADDR retAddr,
+ TADDR* whereCalled) const;
+ virtual BOOL GetExceptionContext (
+ TADDR stack,
+ TADDR PC,
+ TADDR *cxrAddr,
+ CROSS_PLATFORM_CONTEXT * cxr,
+ TADDR *exrAddr,
+ PEXCEPTION_RECORD exr) const;
+
+ // retrieve stack pointer, frame pointer, and instruction pointer from the target context
+ virtual TADDR GetSP(const CROSS_PLATFORM_CONTEXT & ctx) const { return ctx.ArmContext.Sp; }
+ // @ARMTODO: frame pointer
+ virtual TADDR GetBP(const CROSS_PLATFORM_CONTEXT & ctx) const { return 0; }
+ virtual TADDR GetIP(const CROSS_PLATFORM_CONTEXT & ctx) const { return ctx.ArmContext.Pc; }
+
+ virtual void FillSimpleContext(StackTrace_SimpleContext * dest, LPVOID srcCtx) const;
+ virtual void FillTargetContext(LPVOID destCtx, LPVOID srcCtx, int idx = 0) const;
+
+ virtual LPCSTR GetDumpStackHeading() const { return s_DumpStackHeading; }
+ virtual LPCSTR GetDumpStackObjectsHeading() const { return s_DSOHeading; }
+ virtual LPCSTR GetSPName() const { return s_SPName; }
+ virtual void GetGCRegisters(LPCSTR** regNames, unsigned int* cntRegs) const
+ { _ASSERTE(cntRegs != NULL); *regNames = s_GCRegs; *cntRegs = _countof(s_GCRegs); }
+
+ virtual void DumpGCInfo(GCInfoToken gcInfoToken, unsigned methodSize, printfFtn gcPrintf, bool encBytes, bool bPrintHeader) const;
+
+private:
+ ARMMachine() {}
+ ~ARMMachine() {}
+ ARMMachine(const ARMMachine& machine); // undefined
+ ARMMachine & operator=(const ARMMachine&); // undefined
+
+private:
+ static LPCSTR s_DumpStackHeading;
+ static LPCSTR s_DSOHeading;
+ static LPCSTR s_GCRegs[14];
+ static LPCSTR s_SPName;
+ static ARMMachine s_ARMMachineInstance;
+}; // class ARMMachine
+
+#endif // SOS_TARGET_ARM
+
+#ifdef SOS_TARGET_AMD64
+
+/// AMD64 Machine specific code
+class AMD64Machine : public IMachine
+{
+public:
+ typedef AMD64_CONTEXT TGT_CTXT;
+
+ static IMachine* GetInstance()
+ { static AMD64Machine s_AMD64MachineInstance; return &s_AMD64MachineInstance; }
+
+ ULONG GetPlatform() const { return IMAGE_FILE_MACHINE_AMD64; }
+ ULONG GetContextSize() const { return sizeof(AMD64_CONTEXT); }
+
+ virtual void Unassembly(
+ TADDR IPBegin,
+ TADDR IPEnd,
+ TADDR IPAskedFor,
+ TADDR GCStressCodeCopy,
+ GCEncodingInfo *pGCEncodingInfo,
+ SOSEHInfo *pEHInfo,
+ BOOL bSuppressLines,
+ BOOL bDisplayOffsets) const;
+
+ virtual void IsReturnAddress(
+ TADDR retAddr,
+ TADDR* whereCalled) const;
+
+ virtual BOOL GetExceptionContext (
+ TADDR stack,
+ TADDR PC,
+ TADDR *cxrAddr,
+ CROSS_PLATFORM_CONTEXT * cxr,
+ TADDR *exrAddr,
+ PEXCEPTION_RECORD exr) const;
+
+ // retrieve stack pointer, frame pointer, and instruction pointer from the target context
+ virtual TADDR GetSP(const CROSS_PLATFORM_CONTEXT & ctx) const { return ctx.Amd64Context.Rsp; }
+ virtual TADDR GetBP(const CROSS_PLATFORM_CONTEXT & ctx) const { return ctx.Amd64Context.Rbp; }
+ virtual TADDR GetIP(const CROSS_PLATFORM_CONTEXT & ctx) const { return ctx.Amd64Context.Rip; }
+
+ virtual void FillSimpleContext(StackTrace_SimpleContext * dest, LPVOID srcCtx) const;
+ virtual void FillTargetContext(LPVOID destCtx, LPVOID srcCtx, int idx = 0) const;
+
+ virtual LPCSTR GetDumpStackHeading() const { return s_DumpStackHeading; }
+ virtual LPCSTR GetDumpStackObjectsHeading() const { return s_DSOHeading; }
+ virtual LPCSTR GetSPName() const { return s_SPName; }
+ virtual void GetGCRegisters(LPCSTR** regNames, unsigned int* cntRegs) const
+ { _ASSERTE(cntRegs != NULL); *regNames = s_GCRegs; *cntRegs = _countof(s_GCRegs); }
+
+ virtual void DumpGCInfo(GCInfoToken gcInfoToken, unsigned methodSize, printfFtn gcPrintf, bool encBytes, bool bPrintHeader) const;
+
+private:
+ AMD64Machine() {}
+ ~AMD64Machine() {}
+ AMD64Machine(const AMD64Machine& machine); // undefined
+ AMD64Machine & operator=(const AMD64Machine&); // undefined
+
+private:
+ static LPCSTR s_DumpStackHeading;
+ static LPCSTR s_DSOHeading;
+ static LPCSTR s_GCRegs[15];
+ static LPCSTR s_SPName;
+}; // class AMD64Machine
+
+#endif // SOS_TARGET_AMD64
+
+#ifdef SOS_TARGET_ARM64
+
+/// ARM64 Machine specific code
+class ARM64Machine : public IMachine
+{
+public:
+ typedef ARM64_CONTEXT TGT_CTXT;
+
+ static IMachine* GetInstance()
+ { static ARM64Machine s_ARM64MachineInstance; return &s_ARM64MachineInstance; }
+
+ ULONG GetPlatform() const { return IMAGE_FILE_MACHINE_ARM64; }
+ ULONG GetContextSize() const { return sizeof(ARM64_CONTEXT); }
+ virtual void Unassembly(
+ TADDR IPBegin,
+ TADDR IPEnd,
+ TADDR IPAskedFor,
+ TADDR GCStressCodeCopy,
+ GCEncodingInfo *pGCEncodingInfo,
+ SOSEHInfo *pEHInfo,
+ BOOL bSuppressLines,
+ BOOL bDisplayOffsets) const;
+ virtual void IsReturnAddress(
+ TADDR retAddr,
+ TADDR* whereCalled) const;
+ virtual BOOL GetExceptionContext (
+ TADDR stack,
+ TADDR PC,
+ TADDR *cxrAddr,
+ CROSS_PLATFORM_CONTEXT * cxr,
+ TADDR *exrAddr,
+ PEXCEPTION_RECORD exr) const;
+
+ // retrieve stack pointer, frame pointer, and instruction pointer from the target context
+ virtual TADDR GetSP(const CROSS_PLATFORM_CONTEXT & ctx) const { return ctx.Arm64Context.Sp; }
+ virtual TADDR GetBP(const CROSS_PLATFORM_CONTEXT & ctx) const { return ctx.Arm64Context.Fp; }
+ virtual TADDR GetIP(const CROSS_PLATFORM_CONTEXT & ctx) const { return ctx.Arm64Context.Pc; }
+
+ virtual void FillSimpleContext(StackTrace_SimpleContext * dest, LPVOID srcCtx) const;
+ virtual void FillTargetContext(LPVOID destCtx, LPVOID srcCtx, int idx = 0) const;
+
+ virtual LPCSTR GetDumpStackHeading() const { return s_DumpStackHeading; }
+ virtual LPCSTR GetDumpStackObjectsHeading() const { return s_DSOHeading; }
+ virtual LPCSTR GetSPName() const { return s_SPName; }
+ virtual void GetGCRegisters(LPCSTR** regNames, unsigned int* cntRegs) const
+ { _ASSERTE(cntRegs != NULL); *regNames = s_GCRegs; *cntRegs = _countof(s_GCRegs);}
+
+ virtual void DumpGCInfo(GCInfoToken gcInfoToken, unsigned methodSize, printfFtn gcPrintf, bool encBytes, bool bPrintHeader) const;
+
+private:
+ ARM64Machine() {}
+ ~ARM64Machine() {}
+ ARM64Machine(const ARM64Machine& machine); // undefined
+ ARM64Machine & operator=(const ARM64Machine&); // undefined
+
+ static LPCSTR s_DumpStackHeading;
+ static LPCSTR s_DSOHeading;
+ static LPCSTR s_GCRegs[28];
+ static LPCSTR s_SPName;
+
+}; // class ARM64Machine
+
+#endif // SOS_TARGET_ARM64
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif // _MSC_VER
+
+
+//
+// Inline methods
+//
+
+
+#ifdef SOS_TARGET_X86
+inline void X86Machine::FillSimpleContext(StackTrace_SimpleContext * dest, LPVOID srcCtx) const
+{
+ TGT_CTXT& src = *(TGT_CTXT*) srcCtx;
+ dest->StackOffset = src.Esp;
+ dest->FrameOffset = src.Ebp;
+ dest->InstructionOffset = src.Eip;
+}
+
+inline void X86Machine::FillTargetContext(LPVOID destCtx, LPVOID srcCtx, int idx /*= 0*/) const
+{
+ TGT_CTXT* dest = (TGT_CTXT*)destCtx + idx;
+ *dest = *(TGT_CTXT*)srcCtx;
+}
+#endif // SOS_TARGET_X86
+
+
+#ifdef SOS_TARGET_ARM
+inline void ARMMachine::FillSimpleContext(StackTrace_SimpleContext * dest, LPVOID srcCtx) const
+{
+ TGT_CTXT& src = *(TGT_CTXT*) srcCtx;
+ dest->StackOffset = src.Sp;
+ // @ARMTODO: frame pointer - keep in sync with ARMMachine::GetBP
+ dest->FrameOffset = 0;
+ dest->InstructionOffset = src.Pc;
+}
+
+inline void ARMMachine::FillTargetContext(LPVOID destCtx, LPVOID srcCtx, int idx /*= 0*/) const
+{
+ TGT_CTXT* dest = (TGT_CTXT*)destCtx + idx;
+ *dest = *(TGT_CTXT*)srcCtx;
+}
+#endif // SOS_TARGET_ARM
+
+
+#ifdef SOS_TARGET_AMD64
+inline void AMD64Machine::FillSimpleContext(StackTrace_SimpleContext * dest, LPVOID srcCtx) const
+{
+ TGT_CTXT& src = *(TGT_CTXT*) srcCtx;
+ dest->StackOffset = src.Rsp;
+ dest->FrameOffset = src.Rbp;
+ dest->InstructionOffset = src.Rip;
+}
+
+inline void AMD64Machine::FillTargetContext(LPVOID destCtx, LPVOID srcCtx, int idx /*= 0*/) const
+{
+ TGT_CTXT* dest = (TGT_CTXT*)destCtx + idx;
+ *dest = *(TGT_CTXT*)srcCtx;
+}
+#endif // SOS_TARGET_AMD64
+
+#ifdef SOS_TARGET_ARM64
+inline void ARM64Machine::FillSimpleContext(StackTrace_SimpleContext * dest, LPVOID srcCtx) const
+{
+ TGT_CTXT& src = *(TGT_CTXT*) srcCtx;
+ dest->StackOffset = src.Sp;
+ dest->FrameOffset = src.Fp;
+ dest->InstructionOffset = src.Pc;
+}
+
+inline void ARM64Machine::FillTargetContext(LPVOID destCtx, LPVOID srcCtx, int idx /*= 0*/) const
+{
+ TGT_CTXT* dest = (TGT_CTXT*)destCtx + idx;
+ *dest = *(TGT_CTXT*)srcCtx;
+}
+#endif // SOS_TARGET_ARM64
+
+#endif // __disasm_h__