Ejemplo n.º 1
0
        private void PopulateDependenciesInternal(IDictionary <string, FileNode> allFiles, bool preferNativeImage, ILog log, Stack <FileNode> stack)
        {
            if (stack == null)
            {
                stack = new Stack <FileNode>();
            }

            stack.Push(this);

            if (dependencies != null)
            {
                // re-entrant call indicates a cycle, bail
                log.LogMessage($"Cycle detected: {String.Join(" -> ", stack)}");
                stack.Pop();
                return;
            }

            dependencies = new HashSet <FileNode>();

            try
            {
                using (var peReader = new PEReader(new FileStream(SourceFile, FileMode.Open, FileAccess.Read, FileShare.Delete | FileShare.Read)))
                {
                    if (peReader.HasMetadata)
                    {
                        var reader = peReader.GetMetadataReader();

                        var includeDependencies = true;

                        // map of facade handles to enable quickly getting to FileNode without repeatedly looking up by name
                        var facadeHandles = new Dictionary <AssemblyReferenceHandle, FileNode>();

                        if (IsFullFacade(reader))
                        {
                            // don't include dependencies in full facades.  We'll instead follow their typeforwards and promote the dependencies to the parent.
                            includeDependencies = false;

                            // follow typeforwards in any full facade.
                            followTypeForwards = true;
                        }

                        foreach (var handle in reader.AssemblyReferences)
                        {
                            var reference     = reader.GetAssemblyReference(handle);
                            var referenceName = reader.GetString(reference.Name);

                            FileNode referencedFile = TryGetFileForReference(referenceName, allFiles, preferNativeImage);

                            if (referencedFile != null)
                            {
                                if (includeDependencies)
                                {
                                    dependencies.Add(referencedFile);
                                }

                                // populate dependencies of child
                                referencedFile.PopulateDependenciesInternal(allFiles, preferNativeImage, log, stack);

                                // if we're following type-forwards out of any dependency make sure to look at typerefs from this assembly.
                                // and populate the type-forwards in the dependency
                                if (referencedFile.followTypeForwards || followTypeForwards)
                                {
                                    facadeHandles.Add(handle, referencedFile);
                                }
                            }
                            else
                            {
                                // static dependency that wasn't satisfied, this can happen if folks use
                                // lightup code to guard the static dependency.
                                // this can also happen when referencing a package that isn't implemented
                                // on this platform but don't fail the build here
                                log.LogMessage(LogImportance.Low, $"Could not locate assembly dependency {referenceName} of {SourceFile}.");
                            }
                        }

                        if (followTypeForwards)
                        {
                            // if following typeforwards out of this assembly, capture all type forwards
                            foreach (var exportedTypeHandle in reader.ExportedTypes)
                            {
                                var exportedType = reader.GetExportedType(exportedTypeHandle);

                                if (exportedType.IsForwarder)
                                {
                                    var      assemblyReferenceHandle = (AssemblyReferenceHandle)exportedType.Implementation;
                                    FileNode assemblyReferenceNode;

                                    if (facadeHandles.TryGetValue(assemblyReferenceHandle, out assemblyReferenceNode))
                                    {
                                        var typeName = exportedType.Namespace.IsNil ?
                                                       reader.GetString(exportedType.Name) :
                                                       reader.GetString(exportedType.Namespace) + reader.GetString(exportedType.Name);

                                        typeForwards.Add(typeName, assemblyReferenceNode);
                                    }
                                }
                            }
                        }
                        else if (facadeHandles.Count > 0)
                        {
                            // if examining type forwards in some dependency, enumerate type-refs
                            // for any that point at a facade assembly.

                            foreach (var typeReferenceHandle in reader.TypeReferences)
                            {
                                var typeReference   = reader.GetTypeReference(typeReferenceHandle);
                                var resolutionScope = typeReference.ResolutionScope;

                                if (resolutionScope.Kind == HandleKind.AssemblyReference)
                                {
                                    var      assemblyReferenceHandle = (AssemblyReferenceHandle)resolutionScope;
                                    FileNode assemblyReferenceNode;

                                    if (facadeHandles.TryGetValue(assemblyReferenceHandle, out assemblyReferenceNode))
                                    {
                                        var typeName = typeReference.Namespace.IsNil ?
                                                       reader.GetString(typeReference.Name) :
                                                       reader.GetString(typeReference.Namespace) + reader.GetString(typeReference.Name);

                                        FileNode typeForwardedToNode = null;

                                        var forwardAssemblies = new Stack <FileNode>();

                                        // while assembly forwarded to is also a facade, add a dependency on the target
                                        while (assemblyReferenceNode.followTypeForwards)
                                        {
                                            if (!assemblyReferenceNode.typeForwards.TryGetValue(typeName, out typeForwardedToNode))
                                            {
                                                break;
                                            }

                                            dependencies.Add(typeForwardedToNode);
                                            forwardAssemblies.Push(assemblyReferenceNode);

                                            // look at the target in case it is also a facade
                                            assemblyReferenceNode = typeForwardedToNode;

                                            if (forwardAssemblies.Contains(assemblyReferenceNode))
                                            {
                                                // type-forward cycle, bail
                                                log.LogMessage($"Cycle detected involving type-forwards: {String.Join(" -> ", forwardAssemblies)}");
                                                break;
                                            }
                                        }
                                    }
                                }
                            }
                        }

                        // examine native module dependencies
                        for (int i = 1, count = reader.GetTableRowCount(TableIndex.ModuleRef); i <= count; i++)
                        {
                            var moduleRef  = reader.GetModuleReference(MetadataTokens.ModuleReferenceHandle(i));
                            var moduleName = reader.GetString(moduleRef.Name);

                            var moduleRefCandidates = new[] { moduleName, moduleName + ".dll", moduleName + ".so", moduleName + ".dylib" };

                            FileNode referencedNativeFile = null;
                            foreach (var moduleRefCandidate in moduleRefCandidates)
                            {
                                if (allFiles.TryGetValue(moduleRefCandidate, out referencedNativeFile))
                                {
                                    break;
                                }
                            }

                            if (referencedNativeFile != null)
                            {
                                dependencies.Add(referencedNativeFile);
                            }
                            else
                            {
                                // DLLImport that wasn't satisfied
                            }
                        }
                    }
                }
            }
            catch (BadImageFormatException)
            {
                // not a PE
            }

            // allow for components to specify their dependencies themselves, by placing a file next to their source file.
            var additionalDependenciesFile = SourceFile + AdditionalDependenciesFileSuffix;

            if (File.Exists(additionalDependenciesFile))
            {
                foreach (var additionalDependency in File.ReadAllLines(additionalDependenciesFile))
                {
                    if (additionalDependency.Length == 0 || additionalDependency[0] == '#')
                    {
                        continue;
                    }

                    FileNode additionalDependencyFile;
                    if (allFiles.TryGetValue(additionalDependency, out additionalDependencyFile))
                    {
                        dependencies.Add(additionalDependencyFile);
                    }
                    else
                    {
                        log.LogMessage(LogImportance.Low, $"Could not locate explicit dependency {additionalDependency} of {SourceFile} specified in {additionalDependenciesFile}.");
                    }
                }
            }

            stack.Pop();
        }
Ejemplo n.º 2
0
 public static int ToResolutionScope(EntityHandle handle) => MetadataTokens.GetRowNumber(handle).ToCodedIndex(ToResolutionScopeTag(handle.Kind));
Ejemplo n.º 3
0
 public static int ToTypeOrMethodDef(EntityHandle handle) => MetadataTokens.GetRowNumber(handle).ToCodedIndex(ToTypeOrMethodDefTag(handle.Kind));
Ejemplo n.º 4
0
 public static int ToHasSemantics(EntityHandle handle) => MetadataTokens.GetRowNumber(handle).ToCodedIndex(ToHasSemanticsTag(handle.Kind));
