summaryrefslogtreecommitdiff
path: root/src/jit/disasm.h
diff options
context:
space:
mode:
authordotnet-bot <dotnet-bot@microsoft.com>2015-01-30 14:14:42 -0800
committerdotnet-bot <dotnet-bot@microsoft.com>2015-01-30 14:14:42 -0800
commitef1e2ab328087c61a6878c1e84f4fc5d710aebce (patch)
treedee1bbb89e9d722e16b0d1485e3cdd1b6c8e2cfa /src/jit/disasm.h
downloadcoreclr-ef1e2ab328087c61a6878c1e84f4fc5d710aebce.tar.gz
coreclr-ef1e2ab328087c61a6878c1e84f4fc5d710aebce.tar.bz2
coreclr-ef1e2ab328087c61a6878c1e84f4fc5d710aebce.zip
Initial commit to populate CoreCLR repo
[tfs-changeset: 1407945]
Diffstat (limited to 'src/jit/disasm.h')
-rw-r--r--src/jit/disasm.h260
1 files changed, 260 insertions, 0 deletions
diff --git a/src/jit/disasm.h b/src/jit/disasm.h
new file mode 100644
index 0000000000..56f04154ec
--- /dev/null
+++ b/src/jit/disasm.h
@@ -0,0 +1,260 @@
+//
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+//
+
+/*XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XX XX
+XX DisAsm XX
+XX XX
+XX The dis-assembler to display the native code generated XX
+XX XX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+*/
+
+/*****************************************************************************/
+#ifndef _DIS_H_
+#define _DIS_H_
+/*****************************************************************************/
+#ifdef LATE_DISASM
+
+// free() is deprecated (we should only allocate and free memory through CLR hosting interfaces)
+// and is redefined in clrhost.h to cause a compiler error.
+// We don't call free(), but this function is mentioned in STL headers included by msvcdis.h
+// (and free() is only called by STL functions that we don't use).
+// To avoid the compiler error, but at the same time ensure that we don't accidentally use free(),
+// free() is redefined to cause a runtime error instead of a compile time error.
+#undef free
+#ifdef DEBUG
+#define free(x) _ASSERTE(false && "Must not call free(). Use a ClrXXX function instead.")
+#endif
+
+#if CHECK_STRUCT_PADDING
+#pragma warning(pop)
+#endif // CHECK_STRUCT_PADDING
+
+#define _OLD_IOSTREAMS
+// This pragma is needed because public\vc\inc\xiosbase contains
+// a static local variable
+#pragma warning(disable : 4640)
+#include "msvcdis.h"
+#pragma warning(default : 4640)
+
+
+#ifdef _TARGET_XARCH_
+#include "disx86.h"
+#elif defined(_TARGET_ARM64_)
+#include "disarm64.h"
+#else // _TARGET_*
+#error Unsupported or unset target architecture
+#endif
+
+#if CHECK_STRUCT_PADDING
+#pragma warning(push)
+#pragma warning(default:4820) // 'bytes' bytes padding added after construct 'member_name'
+#endif // CHECK_STRUCT_PADDING
+
+/*****************************************************************************/
+
+#ifdef _WIN64
+template<typename T>
+struct SizeTKeyFuncs: LargePrimitiveKeyFuncs<T>
+{
+};
+#else // !_WIN64
+template<typename T>
+struct SizeTKeyFuncs: SmallPrimitiveKeyFuncs<T>
+{
+};
+#endif // !_WIN64
+
+typedef SimplerHashTable<size_t, SizeTKeyFuncs<size_t>, CORINFO_METHOD_HANDLE, DefaultSimplerHashBehavior> AddrToMethodHandleMap;
+typedef SimplerHashTable<size_t, SizeTKeyFuncs<size_t>, size_t, DefaultSimplerHashBehavior> AddrToAddrMap;
+
+class Compiler;
+
+class DisAssembler
+{
+public:
+
+ // Constructor
+ void disInit(Compiler* pComp);
+
+ // Initialize the class for the current method being generated.
+ void disOpenForLateDisAsm(const char* curMethodName,
+ const char* curClassName,
+ PCCOR_SIGNATURE sig);
+
+ // Disassemble a buffer: called after code for a method is generated.
+ void disAsmCode(BYTE* hotCodePtr, size_t hotCodeSize, BYTE* coldCodePtr, size_t coldCodeSize);
+
+ // Register an address to be associated with a method handle.
+ void disSetMethod(size_t addr, CORINFO_METHOD_HANDLE methHnd);
+
+ // Register a relocation address.
+ void disRecordRelocation(size_t relocAddr, size_t targetAddr);
+
+private:
+
+ /* Address of the hot and cold code blocks to dissasemble */
+ size_t disHotCodeBlock;
+ size_t disColdCodeBlock;
+
+ /* Size of the hot and cold code blocks to dissasemble */
+ size_t disHotCodeSize;
+ size_t disColdCodeSize;
+
+ /* Total code size (simply cached version of disHotCodeSize + disColdCodeSize) */
+ size_t disTotalCodeSize;
+
+ /* Address where the code block is to be loaded */
+ size_t disStartAddr;
+
+ /* Current offset in the code block */
+ size_t disCurOffset;
+
+ /* Size (in bytes) of current dissasembled instruction */
+ size_t disInstSize;
+
+ /* Target address of a jump */
+ size_t disTarget;
+
+ /* temporary buffer for function names */
+ // TODO-Review: there is some issue here where this is never set!
+ char disFuncTempBuf[1024];
+
+ /* Method and class name to output */
+ const char* disCurMethodName;
+ const char* disCurClassName;
+
+ /* flag that signals when replacing a symbol name has been deferred for following callbacks */
+ // TODO-Review: there is some issue here where this is never set to 'true'!
+ bool disHasName;
+
+ /* An array of labels, for jumps, LEAs, etc. There is one element in the array for each byte in the generated code.
+ * That byte is zero if the corresponding byte of generated code is not a label. Otherwise, the value
+ * is a label number.
+ */
+ BYTE* disLabels;
+
+ void DisasmBuffer (FILE * pfile,
+ bool printit);
+
+ /* For the purposes of disassembly, we pretend that the hot and cold sections are linear, and not split.
+ * These functions create this model for the rest of the disassembly code.
+ */
+
+ /* Given a linear offset into the code, find a pointer to the actual code (either in the hot or cold section) */
+ const BYTE* disGetLinearAddr(size_t offset);
+
+ /* Given a linear offset into the code, determine how many bytes are left in the hot or cold buffer the offset points to */
+ size_t disGetBufferSize(size_t offset);
+
+ // Map of instruction addresses to call target method handles for normal calls.
+ AddrToMethodHandleMap* disAddrToMethodHandleMap;
+ AddrToMethodHandleMap* GetAddrToMethodHandleMap();
+
+ // Map of instruction addresses to call target method handles for JIT helper calls.
+ AddrToMethodHandleMap* disHelperAddrToMethodHandleMap;
+ AddrToMethodHandleMap* GetHelperAddrToMethodHandleMap();
+
+ // Map of relocation addresses to relocation target.
+ AddrToAddrMap* disRelocationMap;
+ AddrToAddrMap* GetRelocationMap();
+
+ const char* disGetMethodFullName(size_t addr);
+
+ FILE* disAsmFile;
+
+ Compiler* disComp;
+
+ bool disDiffable; // 'true' if the output should be diffable (hide or obscure absolute addresses)
+
+ template<typename T>
+ T dspAddr(T addr)
+ {
+ return (addr == 0) ? 0 : (disDiffable ? T(0xD1FFAB1E) : addr);
+ }
+
+ /* Callbacks from msdis */
+
+ static
+ size_t __stdcall disCchAddr (const DIS* pdis,
+ DIS::ADDR addr,
+ __in_ecount(cchMax) wchar_t* wz,
+ size_t cchMax,
+ DWORDLONG* pdwDisp);
+
+ size_t disCchAddrMember (const DIS* pdis,
+ DIS::ADDR addr,
+ __in_ecount(cchMax) wchar_t* wz,
+ size_t cchMax,
+ DWORDLONG* pdwDisp);
+
+ static
+ size_t __stdcall disCchFixup (const DIS* pdis,
+ DIS::ADDR addr,
+ size_t size,
+ __in_ecount(cchMax) wchar_t* wz,
+ size_t cchMax,
+ DWORDLONG* pdwDisp);
+
+ size_t disCchFixupMember (const DIS* pdis,
+ DIS::ADDR addr,
+ size_t size,
+ __in_ecount(cchMax) wchar_t* wz,
+ size_t cchMax,
+ DWORDLONG* pdwDisp);
+
+ static
+ size_t __stdcall disCchRegRel (const DIS* pdis,
+ DIS::REGA reg,
+ DWORD disp,
+ __in_ecount(cchMax) wchar_t* wz,
+ size_t cchMax,
+ DWORD* pdwDisp);
+
+ size_t disCchRegRelMember (const DIS* pdis,
+ DIS::REGA reg,
+ DWORD disp,
+ __in_ecount(cchMax) wchar_t* wz,
+ size_t cchMax,
+ DWORD* pdwDisp);
+
+ static
+ size_t __stdcall disCchReg (const DIS* pdis,
+ DIS::REGA reg,
+ __in_ecount(cchMax) wchar_t* wz,
+ size_t cchMax);
+
+ size_t disCchRegMember (const DIS* pdis,
+ DIS::REGA reg,
+ __in_ecount(cchMax) wchar_t* wz,
+ size_t cchMax);
+
+ /* Disassemble helper */
+
+ size_t CbDisassemble(DIS* pdis,
+ size_t offs,
+ DIS::ADDR addr,
+ const BYTE* pb,
+ size_t cbMax,
+ FILE* pfile,
+ bool findLabels,
+ bool printit = false,
+ bool dispOffs = false,
+ bool dispCodeBytes = false);
+
+};
+
+
+
+
+/*****************************************************************************/
+#endif // LATE_DISASM
+/*****************************************************************************/
+#endif // _DIS_H_
+/*****************************************************************************/
+