From 254be508723544d2146d6524f1567840a903f762 Mon Sep 17 00:00:00 2001 From: Tomas Rylek Date: Wed, 24 May 2017 15:54:19 -0700 Subject: [PATCH 01/10] Selective RI of ProjectNRel CS# 1659557 - fix for attribute name clash in the updated Microsoft.DiaSymReader.Converter module. [tfs-changeset: 1659576] --- Microsoft.Cci.csproj | 4 +++- PDBReaderAndWriter/PdbReader/PdbFormatProvider.cs | 8 +++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/Microsoft.Cci.csproj b/Microsoft.Cci.csproj index e0aa756..1c82803 100644 --- a/Microsoft.Cci.csproj +++ b/Microsoft.Cci.csproj @@ -62,7 +62,9 @@ - + + DiaSymReaderPdbConverter + diff --git a/PDBReaderAndWriter/PdbReader/PdbFormatProvider.cs b/PDBReaderAndWriter/PdbReader/PdbFormatProvider.cs index c66d06d..6c6ce87 100644 --- a/PDBReaderAndWriter/PdbReader/PdbFormatProvider.cs +++ b/PDBReaderAndWriter/PdbReader/PdbFormatProvider.cs @@ -1,6 +1,8 @@ // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. +extern alias DiaSymReaderPdbConverter; + using System; using System.Collections.Generic; using System.Diagnostics.Contracts; @@ -11,8 +13,8 @@ using System.Reflection.Metadata; using System.Reflection.Metadata.Ecma335; using System.Reflection.PortableExecutable; -using Microsoft.DiaSymReader.PortablePdb; -using Microsoft.DiaSymReader.Tools; +using DiaSymReaderPdbConverter::Microsoft.DiaSymReader.PortablePdb; +using DiaSymReaderPdbConverter::Microsoft.DiaSymReader.Tools; namespace Microsoft.Cci.Pdb { /// @@ -86,7 +88,7 @@ namespace Microsoft.Cci.Pdb { /// The basic idea of the portable PDB conversion is that we let the converter run /// and use this PdbWriterForCci class to construct the CCI-expected data structures. /// - class PdbWriterForCci : Microsoft.DiaSymReader.PdbWriter + class PdbWriterForCci : DiaSymReaderPdbConverter::Microsoft.DiaSymReader.PdbWriter { /// /// List of functions exposed by the PDB. From 399e4763b52c8f18cec2b3f6d40d4d1aa6768a3e Mon Sep 17 00:00:00 2001 From: Tomas Rylek Date: Tue, 27 Jun 2017 14:13:46 -0700 Subject: [PATCH 02/10] Fix ILC compilation of Basic code Jose noticed that UAPAOT testing of new Visual Basic tests started crashing ILC due to a failed range check in MethodBodyEditor. Based on Tomas Matousek's clarification my understanding is that Visual Basic compiler uses different semantics when emitting local scopes into a legacy Windows PDB - namely it emits the "length" of a local scope one less than Roslyn would in an equivalent situation - in other words, the "scope end" as emitted by the VB compiler corresponds to the last byte of the scope whereas, for Roslyn, the end of the scope is the first byte after the end of the scope. As according to Tomas this behavior differs between Windows PDB and Portable PDB (when producing portable PDB's, the VB compiler honors the same semantics as Roslyn), I believe the clean fix is to internally correct this in the Windows PDB reader and that is what my fix does based on Tomas' advice. When reading method sequence points, whenever the Basic language GUID is identified, a new internal method on PdbFunction is called and it adjusts all the local scopes. With this change, I see Jose's test ILC-compile just fine. Thanks Tomas [tfs-changeset: 1663545] --- PDBReaderAndWriter/PdbReader/PdbFile.cs | 11 ++++++ PDBReaderAndWriter/PdbReader/PdbFunction.cs | 37 +++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/PDBReaderAndWriter/PdbReader/PdbFile.cs b/PDBReaderAndWriter/PdbReader/PdbFile.cs index aeb70c0..1dc2462 100644 --- a/PDBReaderAndWriter/PdbReader/PdbFile.cs +++ b/PDBReaderAndWriter/PdbReader/PdbFile.cs @@ -9,6 +9,12 @@ using System.IO; namespace Microsoft.Cci.Pdb { internal class PdbFile { + + /// + /// GUID of the Basic source language. + /// + private static readonly Guid BasicLanguageGuid = new Guid(974311608, -15764, 4560, 180, 66, 0, 160, 36, 74, 29, 210); + private PdbFile() // This class can't be instantiated. { } @@ -220,6 +226,11 @@ namespace Microsoft.Cci.Pdb { bits.ReadUInt32(out file.linsiz); // Size of payload. PdbSource src = (PdbSource)checks[(int)file.index]; + if (src.language.Equals(BasicLanguageGuid)) + { + func.AdjustVisualBasicScopes(); + } + PdbLines tmp = new PdbLines(src, file.count); func.lines[block++] = tmp; PdbLine[] lines = tmp.lines; diff --git a/PDBReaderAndWriter/PdbReader/PdbFunction.cs b/PDBReaderAndWriter/PdbReader/PdbFunction.cs index 01bc88b..ea182aa 100644 --- a/PDBReaderAndWriter/PdbReader/PdbFunction.cs +++ b/PDBReaderAndWriter/PdbReader/PdbFunction.cs @@ -38,6 +38,13 @@ namespace Microsoft.Cci.Pdb { internal List/*?*/ iteratorScopes; internal PdbSynchronizationInformation/*?*/ synchronizationInformation; + /// + /// Flag saying whether the method has been identified as a product of VB compilation using + /// the legacy Windows PDB symbol format, in which case scope ends need to be shifted by 1 + /// due to different semantics of scope limits in VB and C# compilers. + /// + private bool visualBasicScopesAdjusted = false; + private static string StripNamespace(string module) { int li = module.LastIndexOf('.'); if (li > 0) { @@ -46,6 +53,36 @@ namespace Microsoft.Cci.Pdb { return module; } + /// + /// When the Windows PDB reader identifies a PdbFunction as having 'Basic' as its source language, + /// it calls this method which adjusts all scopes by adding 1 to their lengths to compensate + /// for different behavior of VB vs. the C# compiler w.r.t. emission of scope info. + /// + internal void AdjustVisualBasicScopes() + { + if (!visualBasicScopesAdjusted) + { + visualBasicScopesAdjusted = true; + + // Don't adjust root scope as that one is correct + foreach (PdbScope scope in scopes) + { + AdjustVisualBasicScopes(scope.scopes); + } + } + } + + /// + /// Recursively update the entire scope tree by adding 1 to the length of each scope. + /// + private void AdjustVisualBasicScopes(PdbScope[] scopes) + { + foreach (PdbScope scope in scopes) + { + scope.length++; + AdjustVisualBasicScopes(scope.scopes); + } + } internal static PdbFunction[] LoadManagedFunctions(/*string module,*/ BitAccess bits, uint limit, From 3d64541043ff3fdf49afa35bd5548764aca7c4d3 Mon Sep 17 00:00:00 2001 From: Michal Strehovsky Date: Thu, 3 Aug 2017 15:51:20 -0700 Subject: [PATCH 03/10] Fix a copypaste mistake in ReturnValueIsByRef and ReturnValueIsModified [tfs-changeset: 1669108] --- CoreObjectModel/MetadataHelper/Members.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CoreObjectModel/MetadataHelper/Members.cs b/CoreObjectModel/MetadataHelper/Members.cs index c12617e..f768bc5 100644 --- a/CoreObjectModel/MetadataHelper/Members.cs +++ b/CoreObjectModel/MetadataHelper/Members.cs @@ -3220,14 +3220,14 @@ namespace Microsoft.Cci.Immutable { /// True if the return value is passed by reference (using a managed pointer). /// public bool ReturnValueIsByRef { - get { return this.UnspecializedVersion.AcceptsExtraArguments; } + get { return this.UnspecializedVersion.ReturnValueIsByRef; } } /// /// True if the return value has one or more custom modifiers associated with it. /// public bool ReturnValueIsModified { - get { return this.UnspecializedVersion.AcceptsExtraArguments; } + get { return this.UnspecializedVersion.ReturnValueIsModified; } } /// From 4b7a2f9ebdbd9b60421760414c383609ff47b45c Mon Sep 17 00:00:00 2001 From: Faizur Rahman Date: Wed, 8 Nov 2017 16:07:16 -0800 Subject: [PATCH 04/10] Update Microsoft.DiaSymReader and Microsoft.DiaSymReader.Converter This change update the DiaSymReader and DiaSymReader.Converter. With the latest assemblies the internal PdbWriter is replaced with SymUnmanagedWriter. This change ensures that PdbWriterForCci implements that abstract class. Most of the additional functions of SymUnmanagedWriter looks irrelevant to me from CCI's perspective. But I am not an expert in this subject :). I have run couple of tests with CLRTestPortablePdb and CLRTestEmbeddedPdb turned on and it seems like it is working okay. [tfs-changeset: 1680609] --- Microsoft.Cci.csproj | 1 + .../PdbReader/PdbFormatProvider.cs | 85 +++++++++++++++++-- 2 files changed, 81 insertions(+), 5 deletions(-) diff --git a/Microsoft.Cci.csproj b/Microsoft.Cci.csproj index 1c82803..75c1595 100644 --- a/Microsoft.Cci.csproj +++ b/Microsoft.Cci.csproj @@ -62,6 +62,7 @@ + DiaSymReaderPdbConverter diff --git a/PDBReaderAndWriter/PdbReader/PdbFormatProvider.cs b/PDBReaderAndWriter/PdbReader/PdbFormatProvider.cs index 6c6ce87..27ecece 100644 --- a/PDBReaderAndWriter/PdbReader/PdbFormatProvider.cs +++ b/PDBReaderAndWriter/PdbReader/PdbFormatProvider.cs @@ -46,7 +46,7 @@ namespace Microsoft.Cci.Pdb { // Load associated portable PDB PdbWriterForCci cciWriter = new PdbWriterForCci(); - new PdbConverter().ConvertPortableToWindows( + new PdbConverter().ConvertPortableToWindows( peReader, pdbReaderProvider.GetMetadataReader(), cciWriter, @@ -88,7 +88,7 @@ namespace Microsoft.Cci.Pdb { /// The basic idea of the portable PDB conversion is that we let the converter run /// and use this PdbWriterForCci class to construct the CCI-expected data structures. /// - class PdbWriterForCci : DiaSymReaderPdbConverter::Microsoft.DiaSymReader.PdbWriter + class PdbWriterForCci : Microsoft.DiaSymReader.SymUnmanagedWriter { /// /// List of functions exposed by the PDB. @@ -160,7 +160,7 @@ namespace Microsoft.Cci.Pdb { /// Define an indexed document to be subsequently referred to by sequence points. /// /// Document index that the converter will subsequently pass to DefineSequencePoints - public override int DefineDocument(string name, Guid language, Guid vendor, Guid type, Guid algorithmId, byte[] checksum) + public override int DefineDocument(string name, Guid language, Guid vendor, Guid type, Guid algorithmId, byte[] checksum, byte[] source) { int documentIndex = _sourceDocuments.Count; _sourceDocuments.Add(new PdbSource( @@ -334,7 +334,7 @@ namespace Microsoft.Cci.Pdb { /// Variable name /// Variable properties /// Signature token representing the variable type - public override void DefineLocalVariable(int index, string name, LocalVariableAttributes attributes, int localSignatureToken) + public override void DefineLocalVariable(int index, string name, int attributes, int localSignatureToken) { Contract.Assert(_currentScope != null); @@ -353,7 +353,7 @@ namespace Microsoft.Cci.Pdb { /// Constant name /// Constant value /// Signature token representing the constant type - public override void DefineLocalConstant(string name, object value, int constantSignatureToken) + public override bool DefineLocalConstant(string name, object value, int constantSignatureToken) { Contract.Assert(_currentScope != null); @@ -365,7 +365,11 @@ namespace Microsoft.Cci.Pdb { value: value); _currentScope.AddConstant(pdbConstant); + + return true; } + + return false; } /// @@ -418,6 +422,77 @@ namespace Microsoft.Cci.Pdb { // NO-OP for CCI } + public override void Dispose() + { + // NO-OP for CCI + } + + /// + /// Gets the current PDB signature. + /// + public override void GetSignature(out Guid guid, out uint stamp, out int age) + { + guid = Guid; + age = Age; + stamp = 0; + } + + /// + /// Gets the raw data blobs that comprise the written PDB content so far. + /// + public override IEnumerable> GetUnderlyingData() + { + // NO-OP for CCI + return null; + } + + public override int DocumentTableCapacity + { + get => _sourceDocuments.Capacity; + + set + { + if (value > _sourceDocuments.Count) + { + _sourceDocuments.Capacity = value; + } + } + } + + /// + /// Opens a map of tokens to source spans. + /// + public override void OpenTokensToSourceSpansMap() + { + // NO-OP for CCI + } + + /// + /// Maps specified token to a source span. + /// + public override void MapTokenToSourceSpan(int token, int documentIndex, int startLine, int startColumn, int endLine, int endColumn) + { + // NO-OP for CCI + } + + /// + /// Closes map of tokens to source spans previously opened using . + /// + public override void CloseTokensToSourceSpansMap() + { + // NO-OP for CCI + } + + /// + /// Writes the PDB data to specified stream. Once called no more changes to the data can be made using this writer. + /// May be called multiple times. Always writes the same data. + /// + /// Stream to write PDB data to. + public override void WriteTo(Stream stream) + { + // NO-OP for CCI + } + /// /// Helper class used to compose a hierarchical tree of method scopes. /// At method level, we maintain a stack of these builders. Whenever we Open From 9daae59ae1387155b33158e248f584c2b8048b09 Mon Sep 17 00:00:00 2001 From: Faizur Rahman Date: Wed, 8 Nov 2017 20:57:52 -0800 Subject: [PATCH 05/10] Rolling back CS#1680609 as the assemblies I checked in are not signed. [tfs-changeset: 1680664] --- Microsoft.Cci.csproj | 1 - .../PdbReader/PdbFormatProvider.cs | 85 ++----------------- 2 files changed, 5 insertions(+), 81 deletions(-) diff --git a/Microsoft.Cci.csproj b/Microsoft.Cci.csproj index 75c1595..1c82803 100644 --- a/Microsoft.Cci.csproj +++ b/Microsoft.Cci.csproj @@ -62,7 +62,6 @@ - DiaSymReaderPdbConverter diff --git a/PDBReaderAndWriter/PdbReader/PdbFormatProvider.cs b/PDBReaderAndWriter/PdbReader/PdbFormatProvider.cs index 27ecece..6c6ce87 100644 --- a/PDBReaderAndWriter/PdbReader/PdbFormatProvider.cs +++ b/PDBReaderAndWriter/PdbReader/PdbFormatProvider.cs @@ -46,7 +46,7 @@ namespace Microsoft.Cci.Pdb { // Load associated portable PDB PdbWriterForCci cciWriter = new PdbWriterForCci(); - new PdbConverter().ConvertPortableToWindows( + new PdbConverter().ConvertPortableToWindows( peReader, pdbReaderProvider.GetMetadataReader(), cciWriter, @@ -88,7 +88,7 @@ namespace Microsoft.Cci.Pdb { /// The basic idea of the portable PDB conversion is that we let the converter run /// and use this PdbWriterForCci class to construct the CCI-expected data structures. /// - class PdbWriterForCci : Microsoft.DiaSymReader.SymUnmanagedWriter + class PdbWriterForCci : DiaSymReaderPdbConverter::Microsoft.DiaSymReader.PdbWriter { /// /// List of functions exposed by the PDB. @@ -160,7 +160,7 @@ namespace Microsoft.Cci.Pdb { /// Define an indexed document to be subsequently referred to by sequence points. /// /// Document index that the converter will subsequently pass to DefineSequencePoints - public override int DefineDocument(string name, Guid language, Guid vendor, Guid type, Guid algorithmId, byte[] checksum, byte[] source) + public override int DefineDocument(string name, Guid language, Guid vendor, Guid type, Guid algorithmId, byte[] checksum) { int documentIndex = _sourceDocuments.Count; _sourceDocuments.Add(new PdbSource( @@ -334,7 +334,7 @@ namespace Microsoft.Cci.Pdb { /// Variable name /// Variable properties /// Signature token representing the variable type - public override void DefineLocalVariable(int index, string name, int attributes, int localSignatureToken) + public override void DefineLocalVariable(int index, string name, LocalVariableAttributes attributes, int localSignatureToken) { Contract.Assert(_currentScope != null); @@ -353,7 +353,7 @@ namespace Microsoft.Cci.Pdb { /// Constant name /// Constant value /// Signature token representing the constant type - public override bool DefineLocalConstant(string name, object value, int constantSignatureToken) + public override void DefineLocalConstant(string name, object value, int constantSignatureToken) { Contract.Assert(_currentScope != null); @@ -365,11 +365,7 @@ namespace Microsoft.Cci.Pdb { value: value); _currentScope.AddConstant(pdbConstant); - - return true; } - - return false; } /// @@ -422,77 +418,6 @@ namespace Microsoft.Cci.Pdb { // NO-OP for CCI } - public override void Dispose() - { - // NO-OP for CCI - } - - /// - /// Gets the current PDB signature. - /// - public override void GetSignature(out Guid guid, out uint stamp, out int age) - { - guid = Guid; - age = Age; - stamp = 0; - } - - /// - /// Gets the raw data blobs that comprise the written PDB content so far. - /// - public override IEnumerable> GetUnderlyingData() - { - // NO-OP for CCI - return null; - } - - public override int DocumentTableCapacity - { - get => _sourceDocuments.Capacity; - - set - { - if (value > _sourceDocuments.Count) - { - _sourceDocuments.Capacity = value; - } - } - } - - /// - /// Opens a map of tokens to source spans. - /// - public override void OpenTokensToSourceSpansMap() - { - // NO-OP for CCI - } - - /// - /// Maps specified token to a source span. - /// - public override void MapTokenToSourceSpan(int token, int documentIndex, int startLine, int startColumn, int endLine, int endColumn) - { - // NO-OP for CCI - } - - /// - /// Closes map of tokens to source spans previously opened using . - /// - public override void CloseTokensToSourceSpansMap() - { - // NO-OP for CCI - } - - /// - /// Writes the PDB data to specified stream. Once called no more changes to the data can be made using this writer. - /// May be called multiple times. Always writes the same data. - /// - /// Stream to write PDB data to. - public override void WriteTo(Stream stream) - { - // NO-OP for CCI - } - /// /// Helper class used to compose a hierarchical tree of method scopes. /// At method level, we maintain a stack of these builders. Whenever we Open From b4a9e995833de9a690becf9ebad69e724e7a5808 Mon Sep 17 00:00:00 2001 From: Faizur Rahman Date: Wed, 15 Nov 2017 13:35:43 -0800 Subject: [PATCH 06/10] Update Microsoft.DiaSymReader and Microsoft.DiaSymReader.Converter This change updates the DiaSymReader and DiaSymReader.Converter. With the latest assemblies the internal PdbWriter is replaced with SymUnmanagedWriter. This change ensures that PdbWriterForCci implements that abstract class. Most of the additional functions of SymUnmanagedWriter looks irrelevant to me from CCI's perspective. But I am not an expert in this subject :). I have run couple of tests with CLRTestPortablePdb and CLRTestEmbeddedPdb turned on and it seems like it is working okay. Please let me know if additional tests need to be done. [tfs-changeset: 1681215] --- Microsoft.Cci.csproj | 1 + .../PdbReader/PdbFormatProvider.cs | 85 +++++++++++++++++-- 2 files changed, 81 insertions(+), 5 deletions(-) diff --git a/Microsoft.Cci.csproj b/Microsoft.Cci.csproj index 1c82803..75c1595 100644 --- a/Microsoft.Cci.csproj +++ b/Microsoft.Cci.csproj @@ -62,6 +62,7 @@ + DiaSymReaderPdbConverter diff --git a/PDBReaderAndWriter/PdbReader/PdbFormatProvider.cs b/PDBReaderAndWriter/PdbReader/PdbFormatProvider.cs index 6c6ce87..27ecece 100644 --- a/PDBReaderAndWriter/PdbReader/PdbFormatProvider.cs +++ b/PDBReaderAndWriter/PdbReader/PdbFormatProvider.cs @@ -46,7 +46,7 @@ namespace Microsoft.Cci.Pdb { // Load associated portable PDB PdbWriterForCci cciWriter = new PdbWriterForCci(); - new PdbConverter().ConvertPortableToWindows( + new PdbConverter().ConvertPortableToWindows( peReader, pdbReaderProvider.GetMetadataReader(), cciWriter, @@ -88,7 +88,7 @@ namespace Microsoft.Cci.Pdb { /// The basic idea of the portable PDB conversion is that we let the converter run /// and use this PdbWriterForCci class to construct the CCI-expected data structures. /// - class PdbWriterForCci : DiaSymReaderPdbConverter::Microsoft.DiaSymReader.PdbWriter + class PdbWriterForCci : Microsoft.DiaSymReader.SymUnmanagedWriter { /// /// List of functions exposed by the PDB. @@ -160,7 +160,7 @@ namespace Microsoft.Cci.Pdb { /// Define an indexed document to be subsequently referred to by sequence points. /// /// Document index that the converter will subsequently pass to DefineSequencePoints - public override int DefineDocument(string name, Guid language, Guid vendor, Guid type, Guid algorithmId, byte[] checksum) + public override int DefineDocument(string name, Guid language, Guid vendor, Guid type, Guid algorithmId, byte[] checksum, byte[] source) { int documentIndex = _sourceDocuments.Count; _sourceDocuments.Add(new PdbSource( @@ -334,7 +334,7 @@ namespace Microsoft.Cci.Pdb { /// Variable name /// Variable properties /// Signature token representing the variable type - public override void DefineLocalVariable(int index, string name, LocalVariableAttributes attributes, int localSignatureToken) + public override void DefineLocalVariable(int index, string name, int attributes, int localSignatureToken) { Contract.Assert(_currentScope != null); @@ -353,7 +353,7 @@ namespace Microsoft.Cci.Pdb { /// Constant name /// Constant value /// Signature token representing the constant type - public override void DefineLocalConstant(string name, object value, int constantSignatureToken) + public override bool DefineLocalConstant(string name, object value, int constantSignatureToken) { Contract.Assert(_currentScope != null); @@ -365,7 +365,11 @@ namespace Microsoft.Cci.Pdb { value: value); _currentScope.AddConstant(pdbConstant); + + return true; } + + return false; } /// @@ -418,6 +422,77 @@ namespace Microsoft.Cci.Pdb { // NO-OP for CCI } + public override void Dispose() + { + // NO-OP for CCI + } + + /// + /// Gets the current PDB signature. + /// + public override void GetSignature(out Guid guid, out uint stamp, out int age) + { + guid = Guid; + age = Age; + stamp = 0; + } + + /// + /// Gets the raw data blobs that comprise the written PDB content so far. + /// + public override IEnumerable> GetUnderlyingData() + { + // NO-OP for CCI + return null; + } + + public override int DocumentTableCapacity + { + get => _sourceDocuments.Capacity; + + set + { + if (value > _sourceDocuments.Count) + { + _sourceDocuments.Capacity = value; + } + } + } + + /// + /// Opens a map of tokens to source spans. + /// + public override void OpenTokensToSourceSpansMap() + { + // NO-OP for CCI + } + + /// + /// Maps specified token to a source span. + /// + public override void MapTokenToSourceSpan(int token, int documentIndex, int startLine, int startColumn, int endLine, int endColumn) + { + // NO-OP for CCI + } + + /// + /// Closes map of tokens to source spans previously opened using . + /// + public override void CloseTokensToSourceSpansMap() + { + // NO-OP for CCI + } + + /// + /// Writes the PDB data to specified stream. Once called no more changes to the data can be made using this writer. + /// May be called multiple times. Always writes the same data. + /// + /// Stream to write PDB data to. + public override void WriteTo(Stream stream) + { + // NO-OP for CCI + } + /// /// Helper class used to compose a hierarchical tree of method scopes. /// At method level, we maintain a stack of these builders. Whenever we Open From fe4b97797d42a4574dfbf465ed01d10d37ad656f Mon Sep 17 00:00:00 2001 From: Anton Lapounov Date: Mon, 5 Mar 2018 16:21:14 -0800 Subject: [PATCH 07/10] Recognize ARM64 modules in ILC. Before this fix ILC used to complain about the "unexpected CPU architecture '43620'". CR: ZaMont, SergeyK, DavidWr, TRylek [tfs-changeset: 1690733] --- CoreObjectModel/MetadataModel/Units.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CoreObjectModel/MetadataModel/Units.cs b/CoreObjectModel/MetadataModel/Units.cs index c9394c8..c73e054 100644 --- a/CoreObjectModel/MetadataModel/Units.cs +++ b/CoreObjectModel/MetadataModel/Units.cs @@ -743,6 +743,10 @@ namespace Microsoft.Cci { /// M32R = 0x9041, /// + /// ARM64 Little-Endian + /// + ARM64 = 0xAA64, + /// /// CEE /// CEE = 0xC0EE, From 65ee22bb22bf8e0757f78c70e84947282e959aa0 Mon Sep 17 00:00:00 2001 From: Morgan Brown Date: Tue, 20 Mar 2018 19:37:45 -0700 Subject: [PATCH 08/10] Bug 583030: Fix regression detecting IJW assemblies to correctly allow only R2R. Most of the change is exposing CorFlags via CCI so we can find out whether the modue is R2R. Confirmed with NickGu that adding the interface member to IModule is considered acceptable. [tfs-changeset: 1692740] --- CoreObjectModel/MetadataModel/DummyObjects.cs | 9 +++++++++ CoreObjectModel/MetadataModel/Units.cs | 16 +++++++++++++++- CoreObjectModel/MutableMetadataModel/Units.cs | 8 ++++++++ PEReaderAndWriter/PEReader/BinaryObjectModel.cs | 4 ++++ PEReaderAndWriter/PEReader/PEFileStructures.cs | 2 +- 5 files changed, 37 insertions(+), 2 deletions(-) diff --git a/CoreObjectModel/MetadataModel/DummyObjects.cs b/CoreObjectModel/MetadataModel/DummyObjects.cs index 24b0d38..fc66e1e 100644 --- a/CoreObjectModel/MetadataModel/DummyObjects.cs +++ b/CoreObjectModel/MetadataModel/DummyObjects.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.Threading; using System.Diagnostics.Contracts; +using Microsoft.Cci.MetadataReader.PEFileFlags; namespace Microsoft.Cci { @@ -983,6 +984,10 @@ namespace Microsoft.Cci { get { return 0; } } + public COR20Flags COR20Flags { + get { return default(COR20Flags); } + } + public bool ILOnly { get { return false; } } @@ -3085,6 +3090,10 @@ namespace Microsoft.Cci { get { return 0; } } + public COR20Flags COR20Flags { + get { return default(COR20Flags); } + } + public bool ILOnly { get { return false; } } diff --git a/CoreObjectModel/MetadataModel/Units.cs b/CoreObjectModel/MetadataModel/Units.cs index c73e054..1d66124 100644 --- a/CoreObjectModel/MetadataModel/Units.cs +++ b/CoreObjectModel/MetadataModel/Units.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Diagnostics.Contracts; using System.Text; using System.Globalization; +using Microsoft.Cci.MetadataReader.PEFileFlags; namespace Microsoft.Cci { /// @@ -214,6 +215,10 @@ namespace Microsoft.Cci { throw new NotImplementedException(); } + public COR20Flags COR20Flags { + get { throw new NotImplementedException(); } + } + public bool ILOnly { get { throw new NotImplementedException(); } } @@ -847,6 +852,11 @@ namespace Microsoft.Cci { /// IEnumerable GetTypeMemberReferences(); + /// + /// Gets the set of COR flags applied to the module. + /// + COR20Flags COR20Flags { get; } + /// /// True if the module contains only IL and is processor independent. /// @@ -906,7 +916,7 @@ namespace Microsoft.Cci { /// /// A globally unique persistent identifier for this module. /// - System.Guid PersistentIdentifier { get; } + System.Guid PersistentIdentifier { get; } /// /// If set, the module is platform independent but prefers to be loaded in a 32-bit process for performance reasons. @@ -1093,6 +1103,10 @@ namespace Microsoft.Cci { throw new NotImplementedException(); } + public COR20Flags COR20Flags { + get { throw new NotImplementedException(); } + } + public bool ILOnly { get { throw new NotImplementedException(); } } diff --git a/CoreObjectModel/MutableMetadataModel/Units.cs b/CoreObjectModel/MutableMetadataModel/Units.cs index 9b33a6b..7e0af45 100644 --- a/CoreObjectModel/MutableMetadataModel/Units.cs +++ b/CoreObjectModel/MutableMetadataModel/Units.cs @@ -1,6 +1,7 @@ // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. +using Microsoft.Cci.MetadataReader.PEFileFlags; using System; using System.Collections.Generic; using System.Diagnostics.Contracts; @@ -765,6 +766,7 @@ namespace Microsoft.Cci.MutableCodeModel { this.genericMethodInstances = new List(genericMethodInstances); else this.genericMethodInstances = null; + this.cor20Flags = module.COR20Flags; this.ilOnly = module.ILOnly; this.strongNameSigned = module.StrongNameSigned; this.prefers32bits = module.Prefers32bits; @@ -937,6 +939,12 @@ namespace Microsoft.Cci.MutableCodeModel { } List/*?*/ genericMethodInstances; + public COR20Flags COR20Flags { + get { return this.cor20Flags; } + set { this.cor20Flags = value; } + } + COR20Flags cor20Flags; + /// /// True if the module contains only IL and is processor independent. /// diff --git a/PEReaderAndWriter/PEReader/BinaryObjectModel.cs b/PEReaderAndWriter/PEReader/BinaryObjectModel.cs index 61b19d2..22a2e6c 100644 --- a/PEReaderAndWriter/PEReader/BinaryObjectModel.cs +++ b/PEReaderAndWriter/PEReader/BinaryObjectModel.cs @@ -435,6 +435,10 @@ namespace Microsoft.Cci.MetadataReader.ObjectModelImplementation { get { return this.PEFileToObjectModel.PEFileReader.FileAlignment; } } + COR20Flags IModule.COR20Flags { + get { return this.Cor20Flags; } + } + bool IModule.ILOnly { get { return (this.Cor20Flags & COR20Flags.ILOnly) == COR20Flags.ILOnly; } } diff --git a/PEReaderAndWriter/PEReader/PEFileStructures.cs b/PEReaderAndWriter/PEReader/PEFileStructures.cs index 9c7a914..96baeaf 100644 --- a/PEReaderAndWriter/PEReader/PEFileStructures.cs +++ b/PEReaderAndWriter/PEReader/PEFileStructures.cs @@ -147,7 +147,7 @@ namespace Microsoft.Cci.MetadataReader.PEFileFlags { MemWrite = 0x80000000, // Section is writeable. } - internal enum COR20Flags : uint { + public enum COR20Flags : uint { ILOnly = 0x00000001, Bit32Required = 0x00000002, ILLibrary = 0x00000004, From 471efff6ab3c59132e41bf266255f5f1b5a2e39d Mon Sep 17 00:00:00 2001 From: Andrew Au Date: Tue, 19 Jun 2018 10:47:53 -0700 Subject: [PATCH 09/10] Propagating the source link information from input PDBs to output PDB. [tfs-changeset: 1704653] --- CoreObjectModel/SourceModel/Interfaces.cs | 25 ++++++++++ PDBReaderAndWriter/PdbReader/PdbFile.cs | 10 +++- .../PdbReader/PdbFormatProvider.cs | 46 +++++++++++-------- PDBReaderAndWriter/PdbReader/PdbInfo.cs | 5 ++ .../PdbReader/SourceLocationProvider.cs | 14 ++++-- 5 files changed, 74 insertions(+), 26 deletions(-) diff --git a/CoreObjectModel/SourceModel/Interfaces.cs b/CoreObjectModel/SourceModel/Interfaces.cs index 9982005..eb0a404 100644 --- a/CoreObjectModel/SourceModel/Interfaces.cs +++ b/CoreObjectModel/SourceModel/Interfaces.cs @@ -1540,6 +1540,31 @@ namespace Microsoft.Cci { } #endregion + /// + /// An object that can retrieve the source link information embedded in a PDB file. + /// For example, a PDB reader that can read the source link information + /// + [ContractClass(typeof(ISourceLinkProviderContract))] + public interface ISourceLinkProvider { + /// + /// Return the source link data as a byte array or null if there is no source link information embedded + /// + IEnumerable GetSourceLinkData(); + } + + #region ISourceLinkProvider contract binding + [ContractClassFor(typeof(ISourceLinkProvider))] + abstract class ISourceLinkProviderContract : ISourceLinkProvider { + #region ISourceLinkProvider Members + + public IEnumerable GetSourceLinkData() { + throw new NotImplementedException(); + } + + #endregion + } + #endregion + /// /// A range of CLR IL operations that comprise a lexical scope, specified as an IL offset and a length. /// diff --git a/PDBReaderAndWriter/PdbReader/PdbFile.cs b/PDBReaderAndWriter/PdbReader/PdbFile.cs index 1dc2462..35c0d3d 100644 --- a/PDBReaderAndWriter/PdbReader/PdbFile.cs +++ b/PDBReaderAndWriter/PdbReader/PdbFile.cs @@ -360,7 +360,7 @@ namespace Microsoft.Cci.Pdb { internal static PdbInfo LoadFunctions(Stream read) { PdbInfo pdbInfo = new PdbInfo(); - + pdbInfo.TokenToSourceMapping = new Dictionary(); BitAccess bits = new BitAccess(64 * 1024); PdbFileHeader head = new PdbFileHeader(read, bits); @@ -389,6 +389,14 @@ namespace Microsoft.Cci.Pdb { pdbInfo.SourceServerData = bits.ReadBString(bytes.Length); } + int sourceLinkStream; + if (nameIndex.TryGetValue("SOURCELINK", out sourceLinkStream)) { + DataStream dataStream = dir.streams[sourceLinkStream]; + pdbInfo.SourceLinkData = new byte[dataStream.contentSize]; + dataStream.Read(reader, bits); + bits.ReadBytes(pdbInfo.SourceLinkData); + } + dir.streams[3].Read(reader, bits); LoadDbiStream(bits, out modules, out header, true); diff --git a/PDBReaderAndWriter/PdbReader/PdbFormatProvider.cs b/PDBReaderAndWriter/PdbReader/PdbFormatProvider.cs index 27ecece..07b86d8 100644 --- a/PDBReaderAndWriter/PdbReader/PdbFormatProvider.cs +++ b/PDBReaderAndWriter/PdbReader/PdbFormatProvider.cs @@ -45,13 +45,13 @@ namespace Microsoft.Cci.Pdb { { // Load associated portable PDB PdbWriterForCci cciWriter = new PdbWriterForCci(); - + new PdbConverter().ConvertPortableToWindows( peReader, pdbReaderProvider.GetMetadataReader(), cciWriter, PdbConversionOptions.SuppressSourceLinkConversion); - + PdbInfo pdbInfo = new PdbInfo() { Functions = cciWriter.Functions, @@ -59,9 +59,10 @@ namespace Microsoft.Cci.Pdb { Age = cciWriter.Age, Guid = cciWriter.Guid, // Ignored for portable PDBs to avoid bringing in a dependency on Newtonsoft.Json - SourceServerData = null + SourceServerData = null, + SourceLinkData = cciWriter.SourceLinkData }; - + return pdbInfo; } } @@ -110,6 +111,11 @@ namespace Microsoft.Cci.Pdb { /// public Guid Guid { get; private set; } + /// + /// Raw source link data + /// + public byte[] SourceLinkData { get; private set; } + /// /// List of previously defined PdbSource documents /// @@ -269,7 +275,7 @@ namespace Microsoft.Cci.Pdb { public override void CloseMethod() { Contract.Assert(_currentMethod != null); - + List documentLineSets = new List(); foreach (KeyValuePair> tokenLinePair in _linesForCurrentMethod) { @@ -363,12 +369,12 @@ namespace Microsoft.Cci.Pdb { name: name, token: (uint)constantSignatureToken, value: value); - + _currentScope.AddConstant(pdbConstant); - + return true; } - + return false; } @@ -419,7 +425,7 @@ namespace Microsoft.Cci.Pdb { public override void SetSourceLinkData(byte[] sourceLinkData) { - // NO-OP for CCI + SourceLinkData = sourceLinkData; } public override void Dispose() @@ -485,7 +491,7 @@ namespace Microsoft.Cci.Pdb { /// /// Writes the PDB data to specified stream. Once called no more changes to the data can be made using this writer. - /// May be called multiple times. Always writes the same data. + /// May be called multiple times. Always writes the same data. /// /// Stream to write PDB data to. public override void WriteTo(Stream stream) @@ -507,27 +513,27 @@ namespace Microsoft.Cci.Pdb { /// Starting IL offset for the scope gets initialized in the constructor. /// private readonly uint _startOffset; - + /// /// Lazily constructed list of child scopes. /// private List _childScopes; - + /// /// Lazily constructed list of per-scope constants. /// private List _constants; - + /// /// Lazily constructed list of 'using' namespaces within the scope. /// private List _usedNamespaces; - + /// /// Lazily constructed list of slots (local variables). /// private List _slots; - + /// /// Constructor stores the starting IL offset for the scope. /// @@ -538,7 +544,7 @@ namespace Microsoft.Cci.Pdb { _constants = new List(); _slots = new List(); } - + /// /// Finalize construction of the PdbScope and return the complete PdbScope object. /// @@ -555,7 +561,7 @@ namespace Microsoft.Cci.Pdb { scope.scopes = _childScopes.ToArray(); return scope; } - + /// /// Add a scope to the list of immediate child scopes of this scope. /// @@ -564,7 +570,7 @@ namespace Microsoft.Cci.Pdb { { _childScopes.Add(childScope); } - + /// /// Add a slot (local variable) to the list of slots for this scope. /// @@ -573,7 +579,7 @@ namespace Microsoft.Cci.Pdb { { _slots.Add(slot); } - + /// /// Add a constant to the list of constants available within this scope. /// @@ -582,7 +588,7 @@ namespace Microsoft.Cci.Pdb { { _constants.Add(pdbConstant); } - + /// /// Add a used namespace to the list of namespaces used by this scope. /// diff --git a/PDBReaderAndWriter/PdbReader/PdbInfo.cs b/PDBReaderAndWriter/PdbReader/PdbInfo.cs index 0868f8a..38a930c 100644 --- a/PDBReaderAndWriter/PdbReader/PdbInfo.cs +++ b/PDBReaderAndWriter/PdbReader/PdbInfo.cs @@ -36,5 +36,10 @@ namespace Microsoft.Cci { /// GUID of the PDB file is used to match the PDB against the PE binary. /// public Guid Guid; + + /// + /// Source link data information. + /// + public byte[] SourceLinkData; } } diff --git a/PDBReaderAndWriter/PdbReader/SourceLocationProvider.cs b/PDBReaderAndWriter/PdbReader/SourceLocationProvider.cs index 5d956b9..3af6b7d 100644 --- a/PDBReaderAndWriter/PdbReader/SourceLocationProvider.cs +++ b/PDBReaderAndWriter/PdbReader/SourceLocationProvider.cs @@ -16,7 +16,7 @@ namespace Microsoft.Cci { /// /// An object that can map offsets in an IL stream to source locations and block scopes. /// - public class PdbReader : ISourceLocationProvider, ILocalScopeProvider, IDisposable { + public class PdbReader : ISourceLocationProvider, ILocalScopeProvider, ISourceLinkProvider, IDisposable { IMetadataHost host; Dictionary pdbFunctionMap = new Dictionary(); @@ -121,6 +121,10 @@ namespace Microsoft.Cci { .Distinct(); } + public IEnumerable GetSourceLinkData() { + return pdbInfo.SourceLinkData; + } + /// /// Return zero or more locations in primary source documents that correspond to one or more of the given derived (non primary) document locations. /// @@ -274,7 +278,7 @@ namespace Microsoft.Cci { } /// - /// + /// /// /// /// @@ -416,7 +420,7 @@ namespace Microsoft.Cci { if (pdbLocalScope == null) yield break; foreach (PdbSlot slot in pdbLocalScope.pdbScope.slots) { if ((slot.flags & 1) != 0) continue; - if (slot.slot == 0 && slot.name.StartsWith("$VB")) + if (slot.slot == 0 && slot.name.StartsWith("$VB")) yield return new PdbLocalVariable(slot, this.host, pdbLocalScope.methodBody.MethodDefinition); uint index = 0; foreach (ILocalDefinition localDefinition in pdbLocalScope.methodBody.LocalVariables) { @@ -727,7 +731,7 @@ namespace Microsoft.Cci.Pdb { internal sealed class PdbSourceDocument : PrimarySourceDocument { /// - /// Allocates an object that represents a source document, such as file, which is parsed according to the rules of a particular langauge, + /// Allocates an object that represents a source document, such as file, which is parsed according to the rules of a particular langauge, /// such as C#, to produce an object model. /// /// The name of the document. Used to identify the document in user interaction. @@ -739,7 +743,7 @@ namespace Microsoft.Cci.Pdb { } /// - /// Allocates an object that represents a source document, such as file, which is parsed according to the rules of a particular langauge, + /// Allocates an object that represents a source document, such as file, which is parsed according to the rules of a particular langauge, /// such as C#, to produce an object model. /// /// The name of the document. Used to identify the document in user interaction. From 2c28eff606a2de3abc1f8b78f6841e99a2817e1f Mon Sep 17 00:00:00 2001 From: Morgan Brown Date: Thu, 28 Jun 2018 14:10:53 -0700 Subject: [PATCH 10/10] Bug 504667: Fix TypeHelper.IsAttributeTypes to recognize types derived from other attributes [tfs-changeset: 1705951] --- CoreObjectModel/MetadataHelper/TypeHelper.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CoreObjectModel/MetadataHelper/TypeHelper.cs b/CoreObjectModel/MetadataHelper/TypeHelper.cs index 5c754ab..2300dbb 100644 --- a/CoreObjectModel/MetadataHelper/TypeHelper.cs +++ b/CoreObjectModel/MetadataHelper/TypeHelper.cs @@ -2269,6 +2269,13 @@ namespace Microsoft.Cci { foreach (ITypeReference baseClass in type.BaseClasses) { if (TypeHelper.TypesAreEquivalent(baseClass, type.PlatformType.SystemAttribute, true)) return true; } + + // If the type isn't directly derived from Attribute, its parent may be + foreach (ITypeReference baseClass in type.BaseClasses) { + ITypeDefinition baseDef = baseClass.ResolvedType; + if (baseDef != null && IsAttributeType(baseDef)) return true; + } + return false; }