Ejemplo n.º 5
0
 public static int ToMemberForwarded(EntityHandle handle) => MetadataTokens.GetRowNumber(handle).ToCodedIndex(ToMemberForwardedTag(handle.Kind));
Ejemplo n.º 6
0
 public static void VerifyPdb(this CompilationDifference diff, IEnumerable <MethodDefinitionHandle> methodHandles, XElement expectedPdb)
 {
     VerifyPdb(diff, methodHandles.Select(h => MetadataTokens.GetToken(h)), expectedPdb);
 }
Ejemplo n.º 7
0
 public static int ToHasDeclSecurity(EntityHandle handle) => MetadataTokens.GetRowNumber(handle).ToCodedIndex(ToHasDeclSecurityTag(handle.Kind));
Ejemplo n.º 8
0
        protected virtual void WriteInstruction(ITextOutput output, MetadataReader metadata, MethodDefinitionHandle methodHandle, ref BlobReader blob, int methodRva)
        {
            int offset = blob.Offset;

            if (ShowSequencePoints && nextSequencePointIndex < sequencePoints?.Count)
            {
                var sp = sequencePoints[nextSequencePointIndex];
                if (sp.Offset <= offset)
                {
                    output.Write("// sequence point: ");
                    if (sp.Offset != offset)
                    {
                        output.Write("!! at " + DisassemblerHelpers.OffsetToString(sp.Offset) + " !!");
                    }
                    if (sp.IsHidden)
                    {
                        output.WriteLine("hidden");
                    }
                    else
                    {
                        output.WriteLine($"(line {sp.StartLine}, col {sp.StartColumn}) to (line {sp.EndLine}, col {sp.EndColumn}) in {sp.DocumentUrl}");
                    }
                    nextSequencePointIndex++;
                }
            }
            ILOpCode opCode = ILParser.DecodeOpCode(ref blob);

            if (opCode.IsDefined())
            {
                WriteRVA(blob, offset + methodRva, opCode);
                output.WriteLocalReference(DisassemblerHelpers.OffsetToString(offset), offset, isDefinition: true);
                output.Write(": ");
                WriteOpCode(opCode);
                switch (opCode.GetOperandType())
                {
                case OperandType.BrTarget:
                case OperandType.ShortBrTarget:
                    output.Write(' ');
                    int targetOffset = ILParser.DecodeBranchTarget(ref blob, opCode);
                    output.WriteLocalReference($"IL_{targetOffset:x4}", targetOffset);
                    break;

                case OperandType.Field:
                case OperandType.Method:
                case OperandType.Sig:
                case OperandType.Type:
                    output.Write(' ');
                    int          metadataToken = blob.ReadInt32();
                    EntityHandle?handle        = MetadataTokenHelpers.TryAsEntityHandle(metadataToken);
                    try
                    {
                        handle?.WriteTo(module, output, genericContext);
                    }
                    catch (BadImageFormatException)
                    {
                        handle = null;
                    }
                    WriteMetadataToken(handle, metadataToken, spaceBefore: true);
                    break;

                case OperandType.Tok:
                    output.Write(' ');
                    metadataToken = blob.ReadInt32();
                    handle        = MetadataTokenHelpers.TryAsEntityHandle(metadataToken);
                    switch (handle?.Kind)
                    {
                    case HandleKind.MemberReference:
                        switch (metadata.GetMemberReference((MemberReferenceHandle)handle).GetKind())
                        {
                        case MemberReferenceKind.Method:
                            output.Write("method ");
                            break;

                        case MemberReferenceKind.Field:
                            output.Write("field ");
                            break;
                        }
                        break;

                    case HandleKind.FieldDefinition:
                        output.Write("field ");
                        break;

                    case HandleKind.MethodDefinition:
                        output.Write("method ");
                        break;
                    }
                    try
                    {
                        handle?.WriteTo(module, output, genericContext);
                    }
                    catch (BadImageFormatException)
                    {
                        handle = null;
                    }
                    WriteMetadataToken(handle, metadataToken, spaceBefore: true);
                    break;

                case OperandType.ShortI:
                    output.Write(' ');
                    DisassemblerHelpers.WriteOperand(output, blob.ReadSByte());
                    break;

                case OperandType.I:
                    output.Write(' ');
                    DisassemblerHelpers.WriteOperand(output, blob.ReadInt32());
                    break;

                case OperandType.I8:
                    output.Write(' ');
                    DisassemblerHelpers.WriteOperand(output, blob.ReadInt64());
                    break;

                case OperandType.ShortR:
                    output.Write(' ');
                    DisassemblerHelpers.WriteOperand(output, blob.ReadSingle());
                    break;

                case OperandType.R:
                    output.Write(' ');
                    DisassemblerHelpers.WriteOperand(output, blob.ReadDouble());
                    break;

                case OperandType.String:
                    metadataToken = blob.ReadInt32();
                    output.Write(' ');
                    UserStringHandle?userString;
                    string           text;
                    try
                    {
                        userString = MetadataTokens.UserStringHandle(metadataToken);
                        text       = metadata.GetUserString(userString.Value);
                    }
                    catch (BadImageFormatException)
                    {
                        userString = null;
                        text       = null;
                    }
                    if (userString != null)
                    {
                        DisassemblerHelpers.WriteOperand(output, text);
                    }
                    WriteMetadataToken(userString, metadataToken, spaceBefore: true);
                    break;

                case OperandType.Switch:
                    var   tmp     = blob;
                    int[] targets = ILParser.DecodeSwitchTargets(ref blob);
                    if (ShowRawRVAOffsetAndBytes)
                    {
                        output.WriteLine(" (");
                    }
                    else
                    {
                        output.Write(" (");
                    }
                    tmp.ReadInt32();
                    for (int i = 0; i < targets.Length; i++)
                    {
                        if (i > 0)
                        {
                            if (ShowRawRVAOffsetAndBytes)
                            {
                                output.WriteLine(",");
                            }
                            else
                            {
                                output.Write(", ");
                            }
                        }
                        if (ShowRawRVAOffsetAndBytes)
                        {
                            output.Write("/*              ");
                            output.Write($"{tmp.ReadByte():X2}{tmp.ReadByte():X2}{tmp.ReadByte():X2}{tmp.ReadByte():X2}");
                            output.Write("         */ ");
                        }
                        if (ShowRawRVAOffsetAndBytes)
                        {
                            output.Write("                 ");
                        }
                        output.WriteLocalReference($"IL_{targets[i]:x4}", targets[i]);
                    }
                    output.Write(")");
                    break;

                case OperandType.Variable:
                    output.Write(' ');
                    int index = blob.ReadUInt16();
                    if (opCode == ILOpCode.Ldloc || opCode == ILOpCode.Ldloca || opCode == ILOpCode.Stloc)
                    {
                        DisassemblerHelpers.WriteVariableReference(output, metadata, methodHandle, index);
                    }
                    else
                    {
                        DisassemblerHelpers.WriteParameterReference(output, metadata, methodHandle, index);
                    }
                    break;

                case OperandType.ShortVariable:
                    output.Write(' ');
                    index = blob.ReadByte();
                    if (opCode == ILOpCode.Ldloc_s || opCode == ILOpCode.Ldloca_s || opCode == ILOpCode.Stloc_s)
                    {
                        DisassemblerHelpers.WriteVariableReference(output, metadata, methodHandle, index);
                    }
                    else
                    {
                        DisassemblerHelpers.WriteParameterReference(output, metadata, methodHandle, index);
                    }
                    break;
                }
            }
            else
            {
                ushort opCodeValue = (ushort)opCode;
                if (opCodeValue > 0xFF)
                {
                    if (ShowRawRVAOffsetAndBytes)
                    {
                        output.Write("/* ");
                        output.Write($"0x{offset + methodRva:X8} {(ushort)opCode >> 8:X2}");
                        output.Write("                 */ ");
                    }
                    output.WriteLocalReference(DisassemblerHelpers.OffsetToString(offset), offset, isDefinition: true);
                    output.Write(": ");
                    // split 16-bit value into two emitbyte directives
                    output.WriteLine($".emitbyte 0x{(byte)(opCodeValue >> 8):x}");
                    if (ShowRawRVAOffsetAndBytes)
                    {
                        output.Write("/* ");
                        output.Write($"0x{offset + methodRva + 1:X8} {(ushort)opCode & 0xFF:X2}");
                        output.Write("                 */ ");
                    }
                    // add label
                    output.WriteLocalReference(DisassemblerHelpers.OffsetToString(offset + 1), offset + 1, isDefinition: true);
                    output.Write(": ");
                    output.Write($".emitbyte 0x{(byte)(opCodeValue & 0xFF):x}");
                }
                else
                {
                    if (ShowRawRVAOffsetAndBytes)
                    {
                        output.Write("/* ");
                        output.Write($"0x{offset + methodRva:X8} {(ushort)opCode & 0xFF:X2}");
                        output.Write("                 */ ");
                    }
                    output.WriteLocalReference(DisassemblerHelpers.OffsetToString(offset), offset, isDefinition: true);
                    output.Write(": ");
                    output.Write($".emitbyte 0x{(byte)opCodeValue:x}");
                }
            }
            output.WriteLine();
        }
