|
|
|
| 1 |
|
// ==++== |
| 2 |
|
// |
| 3 |
|
// Copyright (c) Microsoft Corporation. All rights reserved. |
| 4 |
|
// |
| 5 |
|
// ==--== |
| 6 |
|
/***************************************************************************** |
| 7 |
|
** ** |
| 8 |
|
** Corhlpr.h - <STRIP>this file contains a set of "as is" code that may be ** |
| 9 |
|
** used by developers writing compilers and tools against ** |
| 10 |
|
** the Common Language Runtime. The code is not officially ** |
| 11 |
|
** supported, but is code being used by the Runtime itself. ** |
| 12 |
|
** </STRIP> ** |
| 13 |
|
** ** |
| 14 |
|
*****************************************************************************/ |
| 15 |
|
|
| 16 |
|
|
| 17 |
|
#ifndef __CORHLPR_H__ |
| 18 |
|
#define __CORHLPR_H__ |
| 19 |
|
|
| 20 |
|
#if defined(_MSC_VER) && defined(_X86_) && !defined(FPO_ON) |
| 21 |
|
#pragma optimize("y", on) // Small critical routines, don't put in EBP frame |
| 22 |
|
#define FPO_ON 1 |
| 23 |
|
#define CORHLPR_TURNED_FPO_ON 1 |
| 24 |
|
#endif |
| 25 |
|
|
| 26 |
|
#include "cor.h" |
| 27 |
|
#include "corhdr.h" |
| 28 |
|
#include "corerror.h" |
| 29 |
|
|
| 30 |
|
// This header is consumed both within the runtime and externally. In the former |
| 31 |
|
// case we need to wrap memory allocations, in the latter there is no |
| 32 |
|
// infrastructure to support this. Detect which way we're building and provide a |
| 33 |
|
// very simple abstraction layer (handles allocating bytes only). |
| 34 |
|
#ifdef _BLD_CLR |
| 35 |
|
#include "new.hpp" |
| 36 |
|
|
| 37 |
|
|
| 38 |
|
#define NEW_NOTHROW(_bytes) new (nothrow) BYTE[_bytes] |
| 39 |
|
#define NEW_THROWS(_bytes) new BYTE[_bytes] |
| 40 |
|
#else |
| 41 |
|
#define NEW_NOTHROW(_bytes) new BYTE[_bytes] |
| 42 |
|
#define NEW_THROWS(_bytes) __CorHlprNewThrows(_bytes) |
| 43 |
|
static inline BYTE *__CorHlprNewThrows(size_t bytes) |
| 44 |
|
{ |
| 45 |
|
BYTE *pbMemory = new BYTE[bytes]; |
| 46 |
|
if (pbMemory == NULL) |
| 47 |
|
RaiseException(STATUS_NO_MEMORY, 0, 0, NULL); |
| 48 |
|
return pbMemory; |
| 49 |
|
} |
| 50 |
|
#endif |
| 51 |
|
|
| 52 |
|
|
| 53 |
|
//***************************************************************************** |
| 54 |
|
// There are a set of macros commonly used in the helpers which you will want |
| 55 |
|
// to override to get richer behavior. The following defines what is needed |
| 56 |
|
// if you chose not to do the extra work. |
| 57 |
|
//***************************************************************************** |
| 58 |
|
#ifndef IfFailGoto |
| 59 |
|
#define IfFailGoto(EXPR, LABEL) \ |
| 60 |
|
do { hr = (EXPR); if(FAILED(hr)) { goto LABEL; } } while (0) |
| 61 |
|
#endif |
| 62 |
|
|
| 63 |
|
#ifndef IfFailGo |
| 64 |
|
#define IfFailGo(EXPR) IfFailGoto(EXPR, ErrExit) |
| 65 |
|
#endif |
| 66 |
|
|
| 67 |
|
#ifndef IfFailRet |
| 68 |
|
#define IfFailRet(EXPR) do { hr = (EXPR); if(FAILED(hr)) { return (hr); } } while (0) |
| 69 |
|
#endif |
| 70 |
|
|
| 71 |
|
#ifndef IfNullRet |
| 72 |
|
#define IfNullRet(EXPR) do { if ((EXPR) == NULL){ return (E_OUTOFMEMORY); } } while (0) |
| 73 |
|
#endif |
| 74 |
|
|
| 75 |
|
|
| 76 |
|
#ifndef _ASSERTE |
| 77 |
|
#define _ASSERTE(expr) |
| 78 |
|
#endif |
| 79 |
|
|
| 80 |
|
#ifndef COUNTOF |
| 81 |
|
#define COUNTOF(a) (sizeof(a) / sizeof(*a)) |
| 82 |
|
#endif |
| 83 |
|
|
| 84 |
|
#if !BIGENDIAN |
| 85 |
|
#define VAL16(x) x |
| 86 |
|
#define VAL32(x) x |
| 87 |
|
#endif |
| 88 |
|
|
| 89 |
|
|
| 90 |
|
//***************************************************************************** |
| 91 |
|
// |
| 92 |
|
//***** Macro to assist with cleaning up local static variables |
| 93 |
|
// |
| 94 |
|
//***************************************************************************** |
| 95 |
|
|
| 96 |
|
#define CHECK_LOCAL_STATIC_VAR(x) \ |
| 97 |
|
x \ |
| 98 |
|
|
| 99 |
|
//***************************************************************************** |
| 100 |
|
// |
| 101 |
|
//***** Utility helpers |
| 102 |
|
// |
| 103 |
|
//***************************************************************************** |
| 104 |
|
|
| 105 |
|
|
| 106 |
|
#define MAX_CLASSNAME_LENGTH 1024 |
| 107 |
|
|
| 108 |
|
#ifndef SOS_INCLUDE |
| 109 |
|
|
| 110 |
|
//***************************************************************************** |
| 111 |
|
// |
| 112 |
|
// **** CQuickBytes |
| 113 |
|
// This helper class is useful for cases where 90% of the time you allocate 512 |
| 114 |
|
// or less bytes for a data structure. This class contains a 512 byte buffer. |
| 115 |
|
// Alloc() will return a pointer to this buffer if your allocation is small |
| 116 |
|
// enough, otherwise it asks the heap for a larger buffer which is freed for |
| 117 |
|
// you. No mutex locking is required for the small allocation case, making the |
| 118 |
|
// code run faster, less heap fragmentation, etc... Each instance will allocate |
| 119 |
|
// 520 bytes, so use accordinly. |
| 120 |
|
// |
| 121 |
|
//***************************************************************************** |
| 122 |
|
template <DWORD SIZE, DWORD INCREMENT> |
| 123 |
|
class CQuickMemoryBase |
| 124 |
|
{ |
| 125 |
|
public: |
| 126 |
|
void Init() |
| 127 |
|
{ |
| 1016 |
|
|
| 1017 |
|
enum DecoderStatus {SUCCESS, FORMAT_ERROR, VERIFICATION_ERROR}; |
| 1018 |
|
|
| 1019 |
|
// If we want the decoder to verify the that local signature is OK we |
| 1020 |
|
// will pass a non-NULL value for wbStatus |
| 1021 |
|
// |
| 1022 |
|
// When using LazyInit we want ask that the local signature be verified |
| 1023 |
|
// But if we fail verification we still need access to the 'Code' field |
| 1024 |
|
// Because we may be able to demand SkipVerification and thus it was OK |
| 1025 |
|
// to have had a verification error. |
| 1026 |
|
|
| 1027 |
|
COR_ILMETHOD_DECODER(COR_ILMETHOD* header, |
| 1028 |
|
void *pInternalImport, |
| 1029 |
|
DecoderStatus* wbStatus); |
| 1030 |
|
|
| 1031 |
|
unsigned EHCount() const |
| 1032 |
|
{ |
| 1033 |
|
return (EH != 0) ? EH->EHCount() : 0; |
| 1034 |
|
} |
| 1035 |
|
|
| 1036 |
|
unsigned GetHeaderSize() const |
| 1037 |
|
{ |
| 1038 |
|
return GetCodeSize() + ((EH != 0) ? EH->DataSize() : 0); |
| 1039 |
|
} |
| 1040 |
|
|
| 1041 |
|
// returns total size of method for use in copying |
| 1042 |
|
int GetOnDiskSize(const COR_ILMETHOD* header) |
| 1043 |
|
{ |
| 1044 |
|
return DecoderGetOnDiskSize(this,(COR_ILMETHOD*)header); |
| 1045 |
|
} |
| 1046 |
|
|
| 1047 |
|
// Flags these are available because we inherit COR_ILMETHOD_FAT |
| 1048 |
|
// MaxStack |
| 1049 |
|
// CodeSize |
| 1050 |
|
const BYTE* Code; |
| 1051 |
|
PCCOR_SIGNATURE LocalVarSig; // pointer to signature blob, or 0 if none |
| 1052 |
|
const COR_ILMETHOD_SECT_EH* EH; // eh table if any 0 if none |
| 1053 |
|
const COR_ILMETHOD_SECT* Sect; // additional sections 0 if none |
| 1054 |
|
}; |
| 1055 |
|
|
| 1056 |
|
#if defined(CORHLPR_TURNED_FPO_ON) |
| 1057 |
|
#pragma optimize("", on) // Go back to command line default optimizations |
| 1058 |
|
#undef CORHLPR_TURNED_FPO_ON |
| 1059 |
|
#undef FPO_ON |
| 1060 |
|
#endif |
| 1061 |
|
|
| 1062 |
|
#endif // __CORHLPR_H__ |
| 1063 |
|
|
| 1064 |
|
|
|
|
|