public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false) { // This node does not trigger generation of other nodes. if (relocsOnly) { return(new ObjectData(Array.Empty <byte>(), Array.Empty <Relocation>(), 1, new ISymbolDefinitionNode[] { this })); } DebugInfoBlob debugData = GetDebugMethodInfoMap(factory); return(new ObjectData(debugData.ToArray(), Array.Empty <Relocation>(), 1, new ISymbolDefinitionNode[] { this })); }
public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false) { // This node does not trigger generation of other nodes. if (relocsOnly) { return(new ObjectData(Array.Empty <byte>(), Array.Empty <Relocation>(), 1, new ISymbolDefinitionNode[] { this })); } DebugInfoBlob debugData = GetDebugTypeIndexToTokenMap(factory.WindowsDebugData.DebugPseudoAssemblySection.PseudoAssembly, factory.WindowsDebugData.UserDefinedTypeDescriptor.CompleteKnownTypes); return(new ObjectData(debugData.ToArray(), Array.Empty <Relocation>(), 1, new ISymbolDefinitionNode[] { this })); }
public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false) { // This node does not trigger generation of other nodes. if (relocsOnly) { return(new ObjectData(Array.Empty <byte>(), Array.Empty <Relocation>(), 1, new ISymbolDefinitionNode[] { this })); } List <Relocation> relocations = new List <Relocation>(); DebugInfoBlob debugData = GetDebugMethodRVAToTokenMap(factory.WindowsDebugData.DebugPseudoAssemblySection.PseudoAssembly, factory.MetadataManager.GetCompiledMethodBodies(), out relocations); return(new ObjectData(debugData.ToArray(), relocations.ToArray(), 1, new ISymbolDefinitionNode[] { this })); }
public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false) { // This node does not trigger generation of other nodes. if (relocsOnly) { return(new ObjectData(Array.Empty <byte>(), Array.Empty <Relocation>(), 1, new ISymbolDefinitionNode[] { this })); } DebugInfoBlob debugBlob = new DebugInfoBlob(); foreach (MergedAssemblyRecord record in _mergedAssemblies.MergedAssemblies) { record.Encode(debugBlob); } byte [] _pdbBlob = debugBlob.ToArray(); Debug.Assert(_pdbBlob.Length > 0); return(new ObjectData(_pdbBlob, Array.Empty <Relocation>(), 1, new ISymbolDefinitionNode[] { this })); }
public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false) { // This node does not trigger generation of other nodes. if (relocsOnly) { return(new ObjectData(Array.Empty <byte>(), Array.Empty <Relocation>(), 1, new ISymbolDefinitionNode[] { this })); } ObjectDataBuilder objDataBuilder = new ObjectDataBuilder(factory, relocsOnly); // Emit number of dictionaries in table objDataBuilder.AddSymbol(this); IReadOnlyCollection <GenericDictionaryNode> dictionariesEmitted = factory.MetadataManager.GetCompiledGenericDictionaries(); objDataBuilder.EmitInt(dictionariesEmitted.Count); DebugInfoBlob signatureData = new DebugInfoBlob(); BlobBuilder signatureBlobBuilder = new BlobBuilder(); BlobBuilder signatureLenBuilder = new BlobBuilder(); ManagedBinaryEmitter pseudoAssembly = factory.WindowsDebugData.DebugPseudoAssemblySection.PseudoAssembly; foreach (GenericDictionaryNode dictionary in dictionariesEmitted) { objDataBuilder.EmitReloc(dictionary, RelocType.IMAGE_REL_BASED_ADDR32NB); objDataBuilder.EmitUInt(signatureData.Size()); signatureBlobBuilder.Clear(); int typeDictLen = dictionary.TypeInstantiation.IsNull ? 0 : dictionary.TypeInstantiation.Length; int methodDictLen = dictionary.MethodInstantiation.IsNull ? 0 : dictionary.MethodInstantiation.Length; signatureBlobBuilder.WriteCompressedInteger(typeDictLen + methodDictLen); if (typeDictLen != 0) { foreach (TypeDesc type in dictionary.TypeInstantiation) { pseudoAssembly.EncodeSignatureForType(type, signatureBlobBuilder); } } if (methodDictLen != 0) { foreach (TypeDesc type in dictionary.MethodInstantiation) { pseudoAssembly.EncodeSignatureForType(type, signatureBlobBuilder); } } int blobSize = signatureBlobBuilder.Count; signatureLenBuilder.Clear(); signatureLenBuilder.WriteCompressedInteger(blobSize); // Prepend the signature data with a length signatureData.WriteBuffer(signatureLenBuilder); // And then attach the actual signature data signatureData.WriteBuffer(signatureBlobBuilder); } // Attach signature information to end after all of the rva/offset pairs objDataBuilder.EmitBytes(signatureData.ToArray()); return(objDataBuilder.ToObjectData()); }
// returns the DEBUG_S_TYPE_MDTOKEN_MAP subsection as a byte array // DEBUG_S_TYPE_MDTOKEN_MAP subsection contains type-index to mdToken mapping // // contents of subsection: // offset 0, 4 bytes: count of entries in the map // offset 4, 8*N bytes: 4 byte type-index + 4 byte 'offset' relative to the start of 'type data' // offset 4+8*N, * bytes: ECMA formatted type signature packed sequentially with no padding // // 'offset' optimization: for type signatures with size<= 4-bytes // we can store the signature in offset field such that // offset = (1 << 31) | (sig[0] << 24 | sig[1] << 16 | sig[2] << 8 | sig[3]) // We chose this bit encoding because sig[0] holds the CorElementType whose // highest bit is always 0 and the highest bit of offset can be used as a flag // to indicate that it is not an offset but the signature itself. // // all entries are sorted by 'offset' field and so offset-based entries are arranged before other // (raw-signature) entries (since raw-signature entries are of the form 0x80000000 | signature, and will always be // numerically bigger than the offset) // private DebugInfoBlob GetDebugTypeIndexToTokenMap(ManagedBinaryEmitter pseudoAssembly, ICollection <KeyValuePair <TypeDesc, uint> > completeKnownTypes) { DebugInfoBlob typeDataBlob = new DebugInfoBlob(); DebugInfoBlob typeIndexToTokenMapBlob = new DebugInfoBlob(); List <KeyValuePair <uint, uint> > sigInOffsetEntries = new List <KeyValuePair <uint, uint> >(); typeIndexToTokenMapBlob.WriteDWORD(checked ((uint)completeKnownTypes.Count)); BlobBuilder blobBuilder = new BlobBuilder(); foreach (var entry in completeKnownTypes) { uint typeIndex = entry.Value; blobBuilder.Clear(); pseudoAssembly.EncodeSignatureForType(entry.Key, blobBuilder); // if signature fits in 4-bytes, store it in sigInOffsetEntries // otherwise store it in the type-data blob if (blobBuilder.Count <= 4) { uint sigInOffset = 0x80000000; int i = 0; // This is a slightly confusing approach, but this is how one iterates through the bytes in a blobBuilder without flattening it to a byte[] foreach (Blob blob in blobBuilder.GetBlobs()) { foreach (byte b in blob.GetBytes()) { sigInOffset |= ((uint)b) << (8 * (3 - i)); i++; } } // sigInOffsetEntries will be later sorted and appended to typeIndexToTokenMapBlob sigInOffsetEntries.Add(new KeyValuePair <uint, uint>(typeIndex, sigInOffset)); } else { typeIndexToTokenMapBlob.WriteDWORD(typeIndex); typeIndexToTokenMapBlob.WriteDWORD(typeDataBlob.Size()); typeDataBlob.WriteBuffer(blobBuilder); } } // sort sigInOffsetEntries based on sigInOffset sigInOffsetEntries.Sort((KeyValuePair <uint, uint> left, KeyValuePair <uint, uint> right) => { if (left.Value < right.Value) { return(-1); } if (left.Value == right.Value) { return(0); } return(1); }); // write the sorted sigInOffsetEntries foreach (KeyValuePair <uint, uint> sigInOffsetEntry in sigInOffsetEntries) { typeIndexToTokenMapBlob.WriteDWORD(sigInOffsetEntry.Key); typeIndexToTokenMapBlob.WriteDWORD(sigInOffsetEntry.Value); } // add typeDataBlob to the end of m_typeIndexToTokenMapBlob typeIndexToTokenMapBlob.WriteBuffer(typeDataBlob.ToArray()); return(typeIndexToTokenMapBlob); }