Ejemplo n.º 9
0
 private void WriteMetadataToken(EntityHandle handle, bool spaceBefore)
 {
     WriteMetadataToken(handle, MetadataTokens.GetToken(handle), spaceBefore);
 }
Ejemplo n.º 10
0
        /// <summary>
        /// Read the EH clause from a given file offset in the PE image.
        /// </summary>
        /// <param name="reader">R2R image reader<param>
        /// <param name="offset">Offset of the EH clause in the image</param>
        public EHClause(ReadyToRunReader reader, int offset)
        {
            Flags                    = (CorExceptionFlag)BitConverter.ToUInt32(reader.Image, offset + 0 * sizeof(uint));
            TryOffset                = BitConverter.ToUInt32(reader.Image, offset + 1 * sizeof(uint));
            TryEnd                   = BitConverter.ToUInt32(reader.Image, offset + 2 * sizeof(uint));
            HandlerOffset            = BitConverter.ToUInt32(reader.Image, offset + 3 * sizeof(uint));
            HandlerEnd               = BitConverter.ToUInt32(reader.Image, offset + 4 * sizeof(uint));
            ClassTokenOrFilterOffset = BitConverter.ToUInt32(reader.Image, offset + 5 * sizeof(uint));

            if ((Flags & CorExceptionFlag.COR_ILEXCEPTION_CLAUSE_KIND_MASK) == CorExceptionFlag.COR_ILEXCEPTION_CLAUSE_NONE)
            {
                ClassName = MetadataNameFormatter.FormatHandle(reader.MetadataReader, MetadataTokens.Handle((int)ClassTokenOrFilterOffset));
            }
        }
Ejemplo n.º 11
0
        internal override void DumpSectionContents(ReadyToRunSection section)
        {
            switch (section.Type)
            {
            case ReadyToRunSectionType.AvailableTypes:
                if (!_options.Naked)
                {
                    uint            availableTypesSectionOffset = (uint)_r2r.GetOffset(section.RelativeVirtualAddress);
                    NativeParser    availableTypesParser        = new NativeParser(_r2r.Image, availableTypesSectionOffset);
                    NativeHashtable availableTypes = new NativeHashtable(_r2r.Image, availableTypesParser, (uint)(availableTypesSectionOffset + section.Size));
                    _writer.WriteLine(availableTypes.ToString());
                }

                int assemblyIndex1 = _r2r.GetAssemblyIndex(section);
                if (assemblyIndex1 != -1)
                {
                    _writer.WriteLine();
                    foreach (string name in _r2r.ReadyToRunAssemblies[assemblyIndex1].AvailableTypes)
                    {
                        _writer.WriteLine(name);
                    }
                }
                break;

            case ReadyToRunSectionType.MethodDefEntryPoints:
                if (!_options.Naked)
                {
                    NativeArray methodEntryPoints = new NativeArray(_r2r.Image, (uint)_r2r.GetOffset(section.RelativeVirtualAddress));
                    _writer.Write(methodEntryPoints.ToString());
                }

                int assemblyIndex2 = _r2r.GetAssemblyIndex(section);
                if (assemblyIndex2 != -1)
                {
                    _writer.WriteLine();
                    foreach (ReadyToRunMethod method in _r2r.ReadyToRunAssemblies[assemblyIndex2].Methods)
                    {
                        _writer.WriteLine($@"{MetadataTokens.GetToken(method.MethodHandle):X8}: {method.SignatureString}");
                    }
                }
                break;

            case ReadyToRunSectionType.InstanceMethodEntryPoints:
                if (!_options.Naked)
                {
                    uint            instanceSectionOffset = (uint)_r2r.GetOffset(section.RelativeVirtualAddress);
                    NativeParser    instanceParser        = new NativeParser(_r2r.Image, instanceSectionOffset);
                    NativeHashtable instMethodEntryPoints = new NativeHashtable(_r2r.Image, instanceParser, (uint)(instanceSectionOffset + section.Size));
                    _writer.Write(instMethodEntryPoints.ToString());
                    _writer.WriteLine();
                }
                foreach (InstanceMethod instanceMethod in _r2r.InstanceMethods)
                {
                    _writer.WriteLine($@"0x{instanceMethod.Bucket:X2} -> {instanceMethod.Method.SignatureString}");
                }
                break;

            case ReadyToRunSectionType.RuntimeFunctions:
                int rtfOffset    = _r2r.GetOffset(section.RelativeVirtualAddress);
                int rtfEndOffset = rtfOffset + section.Size;
                int rtfIndex     = 0;
                _writer.WriteLine("  Index | StartRVA |  EndRVA  | UnwindRVA");
                _writer.WriteLine("-----------------------------------------");
                while (rtfOffset < rtfEndOffset)
                {
                    int startRva = NativeReader.ReadInt32(_r2r.Image, ref rtfOffset);
                    int endRva   = -1;
                    if (_r2r.Machine == Machine.Amd64)
                    {
                        endRva = NativeReader.ReadInt32(_r2r.Image, ref rtfOffset);
                    }
                    int    unwindRva  = NativeReader.ReadInt32(_r2r.Image, ref rtfOffset);
                    string endRvaText = (endRva != -1 ? endRva.ToString("x8") : "        ");
                    _writer.WriteLine($"{rtfIndex,7} | {startRva:X8} | {endRvaText} | {unwindRva:X8}");
                    rtfIndex++;
                }
                break;

            case ReadyToRunSectionType.CompilerIdentifier:
                _writer.WriteLine(_r2r.CompilerIdentifier);
                break;

            case ReadyToRunSectionType.ImportSections:
                if (_options.Naked)
                {
                    DumpNakedImportSections();
                }
                else
                {
                    foreach (ReadyToRunImportSection importSection in _r2r.ImportSections)
                    {
                        importSection.WriteTo(_writer);
                        if (_options.Raw && importSection.Entries.Count != 0)
                        {
                            if (importSection.SectionRVA != 0)
                            {
                                _writer.WriteLine("Section Bytes:");
                                DumpBytes(importSection.SectionRVA, (uint)importSection.SectionSize);
                            }
                            if (importSection.SignatureRVA != 0)
                            {
                                _writer.WriteLine("Signature Bytes:");
                                DumpBytes(importSection.SignatureRVA, (uint)importSection.Entries.Count * sizeof(int));
                            }
                            if (importSection.AuxiliaryDataRVA != 0 && importSection.AuxiliaryDataSize != 0)
                            {
                                _writer.WriteLine("AuxiliaryData Bytes:");
                                DumpBytes(importSection.AuxiliaryDataRVA, (uint)importSection.AuxiliaryDataSize);
                            }
                        }
                        foreach (ReadyToRunImportSection.ImportSectionEntry entry in importSection.Entries)
                        {
                            entry.WriteTo(_writer, _options);
                            _writer.WriteLine();
                        }
                        _writer.WriteLine();
                    }
                }
                break;

            case ReadyToRunSectionType.ManifestMetadata:
                int assemblyRefCount = 0;
                if (!_r2r.Composite)
                {
                    MetadataReader globalReader = _r2r.GetGlobalMetadata().MetadataReader;
                    assemblyRefCount = globalReader.GetTableRowCount(TableIndex.AssemblyRef) + 1;
                    _writer.WriteLine($"MSIL AssemblyRef's ({assemblyRefCount} entries):");
                    for (int assemblyRefIndex = 1; assemblyRefIndex < assemblyRefCount; assemblyRefIndex++)
                    {
                        AssemblyReference assemblyRef     = globalReader.GetAssemblyReference(MetadataTokens.AssemblyReferenceHandle(assemblyRefIndex));
                        string            assemblyRefName = globalReader.GetString(assemblyRef.Name);
                        _writer.WriteLine($"[ID 0x{assemblyRefIndex:X2}]: {assemblyRefName}");
                    }
                }

                _writer.WriteLine($"Manifest metadata AssemblyRef's ({_r2r.ManifestReferenceAssemblies.Count} entries):");
                int manifestAsmIndex = 0;
                foreach (string manifestReferenceAssembly in _r2r.ManifestReferenceAssemblies.OrderBy(kvp => kvp.Value).Select(kvp => kvp.Key))
                {
                    _writer.WriteLine($"[ID 0x{manifestAsmIndex + assemblyRefCount + 1:X2}]: {manifestReferenceAssembly}");
                    manifestAsmIndex++;
                }
                break;

            case ReadyToRunSectionType.AttributePresence:
                int attributesStartOffset     = _r2r.GetOffset(section.RelativeVirtualAddress);
                int attributesEndOffset       = attributesStartOffset + section.Size;
                NativeCuckooFilter attributes = new NativeCuckooFilter(_r2r.Image, attributesStartOffset, attributesEndOffset);
                _writer.WriteLine("Attribute presence filter");
                _writer.WriteLine(attributes.ToString());
                break;

            case ReadyToRunSectionType.InliningInfo:
                int iiOffset    = _r2r.GetOffset(section.RelativeVirtualAddress);
                int iiEndOffset = iiOffset + section.Size;
                InliningInfoSection inliningInfoSection = new InliningInfoSection(_r2r, iiOffset, iiEndOffset);
                _writer.WriteLine(inliningInfoSection.ToString());
                break;

            case ReadyToRunSectionType.InliningInfo2:
                int ii2Offset    = _r2r.GetOffset(section.RelativeVirtualAddress);
                int ii2EndOffset = ii2Offset + section.Size;
                InliningInfoSection2 inliningInfoSection2 = new InliningInfoSection2(_r2r, ii2Offset, ii2EndOffset);
                _writer.WriteLine(inliningInfoSection2.ToString());
                break;

            case ReadyToRunSectionType.OwnerCompositeExecutable:
                int oceOffset = _r2r.GetOffset(section.RelativeVirtualAddress);
                if (_r2r.Image[oceOffset + section.Size - 1] != 0)
                {
                    R2RDump.WriteWarning("String is not zero-terminated");
                }
                string ownerCompositeExecutable = Encoding.UTF8.GetString(_r2r.Image, oceOffset, section.Size - 1);     // exclude the zero terminator
                _writer.WriteLine("Composite executable: {0}", ownerCompositeExecutable.ToEscapedString());
                break;

            case ReadyToRunSectionType.ManifestAssemblyMvids:
                int mvidCount = section.Size / ReadyToRunReader.GuidByteSize;
                for (int mvidIndex = 0; mvidIndex < mvidCount; mvidIndex++)
                {
                    _writer.WriteLine("MVID[{0}] = {1:b}", mvidIndex, _r2r.GetAssemblyMvid(mvidIndex));
                }
                break;

            default:
                _writer.WriteLine("Unsupported section type {0}", section.Type);
                break;
            }
        }
