123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400 |
- #pragma once
- #include "../CommonDef.h"
- #include "vm/String.h"
- #include "MetadataDef.h"
- #include "BlobReader.h"
- #include "MetadataUtil.h"
- namespace hybridclr
- {
- namespace metadata
- {
- enum class LoadImageErrorCode
- {
- OK = 0,
- BAD_IMAGE,
- NOT_IMPLEMENT,
- AOT_ASSEMBLY_NOT_FIND,
- HOMOLOGOUS_ONLY_SUPPORT_AOT_ASSEMBLY,
- HOMOLOGOUS_ASSEMBLY_HAS_BEEN_LOADED,
- INVALID_HOMOLOGOUS_MODE,
- PDB_BAD_FILE,
- };
- struct SectionHeader
- {
- uint32_t virtualAddressBegin;
- uint32_t virtualAddressEnd;
- uint32_t ptrRawDataRelatedToVirtualAddress;
- };
- class RawImageBase
- {
- public:
- RawImageBase() : _imageData(nullptr), _imageLength(0), _ptrRawDataEnd(nullptr),
- _streamStringHeap{}, _streamUS{}, _streamBlobHeap{}, _streamGuidHeap{}, _streamTables{},
- _4byteStringIndex(false), _4byteGUIDIndex(false), _4byteBlobIndex(false)
- {
- }
- virtual ~RawImageBase()
- {
- if (_imageData)
- {
- HYBRIDCLR_FREE((void*)_imageData);
- _imageData = nullptr;
- }
- }
- virtual LoadImageErrorCode Load(const void* imageData, size_t length);
- virtual LoadImageErrorCode PostLoadStreams() { return LoadImageErrorCode::OK; }
- virtual LoadImageErrorCode PostLoadTables() { return LoadImageErrorCode::OK; }
- virtual Il2CppString* GetUserStringBlogByIndex(uint32_t index) const = 0;
- virtual void DecryptMethodBodyIfNeed(const byte* methodBody, uint32_t methodBodySize) {}
- const char* GetStringFromRawIndex(StringIndex index) const
- {
- IL2CPP_ASSERT(DecodeImageIndex(index) == 0);
- IL2CPP_ASSERT(index >= 0 && (uint32_t)index < _streamStringHeap.size);
- return (const char*)(_streamStringHeap.data + index);
- }
- const byte* GetBlobFromRawIndex(StringIndex index) const
- {
- IL2CPP_ASSERT(DecodeImageIndex(index) == 0);
- IL2CPP_ASSERT(index == 0 || (index > 0 && (size_t)index < _streamBlobHeap.size));
- return _streamBlobHeap.data + index;
- }
- const uint8_t* GetFieldOrParameterDefalutValueByRawIndex(uint32_t index) const
- {
- return _imageData + index;
- }
- static BlobReader DecodeBlob(const byte* buf)
- {
- uint32_t sizeLength;
- uint32_t length = BlobReader::ReadCompressedUint32(buf, sizeLength);
- return BlobReader(buf + sizeLength, length);
- }
- BlobReader GetBlobReaderByRawIndex(uint32_t rawIndex) const
- {
- IL2CPP_ASSERT(DecodeImageIndex(rawIndex) == 0);
- const byte* buf = _streamBlobHeap.data + rawIndex;
- return DecodeBlob(buf);
- }
- uint32_t GetImageOffsetOfBlob(Il2CppTypeEnum type, uint32_t index) const
- {
- if (type != IL2CPP_TYPE_STRING)
- {
- return (uint32_t)(GetBlobReaderByRawIndex(index).GetData() - _imageData);
- }
- else
- {
- return (uint32_t)(_streamBlobHeap.data + index - _imageData);
- }
- }
- const byte* GetDataPtrByImageOffset(uint32_t imageOffset) const
- {
- IL2CPP_ASSERT(imageOffset < _imageLength);
- return _imageData + imageOffset;
- }
- uint32_t GetEntryPointToken() const
- {
- return _entryPointToken;
- }
- const Table& GetTable(TableType type) const
- {
- return _tables[(int)type];
- }
- uint32_t GetTableRowNum(TableType tableIndex) const
- {
- return _tables[(int)tableIndex].rowNum;
- }
- bool TranslateRVAToImageOffset(uint32_t rvaOffset, uint32_t& imageOffset) const
- {
- for (const SectionHeader& sh : _sections)
- {
- if (sh.virtualAddressBegin <= rvaOffset && rvaOffset < sh.virtualAddressEnd)
- {
- imageOffset = sh.ptrRawDataRelatedToVirtualAddress + rvaOffset;
- return true;
- }
- }
- return false;
- }
- LoadImageErrorCode LoadStreamHeaders(uint32_t metadataRva, uint32_t metadataSize);
- LoadImageErrorCode ValidateStreams();
- LoadImageErrorCode LoadTables();
- void BuildTableRowMetas();
- uint32_t ComputTableRowMetaDataSize(TableType tableIndex) const;
- uint32_t ComputStringIndexByte() const
- {
- return _4byteStringIndex ? 4 : 2;
- }
- uint32_t ComputGUIDIndexByte() const
- {
- return _4byteGUIDIndex ? 4 : 2;
- }
- uint32_t ComputBlobIndexByte() const
- {
- return _4byteBlobIndex ? 4 : 2;
- }
- uint32_t ComputTableIndexByte(TableType tableIndex) const
- {
- return _tables[(int)tableIndex].rowNum < 65536 ? 2 : 4;
- }
- uint32_t ComputIndexByte(uint32_t maxRowNum, uint32_t tagBitNum) const
- {
- return (maxRowNum << tagBitNum) < 65536 ? 2 : 4;
- }
- uint32_t ComputTableIndexByte(TableType t1, TableType t2, uint32_t tagBitNum) const
- {
- uint32_t n = GetTableRowNum(t1);
- n = std::max(n, GetTableRowNum(t2));
- return ComputIndexByte(n, tagBitNum);
- }
- uint32_t ComputTableIndexByte(TableType t1, TableType t2, TableType t3, uint32_t tagBitNum) const
- {
- uint32_t n = GetTableRowNum(t1);
- n = std::max(n, GetTableRowNum(t2));
- n = std::max(n, GetTableRowNum(t3));
- return ComputIndexByte(n, tagBitNum);
- }
- uint32_t ComputTableIndexByte(TableType t1, TableType t2, TableType t3, TableType t4, uint32_t tagBitNum) const
- {
- uint32_t n = GetTableRowNum(t1);
- n = std::max(n, GetTableRowNum(t2));
- n = std::max(n, GetTableRowNum(t3));
- n = std::max(n, GetTableRowNum(t4));
- return ComputIndexByte(n, tagBitNum);
- }
- uint32_t ComputTableIndexByte(TableType t1, TableType t2, TableType t3, TableType t4, TableType t5, uint32_t tagBitNum) const
- {
- uint32_t n = GetTableRowNum(t1);
- n = std::max(n, GetTableRowNum(t2));
- n = std::max(n, GetTableRowNum(t3));
- n = std::max(n, GetTableRowNum(t4));
- n = std::max(n, GetTableRowNum(t5));
- return ComputIndexByte(n, tagBitNum);
- }
- uint32_t ComputTableIndexByte(const TableType* ts, int num, uint32_t tagBitNum) const
- {
- uint32_t n = 0;
- for (int i = 0; i < num; i++)
- {
- n = std::max(n, GetTableRowNum(ts[i]));
- }
- return ComputIndexByte(n, tagBitNum);
- }
- protected:
- virtual LoadImageErrorCode LoadCLIHeader(uint32_t& entryPointToken, uint32_t& metadataRva, uint32_t& metadataSize) = 0;
- const byte* GetTableRowPtr(TableType type, uint32_t rawIndex) const
- {
- auto& tb = _tables[(int)type];
- IL2CPP_ASSERT(rawIndex > 0 && rawIndex <= tb.rowNum);
- return tb.data + tb.rowMetaDataSize * (rawIndex - 1);
- }
- const std::vector<ColumnOffsetSize>& GetRowSchema(TableType type) const
- {
- return _tableRowMetas[(int)type];
- }
- uint32_t ReadColumn(const byte* rowPtr, const ColumnOffsetSize& columnMt) const
- {
- return ReadColumn(rowPtr, columnMt.offset, columnMt.size);
- }
- uint32_t ReadColumn(const byte* data, uint32_t offset, uint32_t size) const
- {
- IL2CPP_ASSERT(size == 2 || size == 4);
- return (size == 2 ? *(uint16_t*)(data + offset) : *(uint32_t*)(data + offset));
- }
- static Il2CppString* CreateUserString(const char* str, uint32_t length)
- {
- if (length == 0)
- {
- return il2cpp::vm::String::Empty();
- }
- else
- {
- IL2CPP_ASSERT(length % 2 == 1);
- UserStringEncoding charEncoding = (UserStringEncoding)str[length - 1];
- return il2cpp::vm::String::NewUtf16((const Il2CppChar*)str, (length - 1) / 2);
- }
- }
- public:
- #define TABLE_BEGIN(name, tableType) Tb##name Read##name(uint32_t rawIndex) \
- { \
- IL2CPP_ASSERT(rawIndex > 0 && rawIndex <= GetTable(tableType).rowNum); \
- const byte* rowPtr = GetTableRowPtr(tableType, rawIndex); \
- auto& rowSchema = GetRowSchema(tableType); \
- uint32_t __fieldIndex = 0; \
- Tb##name __r = {};
- #define __F(fieldName) const ColumnOffsetSize& col_##fieldName = rowSchema[__fieldIndex++]; \
- __r.fieldName = ReadColumn(rowPtr, col_##fieldName);
- #define TABLE_END return __r; \
- }
- #define TABLE1(name, tableType, f1) TABLE_BEGIN(name, tableType) \
- __F(f1) \
- TABLE_END
- #define TABLE2(name, tableType, f1, f2) TABLE_BEGIN(name, tableType) \
- __F(f1) \
- __F(f2) \
- TABLE_END
- #define TABLE3(name, tableType, f1, f2, f3) TABLE_BEGIN(name, tableType) \
- __F(f1) \
- __F(f2) \
- __F(f3) \
- TABLE_END
- #define TABLE4(name, tableType, f1, f2, f3, f4) TABLE_BEGIN(name, tableType) \
- __F(f1) \
- __F(f2) \
- __F(f3) \
- __F(f4) \
- TABLE_END
- #define TABLE5(name, tableType, f1, f2, f3, f4, f5) TABLE_BEGIN(name, tableType) \
- __F(f1) \
- __F(f2) \
- __F(f3) \
- __F(f4) \
- __F(f5) \
- TABLE_END
- #define TABLE6(name, tableType, f1, f2, f3, f4, f5, f6) TABLE_BEGIN(name, tableType) \
- __F(f1) \
- __F(f2) \
- __F(f3) \
- __F(f4) \
- __F(f5) \
- __F(f6) \
- TABLE_END
- TABLE5(Module, TableType::MODULE, generation, name, mvid, encid, encBaseId);
- TABLE3(TypeRef, TableType::TYPEREF, resolutionScope, typeName, typeNamespace)
- virtual TABLE6(TypeDef, TableType::TYPEDEF, flags, typeName, typeNamespace, extends, fieldList, methodList)
- TABLE1(TypeSpec, TableType::TYPESPEC, signature);
- TABLE3(Field, TableType::FIELD, flags, name, signature)
- TABLE4(GenericParam, TableType::GENERICPARAM, number, flags, owner, name)
- TABLE2(GenericParamConstraint, TableType::GENERICPARAMCONSTRAINT, owner, constraint)
- TABLE3(MemberRef, TableType::MEMBERREF, classIdx, name, signature)
- TABLE1(StandAloneSig, TableType::STANDALONESIG, signature)
- TABLE3(MethodImpl, TableType::METHODIMPL, classIdx, methodBody, methodDeclaration)
- TABLE2(FieldRVA, TableType::FIELDRVA, rva, field)
- TABLE2(FieldLayout, TableType::FIELDLAYOUT, offset, field)
- TABLE3(Constant, TableType::CONSTANT, type, parent, value)
- TABLE2(MethodSpec, TableType::METHODSPEC, method, instantiation)
- TABLE3(CustomAttribute, TableType::CUSTOMATTRIBUTE, parent, type, value)
- TABLE2(PropertyMap, TableType::PROPERTYMAP, parent, propertyList)
- TABLE3(Property, TableType::PROPERTY, flags, name, type)
- TABLE2(EventMap, TableType::EVENTMAP, parent, eventList)
- TABLE3(Event, TableType::EVENT, eventFlags, name, eventType)
- TABLE3(MethodSemantics, TableType::METHODSEMANTICS, semantics, method, association)
- TABLE2(NestedClass, TableType::NESTEDCLASS, nestedClass, enclosingClass)
- TABLE6(Method, TableType::METHOD, rva, implFlags, flags, name, signature, paramList)
- TABLE3(Param, TableType::PARAM, flags, sequence, name)
- TABLE3(ClassLayout, TableType::CLASSLAYOUT, packingSize, classSize, parent)
- TABLE2(InterfaceImpl, TableType::INTERFACEIMPL, classIdx, interfaceIdx)
- TABLE_BEGIN(Assembly, TableType::ASSEMBLY)
- __F(hashAlgId)
- __F(majorVersion)
- __F(minorVersion)
- __F(buildNumber)
- __F(revisionNumber)
- __F(flags)
- __F(publicKey)
- __F(name)
- __F(culture)
- TABLE_END
- TABLE_BEGIN(AssemblyRef, TableType::ASSEMBLYREF)
- __F(majorVersion)
- __F(minorVersion)
- __F(buildNumber)
- __F(revisionNumber)
- __F(flags)
- __F(publicKeyOrToken)
- __F(name)
- __F(culture)
- __F(hashValue)
- TABLE_END
- TABLE4(SymbolDocument, TableType::DOCUMENT, name, hashAlgorithm, hash, language)
- TABLE2(SymbolMethodBody, TableType::METHODBODY, document, sequencePoints)
- TABLE6(SymbolLocalScope, TableType::LOCALSCOPE, method, importScope, variables, constants, startOffset, length)
- TABLE3(SymbolLocalVariable, TableType::LOCALVARIABLE, attributes, index, name)
- TABLE2(SymbolConstant, TableType::LOCALCONSTANT, name, signature)
- TABLE2(SymbolImportScope, TableType::IMPORTSCOPE, parent, imports)
- TABLE2(SymbolStateMachineMethod, TableType::STATEMACHINEMETHOD, moveNextMethod, kickoffMethod)
- TABLE3(SymbolCustomDebugInformation, TableType::CUSTOMDEBUGINFORMATION, parent, kind, value)
- protected:
- const byte* _imageData;
- uint32_t _imageLength;
- const byte* _ptrRawDataEnd;
- std::vector<SectionHeader> _sections;
- uint32_t _entryPointToken;
- CliStream _streamStringHeap;
- CliStream _streamUS;
- CliStream _streamBlobHeap;
- CliStream _streamGuidHeap;
- CliStream _streamTables;
- bool _4byteStringIndex;
- bool _4byteGUIDIndex;
- bool _4byteBlobIndex;
- Table _tables[TABLE_NUM];
- std::vector<ColumnOffsetSize> _tableRowMetas[TABLE_NUM];
- };
- }
- }
|