singrdk/base/Windows/mkmsil/msil/MetaDataLoader.cs

3388 lines
150 KiB
C#
Raw Permalink Normal View History

2008-11-17 18:29:00 -05:00
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// Loader of MetaData information
namespace Bartok.MSIL
{
using System;
using System.Collections;
using System.IO;
using System.Reflection;
using System.Text;
using Bartok.DebugInfo;
internal class MetaDataLoader {
// Constructor Methods
internal static MetaData getMetaData(String name,
PELoader peLoader,
bool fLoadCode,
bool fLoadDebugInfo)
{
int metaDataOffset = peLoader.getMetaDataOffset();
Stream fileStream = peLoader.getStream();
fileStream.Seek(metaDataOffset, SeekOrigin.Begin);
BinaryReader reader = new BinaryReader(fileStream);
StorageSignature storageSignature = new StorageSignature(reader);
StorageHeader storageHeader = new StorageHeader(reader);
// The pointer is at the first stream in the list
MetaDataFormat format = MetaDataFormat.Invalid;
// Lightning/Src/MD/Runtime/MDInternalDisp.cpp
StorageStream dataStream = null;
StorageStream stringPoolStream = null;
StorageStream blobPoolStream = null;
StorageStream userBlobPoolStream = null;
StorageStream guidPoolStream = null;
MetaDataLoader mdLoader;
for (int i = 0; i < storageHeader.streamCount; i++) {
StorageStream storageStream = new StorageStream(reader);
switch (storageStream.name) {
case StorageStream.COMPRESSED_MODEL:
if (format == MetaDataFormat.Invalid ||
format == MetaDataFormat.ICR) {
format = MetaDataFormat.ReadOnly;
dataStream = storageStream;
}
break;
case StorageStream.ENC_MODEL:
if (format == MetaDataFormat.Invalid ||
format == MetaDataFormat.ICR) {
format = MetaDataFormat.ReadWrite;
dataStream = storageStream;
}
break;
case StorageStream.SCHEMA:
if (format == MetaDataFormat.Invalid) {
format = MetaDataFormat.ICR;
dataStream = storageStream;
}
break;
case StorageStream.STRING_POOL:
stringPoolStream = storageStream;
break;
case StorageStream.BLOB_POOL:
blobPoolStream = storageStream;
break;
case StorageStream.USER_BLOB_POOL:
userBlobPoolStream = storageStream;
break;
case StorageStream.VARIANT_POOL:
// It doesn't look like we are using this stream, ever
break;
case StorageStream.GUID_POOL:
guidPoolStream = storageStream;
break;
default:
throw new IllegalMetaDataFormatException("Unknown stream name "+storageStream.name);
}
}
switch (format) {
case MetaDataFormat.Invalid:
throw new IllegalMetaDataFormatException("No valid metadata format found");
case MetaDataFormat.ReadOnly:
mdLoader = new MetaDataLoader(peLoader,
fileStream,
metaDataOffset,
dataStream,
stringPoolStream,
blobPoolStream,
userBlobPoolStream,
guidPoolStream);
break;
case MetaDataFormat.ReadWrite:
throw new IllegalMetaDataFormatException("MetaDataReadWrite format on disk");
case MetaDataFormat.ICR:
throw new IllegalMetaDataFormatException("Cannot handle ICR metadata format");
default:
throw new IllegalMetaDataFormatException("Unknown format "+format);
}
int methodIndex = 1;
bool dllHasDebugInfo = false;
try {
if (fLoadDebugInfo && fLoadCode) {
if (PDBLoader.OpenPdbFile(name) == 0) {
dllHasDebugInfo = true;
mdLoader.LoadDebugSymbolInfo();
}
}
foreach (MetaDataMethod method in mdLoader.methodArray) {
if (fLoadCode) {
bool methodHasDebugInfo = false;
int baseLineNumber = 0;
int lastLineNumber = 0;
int numOfLines = 0;
String srcFileName = null;
if (fLoadDebugInfo && dllHasDebugInfo) {
// load line number information from the dll.
int token = ((int)MetaDataTableIndices.Method <<24) | methodIndex;
long count; // line number count
uint length; // src file name length
PDBLoader.GetLineNumberCount(token,
out count,
out length);
if (count > 0) {
// there is line number infor. for this method
int[] lines = new int[count];
int[] offsets = new int[count];
int[] columns = new int[count];
StringBuilder fileName =
new StringBuilder((int)length);
int lineCount =
PDBLoader.LoadLineNumber(token,
lines,
columns,
offsets,
fileName);
if (lineCount != count)
Console.WriteLine("Error! Reading line number" + lineCount + " " + count);
int baseOffset = offsets[0];
for (int i = 0; i < lineCount; i++) {
if (lines[i] == 0xFEEFEE) {
// Mask noise from the dll files
if (i > 0) {
lines[i] = lines[i-1];
columns[i] = columns[i-1];
}
else if (i < (lineCount - 1)) {
lines[i] = lines[i+1] - 1;
columns[i] = 0;
}
else {
Console.WriteLine("Error! No Valid lineNumber");
lines[i] = 1;
columns[i] = 0;
}
}
// adjust offset to be 0 based.
offsets[i] -= baseOffset;
}
// load instructions
srcFileName = fileName.ToString();
method.loadInstructions(mdLoader, peLoader,
fileStream, lines, columns,
offsets, srcFileName,
lineCount);
baseLineNumber = lines[0] - 1;
lastLineNumber = lines[lineCount-1] + 1;
numOfLines = lineCount;
methodHasDebugInfo = true;
}
else {
method.loadInstructions(mdLoader, peLoader,
fileStream, null,
null, null, null, 0);
}
}
else {
method.loadInstructions(mdLoader, peLoader,
fileStream, null,
null, null, null, 0);
}
method.BaseLineNumber = new CVLineNumber(baseLineNumber, 0,
srcFileName);
method.LastLineNumber = new CVLineNumber(lastLineNumber, 0,
srcFileName);
method.NumOfLines = numOfLines;
method.SrcFileName = srcFileName;
method.HasDebugInfo = methodHasDebugInfo;
}
if (method.Rva == 0) {
method.IsEmpty = true;
}
methodIndex++;
}
}
finally {
if (dllHasDebugInfo) {
PDBLoader.ClosePdbFile();
}
}
int entryPointToken = peLoader.getEntryPoint();
MetaDataMethod entryPoint = (entryPointToken == 0) ? null :
(MetaDataMethod) mdLoader.getObjectFromToken(entryPointToken);
int imageBase = peLoader.getImageBase();
return new MetaData(name,
entryPoint,
imageBase,
mdLoader.moduleArray,
mdLoader.typeRefArray,
mdLoader.typeDefArray,
mdLoader.fieldPtrArray,
mdLoader.fieldArray,
mdLoader.methodPtrArray,
mdLoader.methodArray,
mdLoader.paramPtrArray,
mdLoader.paramArray,
mdLoader.interfaceImplArray,
mdLoader.memberRefArray,
mdLoader.constantArray,
mdLoader.customAttributeArray,
mdLoader.fieldMarshalArray,
mdLoader.declSecurityArray,
mdLoader.classLayoutArray,
mdLoader.fieldLayoutArray,
mdLoader.standAloneSigArray,
mdLoader.eventMapArray,
mdLoader.eventPtrArray,
mdLoader.eventArray,
mdLoader.propertyMapArray,
mdLoader.propertyPtrArray,
mdLoader.propertyArray,
mdLoader.methodSemanticsArray,
mdLoader.methodImplArray,
mdLoader.moduleRefArray,
mdLoader.typeSpecArray,
mdLoader.implMapArray,
mdLoader.fieldRVAArray,
mdLoader.assemblyArray,
mdLoader.assemblyProcessorArray,
mdLoader.assemblyOSArray,
mdLoader.assemblyRefArray,
mdLoader.assemblyRefProcessorArray,
mdLoader.assemblyRefOSArray,
mdLoader.fileArray,
mdLoader.exportedTypeArray,
mdLoader.manifestResourceArray,
mdLoader.nestedClassArray,
mdLoader.relocationArray,
mdLoader.vtableFixupArray,
mdLoader.delayImportTable);
}
private void LoadDebugSymbolInfo() {
// read in local var info
int varCount;
int nameLength;
int methodCount = PDBLoader.GetMethodCount(out varCount,
out nameLength);
int[] slots = new int[varCount];
String[] varNames = new String[varCount];
StringBuilder varName = new StringBuilder(nameLength);
int slot;
int methodToken;
int symTable = PDBLoader.OpenSymbolTable();
while (symTable != -1) {
int symTag = PDBLoader.GetNextVar(out slot, out methodToken,
varName);
int count = 0;
int lastMethod = -1;
int maxslot = 0; // somehow certain locals are not in the
// sym table, however, they have slots,
// therefore slot number can be bigger than
// sym count
while (symTag != (int)SymTag.SymTagEnd) {
if (symTag == (int) SymTag.SymTagFunction) {
if (lastMethod != -1) {
// finish last method
int numOfLocals = maxslot + 1;
if (numOfLocals < count) {
numOfLocals = count;
}
UpdateMethodDebugVarInfo(lastMethod,
count, slots,
numOfLocals, varNames);
lastMethod = -1;
}
// start current method
count = 0;
maxslot = 0;
lastMethod = methodToken;
}
else if (symTag == (int)SymTag.SymTagLocal) {
slots[count] = slot;
if (slot > maxslot) {
maxslot = slot;
}
varNames[count] = varName.ToString();
count++;
}
else {
Console.WriteLine("wrong sym tag");
}
symTag = PDBLoader.GetNextVar(out slot, out methodToken,
varName);
}
if (lastMethod != -1) {
int numOfLocals = maxslot + 1;
if (numOfLocals < count) {
numOfLocals = count;
}
UpdateMethodDebugVarInfo(lastMethod,
count, slots,
numOfLocals, varNames);
lastMethod = -1;
}
symTable = PDBLoader.NextSymbolTable();
}
PDBLoader.CloseSymbolTable();
}
private void UpdateMethodDebugVarInfo(int token, int count,
int[] slots,
int numOfLocals,
String[] names) {
MetaDataMethod method =
(MetaDataMethod) this.getObjectFromToken(token);
String[] varNames = new String[numOfLocals];
for (int i = 0; i < count; i++) {
varNames[slots[i]] = names[i];
}
method.LocalVarNames = varNames;
}
private static void LoadDebugLineNumberInfo() {
}
private MetaDataLoader(PELoader peLoader,
Stream fileStream,
int metaDataOffset,
StorageStream dataStream,
StorageStream stringPoolStream,
StorageStream blobPoolStream,
StorageStream userBlobPoolStream,
StorageStream guidPoolStream)
{
this.peLoader = peLoader;
this.fileStream = fileStream;
this.metaDataOffset = metaDataOffset;
this.dataStream = dataStream;
this.stringPoolStream = stringPoolStream;
this.blobPoolStream = blobPoolStream;
this.userBlobPoolStream = userBlobPoolStream;
this.guidPoolStream = guidPoolStream;
// Read the stream of GUIDs
int guidCount = guidPoolStream.size / 16;
fileStream.Seek(metaDataOffset + guidPoolStream.offset,
SeekOrigin.Begin);
this.guidArray = new Guid[guidCount];
byte[] guidBuffer = new byte[16];
for (int i = 0; i < guidCount; i++) {
fileStream.Read(guidBuffer, 0, 16);
guidArray[i] = new Guid(guidBuffer);
}
// Read the stream of strings
// Ensure that last byte is always zero
if (stringPoolStream != null && stringPoolStream.size > 0) {
this.stringStreamBuffer = new byte[stringPoolStream.size+1];
fileStream.Seek(metaDataOffset + stringPoolStream.offset,
SeekOrigin.Begin);
int stringByteCount = fileStream.Read(this.stringStreamBuffer, 0,
stringPoolStream.size);
if (stringByteCount != stringPoolStream.size) {
throw new IllegalMetaDataFormatException("Didn't get all the string bytes");
}
}
// Read the stream of blobs
if (blobPoolStream != null && blobPoolStream.size > 0) {
this.blobStreamBuffer = new byte[blobPoolStream.size];
fileStream.Seek(metaDataOffset + blobPoolStream.offset,
SeekOrigin.Begin);
int blobByteCount = fileStream.Read(this.blobStreamBuffer, 0,
blobPoolStream.size);
if (blobByteCount != blobPoolStream.size) {
throw new IllegalMetaDataFormatException("Didn't get all the blob bytes");
}
}
// Read the stream of user strings, if there is one
if (userBlobPoolStream != null && userBlobPoolStream.size > 0) {
this.userStringStreamBuffer = new byte[userBlobPoolStream.size];
fileStream.Seek(metaDataOffset + userBlobPoolStream.offset,
SeekOrigin.Begin);
int userStringByteCount =
fileStream.Read(this.userStringStreamBuffer, 0,
userBlobPoolStream.size);
if (userStringByteCount != userBlobPoolStream.size) {
throw new IllegalMetaDataFormatException("Didn't get all the user string bytes");
}
}
// Read the resource data, if there is any
int resourceOffset = peLoader.getResourceOffset();
int resourceSize = peLoader.getResourceSize();
if (resourceOffset > 0 && resourceSize > 0) {
this.resourceBuffer = new byte[resourceSize];
fileStream.Seek(resourceOffset, SeekOrigin.Begin);
int resourceCount =
fileStream.Read(this.resourceBuffer, 0, resourceSize);
if (resourceCount != resourceSize) {
throw new IllegalMetaDataFormatException("Didn't get all the resource bytes");
}
}
// Read the schema
fileStream.Seek(metaDataOffset + dataStream.offset,
SeekOrigin.Begin);
BinaryReader reader = new BinaryReader(fileStream);
// First read the fixed fields (CMiniMdSchemaBase)
this.ReadSchemaBase(reader);
int readBytes = 24; // sizeof(CMiniMDSchemaBase)
// Read the variable fields (this is the compressed part)
int count = (int) MetaDataTableIndices.Count;
long mask = this.maskValid;
for (int dst = 0; dst < count; dst++) {
if ((mask & 1) != 0) {
this.countArray[dst] = reader.ReadInt32();
readBytes += 4;
}
mask >>= 1;
}
// Skip the counters we don't understand
for (int dst = count; dst < 64; dst++) {
if ((mask & 1) != 0) {
reader.ReadInt32();
readBytes += 4;
}
}
// Retrieve any extra data
if ((this.heapBits & HEAPBITS_MASK_EXTRA_DATA) != 0) {
this.extraData = reader.ReadInt32();
readBytes += 4;
}
if (this.majorVersion != METAMODEL_MAJOR_VER ||
(this.minorVersion != METAMODEL_MINOR_VER_A
&& this.minorVersion != METAMODEL_MINOR_VER_B)) {
throw new IllegalMetaDataFormatException("Unknown version "+this.majorVersion+"."+this.minorVersion);
}
if (this.countArray[(int) MetaDataTableIndices.MethodPtr] != 0 ||
this.countArray[(int) MetaDataTableIndices.FieldPtr] != 0) {
throw new IllegalMetaDataFormatException("Trying to open R/W format at R/O");
}
// Read the data into the tables
int tableSize = this.InitializeRowInfo();
if (readBytes + tableSize > dataStream.size) {
throw new IllegalMetaDataFormatException("Table bigger than metadata stream");
}
this.InitializeMetaDataTables(reader);
}
// Helper Methods
private void ReadSchemaBase(BinaryReader reader) {
this.reserved = reader.ReadInt32(); // Must be zero
this.majorVersion = reader.ReadByte(); // Version numbers
this.minorVersion = reader.ReadByte();
this.heapBits = reader.ReadByte(); // Bits for heap sizes
this.rowId = reader.ReadByte(); // log-base-2 of largest rid
this.maskValid = reader.ReadInt64(); // Present table counts
this.maskSorted = reader.ReadInt64(); // Sorted tables
if (this.reserved != 0) {
throw new IllegalMetaDataFormatException("Reserved not zero");
}
}
private int InitializeRowInfo() {
if ((this.heapBits & HEAPBITS_MASK_STRINGS) != 0) {
this.stringIndexSize = 4;
}
else {
this.stringIndexSize = 2;
}
if ((this.heapBits & HEAPBITS_MASK_GUID) != 0) {
this.guidIndexSize = 4;
}
else {
this.guidIndexSize = 2;
}
if ((this.heapBits & HEAPBITS_MASK_BLOB) != 0) {
this.blobIndexSize = 4;
}
else {
this.blobIndexSize = 2;
}
int tableSize = 0;
for (int tableIndex = 0; tableIndex < (int) MetaDataTableIndices.Count; tableIndex++) {
byte[] columnKinds = TableColumnKinds[tableIndex];
int columnCount = columnKinds.Length;
byte[] columnSizes = new byte[columnCount];
byte[] columnOffsets = new byte[columnCount];
this.tableColumnSizes[tableIndex] = columnSizes;
this.tableColumnOffsets[tableIndex] = columnOffsets;
byte columnOffset = 0; // Running size of record
for (int columnIndex = 0; columnIndex < columnCount; columnIndex++) {
byte columnKind = columnKinds[columnIndex];
byte columnSize;
if (columnKind <= (byte) ColumnKindId.RowIdMax) {
if (this.countArray[columnKind] > 0xffff) {
columnSize = 4;
}
else {
columnSize = 2;
}
}
else if (columnKind <= (byte) ColumnKindId.CodedTokenMax) {
byte codeToken = (byte)
(columnKind - (byte) ColumnKindId.CodedToken);
TokenType[] tokenTypeList =
CodeTokenTypeLists[codeToken];
int maxCount = 0;
int listLength = tokenTypeList.Length;
for (int i = 0; i < listLength; i++) {
TokenType tokenType = tokenTypeList[i];
// Ignore string tokens
if (tokenType != TokenType.String) {
int index = ((int) tokenType >> 24);
if (this.countArray[index] > maxCount) {
maxCount = this.countArray[index];
}
}
}
int maxIndex = maxCount << BitsForCountArray[listLength];
if (maxIndex > 0xffff) {
columnSize = 4;
}
else {
columnSize = 2;
}
}
else {
switch ((ColumnKindId) columnKind) {
case ColumnKindId.Byte:
columnSize = 1;
break;
case ColumnKindId.Short:
case ColumnKindId.UShort:
columnSize = 2;
break;
case ColumnKindId.Long:
case ColumnKindId.ULong:
columnSize = 4;
break;
case ColumnKindId.String:
columnSize = this.stringIndexSize;
break;
case ColumnKindId.Guid:
columnSize = this.guidIndexSize;
break;
case ColumnKindId.Blob:
columnSize = this.blobIndexSize;
break;
default:
throw new IllegalMetaDataFormatException("Unexpected schema kind: "+columnKind);
}
}
// Save away the size and offset
columnSizes[columnIndex] = columnSize;
columnOffsets[columnIndex] = columnOffset;
// Align to 2 bytes
columnSize += (byte) (columnSize & 1);
columnOffset += columnSize;
}
this.tableRowSizes[tableIndex] = columnOffset;
tableSize += columnOffset * this.countArray[tableIndex];
}
return tableSize;
}
private String getString(int stringIndex) {
int limit = this.stringStreamBuffer.Length;
if (stringIndex < 0 || stringIndex >= limit) {
Console.WriteLine("Cannot find string "+stringIndex);
return null;
}
else {
int endIndex = stringIndex;
while (this.stringStreamBuffer[endIndex] != 0) {
endIndex++;
}
return stringEncoding.GetString(this.stringStreamBuffer,
stringIndex,
endIndex - stringIndex);
}
}
private byte[] getBlobBytes(int blobIndex) {
byte headerByte = this.blobStreamBuffer[blobIndex];
int size, startIndex;
if ((headerByte & 0x80) == 0x00) {
size = headerByte;
startIndex = blobIndex+1;
}
else if ((headerByte & 0x40) == 0x00) {
size = (((headerByte & 0x3f) << 8) |
this.blobStreamBuffer[blobIndex+1]);
startIndex = blobIndex+2;
}
else {
size = (((headerByte & 0x3f) << 24) |
(this.blobStreamBuffer[blobIndex+1] << 16) |
(this.blobStreamBuffer[blobIndex+2] << 8) |
(this.blobStreamBuffer[blobIndex+3]));
startIndex = blobIndex+4;
}
byte[] buffer = new byte[size];
System.Array.Copy(this.blobStreamBuffer, startIndex,
buffer, 0, size);
return buffer;
}
private byte[] getResourceBytes(int offset) {
int size = ((this.resourceBuffer[offset]) |
(this.resourceBuffer[offset+1] << 8) |
(this.resourceBuffer[offset+2] << 16) |
(this.resourceBuffer[offset+3] << 24));
byte[] buffer = new byte[size];
System.Array.Copy(this.resourceBuffer, offset+4, buffer, 0, size);
return buffer;
}
private Signature getSignature(int signatureIndex) {
byte[] buffer = this.getBlobBytes(signatureIndex);
return new SignatureBuffer(buffer);
}
private byte[] getValueBuffer(int valueIndex) {
return this.getBlobBytes(valueIndex);
}
private MarshalSpec getNativeType(int nativeTypeIndex) {
byte[] buffer = this.getBlobBytes(nativeTypeIndex);
return MarshalSpec.Create(buffer);
}
private byte[] getPublicKey(int publicKeyIndex) {
return this.getBlobBytes(publicKeyIndex);
}
private MetaDataBlob getPermissionSet(int permissionSetIndex) {
// BUGBUG
return new MetaDataBlob(this.getBlobBytes(permissionSetIndex));
}
private byte[] getHashValue(int hashValueIndex) {
return this.getBlobBytes(hashValueIndex);
}
private Guid getGuid(int guidIndex) {
if (guidIndex < 0 || guidIndex >= this.guidArray.Length) {
Console.WriteLine("Cannot find GUID "+guidIndex);
return Guid.Empty;
}
else {
return this.guidArray[guidIndex];
}
}
private MetaDataObject getObjectFromTableSet(int codedIndex,
CodeToken codeToken) {
if (codedIndex == 0) {
return null;
}
int codeCount = CodeTokenTypeLists[(int) codeToken].Length;
int kind = codedIndex & MaskForCountArray[codeCount];
int index = codedIndex >> BitsForCountArray[codeCount];
TokenType tokenType = CodeTokenTypeLists[(int) codeToken][kind];
MetaDataObject[] array = this.metaDataTable[(int) tokenType >> 24];
if (array == null) {
Console.WriteLine("Missing table for kind "+kind+" of "+codeToken);
return null;
}
else {
return array[index-1];
}
}
private void InitializeMetaDataTables(BinaryReader reader) {
this.metaDataTable =
new MetaDataObject[(int) MetaDataTableIndices.Count][];
// First read in what goes in the tables
this.initializeModuleTable(reader);
this.initializeTypeRefTable(reader);
this.initializeTypeDefTable(reader);
this.initializeFieldPtrTable(reader);
this.initializeFieldTable(reader);
this.initializeMethodPtrTable(reader);
this.initializeMethodTable(reader);
this.initializeParamPtrTable(reader);
this.initializeParamTable(reader);
this.initializeInterfaceImplTable(reader);
this.initializeMemberRefTable(reader);
this.initializeConstantTable(reader);
this.initializeCustomAttributeTable(reader);
this.initializeFieldMarshalTable(reader);
this.initializeDeclSecurityTable(reader);
this.initializeClassLayoutTable(reader);
this.initializeFieldLayoutTable(reader);
this.initializeStandAloneSigTable(reader);
this.initializeEventMapTable(reader);
this.initializeEventPtrTable(reader);
this.initializeEventTable(reader);
this.initializePropertyMapTable(reader);
this.initializePropertyPtrTable(reader);
this.initializePropertyTable(reader);
this.initializeMethodSemanticsTable(reader);
this.initializeMethodImplTable(reader);
this.initializeModuleRefTable(reader);
this.initializeTypeSpecTable(reader);
this.initializeImplMapTable(reader);
this.initializeFieldRVATable(reader);
this.initializeENCLogTable(reader);
this.initializeENCMapTable(reader);
this.initializeAssemblyTable(reader);
this.initializeAssemblyProcessorTable(reader);
this.initializeAssemblyOSTable(reader);
this.initializeAssemblyRefTable(reader);
this.initializeAssemblyRefProcessorTable(reader);
this.initializeAssemblyRefOSTable(reader);
this.initializeFileTable(reader);
this.initializeExportedTypeTable(reader);
this.initializeManifestResourceTable(reader);
this.initializeNestedClassTable(reader);
this.initializeGenericParamTable(reader);
this.initializeMethodSpecTable(reader);
this.initializeGenericParamConstraintTable(reader);
this.initializeRelocationTable();
this.initializeVtableFixupTable();
this.initializeDelayIATTable();
// Then resolve references between tables
this.resolveModuleReferences();
this.resolveTypeRefReferences();
this.resolveTypeDefReferences();
this.resolveFieldPtrReferences();
this.resolveFieldReferences();
this.resolveMethodPtrReferences();
this.resolveMethodReferences();
this.resolveParamPtrReferences();
this.resolveParamReferences();
this.resolveInterfaceImplReferences();
this.resolveMemberRefReferences();
this.resolveConstantReferences();
this.resolveCustomAttributeReferences();
this.resolveFieldMarshalReferences();
this.resolveDeclSecurityReferences();
this.resolveClassLayoutReferences();
this.resolveFieldLayoutReferences();
this.resolveStandAloneSigReferences();
this.resolveEventMapReferences();
this.resolveEventPtrReferences();
this.resolveEventReferences();
this.resolvePropertyMapReferences();
this.resolvePropertyPtrReferences();
this.resolvePropertyReferences();
this.resolveMethodSemanticsReferences();
this.resolveMethodImplReferences();
this.resolveModuleRefReferences();
this.resolveTypeSpecReferences();
this.resolveImplMapReferences();
this.resolveFieldRVAReferences();
this.resolveENCLogReferences();
this.resolveENCMapReferences();
this.resolveAssemblyReferences();
this.resolveAssemblyProcessorReferences();
this.resolveAssemblyOSReferences();
this.resolveAssemblyRefReferences();
this.resolveAssemblyRefProcessorReferences();
this.resolveAssemblyRefOSReferences();
this.resolveFileReferences();
this.resolveExportedTypeReferences();
this.resolveManifestResourceReferences();
this.resolveNestedClassReferences();
this.resolveGenericParamReferences();
this.resolveMethodSpecReferences();
this.resolveGenericParamConstraintReferences();
}
private void initializeModuleTable(BinaryReader reader) {
int count = this.countArray[(int) MetaDataTableIndices.Module];
this.moduleArray = new MetaDataModule[count];
this.metaDataTable[(int) MetaDataTableIndices.Module] =
this.moduleArray;
for (int i = 0; i < count; i++) {
short generation = reader.ReadInt16();
int nameIndex, mvid, encodingIndex, encodingBaseIdIndex;
if (this.stringIndexSize == 4) {
nameIndex = reader.ReadInt32();
}
else {
nameIndex = reader.ReadUInt16();
}
String name = this.getString(nameIndex);
if (this.guidIndexSize == 4) {
mvid = reader.ReadInt32();
encodingIndex = reader.ReadInt32();
encodingBaseIdIndex = reader.ReadInt32();
}
else {
mvid = reader.ReadUInt16();
encodingIndex = reader.ReadUInt16();
encodingBaseIdIndex = reader.ReadUInt16();
}
Guid encoding = this.getGuid(encodingIndex);
Guid encodingBaseId = this.getGuid(encodingBaseIdIndex);
this.moduleArray[i] =
new MetaDataModule(generation, name, mvid,
encodingIndex, encoding,
encodingBaseIdIndex, encodingBaseId);
}
}
// Access Methods
internal String getUserString(int stringIndex) {
byte headerByte = this.userStringStreamBuffer[stringIndex];
int size, startIndex;
if ((headerByte & 0x80) == 0x00) {
size = headerByte;
startIndex = stringIndex + 1;
}
else if ((headerByte & 0x40) == 0x00) {
size = (((headerByte & 0x3f) << 8) |
this.userStringStreamBuffer[stringIndex + 1]);
startIndex = stringIndex + 2;
}
else {
size = (((headerByte & 0x3f) << 24) |
(this.userStringStreamBuffer[stringIndex+1] << 16) |
(this.userStringStreamBuffer[stringIndex+2] << 8) |
(this.userStringStreamBuffer[stringIndex+3]));
startIndex = stringIndex+4;
}
int stringSize = size/2;
char[] chars = new char[stringSize];
for (int i = 0; i < stringSize; i++) {
char ch =
(char ) (this.userStringStreamBuffer[startIndex] |
this.userStringStreamBuffer[startIndex+1] << 8);
chars[i] = ch;
startIndex += 2;
}
return new String(chars);
}
internal MetaDataObject getTypeDefOrRef(int codedIndex) {
return this.getObjectFromTableSet(codedIndex,
CodeToken.TypeDefOrRef);
}
internal MetaDataObject getHasConstant(int codedIndex) {
return this.getObjectFromTableSet(codedIndex,
CodeToken.HasConstant);
}
internal MetaDataObject getHasCustomAttribute(int codedIndex) {
return this.getObjectFromTableSet(codedIndex,
CodeToken.HasCustomAttribute);
}
internal MetaDataObject getHasFieldMarshal(int codedIndex) {
return this.getObjectFromTableSet(codedIndex,
CodeToken.HasFieldMarshal);
}
internal MetaDataObject getHasDeclSecurity(int codedIndex) {
return this.getObjectFromTableSet(codedIndex,
CodeToken.HasDeclSecurity);
}
internal MetaDataObject getMemberRefParent(int codedIndex) {
return this.getObjectFromTableSet(codedIndex,
CodeToken.MemberRefParent);
}
internal MetaDataObject getHasSemantic(int codedIndex) {
return this.getObjectFromTableSet(codedIndex,
CodeToken.HasSemantic);
}
internal MetaDataObject getMethodDefOrRef(int codedIndex) {
return this.getObjectFromTableSet(codedIndex,
CodeToken.MethodDefOrRef);
}
internal MetaDataObject getMemberForwarded(int codedIndex) {
return this.getObjectFromTableSet(codedIndex,
CodeToken.MemberForwarded);
}
internal MetaDataObject getImplementation(int codedIndex) {
return this.getObjectFromTableSet(codedIndex,
CodeToken.Implementation);
}
internal MetaDataObject getCustomAttributeType(int codedIndex) {
return this.getObjectFromTableSet(codedIndex,
CodeToken.CustomAttributeType);
}
internal MetaDataObject getResolutionScope(int resolutionIndex) {
return this.getObjectFromTableSet(resolutionIndex,
CodeToken.ResolutionScope);
}
internal MetaDataObject getTypeOrMethodDef(int resolutionIndex) {
return this.getObjectFromTableSet(resolutionIndex,
CodeToken.TypeOrMethodDef);
}
internal MetaDataObject getObjectFromToken(int token) {
int type = token >> 24;
int index = token & 0x00FFFFFF;
return this.metaDataTable[type][index-1];
}
internal MetaDataTypeDefinition getTypeDef(int typeDefIndex) {
if (typeDefIndex < 1 || typeDefIndex > this.typeDefArray.Length) {
Console.WriteLine("Cannot find TypeDef "+typeDefIndex);
return null;
}
else {
return this.typeDefArray[typeDefIndex-1];
}
}
internal MetaDataField getField(int fieldIndex) {
if (fieldIndex < 1 || fieldIndex > this.fieldArray.Length) {
Console.WriteLine("Cannot find field "+fieldIndex);
return null;
}
else {
return this.fieldArray[fieldIndex-1];
}
}
internal MetaDataField[] getFields(int startIndex, int count) {
if (count <= 0) {
return emptyFieldArray;
}
MetaDataField[] result = new MetaDataField[count];
Array.Copy(this.fieldArray, startIndex-1, result, 0, count);
return result;
}
internal MetaDataMethod getMethod(int methodIndex) {
if (methodIndex < 1 || methodIndex > this.methodArray.Length) {
Console.WriteLine("Cannot find method "+methodIndex);
return null;
}
else {
return this.methodArray[methodIndex-1];
}
}
internal MetaDataMethod[] getMethods(int startIndex, int count) {
if (count <= 0) {
return emptyMethodArray;
}
MetaDataMethod[] result = new MetaDataMethod[count];
Array.Copy(this.methodArray, startIndex-1, result, 0, count);
return result;
}
internal MetaDataParam getParam(int paramIndex) {
if (paramIndex < 1 || paramIndex > this.paramArray.Length) {
Console.WriteLine("Cannot find parameter "+paramIndex);
return null;
}
else {
return this.paramArray[paramIndex-1];
}
}
internal MetaDataParam[] getParams(int startIndex, int count) {
if (count <= 0) {
return emptyParamArray;
}
if (startIndex < this.paramArray.Length &&
this.getParam(startIndex).Sequence == 0) {
startIndex++;
count--;
}
for (int i = 0; i < count; i++) {
if (startIndex + i < this.paramArray.Length) {
if (this.getParam(startIndex + i).Sequence == 0) {
throw new Exception("Asking for non-owned parameters");
}
}
}
MetaDataParam[] result = new MetaDataParam[count];
Array.Copy(this.paramArray, startIndex-1, result, 0, count);
return result;
}
internal MetaDataEvent getEvent(int eventIndex) {
if (eventIndex < 1 || eventIndex > this.eventArray.Length) {
Console.WriteLine("Cannot find event "+eventIndex);
return null;
}
else {
return this.eventArray[eventIndex-1];
}
}
internal MetaDataProperty getProperty(int propertyIndex) {
if (propertyIndex < 1 || propertyIndex > this.propertyArray.Length) {
Console.WriteLine("Cannot find property "+propertyIndex);
return null;
}
else {
return this.propertyArray[propertyIndex-1];
}
}
internal MetaDataModuleRef getModuleRef(int moduleRefIndex) {
if (moduleRefIndex < 1 ||
moduleRefIndex > this.moduleRefArray.Length) {
Console.WriteLine("Cannot find moduleref "+moduleRefIndex);
return null;
}
else {
return this.moduleRefArray[moduleRefIndex-1];
}
}
internal MetaDataAssemblyRef getAssemblyRef(int assemblyRefIndex) {
if (assemblyRefIndex < 1 ||
assemblyRefIndex > this.assemblyRefArray.Length) {
Console.WriteLine("Cannot find assemblyref "+assemblyRefIndex);
return null;
}
else {
return this.assemblyRefArray[assemblyRefIndex-1];
}
}
internal MetaDataGenericParam getGenericParam(int genericParamIndex) {
if (genericParamIndex < 1 ||
genericParamIndex > this.genericParamArray.Length) {
Console.WriteLine("Cannot find genericparam "+genericParamIndex);
return null;
}
return this.genericParamArray[genericParamIndex-1];
}
// Methods for initializing the tables and table objects
private void resolveModuleReferences() {
// foreach (MetaDataModule module in this.moduleArray) {
// Console.WriteLine(module.ToStringLong());
// }
}
private void initializeTypeRefTable(BinaryReader reader) {
int count = this.countArray[(int) MetaDataTableIndices.TypeRef];
this.typeRefArray = new MetaDataTypeReference[count];
this.metaDataTable[(int) MetaDataTableIndices.TypeRef] =
this.typeRefArray;
byte bigScopeIndexSize =
this.tableColumnSizes[(int)MetaDataTableIndices.TypeRef][0];
for (int i = 0; i < count; i++) {
int resolutionScopeIndex = ((bigScopeIndexSize == 4) ?
reader.ReadInt32() :
reader.ReadUInt16());
int nameIndex, nameSpaceIndex;
if (this.stringIndexSize == 4) {
nameIndex = reader.ReadInt32();
nameSpaceIndex = reader.ReadInt32();
}
else {
nameIndex = reader.ReadUInt16();
nameSpaceIndex = reader.ReadUInt16();
}
String name = this.getString(nameIndex);
String nameSpace = this.getString(nameSpaceIndex);
this.typeRefArray[i] =
new MetaDataTypeReference(resolutionScopeIndex,
name, nameSpace);
}
}
private void resolveTypeRefReferences() {
foreach (MetaDataTypeReference typeRef in this.typeRefArray) {
typeRef.resolveReferences(this);
// Console.WriteLine(typeRef.ToStringLong());
}
}
private void initializeTypeDefTable(BinaryReader reader) {
int count = this.countArray[(int) MetaDataTableIndices.TypeDef];
this.typeDefArray = new MetaDataTypeDefinition[count];
this.metaDataTable[(int) MetaDataTableIndices.TypeDef] =
this.typeDefArray;
byte extendsSize =
this.tableColumnSizes[(int)MetaDataTableIndices.TypeDef][3];
byte fieldSize =
this.tableColumnSizes[(int)MetaDataTableIndices.TypeDef][4];
byte methodSize =
this.tableColumnSizes[(int)MetaDataTableIndices.TypeDef][5];
for (int i = 0; i < count; i++) {
TypeAttributes flags = (TypeAttributes) reader.ReadInt32();
int nameIndex, nameSpaceIndex;
if (this.stringIndexSize == 4) {
nameIndex = reader.ReadInt32();
nameSpaceIndex = reader.ReadInt32();
}
else {
nameIndex = reader.ReadUInt16();
nameSpaceIndex = reader.ReadUInt16();
}
String name = this.getString(nameIndex);
String nameSpace = this.getString(nameSpaceIndex);
int extendsIndex = ((extendsSize == 4) ?
reader.ReadInt32() :
reader.ReadUInt16());
int fieldIndex = ((fieldSize == 4) ?
reader.ReadInt32() :
reader.ReadUInt16());
int methodIndex = ((methodSize == 4) ?
reader.ReadInt32() :
reader.ReadUInt16());
this.typeDefArray[i] =
new MetaDataTypeDefinition(flags, name, nameSpace,
extendsIndex, fieldIndex,
methodIndex);
}
}
private void resolveTypeDefReferences() {
int fieldCount = this.fieldArray.Length;
int methodCount = this.methodArray.Length;
MetaDataTypeDefinition[] fieldOwners =
new MetaDataTypeDefinition[fieldCount+2];
MetaDataTypeDefinition[] methodOwners =
new MetaDataTypeDefinition[methodCount+2];
foreach (MetaDataTypeDefinition typedef in this.typeDefArray) {
typedef.registerReferences(fieldCount, methodCount,
fieldOwners, methodOwners);
}
MetaDataTypeDefinition current = null;
for (int i = 0; i <= fieldCount; i++) {
if (fieldOwners[i] == null) {
fieldOwners[i] = current;
}
else {
current = fieldOwners[i];
}
}
current = null;
for (int i = 0; i <= methodCount; i++) {
if (methodOwners[i] == null) {
methodOwners[i] = current;
}
else {
current = methodOwners[i];
}
}
foreach (MetaDataTypeDefinition typedef in this.typeDefArray) {
typedef.resolveReferences(this, fieldOwners, methodOwners);
}
}
private void initializeFieldPtrTable(BinaryReader reader) {
int count = this.countArray[(int) MetaDataTableIndices.FieldPtr];
this.fieldPtrArray = new MetaDataFieldPtr[count];
this.metaDataTable[(int) MetaDataTableIndices.FieldPtr] =
this.fieldPtrArray;
byte indexSize =
this.tableColumnSizes[(int)MetaDataTableIndices.FieldPtr][0];
for (int i = 0; i < count; i++) {
int fieldIndex = ((indexSize == 4) ?
reader.ReadInt32() :
reader.ReadUInt16());
this.fieldPtrArray[i] = new MetaDataFieldPtr(fieldIndex);
}
}
private void resolveFieldPtrReferences() {
foreach (MetaDataFieldPtr fieldPtr in this.fieldPtrArray) {
fieldPtr.resolveReferences(this);
// Console.WriteLine(fieldPtr);
}
}
private void initializeFieldTable(BinaryReader reader) {
int count = this.countArray[(int) MetaDataTableIndices.Field];
this.fieldArray = new MetaDataField[count];
this.metaDataTable[(int) MetaDataTableIndices.Field] =
this.fieldArray;
for (int i = 0; i < count; i++) {
short flags = reader.ReadInt16();
int nameIndex = ((this.stringIndexSize == 4) ?
reader.ReadInt32() :
reader.ReadUInt16());
String name = this.getString(nameIndex);
int signatureIndex = ((this.blobIndexSize == 4) ?
reader.ReadInt32() :
reader.ReadUInt16());
Signature signature = this.getSignature(signatureIndex);
this.fieldArray[i] = new MetaDataField(flags, name, signature);
}
}
private void resolveFieldReferences() {
foreach (MetaDataField field in this.fieldArray) {
field.resolveReferences(this);
// Console.WriteLine(field.ToStringLong());
}
}
private void initializeMethodPtrTable(BinaryReader reader) {
int count = this.countArray[(int) MetaDataTableIndices.MethodPtr];
this.methodPtrArray = new MetaDataMethodPtr[count];
this.metaDataTable[(int) MetaDataTableIndices.MethodPtr] =
this.methodPtrArray;
byte indexSize =
this.tableColumnSizes[(int)MetaDataTableIndices.MethodPtr][0];
for (int i = 0; i < count; i++) {
int methodIndex = ((indexSize == 4) ?
reader.ReadInt32() :
reader.ReadUInt16());
this.methodPtrArray[i] = new MetaDataMethodPtr(methodIndex);
}
}
private void resolveMethodPtrReferences() {
foreach (MetaDataMethodPtr methodPtr in this.methodPtrArray) {
methodPtr.resolveReferences(this);
// Console.WriteLine(methodPtr.ToStringLong());
}
}
private void initializeMethodTable(BinaryReader reader) {
int count = this.countArray[(int) MetaDataTableIndices.Method];
this.methodArray = new MetaDataMethod[count];
this.metaDataTable[(int) MetaDataTableIndices.Method] =
this.methodArray;
byte paramSize =
this.tableColumnSizes[(int)MetaDataTableIndices.Method][5];
for (int i = 0; i < count; i++) {
int rva = reader.ReadInt32();
short implFlags = reader.ReadInt16();
short flags = reader.ReadInt16();
int nameIndex = ((this.stringIndexSize == 4) ?
reader.ReadInt32() :
reader.ReadUInt16());
String name = this.getString(nameIndex);
int signatureIndex = ((this.blobIndexSize == 4) ?
reader.ReadInt32() :
reader.ReadUInt16());
Signature signature = this.getSignature(signatureIndex);
int paramIndex = ((paramSize == 4) ?
reader.ReadInt32() :
reader.ReadUInt16());
this.methodArray[i] =
new MetaDataMethod(rva, implFlags, flags, name,
signature, paramIndex);
}
}
private void resolveMethodReferences() {
int paramCount = this.paramArray.Length;
MetaDataMethod[] paramOwners = new MetaDataMethod[paramCount+2];
foreach (MetaDataMethod method in this.methodArray) {
method.registerReferences(paramCount, paramOwners);
}
MetaDataMethod current = null;
for (int i = 1; i <= paramCount; i++) {
if (paramOwners[i] == null) {
paramOwners[i] = current;
}
else {
current = paramOwners[i];
}
}
foreach (MetaDataMethod method in this.methodArray) {
method.resolveReferences(this, paramOwners);
// Console.WriteLine(method.ToStringLong());
}
}
private void initializeParamPtrTable(BinaryReader reader) {
int count = this.countArray[(int) MetaDataTableIndices.ParamPtr];
this.paramPtrArray = new MetaDataParamPtr[count];
this.metaDataTable[(int) MetaDataTableIndices.ParamPtr] =
this.paramPtrArray;
byte indexSize =
this.tableColumnSizes[(int)MetaDataTableIndices.ParamPtr][0];
for (int i = 0; i < count; i++) {
int paramIndex = ((indexSize == 4) ?
reader.ReadInt32() :
reader.ReadUInt16());
this.paramPtrArray[i] = new MetaDataParamPtr(paramIndex);
}
}
private void resolveParamPtrReferences() {
foreach (MetaDataParamPtr paramPtr in this.paramPtrArray) {
paramPtr.resolveReferences(this);
// Console.WriteLine(paramPtr.ToStringLong());
}
}
private void initializeParamTable(BinaryReader reader) {
int count = this.countArray[(int) MetaDataTableIndices.Param];
this.paramArray = new MetaDataParam[count];
this.metaDataTable[(int) MetaDataTableIndices.Param] =
this.paramArray;
for (int i = 0; i < count; i++) {
short flags = reader.ReadInt16();
short sequence = reader.ReadInt16();
int nameIndex = ((this.stringIndexSize == 4) ?
reader.ReadInt32() :
reader.ReadUInt16());
String name = this.getString(nameIndex);
this.paramArray[i] = new MetaDataParam(flags, sequence, name);
}
}
private void resolveParamReferences() {
// foreach (MetaDataParam param in this.paramArray) {
// Console.WriteLine(param.ToStringLong());
// }
}
private void initializeInterfaceImplTable(BinaryReader reader) {
int count =
this.countArray[(int) MetaDataTableIndices.InterfaceImpl];
this.interfaceImplArray = new MetaDataInterfaceImpl[count];
this.metaDataTable[(int) MetaDataTableIndices.InterfaceImpl] =
this.interfaceImplArray;
int classSize = this.tableColumnSizes[(int)MetaDataTableIndices.InterfaceImpl][0];
int interfaceSize = this.tableColumnSizes[(int)MetaDataTableIndices.InterfaceImpl][1];
for (int i = 0; i < count; i++) {
int classIndex = ((classSize == 4) ?
reader.ReadInt32() :
reader.ReadUInt16());
int interfaceIndex = ((interfaceSize == 4) ?
reader.ReadInt32() :
reader.ReadUInt16());
this.interfaceImplArray[i] =
new MetaDataInterfaceImpl(classIndex, interfaceIndex);
}
}
private void resolveInterfaceImplReferences() {
int typeDefCount = this.typeDefArray.Length;
ArrayList[] interfaceListArray = new ArrayList[typeDefCount+1];
foreach (MetaDataInterfaceImpl interfaceImpl in
this.interfaceImplArray) {
interfaceImpl.resolveReferences(this, interfaceListArray);
// Console.WriteLine(interfaceImpl.ToStringLong());
}
for (int i = 1; i <= typeDefCount; i++) {
MetaDataTypeDefinition classObject = this.getTypeDef(i);
if (interfaceListArray[i] != null) {
MetaDataObject[] interfaceArray =
new MetaDataObject[interfaceListArray[i].Count];
interfaceListArray[i].CopyTo(interfaceArray);
classObject.resolveReferences(interfaceArray);
}
else {
classObject.resolveReferences(emptyInterfaceArray);
}
}
}
private void initializeMemberRefTable(BinaryReader reader) {
int count = this.countArray[(int) MetaDataTableIndices.MemberRef];
this.memberRefArray = new MetaDataMemberRef[count];
this.metaDataTable[(int) MetaDataTableIndices.MemberRef] =
this.memberRefArray;
int classSize =
this.tableColumnSizes[(int)MetaDataTableIndices.MemberRef][0];
for (int i = 0; i < count; i++) {
int classIndex = ((classSize == 4) ?
reader.ReadInt32() :
reader.ReadUInt16());
int nameIndex = ((this.stringIndexSize == 4) ?
reader.ReadInt32() :
reader.ReadUInt16());
String name = this.getString(nameIndex);
int signatureIndex = ((this.blobIndexSize == 4) ?
reader.ReadInt32() :
reader.ReadUInt16());
Signature signature = this.getSignature(signatureIndex);
this.memberRefArray[i] =
new MetaDataMemberRef(classIndex, name, signature);
}
}
private void resolveMemberRefReferences() {
foreach (MetaDataMemberRef memberRef in this.memberRefArray) {
memberRef.resolveReferences(this);
// Console.WriteLine(memberRef.ToStringLong());
}
}
private void initializeConstantTable(BinaryReader reader) {
int count = this.countArray[(int) MetaDataTableIndices.Constant];
this.constantArray = new MetaDataConstant[count];
this.metaDataTable[(int) MetaDataTableIndices.Constant] =
this.constantArray;
int parentSize =
this.tableColumnSizes[(int)MetaDataTableIndices.Constant][1];
for (int i = 0; i < count; i++) {
ElementTypes type = (ElementTypes) reader.ReadByte();
byte padding = reader.ReadByte();
int parentIndex = ((parentSize == 4) ?
reader.ReadInt32() :
reader.ReadUInt16());
int valueIndex = ((this.blobIndexSize == 4) ?
reader.ReadInt32() :
reader.ReadUInt16());
byte[] valueBuffer = this.getValueBuffer(valueIndex);
this.constantArray[i] =
new MetaDataConstant(type, parentIndex, valueBuffer);
}
}
private void resolveConstantReferences() {
foreach (MetaDataConstant constant in this.constantArray) {
constant.resolveReferences(this);
MetaDataObject parent = constant.Parent;
if (parent is MetaDataField) {
((MetaDataField) parent).resolveReferences(constant);
}
else if (parent is MetaDataParam) {
((MetaDataParam) parent).resolveReferences(constant);
}
else if (parent is MetaDataProperty) {
((MetaDataProperty) parent).resolveReferences(constant);
}
else {
throw new IllegalMetaDataFormatException("Unexpected parent of constant: "+parent);
}
// Console.WriteLine(constant.ToStringLong());
}
}
private void initializeCustomAttributeTable(BinaryReader reader) {
int count =
this.countArray[(int) MetaDataTableIndices.CustomAttribute];
this.customAttributeArray = new MetaDataCustomAttribute[count];
this.metaDataTable[(int) MetaDataTableIndices.CustomAttribute] =
this.customAttributeArray;
int parentSize = this.tableColumnSizes[(int)MetaDataTableIndices.CustomAttribute][0];
int typeSize = this.tableColumnSizes[(int)MetaDataTableIndices.CustomAttribute][1];
for (int i = 0; i < count; i++) {
int parentIndex = ((parentSize == 4) ?
reader.ReadInt32() :
reader.ReadUInt16());
int typeIndex = ((typeSize == 4) ?
reader.ReadInt32() :
reader.ReadUInt16());
int valueIndex = ((this.blobIndexSize == 4) ?
reader.ReadInt32() :
reader.ReadUInt16());
MetaDataObject type = this.getCustomAttributeType(typeIndex);
byte[] valueBuffer = this.getBlobBytes(valueIndex);
this.customAttributeArray[i] =
new MetaDataCustomAttribute(parentIndex, type, valueBuffer);
}
}
private void resolveCustomAttributeReferences() {
foreach (MetaDataCustomAttribute attribute in
this.customAttributeArray) {
attribute.resolveReferences(this);
// Console.WriteLine(attribute.ToStringLong());
}
}
private void initializeFieldMarshalTable(BinaryReader reader) {
int count = this.countArray[(int) MetaDataTableIndices.FieldMarshal];
this.fieldMarshalArray = new MetaDataFieldMarshal[count];
this.metaDataTable[(int) MetaDataTableIndices.FieldMarshal] =
this.fieldMarshalArray;
int parentSize =
this.tableColumnSizes[(int)MetaDataTableIndices.FieldMarshal][0];
for (int i = 0; i < count; i++) {
int parentIndex = ((parentSize == 4) ?
reader.ReadInt32() :
reader.ReadUInt16());
int nativeTypeIndex = ((this.blobIndexSize == 4) ?
reader.ReadInt32() :
reader.ReadUInt16());
MarshalSpec nativeType = this.getNativeType(nativeTypeIndex);
this.fieldMarshalArray[i] =
new MetaDataFieldMarshal(parentIndex, nativeType);
}
}
private void resolveFieldMarshalReferences() {
foreach (MetaDataFieldMarshal fieldMarshal in
this.fieldMarshalArray) {
fieldMarshal.resolveReferences(this);
// Console.WriteLine(fieldMarshal.ToStringLong());
}
}
private void initializeDeclSecurityTable(BinaryReader reader) {
int count = this.countArray[(int) MetaDataTableIndices.DeclSecurity];
this.declSecurityArray = new MetaDataDeclSecurity[count];
this.metaDataTable[(int) MetaDataTableIndices.DeclSecurity] =
this.declSecurityArray;
int parentSize = this.tableColumnSizes[(int) MetaDataTableIndices.DeclSecurity][1];
for (int i = 0; i < count; i++) {
short action = reader.ReadInt16();
int parentIndex = ((parentSize == 4) ?
reader.ReadInt32() :
reader.ReadUInt16());
int permissionSetIndex = ((this.blobIndexSize == 4) ?
reader.ReadInt32() :
reader.ReadUInt16());
MetaDataBlob permissionSet =
this.getPermissionSet(permissionSetIndex);
this.declSecurityArray[i] =
new MetaDataDeclSecurity(action, parentIndex, permissionSet);
}
}
private void resolveDeclSecurityReferences() {
foreach (MetaDataDeclSecurity declSecurity in
this.declSecurityArray) {
declSecurity.resolveReferences(this);
// Console.WriteLine(declSecurity.ToStringLong());
}
}
private void initializeClassLayoutTable(BinaryReader reader) {
int count = this.countArray[(int) MetaDataTableIndices.ClassLayout];
this.classLayoutArray = new MetaDataClassLayout[count];
this.metaDataTable[(int) MetaDataTableIndices.ClassLayout] =
this.classLayoutArray;
int parentSize =
this.tableColumnSizes[(int) MetaDataTableIndices.ClassLayout][2];
for (int i = 0; i < count; i++) {
short packingSize = reader.ReadInt16();
int classSize = reader.ReadInt32();
int parentIndex = ((parentSize == 4) ?
reader.ReadInt32() :
reader.ReadUInt16());
this.classLayoutArray[i] =
new MetaDataClassLayout(packingSize, classSize, parentIndex);
}
}
private void resolveClassLayoutReferences() {
foreach (MetaDataClassLayout classLayout in
this.classLayoutArray) {
classLayout.resolveReferences(this);
// Console.WriteLine(classLayout.ToStringLong());
}
}
private void initializeFieldLayoutTable(BinaryReader reader) {
int count = this.countArray[(int) MetaDataTableIndices.FieldLayout];
this.fieldLayoutArray = new MetaDataFieldLayout[count];
this.metaDataTable[(int) MetaDataTableIndices.FieldLayout] =
this.fieldLayoutArray;
int fieldSize =
this.tableColumnSizes[(int) MetaDataTableIndices.FieldLayout][1];
for (int i = 0; i < count; i++) {
int offset = reader.ReadInt32();
int fieldIndex = ((fieldSize == 4) ?
reader.ReadInt32() :
reader.ReadUInt16());
MetaDataField field = this.getField(fieldIndex);
MetaDataFieldLayout fieldLayout =
new MetaDataFieldLayout(offset, field);
field.resolveReferences(fieldLayout);
this.fieldLayoutArray[i] = fieldLayout;
}
}
private void resolveFieldLayoutReferences() {
// foreach (MetaDataFieldLayout fieldLayout in
// this.fieldLayoutArray) {
// Console.WriteLine(fieldLayout.ToStringLong());
// }
}
private void initializeStandAloneSigTable(BinaryReader reader) {
int count =
this.countArray[(int) MetaDataTableIndices.StandAloneSig];
this.standAloneSigArray = new MetaDataStandAloneSig[count];
this.metaDataTable[(int) MetaDataTableIndices.StandAloneSig] =
this.standAloneSigArray;
int signatureSize = this.tableColumnSizes[(int) MetaDataTableIndices.StandAloneSig][0];
for (int i = 0; i < count; i++) {
int signatureIndex = ((signatureSize == 4) ?
reader.ReadInt32() :
reader.ReadUInt16());
Signature signature = this.getSignature(signatureIndex);
this.standAloneSigArray[i] =
new MetaDataStandAloneSig(signature);
}
}
private void resolveStandAloneSigReferences() {
foreach (MetaDataStandAloneSig standAloneSig in
this.standAloneSigArray) {
standAloneSig.resolveReferences(this);
// Console.WriteLine(standAloneSig.ToStringLong());
}
}
private void initializeEventMapTable(BinaryReader reader) {
int count =
this.countArray[(int) MetaDataTableIndices.EventMap];
this.eventMapArray = new MetaDataEventMap[count];
this.metaDataTable[(int) MetaDataTableIndices.EventMap] =
this.eventMapArray;
int parentSize =
this.tableColumnSizes[(int) MetaDataTableIndices.EventMap][0];
int eventListSize =
this.tableColumnSizes[(int) MetaDataTableIndices.EventMap][1];
for (int i = 0; i < count; i++) {
int parentIndex = ((parentSize == 4) ?
reader.ReadInt32() :
reader.ReadUInt16());
int eventListIndex = ((eventListSize == 4) ?
reader.ReadInt32() :
reader.ReadUInt16());
this.eventMapArray[i] =
new MetaDataEventMap(parentIndex, eventListIndex);
}
}
private void resolveEventMapReferences() {
foreach (MetaDataEventMap eventMap in this.eventMapArray) {
eventMap.resolveReferences(this);
// Console.WriteLine(eventMap.ToStringLong());
}
}
private void initializeEventPtrTable(BinaryReader reader) {
int count =
this.countArray[(int) MetaDataTableIndices.EventPtr];
this.eventPtrArray = new MetaDataEventPtr[count];
this.metaDataTable[(int) MetaDataTableIndices.EventPtr] =
this.eventPtrArray;
int eventSize =
this.tableColumnSizes[(int) MetaDataTableIndices.EventPtr][0];
for (int i = 0; i < count; i++) {
int eventIndex = ((eventSize == 4) ?
reader.ReadInt32() :
reader.ReadUInt16());
this.eventPtrArray[i] =
new MetaDataEventPtr(eventIndex);
}
}
private void resolveEventPtrReferences() {
foreach (MetaDataEventPtr eventPtr in this.eventPtrArray) {
eventPtr.resolveReferences(this);
// Console.WriteLine(eventPtr.ToStringLong());
}
}
private void initializeEventTable(BinaryReader reader) {
int count =
this.countArray[(int) MetaDataTableIndices.Event];
this.eventArray = new MetaDataEvent[count];
this.metaDataTable[(int) MetaDataTableIndices.Event] =
this.eventArray;
int eventTypeSize =
this.tableColumnSizes[(int) MetaDataTableIndices.Event][2];
for (int i = 0; i < count; i++) {
short eventFlags = reader.ReadInt16();
int nameIndex = ((this.stringIndexSize == 4) ?
reader.ReadInt32() :
reader.ReadUInt16());
String name = this.getString(nameIndex);
int eventTypeIndex = ((eventTypeSize == 4) ?
reader.ReadInt32() :
reader.ReadUInt16());
this.eventArray[i] =
new MetaDataEvent(eventFlags, name, eventTypeIndex);
}
}
private void resolveEventReferences() {
foreach (MetaDataEvent eventObject in this.eventArray) {
eventObject.resolveReferences(this);
// Console.WriteLine(eventObject.ToStringLong());
}
}
private void initializePropertyMapTable(BinaryReader reader) {
int count =
this.countArray[(int) MetaDataTableIndices.PropertyMap];
this.propertyMapArray = new MetaDataPropertyMap[count];
this.metaDataTable[(int) MetaDataTableIndices.PropertyMap] =
this.propertyMapArray;
int parentSize =
this.tableColumnSizes[(int) MetaDataTableIndices.PropertyMap][0];
int propertyListSize =
this.tableColumnSizes[(int) MetaDataTableIndices.PropertyMap][1];
for (int i = 0; i < count; i++) {
int parentIndex = ((parentSize == 4) ?
reader.ReadInt32() :
reader.ReadUInt16());
int propertyListIndex = ((propertyListSize == 4) ?
reader.ReadInt32() :
reader.ReadUInt16());
this.propertyMapArray[i] =
new MetaDataPropertyMap(parentIndex, propertyListIndex);
}
}
private void resolvePropertyMapReferences() {
foreach (MetaDataPropertyMap propertyMap in this.propertyMapArray) {
propertyMap.resolveReferences(this);
// Console.WriteLine(propertyMap.ToStringLong());
}
}
private void initializePropertyPtrTable(BinaryReader reader) {
int count =
this.countArray[(int) MetaDataTableIndices.PropertyPtr];
this.propertyPtrArray = new MetaDataPropertyPtr[count];
this.metaDataTable[(int) MetaDataTableIndices.PropertyPtr] =
this.propertyPtrArray;
int propertySize =
this.tableColumnSizes[(int) MetaDataTableIndices.PropertyPtr][0];
for (int i = 0; i < count; i++) {
int propertyIndex = ((propertySize == 4) ?
reader.ReadInt32() :
reader.ReadUInt16());
this.propertyPtrArray[i] =
new MetaDataPropertyPtr(propertyIndex);
}
}
private void resolvePropertyPtrReferences() {
foreach (MetaDataPropertyPtr propertyPtr in this.propertyPtrArray) {
propertyPtr.resolveReferences(this);
// Console.WriteLine(propertyPtr.ToStringLong());
}
}
private void initializePropertyTable(BinaryReader reader) {
int count =
this.countArray[(int) MetaDataTableIndices.Property];
this.propertyArray = new MetaDataProperty[count];
this.metaDataTable[(int) MetaDataTableIndices.Property] =
this.propertyArray;
for (int i = 0; i < count; i++) {
short flags = reader.ReadInt16();
int nameIndex = ((this.stringIndexSize == 4) ?
reader.ReadInt32() :
reader.ReadUInt16());
String name = this.getString(nameIndex);
int typeIndex = ((this.blobIndexSize == 4) ?
reader.ReadInt32() :
reader.ReadUInt16());
Signature type = this.getSignature(typeIndex);
this.propertyArray[i] =
new MetaDataProperty(flags, name, type);
}
}
private void resolvePropertyReferences() {
foreach (MetaDataProperty property in this.propertyArray) {
property.resolveReferences(this);
// Console.WriteLine(property.ToStringLong());
}
}
private void initializeMethodSemanticsTable(BinaryReader reader) {
int count =
this.countArray[(int) MetaDataTableIndices.MethodSemantics];
this.methodSemanticsArray = new MetaDataMethodSemantics[count];
this.metaDataTable[(int) MetaDataTableIndices.MethodSemantics] =
this.methodSemanticsArray;
int methodSize = this.tableColumnSizes[(int) MetaDataTableIndices.MethodSemantics][1];
int associationSize = this.tableColumnSizes[(int) MetaDataTableIndices.MethodSemantics][2];
for (int i = 0; i < count; i++) {
short semantic = reader.ReadInt16();
int methodIndex = ((methodSize == 4) ?
reader.ReadInt32() :
reader.ReadUInt16());
int associationIndex = ((associationSize == 4) ?
reader.ReadInt32() :
reader.ReadUInt16());
this.methodSemanticsArray[i] =
new MetaDataMethodSemantics(semantic, methodIndex,
associationIndex);
}
}
private void resolveMethodSemanticsReferences() {
foreach (MetaDataMethodSemantics methodSemantics in
this.methodSemanticsArray) {
methodSemantics.resolveReferences(this);
// Console.WriteLine(methodSemantics.ToStringLong());
}
}
private void initializeMethodImplTable(BinaryReader reader) {
int count =
this.countArray[(int) MetaDataTableIndices.MethodImpl];
this.methodImplArray = new MetaDataMethodImpl[count];
this.metaDataTable[(int) MetaDataTableIndices.MethodImpl] =
this.methodImplArray;
int classSize =
this.tableColumnSizes[(int) MetaDataTableIndices.MethodImpl][0];
int bodySize =
this.tableColumnSizes[(int) MetaDataTableIndices.MethodImpl][1];
int declarationSize =
this.tableColumnSizes[(int) MetaDataTableIndices.MethodImpl][2];
for (int i = 0; i < count; i++) {
int classIndex = ((classSize == 4) ?
reader.ReadInt32() :
reader.ReadUInt16());
int bodyIndex = ((bodySize == 4) ?
reader.ReadInt32() :
reader.ReadUInt16());
int declarationIndex = ((declarationSize == 4) ?
reader.ReadInt32() :
reader.ReadUInt16());
this.methodImplArray[i] =
new MetaDataMethodImpl(classIndex, bodyIndex,
declarationIndex);
}
}
private void resolveMethodImplReferences() {
foreach (MetaDataMethodImpl methodImpl in this.methodImplArray) {
methodImpl.resolveReferences(this);
// Console.WriteLine(methodImpl.ToStringLong());
}
}
private void initializeModuleRefTable(BinaryReader reader) {
int count =
this.countArray[(int) MetaDataTableIndices.ModuleRef];
this.moduleRefArray = new MetaDataModuleRef[count];
this.metaDataTable[(int) MetaDataTableIndices.ModuleRef] =
this.moduleRefArray;
for (int i = 0; i < count; i++) {
int nameIndex = ((this.stringIndexSize == 4) ?
reader.ReadInt32() :
reader.ReadUInt16());
String name = this.getString(nameIndex);
this.moduleRefArray[i] =
new MetaDataModuleRef(name);
}
}
private void resolveModuleRefReferences() {
// foreach (MetaDataModuleRef moduleRef in this.moduleRefArray) {
// Console.WriteLine(moduleRef.ToStringLong());
// }
}
private void initializeTypeSpecTable(BinaryReader reader) {
int count =
this.countArray[(int) MetaDataTableIndices.TypeSpec];
this.typeSpecArray = new MetaDataTypeSpec[count];
this.metaDataTable[(int) MetaDataTableIndices.TypeSpec] =
this.typeSpecArray;
for (int i = 0; i < count; i++) {
int signatureIndex = ((this.blobIndexSize == 4) ?
reader.ReadInt32() :
reader.ReadUInt16());
Signature signature = this.getSignature(signatureIndex);
this.typeSpecArray[i] = new MetaDataTypeSpec(signature);
}
}
private void resolveTypeSpecReferences() {
foreach (MetaDataTypeSpec typeSpec in this.typeSpecArray) {
typeSpec.resolveReferences(this);
// Console.WriteLine(typeSpec.ToStringLong());
}
}
private void initializeImplMapTable(BinaryReader reader) {
int count =
this.countArray[(int) MetaDataTableIndices.ImplMap];
this.implMapArray = new MetaDataImplMap[count];
this.metaDataTable[(int) MetaDataTableIndices.ImplMap] =
this.implMapArray;
int memberForwardedSize =
this.tableColumnSizes[(int) MetaDataTableIndices.ImplMap][1];
int importScopeSize =
this.tableColumnSizes[(int) MetaDataTableIndices.ImplMap][3];
for (int i = 0; i < count; i++) {
short flags = reader.ReadInt16();
int memberForwardedIndex = ((memberForwardedSize == 4) ?
reader.ReadInt32() :
reader.ReadUInt16());
int importNameIndex = ((this.stringIndexSize == 4) ?
reader.ReadInt32() :
reader.ReadUInt16());
String importName = this.getString(importNameIndex);
int importScopeIndex = ((importScopeSize == 4) ?
reader.ReadInt32() :
reader.ReadUInt16());
this.implMapArray[i] =
new MetaDataImplMap(flags, memberForwardedIndex,
importName, importScopeIndex);
}
}
private void resolveImplMapReferences() {
foreach (MetaDataImplMap implMap in this.implMapArray) {
implMap.resolveReferences(this);
// Console.WriteLine(implMap.ToStringLong());
}
}
private void initializeFieldRVATable(BinaryReader reader) {
int count =
this.countArray[(int) MetaDataTableIndices.FieldRVA];
this.fieldRVAArray = new MetaDataFieldRVA[count];
this.metaDataTable[(int) MetaDataTableIndices.FieldRVA] =
this.fieldRVAArray;
int fieldSize =
this.tableColumnSizes[(int) MetaDataTableIndices.FieldRVA][1];
for (int i = 0; i < count; i++) {
int rva = reader.ReadInt32();
int fieldIndex = ((fieldSize == 4) ?
reader.ReadInt32() :
reader.ReadUInt16());
MetaDataField field = this.getField(fieldIndex);
this.fieldRVAArray[i] = new MetaDataFieldRVA(rva, field);
}
}
private void resolveFieldRVAReferences() {
foreach (MetaDataFieldRVA fieldRVA in this.fieldRVAArray) {
// Console.WriteLine(fieldRVA.ToStringLong());
// Console.WriteLine(fieldRVA.Field.ToStringLong());
fieldRVA.resolveReferences(this, this.peLoader, this.fileStream);
// Console.WriteLine(fieldRVA.ToStringLong());
}
}
private void initializeENCLogTable(BinaryReader reader) {
int count =
this.countArray[(int) MetaDataTableIndices.ENCLog];
if (count != 0) {
throw new IllegalMetaDataFormatException("Found ENCLog entries");
}
}
private void resolveENCLogReferences() {
// Do nothing
}
private void initializeENCMapTable(BinaryReader reader) {
int count =
this.countArray[(int) MetaDataTableIndices.ENCMap];
if (count != 0) {
throw new IllegalMetaDataFormatException("Found ENCMap entries");
}
}
private void resolveENCMapReferences() {
// Do nothing
}
private void initializeAssemblyTable(BinaryReader reader) {
int count =
this.countArray[(int) MetaDataTableIndices.Assembly];
this.assemblyArray = new MetaDataAssembly[count];
this.metaDataTable[(int) MetaDataTableIndices.Assembly] =
this.assemblyArray;
for (int i = 0; i < count; i++) {
int hashAlgorithmId = reader.ReadInt32();
short majorVersion = reader.ReadInt16();
short minorVersion = reader.ReadInt16();
short buildNumber = reader.ReadInt16();
short revisionNumber = reader.ReadInt16();
int flags = reader.ReadInt32();
int publicKeyIndex = ((this.blobIndexSize == 4) ?
reader.ReadInt32() :
reader.ReadUInt16());
byte[] publicKey = this.getPublicKey(publicKeyIndex);
int nameIndex, localeIndex;
if (this.stringIndexSize == 4) {
nameIndex = reader.ReadInt32();
localeIndex = reader.ReadInt32();
}
else {
nameIndex = reader.ReadUInt16();
localeIndex = reader.ReadUInt16();
}
String name = this.getString(nameIndex);
String locale = this.getString(localeIndex);
this.assemblyArray[i] =
new MetaDataAssembly(hashAlgorithmId,
majorVersion, minorVersion,
buildNumber, revisionNumber,
flags, publicKey, name, locale);
}
}
private void resolveAssemblyReferences() {
// foreach (MetaDataAssembly assembly in this.assemblyArray) {
// Console.WriteLine(assembly.ToStringLong());
// }
}
private void initializeAssemblyProcessorTable(BinaryReader reader) {
int count =
this.countArray[(int) MetaDataTableIndices.AssemblyProcessor];
this.assemblyProcessorArray = new MetaDataAssemblyProcessor[count];
this.metaDataTable[(int) MetaDataTableIndices.AssemblyProcessor] =
this.assemblyProcessorArray;
for (int i = 0; i < count; i++) {
int processor = reader.ReadInt32();
this.assemblyProcessorArray[i] =
new MetaDataAssemblyProcessor(processor);
}
}
private void resolveAssemblyProcessorReferences() {
// foreach (MetaDataAssemblyProcessor assemblyProcessor in
// this.assemblyProcessorArray) {
// Console.WriteLine(assemblyProcessor.ToStringLong());
// }
}
private void initializeAssemblyOSTable(BinaryReader reader) {
int count =
this.countArray[(int) MetaDataTableIndices.AssemblyOS];
this.assemblyOSArray = new MetaDataAssemblyOS[count];
this.metaDataTable[(int) MetaDataTableIndices.AssemblyOS] =
this.assemblyOSArray;
for (int i = 0; i < count; i++) {
int platformID = reader.ReadInt32();
int majorVersion = reader.ReadInt32();
int minorVersion = reader.ReadInt32();
this.assemblyOSArray[i] =
new MetaDataAssemblyOS(platformID, majorVersion,
minorVersion);
}
}
private void resolveAssemblyOSReferences() {
// foreach (MetaDataAssemblyOS assemblyOS in
// this.assemblyOSArray) {
// Console.WriteLine(assemblyOS.ToStringLong());
// }
}
private void initializeAssemblyRefTable(BinaryReader reader) {
int count =
this.countArray[(int) MetaDataTableIndices.AssemblyRef];
this.assemblyRefArray = new MetaDataAssemblyRef[count];
this.metaDataTable[(int) MetaDataTableIndices.AssemblyRef] =
this.assemblyRefArray;
for (int i = 0; i < count; i++) {
short majorVersion = reader.ReadInt16();
short minorVersion = reader.ReadInt16();
short buildNumber = reader.ReadInt16();
short revisionNumber = reader.ReadInt16();
int flags = reader.ReadInt32();
int publicKeyIndex = ((this.blobIndexSize == 4) ?
reader.ReadInt32() :
reader.ReadUInt16());
byte[] publicKey = this.getPublicKey(publicKeyIndex);
int nameIndex, localeIndex;
if (this.stringIndexSize == 4) {
nameIndex = reader.ReadInt32();
localeIndex = reader.ReadInt32();
}
else {
nameIndex = reader.ReadUInt16();
localeIndex = reader.ReadUInt16();
}
String name = this.getString(nameIndex);
String locale = this.getString(localeIndex);
int hashValueIndex = ((this.blobIndexSize == 4) ?
reader.ReadInt32() :
reader.ReadUInt16());
byte[] hashValue = this.getHashValue(hashValueIndex);
this.assemblyRefArray[i] =
new MetaDataAssemblyRef(majorVersion, minorVersion,
buildNumber, revisionNumber,
flags, publicKey, name, locale,
hashValue);
}
}
private void resolveAssemblyRefReferences() {
// foreach (MetaDataAssemblyRef assemblyRef in
// this.assemblyRefArray) {
// Console.WriteLine(assemblyRef.ToStringLong());
// }
}
private void initializeAssemblyRefProcessorTable(BinaryReader reader) {
int count =
this.countArray[(int) MetaDataTableIndices.AssemblyRefProcessor];
this.assemblyRefProcessorArray =
new MetaDataAssemblyRefProcessor[count];
this.metaDataTable[(int) MetaDataTableIndices.AssemblyRefProcessor] =
this.assemblyRefProcessorArray;
int assemblyRefSize = this.tableColumnSizes[(int) MetaDataTableIndices.AssemblyRefProcessor][1];
for (int i = 0; i < count; i++) {
int processor = reader.ReadInt32();
int assemblyRefIndex = ((assemblyRefSize == 4) ?
reader.ReadInt32() :
reader.ReadUInt16());
MetaDataAssemblyRef assemblyRef =
this.getAssemblyRef(assemblyRefIndex);
this.assemblyRefProcessorArray[i] =
new MetaDataAssemblyRefProcessor(processor, assemblyRef);
}
}
private void resolveAssemblyRefProcessorReferences() {
// foreach (MetaDataAssemblyRefProcessor assemblyRefProcessor in
// this.assemblyRefProcessorArray) {
// Console.WriteLine(assemblyRefProcessor.ToStringLong());
// }
}
private void initializeAssemblyRefOSTable(BinaryReader reader) {
int count =
this.countArray[(int) MetaDataTableIndices.AssemblyRefOS];
this.assemblyRefOSArray = new MetaDataAssemblyRefOS[count];
this.metaDataTable[(int) MetaDataTableIndices.AssemblyRefOS] =
this.assemblyRefOSArray;
int assemblyRefSize = this.tableColumnSizes[(int) MetaDataTableIndices.AssemblyRefOS][3];
for (int i = 0; i < count; i++) {
int platformID = reader.ReadInt32();
int majorVersion = reader.ReadInt32();
int minorVersion = reader.ReadInt32();
int assemblyRefIndex = ((assemblyRefSize == 4) ?
reader.ReadInt32() :
reader.ReadUInt16());
MetaDataAssemblyRef assemblyRef =
this.getAssemblyRef(assemblyRefIndex);
this.assemblyRefOSArray[i] =
new MetaDataAssemblyRefOS(platformID, majorVersion,
minorVersion, assemblyRef);
}
}
private void resolveAssemblyRefOSReferences() {
// foreach (MetaDataAssemblyRefOS assemblyRefOS in
// this.assemblyRefOSArray) {
// Console.WriteLine(assemblyRefOS.ToStringLong());
// }
}
private void initializeFileTable(BinaryReader reader) {
int count =
this.countArray[(int) MetaDataTableIndices.File];
this.fileArray = new MetaDataFile[count];
this.metaDataTable[(int) MetaDataTableIndices.File] =
this.fileArray;
for (int i = 0; i < count; i++) {
int flags = reader.ReadInt32();
int nameIndex = ((this.stringIndexSize == 4) ?
reader.ReadInt32() :
reader.ReadUInt16());
String name = this.getString(nameIndex);
int hashValueIndex = ((this.blobIndexSize == 4) ?
reader.ReadInt32() :
reader.ReadUInt16());
byte[] hashValue = this.getHashValue(hashValueIndex);
this.fileArray[i] = new MetaDataFile(flags, name, hashValue);
}
}
private void resolveFileReferences() {
// foreach (MetaDataFile file in this.fileArray) {
// Console.WriteLine(file.ToStringLong());
// }
}
private void initializeExportedTypeTable(BinaryReader reader) {
int count =
this.countArray[(int) MetaDataTableIndices.ExportedType];
this.exportedTypeArray = new MetaDataExportedType[count];
this.metaDataTable[(int) MetaDataTableIndices.ExportedType] =
this.exportedTypeArray;
int implementationSize = this.tableColumnSizes[(int) MetaDataTableIndices.ExportedType][4];
for (int i = 0; i < count; i++) {
int flags = reader.ReadInt32();
int typeDefId = reader.ReadInt32();
int typeNameIndex, typeNamespaceIndex;
if (this.stringIndexSize == 4) {
typeNameIndex = reader.ReadInt32();
typeNamespaceIndex = reader.ReadInt32();
}
else {
typeNameIndex = reader.ReadUInt16();
typeNamespaceIndex = reader.ReadUInt16();
}
String typeName = this.getString(typeNameIndex);
String typeNamespace = this.getString(typeNamespaceIndex);
int implementationIndex = ((implementationSize == 4) ?
reader.ReadInt32() :
reader.ReadUInt16());
this.exportedTypeArray[i] =
new MetaDataExportedType(flags, typeDefId, typeName,
typeNamespace, implementationIndex);
}
}
private void resolveExportedTypeReferences() {
foreach (MetaDataExportedType exportedType in
this.exportedTypeArray) {
exportedType.resolveReferences(this);
// Console.WriteLine(exportedType.ToStringLong());
}
}
private void initializeManifestResourceTable(BinaryReader reader) {
int count =
this.countArray[(int) MetaDataTableIndices.ManifestResource];
this.manifestResourceArray = new MetaDataManifestResource[count];
this.metaDataTable[(int) MetaDataTableIndices.ManifestResource] =
this.manifestResourceArray;
int implementationSize = this.tableColumnSizes[(int) MetaDataTableIndices.ManifestResource][3];
for (int i = 0; i < count; i++) {
int offset = reader.ReadInt32();
int flags = reader.ReadInt32();
int nameIndex = ((this.stringIndexSize == 4) ?
reader.ReadInt32() :
reader.ReadUInt16());
String name = this.getString(nameIndex);
int implementationIndex = ((implementationSize == 4) ?
reader.ReadInt32() :
reader.ReadUInt16());
byte[] data = ((implementationIndex == 0) ?
this.getResourceBytes(offset) :
null);
// Embedded resource
this.manifestResourceArray[i] =
new MetaDataManifestResource(offset, flags, name, data,
implementationIndex);
}
}
private void resolveManifestResourceReferences() {
foreach (MetaDataManifestResource manifestResource in
this.manifestResourceArray) {
manifestResource.resolveReferences(this);
// Console.WriteLine(manifestResource.ToStringLong());
}
}
private void initializeNestedClassTable(BinaryReader reader) {
int count =
this.countArray[(int) MetaDataTableIndices.NestedClass];
this.nestedClassArray = new MetaDataNestedClass[count];
this.metaDataTable[(int) MetaDataTableIndices.NestedClass] =
this.nestedClassArray;
int nestedClassSize =
this.tableColumnSizes[(int) MetaDataTableIndices.NestedClass][0];
int enclosingClassSize =
this.tableColumnSizes[(int) MetaDataTableIndices.NestedClass][1];
int typeDefCount = this.typeDefArray.Length;;
ArrayList[] nestedClassListArray = new ArrayList[typeDefCount+1];
for (int i = 0; i < count; i++) {
int nestedClassIndex = ((nestedClassSize == 4) ?
reader.ReadInt32() :
reader.ReadUInt16());
int enclosingClassIndex = ((enclosingClassSize == 4) ?
reader.ReadInt32() :
reader.ReadUInt16());
MetaDataTypeDefinition nestedClass =
this.getTypeDef(nestedClassIndex);
MetaDataTypeDefinition enclosingClass =
this.getTypeDef(enclosingClassIndex);
ArrayList nestedClassList =
nestedClassListArray[enclosingClassIndex];
if (nestedClassList == null) {
nestedClassList = new ArrayList(2);
nestedClassListArray[enclosingClassIndex] = nestedClassList;
}
nestedClassList.Add(nestedClass);
nestedClass.resolveReferences(enclosingClass);
this.nestedClassArray[i] =
new MetaDataNestedClass(nestedClass, enclosingClass);
}
for (int i = 1; i <= typeDefCount; i++) {
ArrayList nestedClassList = nestedClassListArray[i];
MetaDataTypeDefinition[] nestedClasses;
if (nestedClassList != null) {
int nestedCount = nestedClassList.Count;
nestedClasses = new MetaDataTypeDefinition[nestedCount];
for (int j = 0; j < nestedCount; j++) {
nestedClasses[j] = (MetaDataTypeDefinition)
nestedClassList[j];
}
}
else {
nestedClasses = emptyNestedClassArray;
}
this.getTypeDef(i).resolveReferences(nestedClasses);
}
}
private void resolveNestedClassReferences() {
// foreach (MetaDataNestedClass nestedClass in
// this.nestedClassArray) {
// Console.WriteLine(nestedClass.ToStringLong());
// }
}
private void initializeGenericParamTable(BinaryReader reader) {
int count =
this.countArray[(int) MetaDataTableIndices.GenericParam];
//System.Console.WriteLine("Found " + count + " GenericParam entries");
this.genericParamArray = new MetaDataGenericParam[count];
this.metaDataTable[(int) MetaDataTableIndices.GenericParam] =
this.genericParamArray;
int ownerSize =
this.tableColumnSizes[(int) MetaDataTableIndices.GenericParam][2];
int kindSize =
this.tableColumnSizes[(int) MetaDataTableIndices.GenericParam][4];
for (int i = 0; i < count; i++) {
short number = reader.ReadInt16();
short flags = reader.ReadInt16();
int ownerIndex = ((ownerSize == 4) ?
reader.ReadInt32() :
reader.ReadUInt16());
int nameIndex = ((this.stringIndexSize == 4) ?
reader.ReadInt32() :
reader.ReadUInt16());
String name = this.getString(nameIndex);
int kind = ((kindSize == 4) ?
reader.ReadInt32() :
reader.ReadUInt16());
this.genericParamArray[i] =
new MetaDataGenericParam(number, flags, ownerIndex,
name, kind);
}
}
private void resolveGenericParamReferences() {
foreach (MetaDataGenericParam genericParam in
this.genericParamArray) {
genericParam.resolveReferences(this);
}
}
private void initializeMethodSpecTable(BinaryReader reader) {
int count =
this.countArray[(int) MetaDataTableIndices.MethodSpec];
//System.Console.WriteLine("Found " + count + " MethodSpec entries");
this.methodSpecArray = new MetaDataMethodSpec[count];
this.metaDataTable[(int) MetaDataTableIndices.MethodSpec] =
this.methodSpecArray;
int methodSize =
this.tableColumnSizes[(int) MetaDataTableIndices.MethodSpec][0];
for (int i = 0; i < count; i++) {
int methodIndex = ((methodSize == 4) ?
reader.ReadInt32() :
reader.ReadUInt16());
int instantiationIndex = ((this.blobIndexSize == 4) ?
reader.ReadInt32() :
reader.ReadUInt16());
byte[] instantiationValue = this.getHashValue(instantiationIndex);
this.methodSpecArray[i] =
new MetaDataMethodSpec(methodIndex, instantiationValue);
}
}
private void resolveMethodSpecReferences() {
foreach (MetaDataMethodSpec methodSpec in
this.methodSpecArray) {
methodSpec.resolveReferences(this);
// Console.WriteLine(methodSpec.ToStringLong());
}
}
private void initializeGenericParamConstraintTable(BinaryReader reader) {
int count =
this.countArray[(int)
MetaDataTableIndices.GenericParamConstraint];
//System.Console.WriteLine("Found " + count
// + " GenericParamConstraint entries");
this.genericParamConstraintArray =
new MetaDataGenericParamConstraint[count];
this.metaDataTable[(int) MetaDataTableIndices.GenericParamConstraint]
= this.genericParamConstraintArray;
int ownerSize = this.tableColumnSizes
[(int) MetaDataTableIndices.GenericParamConstraint][0];
int constraintSize = this.tableColumnSizes
[(int) MetaDataTableIndices.GenericParamConstraint][1];
for (int i = 0; i < count; i++) {
int ownerIndex = ((ownerSize == 4) ?
reader.ReadInt32() :
reader.ReadUInt16());
int constraintIndex = ((constraintSize == 4) ?
reader.ReadInt32() :
reader.ReadUInt16());
this.genericParamConstraintArray[i] =
new MetaDataGenericParamConstraint(ownerIndex,
constraintIndex);
}
}
private void resolveGenericParamConstraintReferences() {
foreach (MetaDataGenericParamConstraint constraint in
this.genericParamConstraintArray) {
constraint.resolveReferences(this);
}
}
private void initializeRelocationTable() {
// read in relocation tables
int relocationOffset = peLoader.getRelocationOffset();
ArrayList relocations = new ArrayList();
if (relocationOffset > 0) {
System.Console.WriteLine("Has relocation table");
// has relocation table
fileStream.Seek(relocationOffset, SeekOrigin.Begin);
BinaryReader relocReader = new BinaryReader(fileStream);
int rva = relocReader.ReadInt32();
while (rva > 0) {
int size = relocReader.ReadInt32();
for (int i = 8; i < size; i += 2) {
int relocRVA = relocReader.ReadInt16();
if (relocRVA != 0) {
if ((relocRVA & 0x3000) != 0x3000)
System.Console.WriteLine("Warnging: unknown relocation type");
relocRVA &= 0x0FFF; // the first 4 bits are types
relocRVA += rva;
relocations.Add(relocRVA);
}
}
rva = relocReader.ReadInt32();
}
}
else {
System.Console.WriteLine("Has no relocation table");
}
relocationArray = relocations.ToArray();
}
public bool RVAHasRelocation(int rva) {
Object[] relocations = this.relocationArray;
for (int i = 0; i < relocations.Length; i++) {
if (rva == (int) relocations[i]) {
return true;
}
}
return false;
}
private void initializeVtableFixupTable() {
// Read the vtableFixup data, if there is any
int vtableFixupOffset = peLoader.getVtableFixupOffset();
int vtableFixupSize = peLoader.getVtableFixupSize();
if (vtableFixupOffset > 0 && vtableFixupSize > 0) {
fileStream.Seek(vtableFixupOffset, SeekOrigin.Begin);
BinaryReader vtableReader = new BinaryReader(fileStream);
if (vtableFixupSize % 8 != 0) {
System.Console.WriteLine("Warning: fixup size is not multiple of 8 bytes !!");
}
// each entry is 8 bytes, first 4 bytes is RVA,
// followed by 2 bytes of count, 2 bytes of type
int fixupCount = vtableFixupSize / 8;
int[] rva = new int[fixupCount];
short[] size = new short[fixupCount];
short[] type = new short[fixupCount];
for (int i = 0; i < fixupCount; i++) {
rva[i] = vtableReader.ReadInt32();
size[i] = vtableReader.ReadInt16();
type[i] = vtableReader.ReadInt16();
}
this.vtableFixupArray = new MetaDataVtableFixup[fixupCount];
for (int i = 0; i < fixupCount; i++) {
int currRVA = rva[i];
short currSize = size[i];
COR_VTABLE currType = (COR_VTABLE) type[i];
// read in the fixup token
int offset = peLoader.VaToOffset(currRVA);
fileStream.Seek(offset, SeekOrigin.Begin);
BinaryReader tokenReader = new BinaryReader(fileStream);
MetaDataMethod[] fixupMethods = new MetaDataMethod[currSize];
for (int index = 0; index < currSize; index++) {
int token = tokenReader.ReadInt32();
fixupMethods[index] =
(MetaDataMethod)this.getObjectFromToken(token);
}
this.vtableFixupArray[i] =
new MetaDataVtableFixup(currRVA, currSize, currType,
fixupMethods);
}
}
}
public bool HasVtableFixup() {
return (this.vtableFixupArray != null);
}
private void initializeDelayIATTable() {
// Read in the dalay IAT table, if there is any
int delayIATOffset = peLoader.getDelayIATOffset();
int delayIATSize = peLoader.getDelayIATSize();
if (delayIATOffset > 0 && delayIATSize > 0) {
fileStream.Seek(delayIATOffset, SeekOrigin.Begin);
BinaryReader delayIATReader = new BinaryReader(fileStream);
int characteristics = delayIATReader.ReadInt32();
int addressOfDllName =
peLoader.VaToOffset(delayIATReader.ReadInt32());
int addressOfHModule = delayIATReader.ReadInt32();
int rvaOfIAT = peLoader.VaToOffset(delayIATReader.ReadInt32());
int nameTable = peLoader.VaToOffset(delayIATReader.ReadInt32());
// read in dll name
string dllName = peLoader.readString(addressOfDllName);
// read in import address table
fileStream.Seek(rvaOfIAT, SeekOrigin.Begin);
BinaryReader IATReader = new BinaryReader(fileStream);
int importAddress = IATReader.ReadInt32();
int count = 0;
ArrayList imports = new ArrayList();
while (importAddress != 0) {
count++;
imports.Add(importAddress);
importAddress = IATReader.ReadInt32();
}
object[] importArray = imports.ToArray();
// read in the names
fileStream.Seek(nameTable, SeekOrigin.Begin);
BinaryReader nameAddrReader = new BinaryReader(fileStream);
int[] nameAddress = new int[count];
for (int i = 0; i < count; i++) {
int nameAddr = nameAddrReader.ReadInt32();
nameAddress[i] = peLoader.VaToOffset(nameAddr + 2);
}
String[] names = new String[count];
for (int i = 0; i < count; i++) {
names[i] = peLoader.readString(nameAddress[i]);
}
this.delayImportTable =
new MetaDataDelayImportTable(dllName, importArray,
names);
System.Console.WriteLine(this.delayImportTable.ToString());
}
}
// State
private readonly PELoader peLoader;
private readonly Stream fileStream;
private readonly int metaDataOffset;
private readonly StorageStream dataStream;
private readonly StorageStream stringPoolStream;
private readonly StorageStream userBlobPoolStream;
private readonly StorageStream guidPoolStream;
private readonly StorageStream blobPoolStream;
// Schema fields (for logical tables)
private int reserved;
private byte majorVersion;
private byte minorVersion;
private byte heapBits;
private byte rowId;
private long maskValid;
private long maskSorted;
private int[] countArray = new int[(int) MetaDataTableIndices.Count];
private byte[][] tableColumnSizes = new byte[(int) MetaDataTableIndices.Count][];
private byte[][] tableColumnOffsets = new byte[(int) MetaDataTableIndices.Count][];
private byte[] tableRowSizes = new byte[(int) MetaDataTableIndices.Count];
private int extraData;
private byte stringIndexSize;
private byte guidIndexSize;
private byte blobIndexSize;
private readonly byte[] stringStreamBuffer;
private readonly byte[] blobStreamBuffer;
private readonly byte[] userStringStreamBuffer;
private readonly byte[] resourceBuffer;
private readonly Guid[] guidArray;
private MetaDataObject[][] metaDataTable;
private MetaDataModule[] moduleArray;
private MetaDataTypeReference[] typeRefArray;
private MetaDataTypeDefinition[] typeDefArray;
private MetaDataFieldPtr[] fieldPtrArray;
private MetaDataField[] fieldArray;
private MetaDataMethodPtr[] methodPtrArray;
private MetaDataMethod[] methodArray;
private MetaDataParamPtr[] paramPtrArray;
private MetaDataParam[] paramArray;
private MetaDataInterfaceImpl[] interfaceImplArray;
private MetaDataMemberRef[] memberRefArray;
private MetaDataConstant[] constantArray;
private MetaDataCustomAttribute[] customAttributeArray;
private MetaDataFieldMarshal[] fieldMarshalArray;
private MetaDataDeclSecurity[] declSecurityArray;
private MetaDataClassLayout[] classLayoutArray;
private MetaDataFieldLayout[] fieldLayoutArray;
private MetaDataStandAloneSig[] standAloneSigArray;
private MetaDataEventMap[] eventMapArray;
private MetaDataEventPtr[] eventPtrArray;
private MetaDataEvent[] eventArray;
private MetaDataPropertyMap[] propertyMapArray;
private MetaDataPropertyPtr[] propertyPtrArray;
private MetaDataProperty[] propertyArray;
private MetaDataMethodSemantics[] methodSemanticsArray;
private MetaDataMethodImpl[] methodImplArray;
private MetaDataModuleRef[] moduleRefArray;
private MetaDataTypeSpec[] typeSpecArray;
private MetaDataImplMap[] implMapArray;
private MetaDataFieldRVA[] fieldRVAArray;
private MetaDataAssembly[] assemblyArray;
private MetaDataAssemblyProcessor[] assemblyProcessorArray;
private MetaDataAssemblyOS[] assemblyOSArray;
private MetaDataAssemblyRef[] assemblyRefArray;
private MetaDataAssemblyRefProcessor[] assemblyRefProcessorArray;
private MetaDataAssemblyRefOS[] assemblyRefOSArray;
private MetaDataFile[] fileArray;
private MetaDataExportedType[] exportedTypeArray;
private MetaDataManifestResource[] manifestResourceArray;
private MetaDataNestedClass[] nestedClassArray;
private MetaDataGenericParam[] genericParamArray;
private MetaDataMethodSpec[] methodSpecArray;
private MetaDataGenericParamConstraint[] genericParamConstraintArray;
private Object[] relocationArray;
private MetaDataVtableFixup[] vtableFixupArray;
private MetaDataDelayImportTable delayImportTable;
private readonly static MetaDataTypeDefinition[] emptyNestedClassArray = new MetaDataTypeDefinition[0];
private readonly static MetaDataParam[] emptyParamArray = new MetaDataParam[0];
private readonly static MetaDataField[] emptyFieldArray = new MetaDataField[0];
private readonly static MetaDataMethod[] emptyMethodArray = new MetaDataMethod[0];
private readonly static MetaDataObject[] emptyInterfaceArray = new MetaDataObject[0];
private const int METAMODEL_MAJOR_VER = 1;
private const int METAMODEL_MINOR_VER_A = 0;
private const int METAMODEL_MINOR_VER_B = 1;
private const int HEAPBITS_MASK_STRINGS = 0x01;
private const int HEAPBITS_MASK_GUID = 0x02;
private const int HEAPBITS_MASK_BLOB = 0x04;
private const int HEAPBITS_MASK_PADDING_BIT = 0x08;
private const int HEAPBITS_MASK_DELTA_ONLY = 0x20;
private const int HEAPBITS_MASK_EXTRA_DATA = 0x40;
private const int HEAPBITS_MASK_HAS_DELETE = 0x80;
internal static readonly System.Text.UTF8Encoding stringEncoding = new System.Text.UTF8Encoding();
private static readonly byte[][] TableColumnKinds = new byte[(int) MetaDataTableIndices.Count][] {
// rModuleCols
new byte[] { (byte) (byte) ColumnKindId.UShort,
(byte) ColumnKindId.String,
(byte) ColumnKindId.Guid,
(byte) ColumnKindId.Guid,
(byte) ColumnKindId.Guid },
// rTypeRefCols
new byte[] { (byte) ColumnKindId.CodedToken + (byte) CodeToken.ResolutionScope,
(byte) ColumnKindId.String,
(byte) ColumnKindId.String },
// rTypeDefCols
new byte[] { (byte) ColumnKindId.ULong,
(byte) ColumnKindId.String,
(byte) ColumnKindId.String,
(byte) ColumnKindId.CodedToken + (byte) CodeToken.TypeDefOrRef,
(byte) MetaDataTableIndices.Field,
(byte) MetaDataTableIndices.Method },
// rFieldPtrCols
new byte[] { (byte) MetaDataTableIndices.Field },
// rFieldCols
new byte[] { (byte) ColumnKindId.UShort,
(byte) ColumnKindId.String,
(byte) ColumnKindId.Blob },
// rMethodPtrCols
new byte[] { (byte) MetaDataTableIndices.Method },
// rMethodCols
new byte[] { (byte) ColumnKindId.ULong,
(byte) ColumnKindId.UShort,
(byte) ColumnKindId.UShort,
(byte) ColumnKindId.String,
(byte) ColumnKindId.Blob,
(byte) MetaDataTableIndices.Param },
// rParamPtrCols
new byte[] { (byte) MetaDataTableIndices.Param },
// rParamCols
new byte[] { (byte) ColumnKindId.UShort,
(byte) ColumnKindId.UShort,
(byte) ColumnKindId.String },
// rInterfaceImplCols
new byte[] { (byte) MetaDataTableIndices.TypeDef,
(byte) ColumnKindId.CodedToken + (byte) CodeToken.TypeDefOrRef },
// rMemberRefCols
new byte[] { (byte) ColumnKindId.CodedToken + (byte) CodeToken.MemberRefParent,
(byte) ColumnKindId.String,
(byte) ColumnKindId.Blob },
// rConstantCols
new byte[] { (byte) ColumnKindId.Byte,
(byte) ColumnKindId.CodedToken + (byte) CodeToken.HasConstant,
(byte) ColumnKindId.Blob },
// rCustomAttributeCols
new byte[] { (byte) ColumnKindId.CodedToken + (byte) CodeToken.HasCustomAttribute,
(byte) ColumnKindId.CodedToken + (byte) CodeToken.CustomAttributeType,
(byte) ColumnKindId.Blob },
// rFieldMarshalCols
new byte[] { (byte) ColumnKindId.CodedToken + (byte) CodeToken.HasFieldMarshal,
(byte) ColumnKindId.Blob },
// rDeclSecurityCols
new byte[] { (byte) ColumnKindId.Short,
(byte) ColumnKindId.CodedToken + (byte) CodeToken.HasDeclSecurity,
(byte) ColumnKindId.Blob },
// rClassLayoutCols
new byte[] { (byte) ColumnKindId.UShort,
(byte) ColumnKindId.ULong,
(byte) MetaDataTableIndices.TypeDef },
// rFieldLayoutCols
new byte[] { (byte) ColumnKindId.ULong,
(byte) MetaDataTableIndices.Field },
// rStandAloneSigCols
new byte[] { (byte) ColumnKindId.Blob },
// rEventMapCols
new byte[] { (byte) MetaDataTableIndices.TypeDef,
(byte) MetaDataTableIndices.Event },
// rEventPtrCols
new byte[] { (byte) MetaDataTableIndices.Event },
// rEventCols
new byte[] { (byte) ColumnKindId.UShort,
(byte) ColumnKindId.String,
(byte) ColumnKindId.CodedToken + (byte) CodeToken.TypeDefOrRef },
// rPropertyMapCols
new byte[] { (byte) MetaDataTableIndices.TypeDef,
(byte) MetaDataTableIndices.Property },
// rPropertyPtrCols
new byte[] { (byte) MetaDataTableIndices.Property },
// rPropertyCols
new byte[] { (byte) ColumnKindId.UShort,
(byte) ColumnKindId.String,
(byte) ColumnKindId.Blob },
// rMethodSemanticsCols
new byte[] { (byte) ColumnKindId.UShort,
(byte) MetaDataTableIndices.Method,
(byte) ColumnKindId.CodedToken + (byte) CodeToken.HasSemantic },
// rMethodImplCols
new byte[] { (byte) MetaDataTableIndices.TypeDef,
(byte) ColumnKindId.CodedToken + (byte) CodeToken.MethodDefOrRef,
(byte) ColumnKindId.CodedToken + (byte) CodeToken.MethodDefOrRef },
// rModuleRefCols
new byte[] { (byte) ColumnKindId.String },
// rTypeSpecCols
new byte[] { (byte) ColumnKindId.Blob },
// rImplMapCols
new byte[] { (byte) ColumnKindId.UShort,
(byte) ColumnKindId.CodedToken + (byte) CodeToken.MemberForwarded,
(byte) ColumnKindId.String,
(byte) MetaDataTableIndices.ModuleRef },
// rFieldRVACols
new byte[] { (byte) ColumnKindId.ULong,
(byte) MetaDataTableIndices.Field },
// rENCLogCols
new byte[] { (byte) ColumnKindId.ULong,
(byte) ColumnKindId.ULong },
// rENCMapCols
new byte[] { (byte) ColumnKindId.ULong },
// rAssemblyCols
new byte[] { (byte) ColumnKindId.ULong,
(byte) ColumnKindId.UShort,
(byte) ColumnKindId.UShort,
(byte) ColumnKindId.UShort,
(byte) ColumnKindId.UShort,
(byte) ColumnKindId.ULong,
(byte) ColumnKindId.Blob,
(byte) ColumnKindId.String,
(byte) ColumnKindId.String },
// rAssemblyProcessorCols
new byte[] { (byte) ColumnKindId.ULong },
// rAssemblyOSCols
new byte[] { (byte) ColumnKindId.ULong,
(byte) ColumnKindId.ULong,
(byte) ColumnKindId.ULong },
// rAssemblyRefCols
new byte[] { (byte) ColumnKindId.UShort,
(byte) ColumnKindId.UShort,
(byte) ColumnKindId.UShort,
(byte) ColumnKindId.UShort,
(byte) ColumnKindId.ULong,
(byte) ColumnKindId.Blob,
(byte) ColumnKindId.String,
(byte) ColumnKindId.String,
(byte) ColumnKindId.Blob },
// rAssemblyRefProcessorCols
new byte[] { (byte) ColumnKindId.ULong,
(byte) MetaDataTableIndices.AssemblyRef },
// rAssemblyRefOSCols
new byte[] { (byte) ColumnKindId.ULong,
(byte) ColumnKindId.ULong,
(byte) ColumnKindId.ULong,
(byte) MetaDataTableIndices.AssemblyRef },
// rFileCols
new byte[] { (byte) ColumnKindId.ULong,
(byte) ColumnKindId.String,
(byte) ColumnKindId.Blob },
// rExportedTypeCols
new byte[] { (byte) ColumnKindId.ULong,
(byte) ColumnKindId.ULong,
(byte) ColumnKindId.String,
(byte) ColumnKindId.String,
(byte) ColumnKindId.CodedToken + (byte) CodeToken.Implementation },
// rManifestResourceCols
new byte[] { (byte) ColumnKindId.ULong,
(byte) ColumnKindId.ULong,
(byte) ColumnKindId.String,
(byte) ColumnKindId.CodedToken + (byte) CodeToken.Implementation },
// rNestedClassCols
new byte[] { (byte) MetaDataTableIndices.TypeDef,
(byte) MetaDataTableIndices.TypeDef },
// rGenericParamCols
new byte[] { (byte) ColumnKindId.UShort,
(byte) ColumnKindId.UShort,
(byte) ColumnKindId.CodedToken + (byte) CodeToken.TypeOrMethodDef,
(byte) ColumnKindId.String,
(byte) ColumnKindId.CodedToken + (byte) CodeToken.TypeDefOrRef,
// (byte) ColumnKindId.CodedToken + (byte) CodeToken.TypeDefOrRef
},
// rMethodSpecCols
new byte[] { (byte) ColumnKindId.CodedToken + (byte) CodeToken.MethodDefOrRef,
(byte) ColumnKindId.Blob
},
// rGenericParamConstraintCols
new byte[] { (byte) ColumnKindId.CodedToken + (byte) CodeToken.GenericParam,
(byte) ColumnKindId.CodedToken + (byte) CodeToken.TypeDefOrRef },
};
// These are for informational use only! Not used anywhere.
private static readonly String[][] TableColumnNames = new String[(int) MetaDataTableIndices.Count][] {
// rModuleColNames
new String[] { "Generation", "Name", "Mvid", "EncId", "EncBaseId" },
// rTypeRefColNames
new String[] { "ResolutionScope", "Name", "Namespace" },
// rTypeDefColNames
new String[] { "Flags", "Name", "Namespace", "Extends", "FieldList",
"MethodList" },
// rFieldPtrColNames
new String[] { "Field" },
// rFieldColNames
new String[] { "Flags", "Name", "Signature" },
// rMethodPtrColNames
new String[] { "Method" },
// rMethodColNames
new String[] { "RVA", "ImplFlags", "Flags", "Name", "Signature",
"ParamList" },
// rParamPtrColNames
new String[] { "Param" },
// rParamColNames
new String[] { "Flags", "Sequence", "Name" },
// rInterfaceImplColNames
new String[] { "Class", "Interface" },
// rMemberRefColNames
new String[] { "Class", "Name", "Signature" },
// rConstantColNames
new String[] { "Type", "Parent", "Value" },
// rCustomAttributeColNames
new String[] { "Parent", "Type", "Value" },
// rFieldMarshalColNames
new String[] { "Parent", "NativeType" },
// rDeclSecurityColNames
new String[] { "Action", "Parent", "PermissionSet" },
// rClassLayoutColNames
new String[] { "PackingSize", "ClassSize", "Parent" },
// rFieldLayoutColNames
new String[] { "OffSet", "Field" },
// rStandAloneSigColNames
new String[] { "Signature" },
// rEventMapColNames
new String[] { "Parent", "EventList" },
// rEventPtrColNames
new String[] { "Event" },
// rEventColNames
new String[] { "EventFlags", "Name", "EventType" },
// rPropertyMapColNames
new String[] { "Parent", "PropertyList" },
// rPropertyPtrColNames
new String[] { "Property" },
// rPropertyColNames
new String[] { "PropFlags", "Name", "Type" },
// rMethodSemanticsColNames
new String[] { "Semantic", "Method", "Association" },
// rMethodImplColNames
new String[] { "Class", "MethodBody", "MethodDeclaration" },
// rModuleRefColNames
new String[] { "Name" },
// rTypeSpecColNames
new String[] { "Signature" },
// rImplMapColNames
new String[] { "MappingFlags", "MemberForwarded", "ImportName",
"ImportScope" },
// rFieldRVAColNames
new String[] { "RVA", "Field" },
// rENCLogColNames
new String[] { "Token", "FuncCode" },
// rENCMapColNames
new String[] { "Token" },
// rAssemblyColNames
new String[] { "HashAlgId", "MajorVersion", "MinorVersion",
"BuildNumber", "RevisionNumber", "Flags",
"PublicKey", "Name", "Locale" },
// rAssemblyProcessorColNames
new String[] { "Processor" },
// rAssemblyOSColNames
new String[] { "OSPlatformId", "OSMajorVersion", "OSMinorVersion" },
// rAssemblyRefColNames
new String[] { "MajorVersion", "MinorVersion", "BuildNumber",
"RevisionNumber", "Flags", "PublicKeyOrToken",
"Name", "Locale", "HashValue" },
// rAssemblyRefProcessorColNames
new String[] { "Processor", "AssemblyRef" },
// rAssemblyRefOSColNames
new String[] { "OSPlatformId", "OSMajorVersion", "OSMinorVersion",
"AssemblyRef" },
// rFileColNames
new String[] { "Flags", "Name", "HashValue" },
// rExportedTypeColNames
new String[] { "Flags", "TypeDefId", "TypeName", "TypeNamespace",
"Implementation" },
// rManifestResourceColNames
new String[] { "Offset", "Flags", "Name", "Implementation" },
// rNestedClassColNames
new String[] { "NestedClass", "EnclosingClass" },
// rGenericParamColNames
new String[] { "Number", "Flags", "Owner", "Name", "Kind" },//, "DeprecatedConstraint" },
// rMethodSpecNames
new String[] { "Method", "Instantiation" },
// rGenericParamConstraintColNames
new String[] { "Owner", "Constraint" },
};
private static readonly int[] BitsForCountArray = new int[] {
0,1,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5
};
private static readonly int[] MaskForCountArray = new int[] {
0,1,1,3,3,7,7,7,7,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0x1f,0x1f,0x1f,
0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f
};
private static readonly TokenType[][] CodeTokenTypeLists = new TokenType[(int) CodeToken.Count][] {
// TypeDefOrRef
new TokenType[] { TokenType.TypeDef,
TokenType.TypeRef,
TokenType.TypeSpec },
// HasConstant
new TokenType[] { TokenType.FieldDef,
TokenType.ParamDef,
TokenType.Property },
// HasCustomAttribute
new TokenType[] { TokenType.MethodDef,
TokenType.FieldDef,
TokenType.TypeRef,
TokenType.TypeDef,
TokenType.ParamDef,
TokenType.InterfaceImpl,
TokenType.MemberRef,
TokenType.Module,
TokenType.Permission,
TokenType.Property,
TokenType.Event,
TokenType.Signature,
TokenType.ModuleRef,
TokenType.TypeSpec,
TokenType.Assembly,
TokenType.AssemblyRef,
TokenType.File,
TokenType.ExportedType,
TokenType.ManifestResource},
// HasFieldMarshal
new TokenType[] { TokenType.FieldDef,
TokenType.ParamDef },
// HasDeclSecurity
new TokenType[] { TokenType.TypeDef,
TokenType.MethodDef,
TokenType.Assembly },
// MemberRefParent
new TokenType[] { TokenType.TypeDef,
TokenType.TypeRef,
TokenType.ModuleRef,
TokenType.MethodDef,
TokenType.TypeSpec },
// HasSemantic
new TokenType[] { TokenType.Event,
TokenType.Property },
// MethodDefOrRef
new TokenType[] { TokenType.MethodDef,
TokenType.MemberRef },
// MemberForwarded
new TokenType[] { TokenType.FieldDef,
TokenType.MethodDef },
// Implementation
new TokenType[] { TokenType.File,
TokenType.AssemblyRef,
TokenType.ExportedType },
// CustomAttributeType
new TokenType[] { TokenType.TypeRef, // as per 3705: 0
TokenType.TypeDef, // as per 3705: 0
TokenType.MethodDef,
TokenType.MemberRef,
TokenType.String }, // as per 3705: 0
// ResolutionScope
new TokenType[] { TokenType.Module,
TokenType.ModuleRef,
TokenType.AssemblyRef,
TokenType.TypeRef },
// TypeOrMethodDef
new TokenType[] { TokenType.TypeDef,
TokenType.MethodDef },
// GenericParam
new TokenType[] { TokenType.GenericParam },
};
// static MetaDataLoader() {
// if ((int) TokenType.Module >> 24 != (int) MetaDataTableIndices.Module ||
// (int) TokenType.TypeRef >> 24 != (int) MetaDataTableIndices.TypeRef ||
// (int) TokenType.TypeDef >> 24 != (int) MetaDataTableIndices.TypeDef ||
// (int) TokenType.FieldDef >> 24 != (int) MetaDataTableIndices.Field ||
// (int) TokenType.MethodDef >> 24 != (int) MetaDataTableIndices.Method ||
// (int) TokenType.ParamDef >> 24 != (int) MetaDataTableIndices.Param ||
// (int) TokenType.InterfaceImpl >> 24 != (int) MetaDataTableIndices.InterfaceImpl ||
// (int) TokenType.MemberRef >> 24 != (int) MetaDataTableIndices.MemberRef ||
// (int) TokenType.CustomAttribute >> 24 != (int) MetaDataTableIndices.CustomAttribute ||
// (int) TokenType.Permission >> 24 != (int) MetaDataTableIndices.DeclSecurity ||
// (int) TokenType.Signature >> 24 != (int) MetaDataTableIndices.StandAloneSig ||
// (int) TokenType.Event >> 24 != (int) MetaDataTableIndices.Event ||
// (int) TokenType.Property >> 24 != (int) MetaDataTableIndices.Property ||
// (int) TokenType.ModuleRef >> 24 != (int) MetaDataTableIndices.ModuleRef ||
// (int) TokenType.TypeSpec >> 24 != (int) MetaDataTableIndices.TypeSpec ||
// (int) TokenType.Assembly >> 24 != (int) MetaDataTableIndices.Assembly ||
// (int) TokenType.AssemblyRef >> 24 != (int) MetaDataTableIndices.AssemblyRef ||
// (int) TokenType.File >> 24 != (int) MetaDataTableIndices.File ||
// (int) TokenType.ExportedType >> 24 != (int) MetaDataTableIndices.ExportedType ||
// (int) TokenType.ManifestResource >> 24 != (int) MetaDataTableIndices.ManifestResource) {
// throw new IllegalMetaDataFormatException("TBL invariant broken");
// }
// for (int i = 0; i < (int) MetaDataTableIndices.Count; i++) {
// if (TableColumnKinds[i].Length != TableColumnNames[i].Length) {
// throw new IllegalMetaDataFormatException("Column spec mismatch at "+i);
// }
// }
// }
protected enum MetaDataFormat: byte {
Invalid, ReadOnly, ReadWrite, ICR
}
protected enum MetaDataTableIndices: byte {
Module,
TypeRef,
TypeDef,
FieldPtr,
Field,
MethodPtr,
Method,
ParamPtr,
Param,
InterfaceImpl,
MemberRef,
Constant,
CustomAttribute,
FieldMarshal,
DeclSecurity,
ClassLayout,
FieldLayout,
StandAloneSig,
EventMap,
EventPtr,
Event,
PropertyMap,
PropertyPtr,
Property,
MethodSemantics,
MethodImpl,
ModuleRef,
TypeSpec,
ImplMap,
FieldRVA,
ENCLog,
ENCMap,
Assembly,
AssemblyProcessor,
AssemblyOS,
AssemblyRef,
AssemblyRefProcessor,
AssemblyRefOS,
File,
ExportedType,
ManifestResource,
NestedClass,
GenericParam,
MethodSpec,
GenericParamConstraint,
Count
}
internal enum TokenType: int {
Module = 0x00000000,
TypeRef = 0x01000000,
TypeDef = 0x02000000,
FieldDef = 0x04000000,
MethodDef = 0x06000000,
ParamDef = 0x08000000,
InterfaceImpl = 0x09000000,
MemberRef = 0x0a000000,
CustomAttribute = 0x0c000000,
Permission = 0x0e000000,
Signature = 0x11000000,
Event = 0x14000000,
Property = 0x17000000,
ModuleRef = 0x1a000000,
TypeSpec = 0x1b000000,
Assembly = 0x20000000,
AssemblyRef = 0x23000000,
File = 0x26000000,
ExportedType = 0x27000000,
ManifestResource = 0x28000000,
GenericParam = 0x2a000000,
String = 0x70000000,
Name = 0x71000000,
BaseType = 0x72000000
};
private enum ColumnKindId {
RowIdMax = 63,
CodedToken = 64,
CodedTokenMax = 95,
Short = 96,
UShort = 97,
Long = 98,
ULong = 99,
Byte = 100,
String = 101,
Guid = 102,
Blob = 103
};
private enum CodeToken: byte {
TypeDefOrRef,
HasConstant,
HasCustomAttribute,
HasFieldMarshal,
HasDeclSecurity,
MemberRefParent,
HasSemantic,
MethodDefOrRef,
MemberForwarded,
Implementation,
CustomAttributeType,
ResolutionScope,
TypeOrMethodDef,
GenericParam,
Count
};
private enum SymTag {
SymTagEnd = -1,
SymTagFunction,
SymTagLocal
};
// Nested Classes
private class StorageSignature {
// Constructor Methods
internal StorageSignature(Stream stream):
this(new BinaryReader(stream))
{
// Do nothing extra
}
internal StorageSignature(BinaryReader reader) {
this.signature = reader.ReadInt32();
this.majorVersion = reader.ReadInt16();
this.minorVersion = reader.ReadInt16();
this.extraData = reader.ReadInt32();
int length = reader.ReadInt32();
byte[] bytes = new byte[length];
reader.Read(bytes, 0, length);
char[] chars = new char[length];
for (int i = 0; i < length; i++) {
chars[i] = (char) bytes[i];
}
this.versionString = new String(chars);
if (this.signature != StorageSignature.STORAGE_MAGIC_SIG) {
throw new IllegalMetaDataFormatException("Don't know signature "+this.signature.ToString("x8"));
}
if (this.majorVersion != StorageSignature.FILE_MAJOR_VERSION ||
this.minorVersion != StorageSignature.FILE_MINOR_VERSION) {
throw new IllegalMetaDataFormatException("Unknown version");
}
}
// State
internal readonly int signature;
internal readonly short majorVersion;
internal readonly short minorVersion;
internal readonly int extraData;
internal readonly String versionString;
private const int STORAGE_MAGIC_SIG = 0x424A5342;
private const int FILE_MAJOR_VERSION = 1;
private const int FILE_MINOR_VERSION = 1;
}
private class StorageHeader {
// Constructor Methods
internal StorageHeader(Stream stream):
this(new BinaryReader(stream))
{ }
internal StorageHeader(BinaryReader reader) {
this.flags = reader.ReadByte();
this.pad = reader.ReadByte();
this.streamCount = reader.ReadInt16();
if ((this.flags & STGHDR_EXTRADATA) != 0) {
int count = reader.ReadInt32();
reader.ReadBytes(count);
}
}
// State
internal Byte flags;
internal Byte pad;
internal short streamCount;
internal const Byte STGHDR_EXTRADATA = 0x01;
}
private class StorageStream {
// Constructor Methods
internal StorageStream(Stream stream):
this(new BinaryReader(stream))
{ }
internal StorageStream(BinaryReader reader) {
this.offset = reader.ReadInt32();
this.size = reader.ReadInt32();
byte[] bytes = new byte[4];
int startIndex = 0;
bool foundEnd = false;
while (!foundEnd) {
int count = reader.Read(bytes, startIndex, 4);
int limit = startIndex + count;
for (int i = startIndex; i < limit; i++) {
if (bytes[i] == 0) {
foundEnd = true;
char[] chars = new char[i];
for (int j = 0; j < i; j++) {
chars[j] = (char) bytes[j];
}
this.name = new String(chars);
break;
}
}
startIndex = limit;
if (startIndex == bytes.Length) {
byte[] newBytes = new byte[2*startIndex];
for (int i = 0; i < startIndex; i++) {
newBytes[i] = bytes[i];
}
bytes = newBytes;
}
}
while (startIndex % 4 != 0) {
startIndex += reader.Read(bytes, 0, startIndex % 4);
}
}
// Output Methods
public override String ToString() {
return "StorageStream("+this.name+","+this.offset+","+this.size+")";
}
// State
internal int offset;
internal int size;
internal String name;
internal const String COMPRESSED_MODEL = "#~";
internal const String ENC_MODEL = "#-";
internal const String SCHEMA = "#Schema";
internal const String STRING_POOL = "#Strings";
internal const String BLOB_POOL = "#Blob";
internal const String USER_BLOB_POOL = "#US";
internal const String VARIANT_POOL = "#Variants";
internal const String GUID_POOL = "#GUID";
}
private class DebugEntry {
// Constructor Methods
internal DebugEntry(Stream stream):
this(new BinaryReader(stream))
{ }
internal DebugEntry(BinaryReader reader) {
this.characteristics = reader.ReadInt32();
this.timeDateStamp = reader.ReadInt32();
this.majorVersion = reader.ReadInt16();
this.minorVersion = reader.ReadInt16();
this.formatType = reader.ReadInt32();
this.sizeOfData = reader.ReadInt32();
this.addressOfRawData = reader.ReadInt32();
this.pointerToRawData = reader.ReadInt32();
}
// State
internal int characteristics;
internal int timeDateStamp;
internal short majorVersion;
internal short minorVersion;
internal int formatType;
internal int sizeOfData;
internal int addressOfRawData;
internal int pointerToRawData;
}
internal class IllegalMetaDataFormatException: Exception {
internal IllegalMetaDataFormatException(String reason):
base(reason)
{ }
}
}
}