Ejemplo n.º 12
0
 public unsafe ClassLayout(byte *ptr, int typeDefSize)
 {
     PackingSize = (ushort)Helpers.GetValue(ptr, 2);
     ClassSize   = (uint)Helpers.GetValue(ptr + 2, 4);
     Parent      = MetadataTokens.TypeDefinitionHandle(Helpers.GetValue(ptr + 6, typeDefSize));
 }
Ejemplo n.º 13
0
 internal static PENamedTypeSymbol GetType(this CSharpCompilation compilation, Guid moduleVersionId, int typeToken)
 {
     return(GetType(compilation.GetModule(moduleVersionId), (TypeDefinitionHandle)MetadataTokens.Handle(typeToken)));
 }
Ejemplo n.º 14
0
        internal static bool WritePeToStream(
            EmitContext context,
            CommonMessageProvider messageProvider,
            Func <Stream> getPeStream,
            Func <Stream> getPortablePdbStreamOpt,
            PdbWriter nativePdbWriterOpt,
            string pdbPathOpt,
            bool metadataOnly,
            bool isDeterministic,
            bool emitTestCoverageData,
            RSAParameters?privateKeyOpt,
            CancellationToken cancellationToken)
        {
            // If PDB writer is given, we have to have PDB path.
            Debug.Assert(nativePdbWriterOpt == null || pdbPathOpt != null);

            var mdWriter = FullMetadataWriter.Create(context, messageProvider, metadataOnly, isDeterministic,
                                                     emitTestCoverageData, getPortablePdbStreamOpt != null, cancellationToken);

            var properties = context.Module.SerializationProperties;

            nativePdbWriterOpt?.SetMetadataEmitter(mdWriter);

            // Since we are producing a full assembly, we should not have a module version ID
            // imposed ahead-of time. Instead we will compute a deterministic module version ID
            // based on the contents of the generated stream.
            Debug.Assert(properties.PersistentIdentifier == default(Guid));

            var ilBuilder = new BlobBuilder(32 * 1024);
            var mappedFieldDataBuilder = new BlobBuilder();
            var managedResourceBuilder = new BlobBuilder(1024);

            Blob mvidFixup, mvidStringFixup;

            mdWriter.BuildMetadataAndIL(
                nativePdbWriterOpt,
                ilBuilder,
                mappedFieldDataBuilder,
                managedResourceBuilder,
                out mvidFixup,
                out mvidStringFixup);

            MethodDefinitionHandle entryPointHandle;
            MethodDefinitionHandle debugEntryPointHandle;

            mdWriter.GetEntryPoints(out entryPointHandle, out debugEntryPointHandle);

            if (!debugEntryPointHandle.IsNil)
            {
                nativePdbWriterOpt?.SetEntryPoint(MetadataTokens.GetToken(debugEntryPointHandle));
            }

            if (nativePdbWriterOpt != null)
            {
                if (context.Module.SourceLinkStreamOpt != null)
                {
                    nativePdbWriterOpt.EmbedSourceLink(context.Module.SourceLinkStreamOpt);
                }

                if (mdWriter.Module.OutputKind == OutputKind.WindowsRuntimeMetadata)
                {
                    // Dev12: If compiling to winmdobj, we need to add to PDB source spans of
                    //        all types and members for better error reporting by WinMDExp.
                    nativePdbWriterOpt.WriteDefinitionLocations(mdWriter.Module.GetSymbolToLocationMap());
                }
                else
                {
#if DEBUG
                    // validate that all definitions are writable
                    // if same scenario would happen in an winmdobj project
                    nativePdbWriterOpt.AssertAllDefinitionsHaveTokens(mdWriter.Module.GetSymbolToLocationMap());
#endif
                }

                nativePdbWriterOpt.WriteRemainingEmbeddedDocuments(mdWriter.Module.DebugDocumentsBuilder.EmbeddedDocuments);
            }

            Stream peStream = getPeStream();
            if (peStream == null)
            {
                return(false);
            }

            BlobContentId pdbContentId = nativePdbWriterOpt?.GetContentId() ?? default;

            // the writer shall not be used after this point for writing:
            nativePdbWriterOpt = null;

            ushort portablePdbVersion  = 0;
            var    metadataRootBuilder = mdWriter.GetRootBuilder();

            var peHeaderBuilder = new PEHeaderBuilder(
                machine: properties.Machine,
                sectionAlignment: properties.SectionAlignment,
                fileAlignment: properties.FileAlignment,
                imageBase: properties.BaseAddress,
                majorLinkerVersion: properties.LinkerMajorVersion,
                minorLinkerVersion: properties.LinkerMinorVersion,
                majorOperatingSystemVersion: 4,
                minorOperatingSystemVersion: 0,
                majorImageVersion: 0,
                minorImageVersion: 0,
                majorSubsystemVersion: properties.MajorSubsystemVersion,
                minorSubsystemVersion: properties.MinorSubsystemVersion,
                subsystem: properties.Subsystem,
                dllCharacteristics: properties.DllCharacteristics,
                imageCharacteristics: properties.ImageCharacteristics,
                sizeOfStackReserve: properties.SizeOfStackReserve,
                sizeOfStackCommit: properties.SizeOfStackCommit,
                sizeOfHeapReserve: properties.SizeOfHeapReserve,
                sizeOfHeapCommit: properties.SizeOfHeapCommit);

            var peIdProvider = isDeterministic ?
                               new Func <IEnumerable <Blob>, BlobContentId>(content => BlobContentId.FromHash(CryptographicHashProvider.ComputeSourceHash(content))) :
                               null;

            // We need to calculate the PDB checksum, so we may as well use the calculated hash for PDB ID regardless of whether deterministic build is requested.
            var portablePdbContentHash = default(ImmutableArray <byte>);

            BlobBuilder portablePdbToEmbed = null;
            if (mdWriter.EmitPortableDebugMetadata)
            {
                mdWriter.AddRemainingEmbeddedDocuments(mdWriter.Module.DebugDocumentsBuilder.EmbeddedDocuments);

                // The algorithm must be specified for deterministic builds (checked earlier).
                Debug.Assert(!isDeterministic || context.Module.PdbChecksumAlgorithm.Name != null);

                var portablePdbIdProvider = (context.Module.PdbChecksumAlgorithm.Name != null) ?
                                            new Func <IEnumerable <Blob>, BlobContentId>(content => BlobContentId.FromHash(portablePdbContentHash = CryptographicHashProvider.ComputeHash(context.Module.PdbChecksumAlgorithm, content))) :
                                            null;

                var portablePdbBlob    = new BlobBuilder();
                var portablePdbBuilder = mdWriter.GetPortablePdbBuilder(metadataRootBuilder.Sizes.RowCounts, debugEntryPointHandle, portablePdbIdProvider);
                pdbContentId       = portablePdbBuilder.Serialize(portablePdbBlob);
                portablePdbVersion = portablePdbBuilder.FormatVersion;

                if (getPortablePdbStreamOpt == null)
                {
                    // embed to debug directory:
                    portablePdbToEmbed = portablePdbBlob;
                }
                else
                {
                    // write to Portable PDB stream:
                    Stream portablePdbStream = getPortablePdbStreamOpt();
                    if (portablePdbStream != null)
                    {
                        try
                        {
                            portablePdbBlob.WriteContentTo(portablePdbStream);
                        }
                        catch (Exception e) when(!(e is OperationCanceledException))
                        {
                            throw new SymUnmanagedWriterException(e.Message, e);
                        }
                    }
                }
            }

            DebugDirectoryBuilder debugDirectoryBuilder;
            if (pdbPathOpt != null || isDeterministic || portablePdbToEmbed != null)
            {
                debugDirectoryBuilder = new DebugDirectoryBuilder();
                if (pdbPathOpt != null)
                {
                    string paddedPath = isDeterministic ? pdbPathOpt : PadPdbPath(pdbPathOpt);
                    debugDirectoryBuilder.AddCodeViewEntry(paddedPath, pdbContentId, portablePdbVersion);

                    if (!portablePdbContentHash.IsDefault)
                    {
                        // Emit PDB Checksum entry for Portable and Embedded PDBs. The checksum is not as useful when the PDB is embedded,
                        // however it allows the client to efficiently validate a standalone Portable PDB that
                        // has been extracted from Embedded PDB and placed next to the PE file.
                        debugDirectoryBuilder.AddPdbChecksumEntry(context.Module.PdbChecksumAlgorithm.Name, portablePdbContentHash);
                    }
                }

                if (isDeterministic)
                {
                    debugDirectoryBuilder.AddReproducibleEntry();
                }

                if (portablePdbToEmbed != null)
                {
                    debugDirectoryBuilder.AddEmbeddedPortablePdbEntry(portablePdbToEmbed, portablePdbVersion);
                }
            }
            else
            {
                debugDirectoryBuilder = null;
            }

            var strongNameProvider = context.Module.CommonCompilation.Options.StrongNameProvider;
            var corFlags           = properties.CorFlags;

            var peBuilder = new ExtendedPEBuilder(
                peHeaderBuilder,
                metadataRootBuilder,
                ilBuilder,
                mappedFieldDataBuilder,
                managedResourceBuilder,
                CreateNativeResourceSectionSerializer(context.Module),
                debugDirectoryBuilder,
                CalculateStrongNameSignatureSize(context.Module, privateKeyOpt),
                entryPointHandle,
                corFlags,
                peIdProvider,
                metadataOnly && !context.IncludePrivateMembers);

            var peBlob      = new BlobBuilder();
            var peContentId = peBuilder.Serialize(peBlob, out Blob mvidSectionFixup);

            PatchModuleVersionIds(mvidFixup, mvidSectionFixup, mvidStringFixup, peContentId.Guid);

            if (privateKeyOpt != null && corFlags.HasFlag(CorFlags.StrongNameSigned))
            {
                strongNameProvider.SignBuilder(peBuilder, peBlob, privateKeyOpt.Value);
            }

            try
            {
                peBlob.WriteContentTo(peStream);
            }
            catch (Exception e) when(!(e is OperationCanceledException))
            {
                throw new PeWritingException(e);
            }

            return(true);
        }
