// This function is used for debugging purposes only. internal void Dump(TreeNode curNode, int indent, ref PTHeap heap, ref StringHeap strHeap) { curNode.Print(indent, ref heap, ref strHeap); for (int i = 0; i < curNode.ChildCount; i++) { Dump(curNode.GetChild(i), indent + 1, ref heap, ref strHeap); } }
// This method is for debugging purposes only. internal void Print(int indent, ref PTHeap heap, ref StringHeap strHeap) { for (int i = 0; i < indent; i++) { Console.Write("\t"); } if (heap != null && strHeap != null && m_type != 0) { Console.Write(strHeap.ReadString(heap.m_tables[PTHeap.TYPEDEF_TABLE][m_type, PTHeap.TYPEDEF_NAMESPACE_COL]) + "." + strHeap.ReadString(heap.m_tables[PTHeap.TYPEDEF_TABLE][m_type, PTHeap.TYPEDEF_NAME_COL])); } else { Console.Write("type: " + m_type); } switch (m_outOfAssem) { case OUTOFASSEMBLY_NONE: Console.WriteLine("\tnone"); break; case OUTOFASSEMBLY_CLASS: Console.WriteLine("\tclass"); break; case OUTOFASSEMBLY_INTERFACE: Console.WriteLine("\tinterface"); break; case OUTOFASSEMBLY_BOTH: Console.WriteLine("\tboth"); break; default: break; } }
internal MetaDataRoot m_mdr; // MetaData Root table /********************************************************************************************************************* * 1) Parse the MetaData Root table. * * 2) Initialize the various heaps. * * 3) Initialize "m_oldNameHash", "m_classTree", and "m_freeSpaceList". * * 4) Initialize the various BitArrays. * * 5) Set the total numbers of the elements (types, methods, fields, properties, events, and parameters). *********************************************************************************************************************/ internal MetaData(ref byte[] buf) { int i, ptHeapIndex = -1; Exception toBeThrown; m_buffer = buf; // Ok. Now we can build a reader and a writer over the memory m_buffer. MemoryStream memStream = new MemoryStream(m_buffer); BinaryReader reader = new BinaryReader(memStream); BinaryWriter writer = new BinaryWriter(memStream); AllHeaders all = new AllHeaders(ref reader); NTHeader nth = all.m_ntHeader; SectionHeader[] sh = all.m_sectionHeaders; #if DEBUG0 Console.WriteLine("Runtime Header Data Directory"); Console.WriteLine("rva: " + nth.m_DataDirectory[14].RVA + "; size: " + nth.m_DataDirectory[14].Size + Environment.NewLine); Console.WriteLine("offset to MetaData section: " + (long)(nth.m_DataDirectory[14].RVA + 8)); #endif // Read the RVA of the physical MetaData section from the Runtime Header Data Directory. reader.BaseStream.Seek((long)(nth.m_DataDirectory[14].RVA + 8), SeekOrigin.Begin); m_startPos = reader.ReadUInt64(); // Theoretically, startPos can be 64 bit long, but in practice, 32 bits are enough. // TODO : Check the docs. The following assertion will fail. // Debug.Assert((startPos >> 32) == 0); m_startPos = m_startPos & 0xffffffff; // use the least significant 4 bytes as the offset m_mdr = new MetaDataRoot(ref reader, ref m_buffer, m_startPos); // We need to initialize the #Strings heap and the #Blob heap before dealing with the #~ heap. for (i = 0; i < m_mdr.m_numStreams; i++) { if (m_mdr.m_streamHeaders[i].name.Equals("#Strings\0")) { m_strHeap = new StringHeap(ref m_buffer, m_startPos + m_mdr.m_streamHeaders[i].offset, m_mdr.m_streamHeaders[i].size); } else if (m_mdr.m_streamHeaders[i].name.Equals("#Blob\0")) { m_blobHeap = new BlobHeap(ref m_buffer, m_startPos + m_mdr.m_streamHeaders[i].offset, m_mdr.m_streamHeaders[i].size); } else if (m_mdr.m_streamHeaders[i].name.Equals("#~\0") || m_mdr.m_streamHeaders[i].name.Equals("#-\0")) { ptHeapIndex = i; } } if (ptHeapIndex != -1) { m_heap = new PTHeap(ref reader, ref writer, ref m_strHeap, m_startPos + m_mdr.m_streamHeaders[ptHeapIndex].offset); } else { toBeThrown = new InvalidFileFormat("Invalid CIL binary file format."); throw toBeThrown; } }