Ejemplo n.º 15
0
 public static byte[] GetCustomDebugInfoBytes(ISymUnmanagedReader3 reader, MethodDefinitionHandle handle, int methodVersion)
 {
     return(reader.GetCustomDebugInfoBytes(MetadataTokens.GetToken(handle), methodVersion));
 }
Ejemplo n.º 16
0
        public virtual void Disassemble(PEFile module, MethodDefinitionHandle handle)
        {
            this.module      = module ?? throw new ArgumentNullException(nameof(module));
            metadata         = module.Metadata;
            genericContext   = new MetadataGenericContext(handle, module);
            signatureDecoder = new DisassemblerSignatureTypeProvider(module, output);
            var methodDefinition = metadata.GetMethodDefinition(handle);

            // start writing IL code
            output.WriteLine("// Method begins at RVA 0x{0:x4}", methodDefinition.RelativeVirtualAddress);
            if (methodDefinition.RelativeVirtualAddress == 0)
            {
                output.WriteLine("// Header size: {0}", 0);
                output.WriteLine("// Code size: {0} (0x{0:x})", 0);
                output.WriteLine(".maxstack {0}", 0);
                output.WriteLine();
                return;
            }
            MethodBodyBlock body;
            BlobReader      bodyBlockReader;

            try
            {
                body            = module.Reader.GetMethodBody(methodDefinition.RelativeVirtualAddress);
                bodyBlockReader = module.Reader.GetSectionData(methodDefinition.RelativeVirtualAddress).GetReader();
            }
            catch (BadImageFormatException ex)
            {
                output.WriteLine("// {0}", ex.Message);
                return;
            }
            var blob       = body.GetILReader();
            int headerSize = ILParser.GetHeaderSize(bodyBlockReader);

            output.WriteLine("// Header size: {0}", headerSize);
            output.WriteLine("// Code size: {0} (0x{0:x})", blob.Length);
            output.WriteLine(".maxstack {0}", body.MaxStack);

            var entrypointHandle = MetadataTokens.MethodDefinitionHandle(module.Reader.PEHeaders.CorHeader.EntryPointTokenOrRelativeVirtualAddress);

            if (handle == entrypointHandle)
            {
                output.WriteLine(".entrypoint");
            }

            DisassembleLocalsBlock(handle, body);
            output.WriteLine();

            sequencePoints         = DebugInfo?.GetSequencePoints(handle) ?? EmptyList <DebugInfo.SequencePoint> .Instance;
            nextSequencePointIndex = 0;
            if (DetectControlStructure && blob.Length > 0)
            {
                blob.Reset();
                HashSet <int> branchTargets = GetBranchTargets(blob);
                blob.Reset();
                WriteStructureBody(new ILStructure(module, handle, genericContext, body), branchTargets, ref blob, methodDefinition.RelativeVirtualAddress + headerSize);
            }
            else
            {
                while (blob.RemainingBytes > 0)
                {
                    cancellationToken.ThrowIfCancellationRequested();
                    WriteInstruction(output, metadata, handle, ref blob, methodDefinition.RelativeVirtualAddress);
                }
                WriteExceptionHandlers(module, handle, body);
            }
            sequencePoints = null;
        }
Ejemplo n.º 17
0
        /// <summary>
        /// Find a method given its metadata token.  This method is used for debugging support.
        /// </summary>
        /// <param name="mdMethodToken">Method metadata token.</param>
        /// <returns></returns>
        public ImportedMethod GetMethod(int mdToken)
        {
            MethodDefinitionHandle methodHandle = (MethodDefinitionHandle)MetadataTokens.EntityHandle(mdToken);

            return(ResolveMethod(methodHandle));
        }
Ejemplo n.º 18
0
 public void VerifyUpdatedMethods(params string[] expectedMethodTokens)
 {
     AssertEx.Equal(
         expectedMethodTokens,
         UpdatedMethods.Select(methodHandle => $"0x{MetadataTokens.GetToken(methodHandle):X8}"));
 }
Ejemplo n.º 19
0
 public static int ToCustomAttributeType(EntityHandle handle) => MetadataTokens.GetRowNumber(handle).ToCodedIndex(ToCustomAttributeTypeTag(handle.Kind));
Ejemplo n.º 20
0
        internal void VerifyIL(
            string qualifiedMethodName,
            string expectedIL,
            Func <Cci.ILocalDefinition, ILVisualizer.LocalInfo> mapLocal = null,
            MethodDefinitionHandle methodToken = default,
            [CallerFilePath] string callerPath = null,
            [CallerLineNumber] int callerLine  = 0)
        {
            var ilBuilder = TestData.GetMethodData(qualifiedMethodName).ILBuilder;

            Dictionary <int, string> sequencePointMarkers = null;

            if (!methodToken.IsNil)
            {
                string actualPdb = PdbToXmlConverter.DeltaPdbToXml(new ImmutableMemoryStream(PdbDelta), new[] { MetadataTokens.GetToken(methodToken) });
                sequencePointMarkers = ILValidation.GetSequencePointMarkers(actualPdb);

                Assert.True(sequencePointMarkers.Count > 0, $"No sequence points found in:{Environment.NewLine}{actualPdb}");
            }

            string actualIL = ILBuilderVisualizer.ILBuilderToString(ilBuilder, mapLocal ?? ToLocalInfo, sequencePointMarkers);

            AssertEx.AssertEqualToleratingWhitespaceDifferences(expectedIL, actualIL, escapeQuotes: true, expectedValueSourcePath: callerPath, expectedValueSourceLine: callerLine);
        }
Ejemplo n.º 21
0
 public static int ToHasFieldMarshal(EntityHandle handle) => MetadataTokens.GetRowNumber(handle).ToCodedIndex(ToHasFieldMarshalTag(handle.Kind));
Ejemplo n.º 22
0
        /// <summary>
        /// Helper method to return all async methods stepping information.
        /// </summary>
        /// <param name="symbolReaderHandle">symbol reader handle returned by LoadSymbolsForModule</param>
        /// <param name="asyncInfo">array with all async methods stepping information</param>
        /// <param name="asyncInfoCount">entry's count in asyncInfo</param>
        internal static void GetAsyncMethodsSteppingInfo(IntPtr symbolReaderHandle, out IntPtr asyncInfo, out int asyncInfoCount)
        {
            Debug.Assert(symbolReaderHandle != IntPtr.Zero);

            asyncInfo      = IntPtr.Zero;
            asyncInfoCount = 0;
            var list = new List <AsyncAwaitInfoBlock>();

            GCHandle       gch    = GCHandle.FromIntPtr(symbolReaderHandle);
            MetadataReader reader = ((OpenedReader)gch.Target).Reader;

            // Guid is taken from Roslyn source code:
            // https://github.com/dotnet/roslyn/blob/afd10305a37c0ffb2cfb2c2d8446154c68cfa87a/src/Dependencies/CodeAnalysis.Debugging/PortableCustomDebugInfoKinds.cs#L13
            Guid asyncMethodSteppingInformationBlob = new Guid("54FD2AC5-E925-401A-9C2A-F94F171072F8");

            foreach (MethodDebugInformationHandle methodDebugInformationHandle in reader.MethodDebugInformation)
            {
                var entityHandle = MetadataTokens.EntityHandle(MetadataTokens.GetToken(methodDebugInformationHandle.ToDefinitionHandle()));

                foreach (var cdiHandle in reader.GetCustomDebugInformation(entityHandle))
                {
                    var cdi = reader.GetCustomDebugInformation(cdiHandle);

                    if (reader.GetGuid(cdi.Kind) == asyncMethodSteppingInformationBlob)
                    {
                        // Format of this blob is taken from Roslyn source code:
                        // https://github.com/dotnet/roslyn/blob/afd10305a37c0ffb2cfb2c2d8446154c68cfa87a/src/Compilers/Core/Portable/PEWriter/MetadataWriter.PortablePdb.cs#L575

                        var blobReader         = reader.GetBlobReader(cdi.Value);
                        var catchHandlerOffset = blobReader.ReadUInt32();

                        while (blobReader.Offset < blobReader.Length)
                        {
                            list.Add(new AsyncAwaitInfoBlock()
                            {
                                catch_handler_offset = catchHandlerOffset,
                                yield_offset         = blobReader.ReadUInt32(),
                                resume_offset        = blobReader.ReadUInt32(),
                                // explicit conversion from int into uint here, see:
                                // https://docs.microsoft.com/en-us/dotnet/api/system.reflection.metadata.blobreader.readcompressedinteger
                                token = (uint)blobReader.ReadCompressedInteger()
                            });
                        }
                    }
                }
            }

            if (list.Count == 0)
            {
                return;
            }

            var    structSize = Marshal.SizeOf <AsyncAwaitInfoBlock>();
            IntPtr allInfo    = Marshal.AllocCoTaskMem(list.Count * structSize);
            var    currentPtr = allInfo;

            foreach (var p in list)
            {
                Marshal.StructureToPtr(p, currentPtr, false);
                currentPtr = (IntPtr)(currentPtr.ToInt64() + structSize);
            }

            asyncInfo      = allInfo;
            asyncInfoCount = list.Count;
        }
Ejemplo n.º 23
0
 public static int ToImplementation(EntityHandle handle) => MetadataTokens.GetRowNumber(handle).ToCodedIndex(ToImplementationTag(handle.Kind));
Ejemplo n.º 24
0
        /// <summary>
        /// Returns source line number and source file name for given IL offset and method token.
        /// </summary>
        /// <param name="symbolReaderHandle">symbol reader handle returned by LoadSymbolsForModule</param>
        /// <param name="methodToken">method token</param>
        /// <param name="ilOffset">IL offset</param>
        /// <param name="sequencePoint">sequence point return</param>
        /// <returns> true if information is available</returns>
        private static bool GetSequencePointByILOffset(IntPtr symbolReaderHandle, int methodToken, long ilOffset, out DbgSequencePoint sequencePoint)
        {
            Debug.Assert(symbolReaderHandle != IntPtr.Zero);
            sequencePoint.document    = IntPtr.Zero;
            sequencePoint.startLine   = 0;
            sequencePoint.startColumn = 0;
            sequencePoint.endLine     = 0;
            sequencePoint.endColumn   = 0;
            sequencePoint.offset      = 0;

            try
            {
                GCHandle       gch    = GCHandle.FromIntPtr(symbolReaderHandle);
                MetadataReader reader = ((OpenedReader)gch.Target).Reader;

                Handle handle = MetadataTokens.Handle(methodToken);
                if (handle.Kind != HandleKind.MethodDefinition)
                {
                    return(false);
                }

                MethodDebugInformationHandle methodDebugHandle = ((MethodDefinitionHandle)handle).ToDebugInformationHandle();
                if (methodDebugHandle.IsNil)
                {
                    return(false);
                }

                MethodDebugInformation  methodDebugInfo = reader.GetMethodDebugInformation(methodDebugHandle);
                SequencePointCollection sequencePoints  = methodDebugInfo.GetSequencePoints();

                SequencePoint nearestPoint = sequencePoints.GetEnumerator().Current;
                bool          found        = false;

                foreach (SequencePoint point in sequencePoints)
                {
                    if (found && point.Offset > ilOffset)
                    {
                        break;
                    }

                    if (!point.IsHidden)
                    {
                        nearestPoint = point;
                        found        = true;
                    }
                }

                if (!found || nearestPoint.StartLine == 0)
                {
                    return(false);
                }


                var fileName = reader.GetString(reader.GetDocument(nearestPoint.Document).Name);
                sequencePoint.document    = Marshal.StringToBSTR(fileName);
                sequencePoint.startLine   = nearestPoint.StartLine;
                sequencePoint.startColumn = nearestPoint.StartColumn;
                sequencePoint.endLine     = nearestPoint.EndLine;
                sequencePoint.endColumn   = nearestPoint.EndColumn;
                sequencePoint.offset      = nearestPoint.Offset;
                fileName = null;

                return(true);
            }
            catch
            {
            }
            return(false);
        }
Ejemplo n.º 25
0
 public static int ToMemberRefParent(EntityHandle handle) => MetadataTokens.GetRowNumber(handle).ToCodedIndex(ToMemberRefParentTag(handle.Kind));
Ejemplo n.º 26
0
        internal static bool GetSequencePoints(IntPtr symbolReaderHandle, int methodToken, out IntPtr points, out int pointsCount)
        {
            Debug.Assert(symbolReaderHandle != IntPtr.Zero);
            var list = new List <DbgSequencePoint>();

            pointsCount = 0;
            points      = IntPtr.Zero;

            GCHandle       gch    = GCHandle.FromIntPtr(symbolReaderHandle);
            MetadataReader reader = ((OpenedReader)gch.Target).Reader;

            try
            {
                Handle handle = MetadataTokens.Handle(methodToken);
                if (handle.Kind != HandleKind.MethodDefinition)
                {
                    return(false);
                }

                MethodDebugInformationHandle methodDebugHandle = ((MethodDefinitionHandle)handle).ToDebugInformationHandle();
                if (methodDebugHandle.IsNil)
                {
                    return(false);
                }

                MethodDebugInformation  methodDebugInfo = reader.GetMethodDebugInformation(methodDebugHandle);
                SequencePointCollection sequencePoints  = methodDebugInfo.GetSequencePoints();

                foreach (SequencePoint p in sequencePoints)
                {
                    string fileName = reader.GetString(reader.GetDocument(p.Document).Name);
                    list.Add(new DbgSequencePoint()
                    {
                        document    = Marshal.StringToBSTR(fileName),
                        startLine   = p.StartLine,
                        endLine     = p.EndLine,
                        startColumn = p.StartColumn,
                        endColumn   = p.EndColumn,
                        offset      = p.Offset
                    });
                }

                if (list.Count == 0)
                {
                    return(true);
                }

                var    structSize = Marshal.SizeOf <DbgSequencePoint>();
                IntPtr allPoints  = Marshal.AllocCoTaskMem(list.Count * structSize);
                var    currentPtr = allPoints;

                foreach (var p in list)
                {
                    Marshal.StructureToPtr(p, currentPtr, false);
                    currentPtr = (IntPtr)(currentPtr.ToInt64() + structSize);
                }

                points      = allPoints;
                pointsCount = list.Count;
                return(true);
            }
            catch
            {
                foreach (var p in list)
                {
                    Marshal.FreeBSTR(p.document);
                }
            }
            return(false);
        }
Ejemplo n.º 27
0
 public static int ToTypeDefOrRefOrSpec(EntityHandle handle) => MetadataTokens.GetRowNumber(handle).ToCodedIndex(ToTypeDefOrRefOrSpecTag(handle.Kind));
Ejemplo n.º 28
0
        internal static bool GetStepRangesFromIP(IntPtr symbolReaderHandle, int ip, int methodToken, out uint ilStartOffset, out uint ilEndOffset)
        {
            Debug.Assert(symbolReaderHandle != IntPtr.Zero);
            ilStartOffset = 0;
            ilEndOffset   = 0;

            Debug.Assert(symbolReaderHandle != IntPtr.Zero);

            GCHandle       gch    = GCHandle.FromIntPtr(symbolReaderHandle);
            MetadataReader reader = ((OpenedReader)gch.Target).Reader;

            try
            {
                Handle handle = MetadataTokens.Handle(methodToken);
                if (handle.Kind != HandleKind.MethodDefinition)
                {
                    return(false);
                }

                MethodDebugInformationHandle methodDebugHandle = ((MethodDefinitionHandle)handle).ToDebugInformationHandle();
                if (methodDebugHandle.IsNil)
                {
                    return(false);
                }

                MethodDebugInformation  methodDebugInfo = reader.GetMethodDebugInformation(methodDebugHandle);
                SequencePointCollection sequencePoints  = methodDebugInfo.GetSequencePoints();

                var list = new List <SequencePoint>();
                foreach (SequencePoint p in sequencePoints)
                {
                    list.Add(p);
                }

                var pointsArray = list.ToArray();

                for (int i = 1; i < pointsArray.Length; i++)
                {
                    SequencePoint p = pointsArray[i];

                    if (p.Offset > ip && p.StartLine != 0 && p.StartLine != SequencePoint.HiddenLine)
                    {
                        ilStartOffset = (uint)pointsArray[0].Offset;
                        for (int j = i - 1; j > 0; j--)
                        {
                            if (pointsArray[j].Offset <= ip)
                            {
                                ilStartOffset = (uint)pointsArray[j].Offset;
                                break;
                            }
                        }
                        ilEndOffset = (uint)p.Offset;
                        return(true);
                    }
                }

                // let's handle correctly last step range from last sequence point till
                // end of the method.
                if (pointsArray.Length > 0)
                {
                    ilStartOffset = (uint)pointsArray[0].Offset;
                    for (int j = pointsArray.Length - 1; j > 0; j--)
                    {
                        if (pointsArray[j].Offset <= ip)
                        {
                            ilStartOffset = (uint)pointsArray[j].Offset;
                            break;
                        }
                    }
                    ilEndOffset = ilStartOffset; // Should set this to IL code size in calling code
                    return(true);
                }
            }
            catch
            {
            }
            return(false);
        }
Ejemplo n.º 29
0
 public static int ToHasCustomDebugInformation(EntityHandle handle) => MetadataTokens.GetRowNumber(handle).ToCodedIndex(ToHasCustomDebugInformationTag(handle.Kind));
Ejemplo n.º 30
0
        internal override void DumpSectionContents(R2RSection section, XmlNode parentNode = null)
        {
            switch (section.Type)
            {
            case R2RSection.SectionType.READYTORUN_SECTION_AVAILABLE_TYPES:
                if (!_options.Naked)
                {
                    uint            availableTypesSectionOffset = (uint)_r2r.GetOffset(section.RelativeVirtualAddress);
                    NativeParser    availableTypesParser        = new NativeParser(_r2r.Image, availableTypesSectionOffset);
                    NativeHashtable availableTypes = new NativeHashtable(_r2r.Image, availableTypesParser, (uint)(availableTypesSectionOffset + section.Size));
                    _writer.WriteLine(availableTypes.ToString());
                }

                foreach (string name in _r2r.AvailableTypes)
                {
                    _writer.WriteLine(name);
                }
                break;

            case R2RSection.SectionType.READYTORUN_SECTION_METHODDEF_ENTRYPOINTS:
                if (!_options.Naked)
                {
                    NativeArray methodEntryPoints = new NativeArray(_r2r.Image, (uint)_r2r.GetOffset(section.RelativeVirtualAddress));
                    _writer.Write(methodEntryPoints.ToString());
                }
                break;

            case R2RSection.SectionType.READYTORUN_SECTION_INSTANCE_METHOD_ENTRYPOINTS:
                if (!_options.Naked)
                {
                    uint            instanceSectionOffset = (uint)_r2r.GetOffset(section.RelativeVirtualAddress);
                    NativeParser    instanceParser        = new NativeParser(_r2r.Image, instanceSectionOffset);
                    NativeHashtable instMethodEntryPoints = new NativeHashtable(_r2r.Image, instanceParser, (uint)(instanceSectionOffset + section.Size));
                    _writer.Write(instMethodEntryPoints.ToString());
                    _writer.WriteLine();
                }
                foreach (InstanceMethod instanceMethod in _r2r.InstanceMethods)
                {
                    _writer.WriteLine($@"0x{instanceMethod.Bucket:X2} -> {instanceMethod.Method.SignatureString}");
                }
                break;

            case R2RSection.SectionType.READYTORUN_SECTION_RUNTIME_FUNCTIONS:
                int rtfOffset    = _r2r.GetOffset(section.RelativeVirtualAddress);
                int rtfEndOffset = rtfOffset + section.Size;
                int rtfIndex     = 0;
                while (rtfOffset < rtfEndOffset)
                {
                    int startRva = NativeReader.ReadInt32(_r2r.Image, ref rtfOffset);
                    int endRva   = -1;
                    if (_r2r.Machine == Machine.Amd64)
                    {
                        endRva = NativeReader.ReadInt32(_r2r.Image, ref rtfOffset);
                    }
                    int unwindRva = NativeReader.ReadInt32(_r2r.Image, ref rtfOffset);
                    _writer.WriteLine($"Index: {rtfIndex}");
                    _writer.WriteLine($"\tStartRva: 0x{startRva:X8}");
                    if (endRva != -1)
                    {
                        _writer.WriteLine($"\tEndRva: 0x{endRva:X8}");
                    }
                    _writer.WriteLine($"\tUnwindRva: 0x{unwindRva:X8}");
                    rtfIndex++;
                }
                break;

            case R2RSection.SectionType.READYTORUN_SECTION_COMPILER_IDENTIFIER:
                _writer.WriteLine(_r2r.CompilerIdentifier);
                break;

            case R2RSection.SectionType.READYTORUN_SECTION_IMPORT_SECTIONS:
                if (_options.Naked)
                {
                    DumpNakedImportSections();
                }
                else
                {
                    foreach (R2RImportSection importSection in _r2r.ImportSections)
                    {
                        importSection.WriteTo(_writer);
                        if (_options.Raw && importSection.Entries.Count != 0)
                        {
                            if (importSection.SectionRVA != 0)
                            {
                                _writer.WriteLine("Section Bytes:");
                                DumpBytes(importSection.SectionRVA, (uint)importSection.SectionSize);
                            }
                            if (importSection.SignatureRVA != 0)
                            {
                                _writer.WriteLine("Signature Bytes:");
                                DumpBytes(importSection.SignatureRVA, (uint)importSection.Entries.Count * sizeof(int));
                            }
                            if (importSection.AuxiliaryDataRVA != 0 && importSection.AuxiliaryDataSize != 0)
                            {
                                _writer.WriteLine("AuxiliaryData Bytes:");
                                DumpBytes(importSection.AuxiliaryDataRVA, (uint)importSection.AuxiliaryDataSize);
                            }
                        }
                        foreach (R2RImportSection.ImportSectionEntry entry in importSection.Entries)
                        {
                            entry.WriteTo(_writer, _options);
                            _writer.WriteLine();
                        }
                        _writer.WriteLine();
                    }
                }
                break;

            case R2RSection.SectionType.READYTORUN_SECTION_MANIFEST_METADATA:
                int assemblyRefCount = _r2r.MetadataReader.GetTableRowCount(TableIndex.AssemblyRef);
                _writer.WriteLine($"MSIL AssemblyRef's ({assemblyRefCount} entries):");
                for (int assemblyRefIndex = 1; assemblyRefIndex <= assemblyRefCount; assemblyRefIndex++)
                {
                    AssemblyReference assemblyRef     = _r2r.MetadataReader.GetAssemblyReference(MetadataTokens.AssemblyReferenceHandle(assemblyRefIndex));
                    string            assemblyRefName = _r2r.MetadataReader.GetString(assemblyRef.Name);
                    _writer.WriteLine($"[ID 0x{assemblyRefIndex:X2}]: {assemblyRefName}");
                }

                _writer.WriteLine($"Manifest metadata AssemblyRef's ({_r2r.ManifestReferenceAssemblies.Count} entries):");
                for (int manifestAsmIndex = 0; manifestAsmIndex < _r2r.ManifestReferenceAssemblies.Count; manifestAsmIndex++)
                {
                    _writer.WriteLine($"[ID 0x{manifestAsmIndex + assemblyRefCount + 2:X2}]: {_r2r.ManifestReferenceAssemblies[manifestAsmIndex]}");
                }
                break;

            case R2RSection.SectionType.READYTORUN_SECTION_ATTRIBUTEPRESENCE:
                int attributesStartOffset     = _r2r.GetOffset(section.RelativeVirtualAddress);
                int attributesEndOffset       = attributesStartOffset + section.Size;
                NativeCuckooFilter attributes = new NativeCuckooFilter(_r2r.Image, attributesStartOffset, attributesEndOffset);
                _writer.WriteLine("Attribute presence filter");
                _writer.WriteLine(attributes.ToString());
                break;
            }
        }