├── .gitattributes ├── ILMerge ├── App.ico ├── app.config ├── ILMerge.v3.ncrunchproject ├── build │ └── ILMerge.props ├── ILMerge.nuspec ├── ILMerge.csproj └── AssemblyResolver.cs ├── Common ├── InterimKey.snk └── Include │ └── version.cs ├── ILMerge.Tests ├── test.pfx ├── test.snk ├── TestFiles.cs ├── BaselineTests.cs ├── Inputs │ └── SerializedTypeName.cs ├── Extensions.cs ├── ILMerge.Tests.csproj ├── Helpers │ ├── TempFile.cs │ ├── ShadowCopyUtils.cs │ ├── CspContainerUtils.cs │ ├── ProcessUtils.cs │ └── StackEnumerator.cs ├── Integration │ └── ConsoleTests.cs └── KeyTests.cs ├── images ├── NuGet_Package_source.png ├── NuGet_references_setting.png └── NuGet_Package_Manager_Console_source.png ├── ILMerge.v3.ncrunchsolution ├── CODE-OF-CONDUCT.md ├── version.json ├── ILMerge.sln.DotSettings ├── scripts ├── SignClient.json └── Sign_Package.ps1 ├── System.Compiler ├── PDBreader │ ├── PdbDebugException.cs │ ├── PdbSource.cs │ ├── PdbTokenLine.cs │ ├── PdbReader.cs │ ├── PdbSlot.cs │ ├── PdbLines.cs │ ├── DbiDbgHdr.cs │ ├── DbiSecCon.cs │ ├── PdbInfo.cs │ ├── CCIAdaptors.cs │ ├── MsfDirectory.cs │ ├── BitSet.cs │ ├── DbiModuleInfo.cs │ ├── DbiHeader.cs │ ├── PdbConstant.cs │ ├── DataStream.cs │ ├── PdbFileHeader.cs │ ├── PdbScope.cs │ └── BitAccess.cs ├── GlobalSuppressions.cs ├── AssemblyInfo.cs ├── ClrStrongName.cs ├── OpCode.cs ├── ExceptionStrings.resx ├── System.Compiler.csproj ├── ExceptionStrings.cs ├── Unstacker.cs ├── AssemblyCache.cs └── MemoryMappedFile.cs ├── LICENSE ├── ILMerge.sln ├── azure-pipelines.yml ├── .gitignore └── README.md /.gitattributes: -------------------------------------------------------------------------------- 1 | *.cs text eol=crlf 2 | -------------------------------------------------------------------------------- /ILMerge/App.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dotnet/ILMerge/HEAD/ILMerge/App.ico -------------------------------------------------------------------------------- /Common/InterimKey.snk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dotnet/ILMerge/HEAD/Common/InterimKey.snk -------------------------------------------------------------------------------- /ILMerge.Tests/test.pfx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dotnet/ILMerge/HEAD/ILMerge.Tests/test.pfx -------------------------------------------------------------------------------- /ILMerge.Tests/test.snk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dotnet/ILMerge/HEAD/ILMerge.Tests/test.snk -------------------------------------------------------------------------------- /images/NuGet_Package_source.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dotnet/ILMerge/HEAD/images/NuGet_Package_source.png -------------------------------------------------------------------------------- /images/NuGet_references_setting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dotnet/ILMerge/HEAD/images/NuGet_references_setting.png -------------------------------------------------------------------------------- /Common/Include/version.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection;[assembly: AssemblyVersion("1.0.21126.0")][assembly: AssemblyFileVersion("1.0.21126.0")] 2 | -------------------------------------------------------------------------------- /images/NuGet_Package_Manager_Console_source.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dotnet/ILMerge/HEAD/images/NuGet_Package_Manager_Console_source.png -------------------------------------------------------------------------------- /ILMerge/app.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /ILMerge/ILMerge.v3.ncrunchproject: -------------------------------------------------------------------------------- 1 | 2 | 3 | True 4 | 5 | -------------------------------------------------------------------------------- /ILMerge.v3.ncrunchsolution: -------------------------------------------------------------------------------- 1 | 2 | 3 | True 4 | True 5 | 6 | -------------------------------------------------------------------------------- /ILMerge/build/ILMerge.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $(MSBuildThisFileDirectory)..\tools\net452\ILMerge.exe 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /CODE-OF-CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Code of Conduct 2 | 3 | This project has adopted the code of conduct defined by the Contributor Covenant 4 | to clarify expected behavior in our community. 5 | 6 | For more information, see the [.NET Foundation Code of Conduct](https://dotnetfoundation.org/code-of-conduct). 7 | -------------------------------------------------------------------------------- /version.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "3.0", 3 | "publicReleaseRefSpec":[ 4 | "^refs/heads/master$", // we release out of master 5 | "^refs/heads/azure-pipelines$" // temporarily add this branch while we're testing 6 | ], 7 | "nugetPackageVersion":{ 8 | "semVer":2 9 | } 10 | } -------------------------------------------------------------------------------- /ILMerge.sln.DotSettings: -------------------------------------------------------------------------------- 1 | 2 | False -------------------------------------------------------------------------------- /scripts/SignClient.json: -------------------------------------------------------------------------------- 1 | { 2 | "SignClient": { 3 | "AzureAd": { 4 | "AADInstance": "https://login.microsoftonline.com/", 5 | "ClientId": "c248d68a-ba6f-4aa9-8a68-71fe872063f8", 6 | "TenantId": "16076fdc-fcc1-4a15-b1ca-32c9a255900e" 7 | }, 8 | "Service": { 9 | "Url": "https://codesign.dotnetfoundation.org/", 10 | "ResourceId": "https://SignService/3c30251f-36f3-490b-a955-520addb85001" 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /ILMerge.Tests/TestFiles.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using NUnit.Framework; 3 | 4 | namespace ILMerging.Tests 5 | { 6 | internal static class TestFiles 7 | { 8 | private static string FromCurrentDir(string fileName) 9 | => Path.Combine(TestContext.CurrentContext.TestDirectory, fileName); 10 | 11 | public static string TestSnk => FromCurrentDir("test.snk"); 12 | 13 | public static string TestPfx => FromCurrentDir("test.pfx"); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /ILMerge.Tests/BaselineTests.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using NUnit.Framework; 3 | 4 | namespace ILMerging.Tests 5 | { 6 | [TestFixture] 7 | public sealed class BaselineTests 8 | { 9 | [Test] 10 | public void Single_input() 11 | { 12 | var ilMerge = new ILMerge(); 13 | ilMerge.SetUpInputAssemblyForTest(Assembly.GetExecutingAssembly()); 14 | ilMerge.MergeToTempFileForTest(".dll"); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /System.Compiler/PDBreader/PdbDebugException.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | // See the LICENSE file in the project root for more information. 4 | 5 | using System; 6 | using System.IO; 7 | 8 | namespace Microsoft.Cci.Pdb 9 | { 10 | internal class PdbDebugException : IOException 11 | { 12 | internal PdbDebugException(String format, params object[] args) 13 | : base(String.Format(format, args)) 14 | { 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /ILMerge.Tests/Inputs/SerializedTypeName.cs: -------------------------------------------------------------------------------- 1 | namespace SerializedTypeName 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Reflection; 7 | 8 | public class M : ITwoTypeArgs 9 | { 10 | internal static void Main() 11 | { 12 | var asm = Assembly.GetCallingAssembly(); 13 | var types = asm.DefinedTypes; 14 | Console.WriteLine(types.First()); 15 | } 16 | 17 | IEnumerator ITwoTypeArgs.Mk() 18 | { 19 | yield return 42; 20 | } 21 | } 22 | 23 | public interface ITwoTypeArgs 24 | { 25 | IEnumerator Mk(); 26 | } 27 | } -------------------------------------------------------------------------------- /System.Compiler/PDBreader/PdbSource.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | // See the LICENSE file in the project root for more information. 4 | 5 | using System; 6 | 7 | namespace Microsoft.Cci.Pdb 8 | { 9 | internal class PdbSource 10 | { 11 | //internal uint index; 12 | internal string name; 13 | internal Guid doctype; 14 | internal Guid language; 15 | internal Guid vendor; 16 | 17 | internal PdbSource(/*uint index, */string name, Guid doctype, Guid language, Guid vendor) 18 | { 19 | //this.index = index; 20 | this.name = name; 21 | this.doctype = doctype; 22 | this.language = language; 23 | this.vendor = vendor; 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /scripts/Sign_Package.ps1: -------------------------------------------------------------------------------- 1 | $currentDirectory = split-path $MyInvocation.MyCommand.Definition 2 | 3 | # See if we have the ClientSecret available 4 | if([string]::IsNullOrEmpty($env:SignClientSecret)){ 5 | Write-Host "Client Secret not found, not signing packages" 6 | return; 7 | } 8 | 9 | dotnet tool install --tool-path . SignClient 10 | 11 | # Setup Variables we need to pass into the sign client tool 12 | 13 | $appSettings = "$currentDirectory\SignClient.json" 14 | 15 | $nupgks = gci $Env:ArtifactDirectory\*.nupkg | Select -ExpandProperty FullName 16 | 17 | foreach ($nupkg in $nupgks){ 18 | Write-Host "Submitting $nupkg for signing" 19 | 20 | .\SignClient 'sign' -c $appSettings -i $nupkg -r $env:SignClientUser -s $env:SignClientSecret -n 'ILMerge' -d 'ILMerge' -u 'https://github.com/dotnet/ILMerge' 21 | 22 | Write-Host "Finished signing $nupkg" 23 | } 24 | 25 | Write-Host "Sign-package complete" -------------------------------------------------------------------------------- /ILMerge.Tests/Extensions.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using System.Reflection; 3 | using ILMerging.Tests.Helpers; 4 | 5 | namespace ILMerging.Tests 6 | { 7 | internal static class Extensions 8 | { 9 | public static void SetUpInputAssemblyForTest(this ILMerge ilMerge, Assembly inputAssembly) 10 | { 11 | ilMerge.SetSearchDirectories(ShadowCopyUtils.GetTransitiveClosureDirectories(inputAssembly).ToArray()); 12 | ilMerge.SetInputAssemblies(new[] { inputAssembly.Location }); 13 | } 14 | 15 | public static void MergeToTempFileForTest(this ILMerge ilMerge, string outputExtension) 16 | { 17 | using (var outputFile = TempFile.WithExtension(outputExtension)) 18 | { 19 | ilMerge.OutputFile = outputFile; 20 | ilMerge.Merge(); 21 | } 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /System.Compiler/GlobalSuppressions.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | // See the LICENSE file in the project root for more information. 4 | 5 | [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes", Scope = "member", Target = "System.Compiler.StandardIds.#Enum")] 6 | // This file is used by Code Analysis to maintain SuppressMessage 7 | // attributes that are applied to this project. 8 | // Project-level suppressions either have no target or are given 9 | // a specific target and scoped to a namespace, type, member, etc. 10 | // 11 | // To add a suppression to this file, right-click the message in the 12 | // Code Analysis results, point to "Suppress Message", and click 13 | // "In Suppression File". 14 | // You do not need to add suppressions to this file manually. 15 | 16 | -------------------------------------------------------------------------------- /System.Compiler/PDBreader/PdbTokenLine.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | // See the LICENSE file in the project root for more information. 4 | 5 | using System; 6 | 7 | namespace Microsoft.Cci.Pdb 8 | { 9 | internal class PdbTokenLine 10 | { 11 | internal uint token; 12 | internal uint file_id; 13 | internal uint line; 14 | internal uint column; 15 | internal uint endLine; 16 | internal uint endColumn; 17 | internal PdbSource sourceFile; 18 | internal PdbTokenLine/*?*/ nextLine; 19 | 20 | internal PdbTokenLine(uint token, uint file_id, uint line, uint column, uint endLine, uint endColumn) 21 | { 22 | this.token = token; 23 | this.file_id = file_id; 24 | this.line = line; 25 | this.column = column; 26 | this.endLine = endLine; 27 | this.endColumn = endColumn; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /ILMerge.Tests/ILMerge.Tests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ILMerging.Tests 5 | net452 6 | 6 7 | false 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /System.Compiler/PDBreader/PdbReader.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | // See the LICENSE file in the project root for more information. 4 | 5 | using System; 6 | using System.IO; 7 | 8 | namespace Microsoft.Cci.Pdb 9 | { 10 | internal class PdbReader 11 | { 12 | internal PdbReader(Stream reader, int pageSize) 13 | { 14 | this.pageSize = pageSize; 15 | this.reader = reader; 16 | } 17 | 18 | internal void Seek(int page, int offset) 19 | { 20 | reader.Seek(page * pageSize + offset, SeekOrigin.Begin); 21 | } 22 | 23 | internal void Read(byte[] bytes, int offset, int count) 24 | { 25 | reader.Read(bytes, offset, count); 26 | } 27 | 28 | internal int PagesFromSize(int size) 29 | { 30 | return (size + pageSize - 1) / (pageSize); 31 | } 32 | 33 | //internal int PageSize { 34 | // get { return pageSize; } 35 | //} 36 | 37 | internal readonly int pageSize; 38 | internal readonly Stream reader; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) .NET Foundation and Contributors 4 | All Rights Reserved 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | -------------------------------------------------------------------------------- /System.Compiler/PDBreader/PdbSlot.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | // See the LICENSE file in the project root for more information. 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Text; 9 | 10 | namespace Microsoft.Cci.Pdb 11 | { 12 | internal class PdbSlot 13 | { 14 | internal uint slot; 15 | internal uint typeToken; 16 | internal string name; 17 | internal ushort flags; 18 | //internal uint segment; 19 | //internal uint address; 20 | 21 | internal PdbSlot(BitAccess bits) 22 | { 23 | AttrSlotSym slot; 24 | 25 | bits.ReadUInt32(out slot.index); 26 | bits.ReadUInt32(out slot.typind); 27 | bits.ReadUInt32(out slot.offCod); 28 | bits.ReadUInt16(out slot.segCod); 29 | bits.ReadUInt16(out slot.flags); 30 | bits.ReadCString(out slot.name); 31 | 32 | this.slot = slot.index; 33 | this.typeToken = slot.typind; 34 | this.name = slot.name; 35 | this.flags = slot.flags; 36 | //this.segment = slot.segCod; 37 | //this.address = slot.offCod; 38 | 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /System.Compiler/PDBreader/PdbLines.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | // See the LICENSE file in the project root for more information. 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Text; 9 | 10 | namespace Microsoft.Cci.Pdb 11 | { 12 | internal struct PdbLine 13 | { 14 | readonly internal uint offset; 15 | readonly internal uint lineBegin; 16 | readonly internal uint lineEnd; 17 | readonly internal ushort colBegin; 18 | readonly internal ushort colEnd; 19 | 20 | internal PdbLine(uint offset, uint lineBegin, ushort colBegin, uint lineEnd, ushort colEnd) 21 | { 22 | this.offset = offset; 23 | this.lineBegin = lineBegin; 24 | this.colBegin = colBegin; 25 | this.lineEnd = lineEnd; 26 | this.colEnd = colEnd; 27 | } 28 | } 29 | internal class PdbLines 30 | { 31 | readonly internal PdbSource file; 32 | readonly internal PdbLine[] lines; 33 | 34 | internal PdbLines(PdbSource file, uint count) 35 | { 36 | this.file = file; 37 | this.lines = new PdbLine[count]; 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /ILMerge.Tests/Helpers/TempFile.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | using System.IO; 4 | using System.Threading; 5 | 6 | namespace ILMerging.Tests.Helpers 7 | { 8 | [DebuggerDisplay("{ToString(),nq}")] 9 | public sealed class TempFile : IDisposable 10 | { 11 | public TempFile() : this(System.IO.Path.GetTempFileName()) 12 | { 13 | } 14 | 15 | public TempFile(string path) 16 | { 17 | this.path = path; 18 | } 19 | 20 | public static TempFile WithExtension(string extension) 21 | { 22 | return new TempFile( 23 | System.IO.Path.Combine( 24 | System.IO.Path.GetTempPath(), 25 | System.IO.Path.ChangeExtension(System.IO.Path.GetRandomFileName(), extension))); 26 | } 27 | 28 | private string path; 29 | public string Path => path; 30 | 31 | public static implicit operator string(TempFile tempFile) => tempFile.path; 32 | 33 | public override string ToString() => path; 34 | 35 | public void Dispose() 36 | { 37 | var path = Interlocked.Exchange(ref this.path, null); 38 | if (path != null) File.Delete(path); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /System.Compiler/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | // See the LICENSE file in the project root for more information. 4 | 5 | #if !FxCop 6 | using System; 7 | using System.Reflection; 8 | using System.Runtime.CompilerServices; 9 | 10 | [assembly: AssemblyTitle("Microsoft.Cci")] 11 | [assembly: AssemblyDescription("Compiler oriented replacement for System.Reflection and System.Reflection.Emit")] 12 | [assembly: AssemblyCompany("Microsoft Corporation")] 13 | [assembly: AssemblyProduct("Microsoft (R) .NET Framework")] 14 | [assembly: AssemblyCopyright("Copyright (C) Microsoft Corp. 2002, 2003, 20004. All rights reserved")] 15 | [assembly: AssemblyTrademark("Microsoft and Windows are either registered trademarks or trademarks of Microsoft Corporation in the U.S. and/or other countries")] 16 | [assembly:System.Resources.NeutralResourcesLanguage("en-US")] 17 | #if DelaySign 18 | //[assembly: AssemblyDelaySign(true)] 19 | //[assembly: AssemblyKeyFile("..\\..\\..\\Common\\FinalPublicKey.snk")] 20 | #else 21 | //[assembly: AssemblyKeyFile("..\\..\\..\\Common\\InterimKey.snk")] 22 | #endif 23 | #if !ROTOR 24 | [assembly: System.Runtime.InteropServices.ComVisible(false)] 25 | #endif 26 | [assembly: CLSCompliant(false)] 27 | #endif -------------------------------------------------------------------------------- /System.Compiler/PDBreader/DbiDbgHdr.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | // See the LICENSE file in the project root for more information. 4 | 5 | using System; 6 | 7 | namespace Microsoft.Cci.Pdb 8 | { 9 | internal struct DbiDbgHdr 10 | { 11 | internal DbiDbgHdr(BitAccess bits) 12 | { 13 | bits.ReadUInt16(out snFPO); 14 | bits.ReadUInt16(out snException); 15 | bits.ReadUInt16(out snFixup); 16 | bits.ReadUInt16(out snOmapToSrc); 17 | bits.ReadUInt16(out snOmapFromSrc); 18 | bits.ReadUInt16(out snSectionHdr); 19 | bits.ReadUInt16(out snTokenRidMap); 20 | bits.ReadUInt16(out snXdata); 21 | bits.ReadUInt16(out snPdata); 22 | bits.ReadUInt16(out snNewFPO); 23 | bits.ReadUInt16(out snSectionHdrOrig); 24 | } 25 | 26 | internal ushort snFPO; // 0..1 27 | internal ushort snException; // 2..3 (deprecated) 28 | internal ushort snFixup; // 4..5 29 | internal ushort snOmapToSrc; // 6..7 30 | internal ushort snOmapFromSrc; // 8..9 31 | internal ushort snSectionHdr; // 10..11 32 | internal ushort snTokenRidMap; // 12..13 33 | internal ushort snXdata; // 14..15 34 | internal ushort snPdata; // 16..17 35 | internal ushort snNewFPO; // 18..19 36 | internal ushort snSectionHdrOrig; // 20..21 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /System.Compiler/PDBreader/DbiSecCon.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | // See the LICENSE file in the project root for more information. 4 | 5 | using System; 6 | 7 | namespace Microsoft.Cci.Pdb 8 | { 9 | internal struct DbiSecCon 10 | { 11 | internal DbiSecCon(BitAccess bits) 12 | { 13 | bits.ReadInt16(out section); 14 | bits.ReadInt16(out pad1); 15 | bits.ReadInt32(out offset); 16 | bits.ReadInt32(out size); 17 | bits.ReadUInt32(out flags); 18 | bits.ReadInt16(out module); 19 | bits.ReadInt16(out pad2); 20 | bits.ReadUInt32(out dataCrc); 21 | bits.ReadUInt32(out relocCrc); 22 | //if (pad1 != 0 || pad2 != 0) { 23 | // throw new PdbException("Invalid DBI section. "+ 24 | // "(pad1={0}, pad2={1})", 25 | // pad1, pad2); 26 | //} 27 | } 28 | 29 | readonly internal short section; // 0..1 30 | readonly internal short pad1; // 2..3 31 | readonly internal int offset; // 4..7 32 | readonly internal int size; // 8..11 33 | readonly internal uint flags; // 12..15 34 | readonly internal short module; // 16..17 35 | readonly internal short pad2; // 18..19 36 | readonly internal uint dataCrc; // 20..23 37 | readonly internal uint relocCrc; // 24..27 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /System.Compiler/PDBreader/PdbInfo.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | // See the LICENSE file in the project root for more information. 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Text; 9 | using Microsoft.Cci.Pdb; 10 | using System.Diagnostics; 11 | 12 | namespace System.Compiler 13 | { 14 | internal class PdbInfo 15 | { 16 | private unsafe Metadata.Reader reader; 17 | string sourceServerData; 18 | Dictionary tokenToSourceMapping; 19 | //private uint[] remapTable; 20 | private Dictionary pdbFunctionMap; 21 | 22 | 23 | public unsafe PdbInfo(IO.FileStream inputStream, Metadata.Reader reader) 24 | { 25 | this.reader = reader; 26 | this.pdbFunctionMap = PdbFile.LoadFunctionMap(inputStream, out tokenToSourceMapping, out sourceServerData, reader); 27 | //inputStream.Seek(0L, IO.SeekOrigin.Begin); 28 | //this.remapTable = PdbFile.LoadRemapTable(inputStream); 29 | } 30 | 31 | #if false 32 | public Method GetMethodFromPdbToken(uint token) 33 | { 34 | // remap if necessary 35 | if (this.remapTable != null) 36 | { 37 | token = 0x06000000 | this.remapTable[token & 0xffffff]; 38 | } 39 | return reader.GetMemberFromToken((int)token) as Method; 40 | } 41 | #endif 42 | 43 | public PdbFunction GetMethodInfo(uint token) 44 | { 45 | PdbFunction result; 46 | this.pdbFunctionMap.TryGetValue(token, out result); 47 | return result; 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /System.Compiler/PDBreader/CCIAdaptors.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | // See the LICENSE file in the project root for more information. 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Compiler; 8 | using System.Linq; 9 | using System.Text; 10 | 11 | namespace Microsoft.Cci.Pdb 12 | { 13 | public interface ILocalScope 14 | { 15 | /// 16 | /// The offset of the first operation in the scope. 17 | /// 18 | uint Offset { get; } 19 | 20 | /// 21 | /// The length of the scope. Offset+Length equals the offset of the first operation outside the scope, or equals the method body length. 22 | /// 23 | uint Length { get; } 24 | 25 | /// 26 | /// The definition of the method in which this local scope is defined. 27 | /// 28 | Method MethodDefinition 29 | { 30 | get; 31 | } 32 | 33 | } 34 | 35 | 36 | internal sealed class PdbIteratorScope : ILocalScope 37 | { 38 | 39 | internal PdbIteratorScope(uint offset, uint length) 40 | { 41 | this.offset = offset; 42 | this.length = length; 43 | } 44 | 45 | public uint Offset 46 | { 47 | get { return this.offset; } 48 | } 49 | uint offset; 50 | 51 | public uint Length 52 | { 53 | get { return this.length; } 54 | } 55 | uint length; 56 | 57 | public Method MethodDefinition 58 | { 59 | get { return this.methodDefinition; } 60 | set { this.methodDefinition = value; } 61 | } 62 | Method methodDefinition; 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /ILMerge.Tests/Helpers/ShadowCopyUtils.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Reflection; 6 | 7 | namespace ILMerging.Tests.Helpers 8 | { 9 | public static class ShadowCopyUtils 10 | { 11 | public static IEnumerable GetTransitiveClosure(params Assembly[] assemblies) 12 | { 13 | var finishedAssemblies = new HashSet(); 14 | 15 | using (var en = StackEnumerator.Create(assemblies)) 16 | foreach (var assembly in en) 17 | { 18 | if (!finishedAssemblies.Add(assembly)) continue; 19 | yield return assembly; 20 | en.Recurse(assembly.GetReferencedAssemblies().Select(Assembly.Load)); 21 | } 22 | } 23 | 24 | /// 25 | /// Necessary because of test runners like ReSharper and NCrunch which shadow copy each assembly to an isolated directory 26 | /// 27 | public static IEnumerable GetTransitiveClosureDirectories(params Assembly[] assemblies) 28 | { 29 | return GetTransitiveClosure(assemblies) 30 | .Where(_ => !_.GlobalAssemblyCache) 31 | .Select(_ => Path.GetDirectoryName(_.Location)) 32 | .Distinct(StringComparer.OrdinalIgnoreCase); 33 | } 34 | 35 | /// 36 | /// Necessary because of test runners like ReSharper and NCrunch which shadow copy each assembly to an isolated directory 37 | /// 38 | public static string GenerateILMergeLibCliSwitches(params Assembly[] assemblies) 39 | { 40 | return string.Join(" ", GetTransitiveClosureDirectories(Assembly.GetExecutingAssembly()).Select(_ => $"/lib:\"{_}\"")); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /ILMerge.Tests/Helpers/CspContainerUtils.cs: -------------------------------------------------------------------------------- 1 | using System.Security.Cryptography; 2 | 3 | namespace ILMerging.Tests.Helpers 4 | { 5 | public static class CspContainerUtils 6 | { 7 | public static void ImportBlob(bool machineLevel, string containerName, KeyNumber keyNumber, byte[] blob) 8 | { 9 | using (var rspCsp = new RSACryptoServiceProvider(new CspParameters 10 | { 11 | KeyContainerName = containerName, 12 | KeyNumber = (int)keyNumber, 13 | Flags = machineLevel ? CspProviderFlags.UseMachineKeyStore : 0 14 | })) 15 | { 16 | rspCsp.ImportCspBlob(blob); 17 | } 18 | } 19 | 20 | public static byte[] ExportBlob(bool machineLevel, string containerName, KeyNumber keyNumber, bool includePrivateParameters) 21 | { 22 | using (var rspCsp = new RSACryptoServiceProvider(new CspParameters 23 | { 24 | KeyContainerName = containerName, 25 | KeyNumber = (int)keyNumber, 26 | Flags = CspProviderFlags.UseExistingKey | (machineLevel ? CspProviderFlags.UseMachineKeyStore : 0) 27 | })) 28 | { 29 | return rspCsp.ExportCspBlob(includePrivateParameters); 30 | } 31 | } 32 | 33 | public static void Delete(bool machineLevel, string containerName, KeyNumber keyNumber) 34 | { 35 | using (var rspCsp = new RSACryptoServiceProvider(new CspParameters 36 | { 37 | KeyContainerName = containerName, 38 | KeyNumber = (int)keyNumber, 39 | Flags = machineLevel ? CspProviderFlags.UseMachineKeyStore : 0 40 | })) 41 | { 42 | rspCsp.PersistKeyInCsp = false; 43 | } 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /ILMerge/ILMerge.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ILMerge 5 | $version$ 6 | ILMerge 7 | en-US 8 | mbarnett 9 | mbarnett 10 | .NET Foundation 11 | https://github.com/dotnet/ILMerge/blob/master/LICENSE 12 | https://github.com/dotnet/ILMerge 13 | true 14 | ILMerge is a static linker for .NET assemblies. 15 | ILMerge is a utility that can be used to merge multiple .NET assemblies into a single assembly. ILMerge takes a set of input assemblies and merges them into one target assembly. The first assembly in the list of input assemblies is the primary assembly. When the primary assembly is an executable, then the target assembly is created as an executable with the same entry point as the primary assembly. Also, if the primary assembly has a strong name, and a .snk file is provided, then the target assembly is re-signed with the specified key so that it also has a strong name. 16 | 17 | ILMerge is packaged as a console application. But all of its functionality is also available programmatically. 18 | 19 | There are several options that control the behavior of ILMerge. See the documentation that comes with the tool for details. 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /System.Compiler/PDBreader/MsfDirectory.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | // See the LICENSE file in the project root for more information. 4 | 5 | using System; 6 | 7 | namespace Microsoft.Cci.Pdb 8 | { 9 | internal class MsfDirectory 10 | { 11 | internal MsfDirectory(PdbReader reader, PdbFileHeader head, BitAccess bits) 12 | { 13 | int pages = reader.PagesFromSize(head.directorySize); 14 | 15 | // 0..n in page of directory pages. 16 | bits.MinCapacity(head.directorySize); 17 | int directoryRootPages = head.directoryRoot.Length; 18 | int pagesPerPage = head.pageSize / 4; 19 | int pagesToGo = pages; 20 | for (int i = 0; i < directoryRootPages; i++) 21 | { 22 | int pagesInThisPage = pagesToGo <= pagesPerPage ? pagesToGo : pagesPerPage; 23 | reader.Seek(head.directoryRoot[i], 0); 24 | bits.Append(reader.reader, pagesInThisPage * 4); 25 | pagesToGo -= pagesInThisPage; 26 | } 27 | bits.Position = 0; 28 | 29 | DataStream stream = new DataStream(head.directorySize, bits, pages); 30 | bits.MinCapacity(head.directorySize); 31 | stream.Read(reader, bits); 32 | 33 | // 0..3 in directory pages 34 | int count; 35 | bits.ReadInt32(out count); 36 | 37 | // 4..n 38 | int[] sizes = new int[count]; 39 | bits.ReadInt32(sizes); 40 | 41 | // n..m 42 | streams = new DataStream[count]; 43 | for (int i = 0; i < count; i++) 44 | { 45 | if (sizes[i] <= 0) 46 | { 47 | streams[i] = new DataStream(); 48 | } 49 | else 50 | { 51 | streams[i] = new DataStream(sizes[i], bits, 52 | reader.PagesFromSize(sizes[i])); 53 | } 54 | } 55 | } 56 | 57 | internal DataStream[] streams; 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /System.Compiler/PDBreader/BitSet.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | // See the LICENSE file in the project root for more information. 4 | 5 | using System; 6 | 7 | namespace Microsoft.Cci.Pdb 8 | { 9 | internal struct BitSet 10 | { 11 | internal BitSet(BitAccess bits) 12 | { 13 | bits.ReadInt32(out size); // 0..3 : Number of words 14 | words = new uint[size]; 15 | bits.ReadUInt32(words); 16 | } 17 | 18 | //internal BitSet(int size) { 19 | // this.size = size; 20 | // words = new uint[size]; 21 | //} 22 | 23 | internal bool IsSet(int index) 24 | { 25 | int word = index / 32; 26 | if (word >= this.size) return false; 27 | return ((words[word] & GetBit(index)) != 0); 28 | } 29 | 30 | //internal void Set(int index) { 31 | // int word = index / 32; 32 | // if (word >= this.size) return; 33 | // words[word] |= GetBit(index); 34 | //} 35 | 36 | //internal void Clear(int index) { 37 | // int word = index / 32; 38 | // if (word >= this.size) return; 39 | // words[word] &= ~GetBit(index); 40 | //} 41 | 42 | private static uint GetBit(int index) 43 | { 44 | return ((uint)1 << (index % 32)); 45 | } 46 | 47 | //private static uint ReverseBits(uint value) { 48 | // uint o = 0; 49 | // for (int i = 0; i < 32; i++) { 50 | // o = (o << 1) | (value & 1); 51 | // value >>= 1; 52 | // } 53 | // return o; 54 | //} 55 | 56 | internal bool IsEmpty 57 | { 58 | get { return size == 0; } 59 | } 60 | 61 | //internal bool GetWord(int index, out uint word) { 62 | // if (index < size) { 63 | // word = ReverseBits(words[index]); 64 | // return true; 65 | // } 66 | // word = 0; 67 | // return false; 68 | //} 69 | 70 | private int size; 71 | private uint[] words; 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /System.Compiler/PDBreader/DbiModuleInfo.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | // See the LICENSE file in the project root for more information. 4 | 5 | using System; 6 | 7 | namespace Microsoft.Cci.Pdb 8 | { 9 | internal class DbiModuleInfo 10 | { 11 | internal DbiModuleInfo(BitAccess bits, bool readStrings) 12 | { 13 | bits.ReadInt32(out opened); 14 | new DbiSecCon(bits); 15 | bits.ReadUInt16(out flags); 16 | bits.ReadInt16(out stream); 17 | bits.ReadInt32(out cbSyms); 18 | bits.ReadInt32(out cbOldLines); 19 | bits.ReadInt32(out cbLines); 20 | bits.ReadInt16(out files); 21 | bits.ReadInt16(out pad1); 22 | bits.ReadUInt32(out offsets); 23 | bits.ReadInt32(out niSource); 24 | bits.ReadInt32(out niCompiler); 25 | if (readStrings) 26 | { 27 | bits.ReadCString(out moduleName); 28 | bits.ReadCString(out objectName); 29 | } 30 | else 31 | { 32 | bits.SkipCString(out moduleName); 33 | bits.SkipCString(out objectName); 34 | } 35 | bits.Align(4); 36 | //if (opened != 0 || pad1 != 0) { 37 | // throw new PdbException("Invalid DBI module. "+ 38 | // "(opened={0}, pad={1})", opened, pad1); 39 | //} 40 | } 41 | 42 | readonly internal int opened; // 0..3 43 | //internal DbiSecCon section; // 4..31 44 | readonly internal ushort flags; // 32..33 45 | readonly internal short stream; // 34..35 46 | readonly internal int cbSyms; // 36..39 47 | readonly internal int cbOldLines; // 40..43 48 | readonly internal int cbLines; // 44..57 49 | readonly internal short files; // 48..49 50 | readonly internal short pad1; // 50..51 51 | readonly internal uint offsets; 52 | readonly internal int niSource; 53 | readonly internal int niCompiler; 54 | readonly internal string moduleName; 55 | readonly internal string objectName; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /System.Compiler/PDBreader/DbiHeader.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | // See the LICENSE file in the project root for more information. 4 | 5 | using System; 6 | 7 | namespace Microsoft.Cci.Pdb 8 | { 9 | internal struct DbiHeader 10 | { 11 | internal DbiHeader(BitAccess bits) 12 | { 13 | bits.ReadInt32(out sig); 14 | bits.ReadInt32(out ver); 15 | bits.ReadInt32(out age); 16 | bits.ReadInt16(out gssymStream); 17 | bits.ReadUInt16(out vers); 18 | bits.ReadInt16(out pssymStream); 19 | bits.ReadUInt16(out pdbver); 20 | bits.ReadInt16(out symrecStream); 21 | bits.ReadUInt16(out pdbver2); 22 | bits.ReadInt32(out gpmodiSize); 23 | bits.ReadInt32(out secconSize); 24 | bits.ReadInt32(out secmapSize); 25 | bits.ReadInt32(out filinfSize); 26 | bits.ReadInt32(out tsmapSize); 27 | bits.ReadInt32(out mfcIndex); 28 | bits.ReadInt32(out dbghdrSize); 29 | bits.ReadInt32(out ecinfoSize); 30 | bits.ReadUInt16(out flags); 31 | bits.ReadUInt16(out machine); 32 | bits.ReadInt32(out reserved); 33 | } 34 | 35 | internal int sig; // 0..3 36 | internal int ver; // 4..7 37 | internal int age; // 8..11 38 | internal short gssymStream; // 12..13 39 | internal ushort vers; // 14..15 40 | internal short pssymStream; // 16..17 41 | internal ushort pdbver; // 18..19 42 | internal short symrecStream; // 20..21 43 | internal ushort pdbver2; // 22..23 44 | internal int gpmodiSize; // 24..27 45 | internal int secconSize; // 28..31 46 | internal int secmapSize; // 32..35 47 | internal int filinfSize; // 36..39 48 | internal int tsmapSize; // 40..43 49 | internal int mfcIndex; // 44..47 50 | internal int dbghdrSize; // 48..51 51 | internal int ecinfoSize; // 52..55 52 | internal ushort flags; // 56..57 53 | internal ushort machine; // 58..59 54 | internal int reserved; // 60..63 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /ILMerge.sln: -------------------------------------------------------------------------------- 1 | Microsoft Visual Studio Solution File, Format Version 12.00 2 | # Visual Studio 15 3 | VisualStudioVersion = 15.0.26403.7 4 | MinimumVisualStudioVersion = 10.0.40219.1 5 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ILMerge", "ILMerge\ILMerge.csproj", "{84B41834-EFDE-4E52-A8CE-B51DFCB1D1B2}" 6 | EndProject 7 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Compiler", "System.Compiler\System.Compiler.csproj", "{D7E16B38-3893-4EEF-847F-A3BE807E9546}" 8 | EndProject 9 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ILMerge.Tests", "ILMerge.Tests\ILMerge.Tests.csproj", "{734805E8-B2FB-41E3-A669-80429AA50C98}" 10 | EndProject 11 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{B2EC5A7D-1059-4EC6-95FB-B2075609DF4B}" 12 | ProjectSection(SolutionItems) = preProject 13 | ilmerge-manual.md = ilmerge-manual.md 14 | README.md = README.md 15 | version.json = version.json 16 | EndProjectSection 17 | EndProject 18 | Global 19 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 20 | Debug|Any CPU = Debug|Any CPU 21 | Release|Any CPU = Release|Any CPU 22 | EndGlobalSection 23 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 24 | {84B41834-EFDE-4E52-A8CE-B51DFCB1D1B2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 25 | {84B41834-EFDE-4E52-A8CE-B51DFCB1D1B2}.Debug|Any CPU.Build.0 = Debug|Any CPU 26 | {84B41834-EFDE-4E52-A8CE-B51DFCB1D1B2}.Release|Any CPU.ActiveCfg = Release|Any CPU 27 | {84B41834-EFDE-4E52-A8CE-B51DFCB1D1B2}.Release|Any CPU.Build.0 = Release|Any CPU 28 | {D7E16B38-3893-4EEF-847F-A3BE807E9546}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 29 | {D7E16B38-3893-4EEF-847F-A3BE807E9546}.Debug|Any CPU.Build.0 = Debug|Any CPU 30 | {D7E16B38-3893-4EEF-847F-A3BE807E9546}.Release|Any CPU.ActiveCfg = Release|Any CPU 31 | {D7E16B38-3893-4EEF-847F-A3BE807E9546}.Release|Any CPU.Build.0 = Release|Any CPU 32 | {734805E8-B2FB-41E3-A669-80429AA50C98}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 33 | {734805E8-B2FB-41E3-A669-80429AA50C98}.Debug|Any CPU.Build.0 = Debug|Any CPU 34 | {734805E8-B2FB-41E3-A669-80429AA50C98}.Release|Any CPU.ActiveCfg = Release|Any CPU 35 | {734805E8-B2FB-41E3-A669-80429AA50C98}.Release|Any CPU.Build.0 = Release|Any CPU 36 | EndGlobalSection 37 | GlobalSection(SolutionProperties) = preSolution 38 | HideSolutionNode = FALSE 39 | EndGlobalSection 40 | GlobalSection(ExtensibilityGlobals) = postSolution 41 | SolutionGuid = {E8E8E0F0-6407-495B-944C-0C19A1830F0A} 42 | EndGlobalSection 43 | EndGlobal 44 | -------------------------------------------------------------------------------- /azure-pipelines.yml: -------------------------------------------------------------------------------- 1 | # .NET Desktop 2 | # Build and run tests for .NET Desktop or Windows classic desktop solutions. 3 | # Add steps that publish symbols, save build artifacts, and more: 4 | # https://docs.microsoft.com/vsts/pipelines/apps/windows/dot-net 5 | 6 | trigger: 7 | - master 8 | 9 | pool: 10 | vmImage: 'VS2017-Win2016' 11 | 12 | variables: 13 | solution: '**/*.sln' 14 | buildPlatform: 'Any CPU' 15 | buildConfiguration: 'Release' 16 | 17 | steps: 18 | - task: DotNetCoreCLI@2 19 | inputs: 20 | command: custom 21 | custom: tool 22 | arguments: install --tool-path . nbgv 23 | displayName: Install NBGV tool 24 | condition: and(succeeded(), eq(variables['system.pullrequest.isfork'], false)) 25 | 26 | # NBGV uses by default the version number found in version.json in the same directory as this file. 27 | - script: nbgv cloud 28 | displayName: Set Version 29 | condition: and(succeeded(), eq(variables['system.pullrequest.isfork'], false)) 30 | 31 | - task: NuGetToolInstaller@0 32 | 33 | - task: NuGetCommand@2 34 | inputs: 35 | restoreSolution: '$(solution)' 36 | 37 | - task: VSBuild@1 38 | inputs: 39 | solution: '$(solution)' 40 | platform: '$(buildPlatform)' 41 | configuration: '$(buildConfiguration)' 42 | 43 | - task: VSTest@2 44 | inputs: 45 | platform: '$(buildPlatform)' 46 | configuration: '$(buildConfiguration)' 47 | 48 | - powershell: | 49 | mkdir $(Build.ArtifactStagingDirectory)\Packages 50 | $version = .\nbgv get-version -f json | ConvertFrom-Json 51 | nuget pack ILMerge/ILMerge.nuspec -version "$($version.NuGetPackageVersion)" -NoPackageAnalysis -OutputDirectory $(Build.ArtifactStagingDirectory)\Packages -Properties "RepositoryType=git;RepositoryCommit=$($version.GitCommitId);RepositoryUrl=https://github.com/dotnet/ilmerge" 52 | displayName: Create packages 53 | condition: and(succeeded(), eq(variables['system.pullrequest.isfork'], false)) 54 | 55 | - task: PowerShell@2 56 | displayName: Authenticode Sign artifacts 57 | inputs: 58 | filePath: scripts/Sign_Package.ps1 59 | env: 60 | SignClientUser: $(SignClientUser) 61 | SignClientSecret: $(SignClientSecret) 62 | ArtifactDirectory: $(Build.ArtifactStagingDirectory)\Packages 63 | condition: and(succeeded(), not(eq(variables['build.reason'], 'PullRequest')), not(eq(variables['SignClientSecret'], '')), not(eq(variables['SignClientUser'], ''))) 64 | 65 | - task: PublishBuildArtifacts@1 66 | inputs: 67 | PathtoPublish: $(Build.ArtifactStagingDirectory)\Packages 68 | ArtifactName: nugetpackage 69 | publishLocation: Container 70 | condition: and(succeeded(), eq(variables['system.pullrequest.isfork'], false)) 71 | 72 | -------------------------------------------------------------------------------- /System.Compiler/PDBreader/PdbConstant.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | // See the LICENSE file in the project root for more information. 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Text; 9 | 10 | namespace Microsoft.Cci.Pdb 11 | { 12 | internal class PdbConstant 13 | { 14 | internal string name; 15 | internal uint token; 16 | internal object value; 17 | 18 | internal PdbConstant(BitAccess bits) 19 | { 20 | bits.ReadUInt32(out this.token); 21 | byte tag1; 22 | bits.ReadUInt8(out tag1); 23 | byte tag2; 24 | bits.ReadUInt8(out tag2); 25 | if (tag2 == 0) 26 | { 27 | this.value = tag1; 28 | } 29 | else if (tag2 == 0x80) 30 | { 31 | switch (tag1) 32 | { 33 | case 0x00: //sbyte 34 | sbyte sb; 35 | bits.ReadInt8(out sb); 36 | this.value = sb; 37 | break; 38 | case 0x01: //short 39 | short s; 40 | bits.ReadInt16(out s); 41 | this.value = s; 42 | break; 43 | case 0x02: //ushort 44 | ushort us; 45 | bits.ReadUInt16(out us); 46 | this.value = us; 47 | break; 48 | case 0x03: //int 49 | int i; 50 | bits.ReadInt32(out i); 51 | this.value = i; 52 | break; 53 | case 0x04: //uint 54 | uint ui; 55 | bits.ReadUInt32(out ui); 56 | this.value = ui; 57 | break; 58 | case 0x05: //float 59 | this.value = bits.ReadFloat(); 60 | break; 61 | case 0x06: //double 62 | this.value = bits.ReadDouble(); 63 | break; 64 | case 0x09: //long 65 | long sl; 66 | bits.ReadInt64(out sl); 67 | this.value = sl; 68 | break; 69 | case 0x0a: //ulong 70 | ulong ul; 71 | bits.ReadUInt64(out ul); 72 | this.value = ul; 73 | break; 74 | case 0x10: //string 75 | string str; 76 | bits.ReadBString(out str); 77 | this.value = str; 78 | break; 79 | case 0x19: //decimal 80 | this.value = bits.ReadDecimal(); 81 | break; 82 | default: 83 | //TODO: error 84 | break; 85 | } 86 | } 87 | else 88 | { 89 | //TODO: error 90 | } 91 | bits.ReadCString(out name); 92 | } 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /ILMerge.Tests/Integration/ConsoleTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | using System.IO; 4 | using System.Reflection; 5 | using System.Runtime.InteropServices; 6 | using ILMerging.Tests.Helpers; 7 | using NUnit.Framework; 8 | 9 | namespace ILMerging.Tests.Integration 10 | { 11 | [TestFixture, Category("Integration")] 12 | public sealed class ConsoleTests 13 | { 14 | [TestCase(true, TestName = "{m}(with mscorsn in path)")] 15 | [TestCase(false, TestName = "{m}(without mscorsn in path)")] 16 | public void No_DLL_load_crashes_when_given_PFX(bool withMscorsnInPath) 17 | { 18 | var ilMergeExePath = typeof(ILMerge).Assembly.Location; 19 | var inputAssembly = Assembly.GetExecutingAssembly(); 20 | 21 | using (var outputFile = TempFile.WithExtension(".dll")) 22 | { 23 | var startInfo = new ProcessStartInfo( 24 | ilMergeExePath, 25 | $"{ShadowCopyUtils.GenerateILMergeLibCliSwitches(inputAssembly)} /keyfile:\"{TestFiles.TestPfx}\" /out:\"{outputFile}\" \"{inputAssembly.Location}\"") 26 | { 27 | WorkingDirectory = Path.GetDirectoryName(inputAssembly.Location) 28 | }; 29 | 30 | if (withMscorsnInPath) 31 | startInfo.EnvironmentVariables["PATH"] = $"{Environment.GetEnvironmentVariable("PATH")};{RuntimeEnvironment.GetRuntimeDirectory()}"; 32 | 33 | // The system runs .NET executables as 64-bit no matter what the architecture of the calling process is. 34 | var result = ProcessUtils.Run(startInfo); 35 | 36 | Assert.That(result.ToString(), Does.Not.Contain("Unable to load DLL 'mscorsn.dll'")); 37 | Assert.That(result.ToString(), Does.Not.Contain("An attempt was made to load a program with an incorrect format.")); 38 | 39 | 40 | // Test failures: 41 | 42 | if (withMscorsnInPath && !Environment.Is64BitOperatingSystem) Assert.Inconclusive("This test can only be run on a 64-bit OS."); 43 | 44 | Assert.That( 45 | result.ToString(), 46 | Does.Not.Contain("Unhandled Exception: System.IO.FileNotFoundException"), 47 | "The test is not being run properly. If you are using ReSharper, disable shadow copy. " + 48 | "If you are using NCrunch, go to NCrunch's configuration for the ILMerge project and " + 49 | "make sure \"Copy referenced assemblies to workspace\" is set to True. " + 50 | "(Both ReSharper and NCrunch settings are saved in the repo, so this should not happen.)"); 51 | } 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /ILMerge/ILMerge.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 2.15.0 5 | A tool for merging multiple .NET assemblies into a single assembly. 6 | Microsoft Corporation 7 | (c) Microsoft Corporation. All rights reserved. 8 | AnyCPU 9 | App.ico 10 | $(MSBuildThisFileDirectory)..\Common\InterimKey.snk 11 | true 12 | Exe 13 | net452 14 | $(DefineConstants);INTERNAL;CROSSPLATFORM;V2 15 | true 16 | 6 17 | false 18 | 19 | 20 | 21 | 22 | $(MSBuildProjectName).nuspec 23 | configuration=$(Configuration);version=$(Version) 24 | 25 | true 26 | false 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | ILMerge.exe /ndebug "/log:$(MSBuildProjectDirectory)/$(IntermediateOutputPath)ilmerge.log" "/delaysign" "/keyfile:$(AssemblyOriginatorKeyFile)" "/targetplatform:v4,%ProgramFiles(x86)%\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0" /t:exe /out:final/ILMerge.exe ILMerge.exe System.Compiler.dll 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | Microsoft 53 | StrongName 54 | 55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /System.Compiler/PDBreader/DataStream.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | // See the LICENSE file in the project root for more information. 4 | 5 | using System; 6 | using System.IO; 7 | 8 | namespace Microsoft.Cci.Pdb 9 | { 10 | internal class DataStream 11 | { 12 | internal DataStream() 13 | { 14 | } 15 | 16 | internal DataStream(int contentSize, BitAccess bits, int count) 17 | { 18 | this.contentSize = contentSize; 19 | if (count > 0) 20 | { 21 | this.pages = new int[count]; 22 | bits.ReadInt32(this.pages); 23 | } 24 | } 25 | 26 | internal void Read(PdbReader reader, BitAccess bits) 27 | { 28 | bits.MinCapacity(contentSize); 29 | Read(reader, 0, bits.Buffer, 0, contentSize); 30 | } 31 | 32 | internal void Read(PdbReader reader, int position, 33 | byte[] bytes, int offset, int data) 34 | { 35 | if (position + data > contentSize) 36 | { 37 | throw new PdbDebugException("DataStream can't read off end of stream. " + 38 | "(pos={0},siz={1})", 39 | position, data); 40 | } 41 | if (position == contentSize) 42 | { 43 | return; 44 | } 45 | 46 | int left = data; 47 | int page = position / reader.pageSize; 48 | int rema = position % reader.pageSize; 49 | 50 | // First get remained of first page. 51 | if (rema != 0) 52 | { 53 | int todo = reader.pageSize - rema; 54 | if (todo > left) 55 | { 56 | todo = left; 57 | } 58 | 59 | reader.Seek(pages[page], rema); 60 | reader.Read(bytes, offset, todo); 61 | 62 | offset += todo; 63 | left -= todo; 64 | page++; 65 | } 66 | 67 | // Now get the remaining pages. 68 | while (left > 0) 69 | { 70 | int todo = reader.pageSize; 71 | if (todo > left) 72 | { 73 | todo = left; 74 | } 75 | 76 | reader.Seek(pages[page], 0); 77 | reader.Read(bytes, offset, todo); 78 | 79 | offset += todo; 80 | left -= todo; 81 | page++; 82 | } 83 | } 84 | 85 | //private void AddPages(int page0, int count) { 86 | // if (pages == null) { 87 | // pages = new int[count]; 88 | // for (int i = 0; i < count; i++) { 89 | // pages[i] = page0 + i; 90 | // } 91 | // } else { 92 | // int[] old = pages; 93 | // int used = old.Length; 94 | 95 | // pages = new int[used + count]; 96 | // Array.Copy(old, pages, used); 97 | // for (int i = 0; i < count; i++) { 98 | // pages[used + i] = page0 + i; 99 | // } 100 | // } 101 | //} 102 | 103 | //internal int Pages { 104 | // get { return pages == null ? 0 : pages.Length; } 105 | //} 106 | 107 | internal int Length 108 | { 109 | get { return contentSize; } 110 | } 111 | 112 | //internal int GetPage(int index) { 113 | // return pages[index]; 114 | //} 115 | 116 | internal int contentSize; 117 | internal int[] pages; 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /System.Compiler/PDBreader/PdbFileHeader.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | // See the LICENSE file in the project root for more information. 4 | 5 | using System; 6 | using System.IO; 7 | using System.Text; 8 | 9 | namespace Microsoft.Cci.Pdb 10 | { 11 | internal class PdbFileHeader 12 | { 13 | //internal PdbFileHeader(int pageSize) { 14 | // this.magic = new byte[32] { 15 | // 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, // "Microsof" 16 | // 0x74, 0x20, 0x43, 0x2F, 0x43, 0x2B, 0x2B, 0x20, // "t C/C++ " 17 | // 0x4D, 0x53, 0x46, 0x20, 0x37, 0x2E, 0x30, 0x30, // "MSF 7.00" 18 | // 0x0D, 0x0A, 0x1A, 0x44, 0x53, 0x00, 0x00, 0x00 // "^^^DS^^^" 19 | // }; 20 | // this.pageSize = pageSize; 21 | //} 22 | 23 | internal PdbFileHeader(Stream reader, BitAccess bits) 24 | { 25 | bits.MinCapacity(56); 26 | reader.Seek(0, SeekOrigin.Begin); 27 | bits.FillBuffer(reader, 52); 28 | 29 | this.magic = new byte[32]; 30 | bits.ReadBytes(this.magic); // 0..31 31 | bits.ReadInt32(out this.pageSize); // 32..35 32 | bits.ReadInt32(out this.freePageMap); // 36..39 33 | bits.ReadInt32(out this.pagesUsed); // 40..43 34 | bits.ReadInt32(out this.directorySize); // 44..47 35 | bits.ReadInt32(out this.zero); // 48..51 36 | 37 | int directoryPages = ((((directorySize + pageSize - 1) / pageSize) * 4) + pageSize - 1) / pageSize; 38 | this.directoryRoot = new int[directoryPages]; 39 | bits.FillBuffer(reader, directoryPages * 4); 40 | bits.ReadInt32(this.directoryRoot); 41 | } 42 | 43 | //internal string Magic { 44 | // get { return StringFromBytesUTF8(magic); } 45 | //} 46 | 47 | //internal void Write(Stream writer, BitAccess bits) { 48 | // bits.MinCapacity(pageSize); 49 | // bits.WriteBytes(magic); // 0..31 50 | // bits.WriteInt32(pageSize); // 32..35 51 | // bits.WriteInt32(freePageMap); // 36..39 52 | // bits.WriteInt32(pagesUsed); // 40..43 53 | // bits.WriteInt32(directorySize); // 44..47 54 | // bits.WriteInt32(zero); // 48..51 55 | // bits.WriteInt32(directoryRoot); // 52..55 56 | 57 | // writer.Seek(0, SeekOrigin.Begin); 58 | // bits.WriteBuffer(writer, pageSize); 59 | //} 60 | 61 | //////////////////////////////////////////////////// Helper Functions. 62 | // 63 | //internal static string StringFromBytesUTF8(byte[] bytes) { 64 | // return StringFromBytesUTF8(bytes, 0, bytes.Length); 65 | //} 66 | 67 | //internal static string StringFromBytesUTF8(byte[] bytes, int offset, int length) { 68 | // for (int i = 0; i < length; i++) { 69 | // if (bytes[offset + i] < ' ') { 70 | // length = i; 71 | // } 72 | // } 73 | // return Encoding.UTF8.GetString(bytes, offset, length); 74 | //} 75 | 76 | ////////////////////////////////////////////////////////////// Fields. 77 | // 78 | internal readonly byte[] magic; 79 | internal readonly int pageSize; 80 | internal int freePageMap; 81 | internal int pagesUsed; 82 | internal int directorySize; 83 | internal readonly int zero; 84 | internal int[] directoryRoot; 85 | } 86 | 87 | } 88 | -------------------------------------------------------------------------------- /ILMerge.Tests/KeyTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Linq; 4 | using System.Reflection; 5 | using System.Security.Cryptography; 6 | using ILMerging.Tests.Helpers; 7 | using NUnit.Framework; 8 | 9 | namespace ILMerging.Tests 10 | { 11 | [TestFixture] 12 | public sealed class KeyTests 13 | { 14 | [Test] 15 | public void Can_sign_using_keyfile() 16 | { 17 | using (var outputFile = TempFile.WithExtension(".dll")) 18 | { 19 | var ilMerge = new ILMerge { KeyFile = TestFiles.TestSnk, OutputFile = outputFile }; 20 | ilMerge.SetUpInputAssemblyForTest(Assembly.GetExecutingAssembly()); 21 | ilMerge.Merge(); 22 | 23 | Assert.That( 24 | AssemblyName.GetAssemblyName(outputFile).GetPublicKey(), 25 | Is.EqualTo(new StrongNameKeyPair(File.ReadAllBytes(TestFiles.TestSnk)).PublicKey)); 26 | } 27 | } 28 | 29 | [Test] 30 | public void Sign_with_keyfile_should_not_throw_error() 31 | { 32 | using (var outputFile = TempFile.WithExtension(".dll")) 33 | using (var logFile = TempFile.WithExtension(".log")) 34 | { 35 | var ilMerge = new ILMerge { KeyFile = TestFiles.TestSnk, OutputFile = outputFile, LogFile = logFile }; 36 | ilMerge.SetUpInputAssemblyForTest(Assembly.GetExecutingAssembly()); 37 | ilMerge.Merge(); 38 | 39 | var errorLines = File.ReadLines(logFile).Where(line => 40 | line.StartsWith("ILMerge error:", StringComparison.OrdinalIgnoreCase)); 41 | 42 | Assert.That(errorLines, Is.Empty); 43 | } 44 | } 45 | 46 | [Test] 47 | public void Can_sign_using_keycontainer() 48 | { 49 | var keyContainerName = Guid.NewGuid().ToString(); 50 | CspContainerUtils.ImportBlob(true, keyContainerName, KeyNumber.Signature, File.ReadAllBytes(TestFiles.TestSnk)); 51 | try 52 | { 53 | using (var outputFile = TempFile.WithExtension(".dll")) 54 | { 55 | var ilMerge = new ILMerge 56 | { 57 | KeyContainer = keyContainerName, 58 | OutputFile = outputFile 59 | }; 60 | ilMerge.SetUpInputAssemblyForTest(Assembly.GetExecutingAssembly()); 61 | ilMerge.Merge(); 62 | 63 | Assert.That( 64 | AssemblyName.GetAssemblyName(outputFile).GetPublicKey(), 65 | Is.EqualTo(new StrongNameKeyPair(File.ReadAllBytes(TestFiles.TestSnk)).PublicKey)); 66 | } 67 | } 68 | finally 69 | { 70 | CspContainerUtils.Delete(true, keyContainerName, KeyNumber.Signature); 71 | } 72 | } 73 | 74 | [Test] 75 | public void Bad_keyfile_gives_diagnostic_warning() 76 | { 77 | using (var logFile = new TempFile()) 78 | using (var outputFile = TempFile.WithExtension(".dll")) 79 | { 80 | var ilMerge = new ILMerge 81 | { 82 | KeyFile = TestFiles.TestPfx, 83 | OutputFile = outputFile, 84 | LogFile = logFile 85 | }; 86 | ilMerge.SetUpInputAssemblyForTest(Assembly.GetExecutingAssembly()); 87 | 88 | ilMerge.Merge(); 89 | 90 | var logText = File.ReadAllText(logFile); 91 | Assert.That(logText, Contains.Substring("Unable to obtain public key for StrongNameKeyPair.")); 92 | Assert.That(logText, Contains.Substring("PFX")); 93 | Assert.That(logText, Contains.Substring("key container")); 94 | } 95 | } 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /System.Compiler/PDBreader/PdbScope.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | // See the LICENSE file in the project root for more information. 4 | 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Text; 9 | 10 | namespace Microsoft.Cci.Pdb 11 | { 12 | internal class PdbScope 13 | { 14 | internal PdbConstant[] constants; 15 | internal PdbSlot[] slots; 16 | internal PdbScope[] scopes; 17 | internal string[] usedNamespaces; 18 | 19 | //internal uint segment; 20 | internal uint address; 21 | internal uint offset; 22 | internal uint length; 23 | 24 | internal PdbScope(uint address, uint length, PdbSlot[] slots, PdbConstant[] constants, string[] usedNamespaces) 25 | { 26 | this.constants = constants; 27 | this.slots = slots; 28 | this.scopes = new PdbScope[0]; 29 | this.usedNamespaces = usedNamespaces; 30 | this.address = address; 31 | this.offset = 0; 32 | this.length = length; 33 | } 34 | 35 | internal PdbScope(uint funcOffset, BlockSym32 block, BitAccess bits, out uint typind) 36 | { 37 | //this.segment = block.seg; 38 | this.address = block.off; 39 | this.offset = block.off - funcOffset; 40 | this.length = block.len; 41 | typind = 0; 42 | 43 | int constantCount; 44 | int scopeCount; 45 | int slotCount; 46 | int namespaceCount; 47 | PdbFunction.CountScopesAndSlots(bits, block.end, out constantCount, out scopeCount, out slotCount, out namespaceCount); 48 | constants = new PdbConstant[constantCount]; 49 | scopes = new PdbScope[scopeCount]; 50 | slots = new PdbSlot[slotCount]; 51 | usedNamespaces = new string[namespaceCount]; 52 | int constant = 0; 53 | int scope = 0; 54 | int slot = 0; 55 | int usedNs = 0; 56 | 57 | while (bits.Position < block.end) 58 | { 59 | ushort siz; 60 | ushort rec; 61 | 62 | bits.ReadUInt16(out siz); 63 | int star = bits.Position; 64 | int stop = bits.Position + siz; 65 | bits.Position = star; 66 | bits.ReadUInt16(out rec); 67 | 68 | switch ((SYM)rec) 69 | { 70 | case SYM.S_BLOCK32: 71 | { 72 | BlockSym32 sub = new BlockSym32(); 73 | 74 | bits.ReadUInt32(out sub.parent); 75 | bits.ReadUInt32(out sub.end); 76 | bits.ReadUInt32(out sub.len); 77 | bits.ReadUInt32(out sub.off); 78 | bits.ReadUInt16(out sub.seg); 79 | bits.SkipCString(out sub.name); 80 | 81 | bits.Position = stop; 82 | scopes[scope++] = new PdbScope(funcOffset, sub, bits, out typind); 83 | break; 84 | } 85 | 86 | case SYM.S_MANSLOT: 87 | slots[slot++] = new PdbSlot(bits); 88 | bits.Position = stop; 89 | break; 90 | 91 | case SYM.S_UNAMESPACE: 92 | bits.ReadCString(out usedNamespaces[usedNs++]); 93 | bits.Position = stop; 94 | break; 95 | 96 | case SYM.S_END: 97 | bits.Position = stop; 98 | break; 99 | 100 | case SYM.S_MANCONSTANT: 101 | constants[constant++] = new PdbConstant(bits); 102 | bits.Position = stop; 103 | break; 104 | 105 | default: 106 | //throw new PdbException("Unknown SYM in scope {0}", (SYM)rec); 107 | bits.Position = stop; 108 | break; 109 | } 110 | } 111 | 112 | if (bits.Position != block.end) 113 | { 114 | throw new Exception("Not at S_END"); 115 | } 116 | 117 | ushort esiz; 118 | ushort erec; 119 | bits.ReadUInt16(out esiz); 120 | bits.ReadUInt16(out erec); 121 | 122 | if (erec != (ushort)SYM.S_END) 123 | { 124 | throw new Exception("Missing S_END"); 125 | } 126 | } 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /ILMerge.Tests/Helpers/ProcessUtils.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Text; 5 | 6 | namespace ILMerging.Tests.Helpers 7 | { 8 | public static class ProcessUtils 9 | { 10 | public static ProcessResult Run(ProcessStartInfo startInfo) 11 | { 12 | startInfo.UseShellExecute = false; 13 | startInfo.RedirectStandardOutput = true; 14 | startInfo.RedirectStandardError = true; 15 | startInfo.CreateNoWindow = true; 16 | 17 | using (var process = new Process { StartInfo = startInfo }) 18 | { 19 | var standardStreamData = new List(); 20 | var currentData = new StringBuilder(); 21 | var currentDataIsError = false; 22 | 23 | process.OutputDataReceived += (sender, e) => 24 | { 25 | if (e.Data == null) return; 26 | if (currentDataIsError) 27 | { 28 | if (currentData.Length != 0) 29 | standardStreamData.Add(new StandardStreamData(currentDataIsError, currentData.ToString())); 30 | currentData.Clear(); 31 | currentDataIsError = false; 32 | } 33 | currentData.AppendLine(e.Data); 34 | }; 35 | process.ErrorDataReceived += (sender, e) => 36 | { 37 | if (e.Data == null) return; 38 | if (!currentDataIsError) 39 | { 40 | if (currentData.Length != 0) 41 | standardStreamData.Add(new StandardStreamData(currentDataIsError, currentData.ToString())); 42 | currentData.Clear(); 43 | currentDataIsError = true; 44 | } 45 | currentData.AppendLine(e.Data); 46 | }; 47 | 48 | process.Start(); 49 | process.BeginOutputReadLine(); 50 | process.BeginErrorReadLine(); 51 | process.WaitForExit(); 52 | 53 | if (currentData.Length != 0) 54 | standardStreamData.Add(new StandardStreamData(currentDataIsError, currentData.ToString())); 55 | 56 | return new ProcessResult(process.ExitCode, standardStreamData.ToArray()); 57 | } 58 | } 59 | 60 | [DebuggerDisplay("{ToString(),nq}")] 61 | public struct ProcessResult 62 | { 63 | public ProcessResult(int exitCode, StandardStreamData[] standardStreamData) 64 | { 65 | ExitCode = exitCode; 66 | StandardStreamData = standardStreamData; 67 | } 68 | 69 | public int ExitCode { get; } 70 | public StandardStreamData[] StandardStreamData { get; } 71 | 72 | public override string ToString() => ToString(true); 73 | 74 | /// If true, appends "[stdout] " or "[stderr] " to the beginning of each line. 75 | public string ToString(bool showStreamSource) 76 | { 77 | var r = new StringBuilder("Exit code ").Append(ExitCode); 78 | 79 | if (StandardStreamData.Length != 0) r.AppendLine(); 80 | 81 | foreach (var data in StandardStreamData) 82 | { 83 | if (showStreamSource) 84 | { 85 | var lines = data.Data.Split(new[] { Environment.NewLine }, StringSplitOptions.None); 86 | 87 | // StandardStreamData.Data always ends with a blank line, so skip that 88 | for (var i = 0; i < lines.Length - 1; i++) 89 | r.Append(data.IsError ? "[stderr] " : "[stdout] ").AppendLine(lines[i]); 90 | } 91 | else 92 | { 93 | r.Append(data.Data); 94 | } 95 | } 96 | 97 | return r.ToString(); 98 | } 99 | } 100 | 101 | [DebuggerDisplay("{ToString(),nq}")] 102 | public struct StandardStreamData 103 | { 104 | public StandardStreamData(bool isError, string data) 105 | { 106 | IsError = isError; 107 | Data = data; 108 | } 109 | 110 | public bool IsError { get; } 111 | public string Data { get; } 112 | 113 | public override string ToString() => (IsError ? "[stderr] " : "[stdout] ") + Data; 114 | } 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | x64/ 19 | x86/ 20 | bld/ 21 | [Bb]in/ 22 | [Oo]bj/ 23 | [Ll]og/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | # Uncomment if you have tasks that create the project's static files in wwwroot 28 | #wwwroot/ 29 | 30 | # MSTest test Results 31 | [Tt]est[Rr]esult*/ 32 | [Bb]uild[Ll]og.* 33 | 34 | # NUNIT 35 | *.VisualState.xml 36 | TestResult.xml 37 | 38 | # Build Results of an ATL Project 39 | [Dd]ebugPS/ 40 | [Rr]eleasePS/ 41 | dlldata.c 42 | 43 | # DNX 44 | project.lock.json 45 | artifacts/ 46 | 47 | *_i.c 48 | *_p.c 49 | *_i.h 50 | *.ilk 51 | *.meta 52 | *.obj 53 | *.pch 54 | *.pdb 55 | *.pgc 56 | *.pgd 57 | *.rsp 58 | *.sbr 59 | *.tlb 60 | *.tli 61 | *.tlh 62 | *.tmp 63 | *.tmp_proj 64 | *.log 65 | *.vspscc 66 | *.vssscc 67 | .builds 68 | *.pidb 69 | *.svclog 70 | *.scc 71 | 72 | # Chutzpah Test files 73 | _Chutzpah* 74 | 75 | # Visual C++ cache files 76 | ipch/ 77 | *.aps 78 | *.ncb 79 | *.opendb 80 | *.opensdf 81 | *.sdf 82 | *.cachefile 83 | *.VC.db 84 | *.VC.VC.opendb 85 | 86 | # Visual Studio profiler 87 | *.psess 88 | *.vsp 89 | *.vspx 90 | *.sap 91 | 92 | # TFS 2012 Local Workspace 93 | $tf/ 94 | 95 | # Guidance Automation Toolkit 96 | *.gpState 97 | 98 | # ReSharper is a .NET coding add-in 99 | _ReSharper*/ 100 | *.[Rr]e[Ss]harper 101 | *.DotSettings.user 102 | 103 | # JustCode is a .NET coding add-in 104 | .JustCode 105 | 106 | # TeamCity is a build add-in 107 | _TeamCity* 108 | 109 | # DotCover is a Code Coverage Tool 110 | *.dotCover 111 | 112 | # NCrunch 113 | _NCrunch_* 114 | .*crunch*.local.xml 115 | nCrunchTemp_* 116 | 117 | # MightyMoose 118 | *.mm.* 119 | AutoTest.Net/ 120 | 121 | # Web workbench (sass) 122 | .sass-cache/ 123 | 124 | # Installshield output folder 125 | [Ee]xpress/ 126 | 127 | # DocProject is a documentation generator add-in 128 | DocProject/buildhelp/ 129 | DocProject/Help/*.HxT 130 | DocProject/Help/*.HxC 131 | DocProject/Help/*.hhc 132 | DocProject/Help/*.hhk 133 | DocProject/Help/*.hhp 134 | DocProject/Help/Html2 135 | DocProject/Help/html 136 | 137 | # Click-Once directory 138 | publish/ 139 | 140 | # Publish Web Output 141 | *.[Pp]ublish.xml 142 | *.azurePubxml 143 | # TODO: Comment the next line if you want to checkin your web deploy settings 144 | # but database connection strings (with potential passwords) will be unencrypted 145 | *.pubxml 146 | *.publishproj 147 | 148 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 149 | # checkin your Azure Web App publish settings, but sensitive information contained 150 | # in these scripts will be unencrypted 151 | PublishScripts/ 152 | 153 | # NuGet Packages 154 | *.nupkg 155 | # The packages folder can be ignored because of Package Restore 156 | **/packages/* 157 | # except build/, which is used as an MSBuild target. 158 | !**/packages/build/ 159 | # Uncomment if necessary however generally it will be regenerated when needed 160 | #!**/packages/repositories.config 161 | # NuGet v3's project.json files produces more ignoreable files 162 | *.nuget.props 163 | *.nuget.targets 164 | 165 | # Microsoft Azure Build Output 166 | csx/ 167 | *.build.csdef 168 | 169 | # Microsoft Azure Emulator 170 | ecf/ 171 | rcf/ 172 | 173 | # Windows Store app package directories and files 174 | AppPackages/ 175 | BundleArtifacts/ 176 | Package.StoreAssociation.xml 177 | _pkginfo.txt 178 | 179 | # Visual Studio cache files 180 | # files ending in .cache can be ignored 181 | *.[Cc]ache 182 | # but keep track of directories ending in .cache 183 | !*.[Cc]ache/ 184 | 185 | # Others 186 | ClientBin/ 187 | ~$* 188 | *~ 189 | *.dbmdl 190 | *.dbproj.schemaview 191 | *.pfx 192 | *.publishsettings 193 | node_modules/ 194 | orleans.codegen.cs 195 | 196 | # Since there are multiple workflows, uncomment next line to ignore bower_components 197 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 198 | #bower_components/ 199 | 200 | # RIA/Silverlight projects 201 | Generated_Code/ 202 | 203 | # Backup & report files from converting an old project file 204 | # to a newer Visual Studio version. Backup files are not needed, 205 | # because we have git ;-) 206 | _UpgradeReport_Files/ 207 | Backup*/ 208 | UpgradeLog*.XML 209 | UpgradeLog*.htm 210 | 211 | # SQL Server files 212 | *.mdf 213 | *.ldf 214 | 215 | # Business Intelligence projects 216 | *.rdl.data 217 | *.bim.layout 218 | *.bim_*.settings 219 | 220 | # Microsoft Fakes 221 | FakesAssemblies/ 222 | 223 | # GhostDoc plugin setting file 224 | *.GhostDoc.xml 225 | 226 | # Node.js Tools for Visual Studio 227 | .ntvs_analysis.dat 228 | 229 | # Visual Studio 6 build log 230 | *.plg 231 | 232 | # Visual Studio 6 workspace options file 233 | *.opt 234 | 235 | # Visual Studio LightSwitch build output 236 | **/*.HTMLClient/GeneratedArtifacts 237 | **/*.DesktopClient/GeneratedArtifacts 238 | **/*.DesktopClient/ModelManifest.xml 239 | **/*.Server/GeneratedArtifacts 240 | **/*.Server/ModelManifest.xml 241 | _Pvt_Extensions 242 | 243 | # Paket dependency manager 244 | .paket/paket.exe 245 | paket-files/ 246 | 247 | # FAKE - F# Make 248 | .fake/ 249 | 250 | # JetBrains Rider 251 | .idea/ 252 | *.sln.iml 253 | -------------------------------------------------------------------------------- /ILMerge.Tests/Helpers/StackEnumerator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | 5 | namespace ILMerging.Tests.Helpers 6 | { 7 | public static class StackEnumerator 8 | { 9 | public static StackEnumerator Create(params T[] initial) => new StackEnumerator(initial); 10 | public static StackEnumerator Create(IEnumerable initial) => new StackEnumerator(initial); 11 | public static StackEnumerator Create(IEnumerator initial) => new StackEnumerator(initial); 12 | public static StackEnumerator Create(TContext initialContext, params T[] initial) => new StackEnumerator(initialContext, initial); 13 | public static StackEnumerator Create(TContext initialContext, IEnumerable initial) => new StackEnumerator(initialContext, initial); 14 | public static StackEnumerator Create(TContext initialContext, IEnumerator initial) => new StackEnumerator(initialContext, initial); 15 | } 16 | 17 | public sealed class StackEnumerator : IDisposable 18 | { 19 | private readonly Stack> stack = new Stack>(); 20 | private IEnumerator current; 21 | 22 | public bool MoveNext() 23 | { 24 | while (!current.MoveNext()) 25 | { 26 | current.Dispose(); 27 | if (stack.Count == 0) return false; 28 | current = stack.Pop(); 29 | } 30 | 31 | return true; 32 | } 33 | 34 | public T Current => current.Current; 35 | 36 | public void Recurse(IEnumerator newCurrent) 37 | { 38 | if (newCurrent == null) return; 39 | stack.Push(current); 40 | current = newCurrent; 41 | } 42 | public void Recurse(IEnumerable newCurrent) 43 | { 44 | if (newCurrent == null) return; 45 | Recurse(newCurrent.GetEnumerator()); 46 | } 47 | public void Recurse(params T[] newCurrent) 48 | { 49 | Recurse((IEnumerable)newCurrent); 50 | } 51 | 52 | public StackEnumerator(IEnumerator initial) 53 | { 54 | current = initial ?? System.Linq.Enumerable.Empty().GetEnumerator(); 55 | } 56 | public StackEnumerator(IEnumerable initial) : this(initial?.GetEnumerator()) 57 | { 58 | } 59 | public StackEnumerator(params T[] initial) : this((IEnumerable)initial) 60 | { 61 | } 62 | 63 | // Foreach support 64 | [EditorBrowsable(EditorBrowsableState.Never)] 65 | public StackEnumerator GetEnumerator() 66 | { 67 | return this; 68 | } 69 | 70 | public void Dispose() 71 | { 72 | current.Dispose(); 73 | foreach (var item in stack) 74 | item.Dispose(); 75 | stack.Clear(); 76 | } 77 | } 78 | 79 | public sealed class StackEnumerator : IDisposable 80 | { 81 | public struct ContextCurrent 82 | { 83 | public TContext Context { get; } 84 | 85 | public T Current { get; } 86 | 87 | public ContextCurrent(TContext context, T current) 88 | { 89 | Context = context; 90 | Current = current; 91 | } 92 | } 93 | 94 | private readonly Stack>> stack = new Stack>>(); 95 | private Tuple> current; 96 | 97 | public bool MoveNext() 98 | { 99 | while (!current.Item2.MoveNext()) 100 | { 101 | current.Item2.Dispose(); 102 | if (stack.Count == 0) return false; 103 | current = stack.Pop(); 104 | } 105 | 106 | return true; 107 | } 108 | 109 | public ContextCurrent Current => new ContextCurrent(current.Item1, current.Item2.Current); 110 | 111 | public void Recurse(TContext newContext, IEnumerator newCurrent) 112 | { 113 | if (newCurrent == null) return; 114 | stack.Push(current); 115 | current = Tuple.Create(newContext, newCurrent); 116 | } 117 | public void Recurse(TContext newContext, IEnumerable newCurrent) 118 | { 119 | if (newCurrent == null) return; 120 | Recurse(newContext, newCurrent.GetEnumerator()); 121 | } 122 | public void Recurse(TContext newContext, params T[] newCurrent) 123 | { 124 | Recurse(newContext, (IEnumerable)newCurrent); 125 | } 126 | 127 | public StackEnumerator(TContext initialContext, IEnumerator initial) 128 | { 129 | current = Tuple.Create(initialContext, initial ?? System.Linq.Enumerable.Empty().GetEnumerator()); 130 | } 131 | public StackEnumerator(TContext initialContext, IEnumerable initial) : this(initialContext, initial?.GetEnumerator()) 132 | { 133 | } 134 | public StackEnumerator(TContext initialContext, params T[] initial) : this(initialContext, (IEnumerable)initial) 135 | { 136 | } 137 | 138 | // Foreach support 139 | [EditorBrowsable(EditorBrowsableState.Never)] 140 | public StackEnumerator GetEnumerator() 141 | { 142 | return this; 143 | } 144 | 145 | public void Dispose() 146 | { 147 | current.Item2.Dispose(); 148 | foreach (var item in stack) 149 | item.Item2.Dispose(); 150 | stack.Clear(); 151 | } 152 | } 153 | } 154 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ILMerge 2 | 3 | [![NuGet](https://img.shields.io/nuget/v/ILMerge.svg?style=flat-square&label=nuget)](https://www.nuget.org/packages/ILMerge/) 4 | 5 | ILMerge is a utility that merges multiple .NET assemblies into a single assembly. 6 | It is freely available for use and is available as a [NuGet package](https://www.nuget.org/packages/ilmerge). 7 | 8 | If you have any problems using it, please get in touch. (mbarnett _at_ microsoft _dot_ com). 9 | But first try reading [the documentation](ilmerge-manual.md). 10 | 11 | ILMerge takes a set of input assemblies and merges them into one target assembly. 12 | The first assembly in the list of input assemblies is the primary assembly. 13 | When the primary assembly is an executable, 14 | then the target assembly is created as an executable with the same entry point as the primary assembly. 15 | Also, if the primary assembly has a strong name, and a .snk file is provided, 16 | then the target assembly is re-signed with the specified key so that it also has a strong name. 17 | 18 | ILMerge is packaged as a console application. 19 | But all of its functionality is also available programmatically. 20 | 21 | There are several options that control the behavior of ILMerge. 22 | See the documentation that comes with the tool for details. 23 | 24 | The current version is 3.0.29 (released on 10 April 2019). 25 | NOTE: There is no longer a version of ILMerge that runs in the v1.1 runtime. 26 | 27 | ILMerge runs in the v4.0 .NET Runtime, 28 | but it is also able to merge assemblies from other framework versions using the `/targetplatformoption`. 29 | Please see the documentation. 30 | (However, it can merge PDB files only for v2 (and later) assemblies.) 31 | 32 | Currently, ILMerge works only on Windows-based platforms. It does not yet support Rotor or Mono. 33 | 34 | If you use ASP.NET v2.0, then it provides a tool (based on ILMerge) to combine assemblies created during precompilation. 35 | You can get more details from the [ASP.NET web site](http://msdn.microsoft.com/en-us/library/bb397866.aspx). 36 | 37 | ## Installation 38 | 39 | As noted on the [ilmerge NuGet page](https://www.nuget.org/packages/ilmerge), the package can be installed from the Visual Studio environment. Expand the project container in the `Solution Explorer` view. Right click on `references` and select `Manage NuGet Packages` 40 | 41 | ![NuGet References Setting](images/NuGet_references_setting.png) 42 | 43 | Ensure the `Package source` is set to `nuget.org` 44 | 45 | ![NuGet Package source](images/NuGet_Package_source.png) 46 | 47 | Next, click on Tools - NuGet Package Manager - Package Manager Console. Ensure the `Package source` is also set to `nuget.org` 48 | 49 | ![NuGet Pakage Manager Console source.PNG](images/NuGet_Package_Manager_Console_source.png) 50 | 51 | To install for the project, use the Install-Package command: 52 | 53 | ``` 54 | Install-Package ilmerge -Version 3.0.29 55 | ``` 56 | 57 | ## Usage 58 | 59 | ### MSBuild 60 | 61 | ILMerge can be used in MSBuild using the NuGet package: 62 | 63 | ```xml 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | ``` 77 | 78 | Edit the project `.csproj` or `.vbproj` files (inside the respective ` .. ` tags, typically at the end of the file. If compiling for a specific target, use explicit directories such as `Bin\x64\Release`: 79 | 80 | 81 | ``` 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | ``` 91 | Although whitespace is usually ignored in XML files, in this case the exact text is processed as a DOS command, so to improve readability, use the carat `^` (shift 6) line extenders: 92 | 93 | ``` 94 | 95 | 96 | 97 | 98 | 99 | 100 | 105 | 106 | ``` 107 | 108 | The DOS dir /b option can be helpful in listing all of the dependencies: 109 | ``` 110 | dir bin\x64\Debug\*.dll /b 111 | ``` 112 | 113 | From Visual Studio Developer Command Prompt: 114 | ```ps1 115 | # Download/install the package reference 116 | msbuild /t:Restore 117 | 118 | # Run the ILMerge target 119 | msbuild /t:ILMerge 120 | ``` 121 | 122 | ### To run `ILMerge` in a batch file: 123 | 124 | The Visual Studio Developer Command Prompt is not needed here, as `msbuild` is not used. 125 | 126 | ``` 127 | @echo off 128 | 129 | :: this script needs https://www.nuget.org/packages/ilmerge 130 | 131 | :: set your target executable name (typically [projectname].exe) 132 | SET APP_NAME=myapp.exe 133 | 134 | :: Set build, used for directory. Typically Release or Debug 135 | SET ILMERGE_BUILD=Debug 136 | 137 | :: Set platform, typically x64 138 | SET ILMERGE_PLATFORM=x64 139 | 140 | :: set your NuGet ILMerge Version, this is the number from the package manager install, for example: 141 | :: PM> Install-Package ilmerge -Version 3.0.29 142 | :: to confirm it is installed for a given project, see the packages.config file 143 | SET ILMERGE_VERSION=3.0.29 144 | 145 | :: the full ILMerge should be found here: 146 | SET ILMERGE_PATH=%USERPROFILE%\.nuget\packages\ilmerge\%ILMERGE_VERSION%\tools\net452 147 | :: dir "%ILMERGE_PATH%"\ILMerge.exe 148 | 149 | echo Merging %APP_NAME% ... 150 | 151 | :: add project DLL's starting with replacing the FirstLib with this project's DLL 152 | "%ILMERGE_PATH%"\ILMerge.exe Bin\%ILMERGE_PLATFORM%\%ILMERGE_BUILD%\%APP_NAME% ^ 153 | /lib:Bin\%ILMERGE_PLATFORM%\%ILMERGE_BUILD%\ ^ 154 | /out:%APP_NAME% ^ 155 | FirstLib.dll ^ 156 | mylib1.dll ^ 157 | Microsoft.lib2.dll ^ 158 | SomeOtherLib.dll ^ 159 | \otherlibdir\otherlib.dll 160 | 161 | 162 | :Done 163 | dir %APP_NAME% 164 | ``` 165 | 166 | 167 | -------------------------------------------------------------------------------- /System.Compiler/ClrStrongName.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | // See the LICENSE file in the project root for more information. 4 | 5 | using System.Runtime.InteropServices; 6 | using Microsoft.Win32.SafeHandles; 7 | 8 | namespace System.Compiler 9 | { 10 | public static class ClrStrongName 11 | { 12 | private static IClrStrongName clrStrongName; 13 | private static IClrStrongName GetClrStrongName() 14 | { 15 | return clrStrongName ?? (clrStrongName = 16 | (IClrStrongName)RuntimeEnvironment.GetRuntimeInterfaceAsObject( 17 | new Guid("B79B0ACD-F5CD-409b-B5A5-A16244610B92"), 18 | typeof(IClrStrongName).GUID)); 19 | } 20 | 21 | public static void SignatureGeneration(string filePath, string keyContainer, byte[] keyBlob) 22 | { 23 | GetClrStrongName().StrongNameSignatureGeneration(filePath, keyContainer, keyBlob, keyBlob.Length, IntPtr.Zero, IntPtr.Zero); 24 | } 25 | 26 | // ReSharper disable UnusedMember.Global – All preceding method declarations are needed 27 | // in order for StrongNameSignatureGeneration to end up at the right COM slot number. 28 | 29 | [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("9FD93CCF-3280-4391-B3A9-96E1CDE77C8D")] 30 | private interface IClrStrongName 31 | { 32 | void GetHashFromAssemblyFile( 33 | string pszFilePath, 34 | ref uint piHashAlg, 35 | [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] byte[] pbHash, 36 | uint cchHash, 37 | out uint pchHash); 38 | 39 | void GetHashFromAssemblyFileW( 40 | string pwzFilePath, 41 | ref uint piHashAlg, 42 | [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] byte[] pbHash, 43 | uint cchHash, 44 | out uint pchHash); 45 | 46 | void GetHashFromBlob( 47 | IntPtr pbBlob, 48 | uint cchBlob, 49 | ref uint piHashAlg, 50 | [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 5)] byte[] pbHash, 51 | uint cchHash, 52 | out uint pchHash); 53 | 54 | void GetHashFromFile( 55 | string pszFilePath, 56 | ref int piHashAlg, 57 | [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] byte[] pbHash, 58 | uint cchHash, 59 | out uint pchHash); 60 | 61 | void GetHashFromFileW( 62 | string pwzFilePath, 63 | ref uint piHashAlg, 64 | [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] byte[] pbHash, 65 | uint cchHash, 66 | out uint pchHash); 67 | 68 | void GetHashFromHandle( 69 | SafeFileHandle hFile, 70 | ref uint piHashAlg, 71 | [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] byte[] pbHash, 72 | uint cchHash, 73 | out uint pchHash); 74 | 75 | uint StrongNameCompareAssemblies(string pwzAssembly1, string pwzAssembly2); 76 | 77 | void StrongNameFreeBuffer(IntPtr pbMemory); 78 | 79 | void StrongNameGetBlob( 80 | string pwzFilePath, 81 | [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] byte[] pbBlob, 82 | ref uint pcbBlob); 83 | 84 | void StrongNameGetBlobFromImage( 85 | IntPtr pbBase, 86 | uint dwLength, 87 | [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] byte[] pbBlob, 88 | ref uint pcbBlob); 89 | 90 | void StrongNameGetPublicKey( 91 | string pwzKeyContainer, 92 | IntPtr pbKeyBlob, 93 | uint cbKeyBlob, 94 | out IntPtr ppbPublicKeyBlob, 95 | out uint pcbPublicKeyBlob); 96 | 97 | uint StrongNameHashSize(uint ulHashAlg); 98 | 99 | void StrongNameKeyDelete(string pwzKeyContainer); 100 | 101 | void StrongNameKeyGen( 102 | string pwzKeyContainer, 103 | uint dwFlags, 104 | out IntPtr ppbKeyBlob, 105 | out uint pcbKeyBlob); 106 | 107 | void StrongNameKeyGenEx( 108 | string pwzKeyContainer, 109 | uint dwFlags, 110 | uint dwKeySize, 111 | out IntPtr ppbKeyBlob, 112 | out uint pcbKeyBlob); 113 | 114 | void StrongNameKeyInstall( 115 | string pwzKeyContainer, 116 | IntPtr pbKeyBlob, 117 | uint cbKeyBlob); 118 | 119 | void StrongNameSignatureGeneration( 120 | string pwzFilePath, 121 | string pwzKeyContainer, 122 | [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] byte[] pbKeyBlob, 123 | int cbKeyBlob, 124 | IntPtr ppbSignatureBlob, 125 | IntPtr pcbSignatureBlob); 126 | 127 | void StrongNameSignatureGenerationEx( 128 | string wszFilePath, 129 | string wszKeyContainer, 130 | IntPtr pbKeyBlob, 131 | uint cbKeyBlob, 132 | out IntPtr ppbSignatureBlob, 133 | out uint pcbSignatureBlob, 134 | uint dwFlags); 135 | 136 | uint StrongNameSignatureSize(IntPtr pbPublicKeyBlob, uint cbPublicKeyBlob); 137 | 138 | uint StrongNameSignatureVerification(string pwzFilePath, uint dwInFlags); 139 | 140 | bool StrongNameSignatureVerificationEx(string pwzFilePath, bool fForceVerification); 141 | 142 | uint StrongNameSignatureVerificationFromImage(IntPtr pbBase, uint dwLength, uint dwInFlags); 143 | 144 | void StrongNameTokenFromAssembly(string pwzFilePath, out IntPtr ppbStrongNameToken, out uint pcbStrongNameToken); 145 | 146 | void StrongNameTokenFromAssemblyEx( 147 | string pwzFilePath, 148 | out IntPtr ppbStrongNameToken, 149 | out uint pcbStrongNameToken, 150 | out IntPtr ppbPublicKeyBlob, 151 | out uint pcbPublicKeyBlob); 152 | 153 | void StrongNameTokenFromPublicKey( 154 | IntPtr pbPublicKeyBlob, 155 | uint cbPublicKeyBlob, 156 | out IntPtr ppbStrongNameToken, 157 | out uint pcbStrongNameToken); 158 | } 159 | } 160 | } 161 | -------------------------------------------------------------------------------- /System.Compiler/OpCode.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | // See the LICENSE file in the project root for more information. 4 | 5 | using System; 6 | 7 | #if CCINamespace 8 | namespace Microsoft.Cci{ 9 | #else 10 | namespace System.Compiler{ 11 | #endif 12 | public enum OpCode{ 13 | Nop = 0x00, 14 | Break = 0x01, 15 | Ldarg_0 = 0x02, 16 | Ldarg_1 = 0x03, 17 | Ldarg_2 = 0x04, 18 | Ldarg_3 = 0x05, 19 | Ldloc_0 = 0x06, 20 | Ldloc_1 = 0x07, 21 | Ldloc_2 = 0x08, 22 | Ldloc_3 = 0x09, 23 | Stloc_0 = 0x0a, 24 | Stloc_1 = 0x0b, 25 | Stloc_2 = 0x0c, 26 | Stloc_3 = 0x0d, 27 | Ldarg_S = 0x0e, 28 | Ldarga_S = 0x0f, 29 | Starg_S = 0x10, 30 | Ldloc_S = 0x11, 31 | Ldloca_S = 0x12, 32 | Stloc_S = 0x13, 33 | Ldnull = 0x14, 34 | Ldc_I4_M1 = 0x15, 35 | Ldc_I4_0 = 0x16, 36 | Ldc_I4_1 = 0x17, 37 | Ldc_I4_2 = 0x18, 38 | Ldc_I4_3 = 0x19, 39 | Ldc_I4_4 = 0x1a, 40 | Ldc_I4_5 = 0x1b, 41 | Ldc_I4_6 = 0x1c, 42 | Ldc_I4_7 = 0x1d, 43 | Ldc_I4_8 = 0x1e, 44 | Ldc_I4_S = 0x1f, 45 | Ldc_I4 = 0x20, 46 | Ldc_I8 = 0x21, 47 | Ldc_R4 = 0x22, 48 | Ldc_R8 = 0x23, 49 | Dup = 0x25, 50 | Pop = 0x26, 51 | Jmp = 0x27, 52 | Call = 0x28, 53 | Calli = 0x29, 54 | Ret = 0x2a, 55 | Br_S = 0x2b, 56 | Brfalse_S = 0x2c, 57 | Brtrue_S = 0x2d, 58 | Beq_S = 0x2e, 59 | Bge_S = 0x2f, 60 | Bgt_S = 0x30, 61 | Ble_S = 0x31, 62 | Blt_S = 0x32, 63 | Bne_Un_S = 0x33, 64 | Bge_Un_S = 0x34, 65 | Bgt_Un_S = 0x35, 66 | Ble_Un_S = 0x36, 67 | Blt_Un_S = 0x37, 68 | Br = 0x38, 69 | Brfalse = 0x39, 70 | Brtrue = 0x3a, 71 | Beq = 0x3b, 72 | Bge = 0x3c, 73 | Bgt = 0x3d, 74 | Ble = 0x3e, 75 | Blt = 0x3f, 76 | Bne_Un = 0x40, 77 | Bge_Un = 0x41, 78 | Bgt_Un = 0x42, 79 | Ble_Un = 0x43, 80 | Blt_Un = 0x44, 81 | @Switch = 0x45, 82 | Ldind_I1 = 0x46, 83 | Ldind_U1 = 0x47, 84 | Ldind_I2 = 0x48, 85 | Ldind_U2 = 0x49, 86 | Ldind_I4 = 0x4a, 87 | Ldind_U4 = 0x4b, 88 | Ldind_I8 = 0x4c, 89 | Ldind_I = 0x4d, 90 | Ldind_R4 = 0x4e, 91 | Ldind_R8 = 0x4f, 92 | Ldind_Ref = 0x50, 93 | Stind_Ref = 0x51, 94 | Stind_I1 = 0x52, 95 | Stind_I2 = 0x53, 96 | Stind_I4 = 0x54, 97 | Stind_I8 = 0x55, 98 | Stind_R4 = 0x56, 99 | Stind_R8 = 0x57, 100 | Add = 0x58, 101 | Sub = 0x59, 102 | Mul = 0x5a, 103 | Div = 0x5b, 104 | Div_Un = 0x5c, 105 | Rem = 0x5d, 106 | Rem_Un = 0x5e, 107 | And = 0x5f, 108 | Or = 0x60, 109 | Xor = 0x61, 110 | Shl = 0x62, 111 | Shr = 0x63, 112 | Shr_Un = 0x64, 113 | Neg = 0x65, 114 | Not = 0x66, 115 | Conv_I1 = 0x67, 116 | Conv_I2 = 0x68, 117 | Conv_I4 = 0x69, 118 | Conv_I8 = 0x6a, 119 | Conv_R4 = 0x6b, 120 | Conv_R8 = 0x6c, 121 | Conv_U4 = 0x6d, 122 | Conv_U8 = 0x6e, 123 | Callvirt = 0x6f, 124 | Cpobj = 0x70, 125 | Ldobj = 0x71, 126 | Ldstr = 0x72, 127 | Newobj = 0x73, 128 | Castclass = 0x74, 129 | Isinst = 0x75, 130 | Conv_R_Un = 0x76, 131 | Unbox = 0x79, 132 | Throw = 0x7a, 133 | Ldfld = 0x7b, 134 | Ldflda = 0x7c, 135 | Stfld = 0x7d, 136 | Ldsfld = 0x7e, 137 | Ldsflda = 0x7f, 138 | Stsfld = 0x80, 139 | Stobj = 0x81, 140 | Conv_Ovf_I1_Un = 0x82, 141 | Conv_Ovf_I2_Un = 0x83, 142 | Conv_Ovf_I4_Un = 0x84, 143 | Conv_Ovf_I8_Un = 0x85, 144 | Conv_Ovf_U1_Un = 0x86, 145 | Conv_Ovf_U2_Un = 0x87, 146 | Conv_Ovf_U4_Un = 0x88, 147 | Conv_Ovf_U8_Un = 0x89, 148 | Conv_Ovf_I_Un = 0x8a, 149 | Conv_Ovf_U_Un = 0x8b, 150 | Box = 0x8c, 151 | Newarr = 0x8d, 152 | Ldlen = 0x8e, 153 | Ldelema = 0x8f, 154 | Ldelem_I1 = 0x90, 155 | Ldelem_U1 = 0x91, 156 | Ldelem_I2 = 0x92, 157 | Ldelem_U2 = 0x93, 158 | Ldelem_I4 = 0x94, 159 | Ldelem_U4 = 0x95, 160 | Ldelem_I8 = 0x96, 161 | Ldelem_I = 0x97, 162 | Ldelem_R4 = 0x98, 163 | Ldelem_R8 = 0x99, 164 | Ldelem_Ref = 0x9a, 165 | Stelem_I = 0x9b, 166 | Stelem_I1 = 0x9c, 167 | Stelem_I2 = 0x9d, 168 | Stelem_I4 = 0x9e, 169 | Stelem_I8 = 0x9f, 170 | Stelem_R4 = 0xa0, 171 | Stelem_R8 = 0xa1, 172 | Stelem_Ref = 0xa2, 173 | Ldelem = 0xa3, 174 | Stelem = 0xa4, 175 | Unbox_Any = 0xa5, 176 | Conv_Ovf_I1 = 0xb3, 177 | Conv_Ovf_U1 = 0xb4, 178 | Conv_Ovf_I2 = 0xb5, 179 | Conv_Ovf_U2 = 0xb6, 180 | Conv_Ovf_I4 = 0xb7, 181 | Conv_Ovf_U4 = 0xb8, 182 | Conv_Ovf_I8 = 0xb9, 183 | Conv_Ovf_U8 = 0xba, 184 | Refanyval = 0xc2, 185 | Ckfinite = 0xc3, 186 | Mkrefany = 0xc6, 187 | Ldtoken = 0xd0, 188 | Conv_U2 = 0xd1, 189 | Conv_U1 = 0xd2, 190 | Conv_I = 0xd3, 191 | Conv_Ovf_I = 0xd4, 192 | Conv_Ovf_U = 0xd5, 193 | Add_Ovf = 0xd6, 194 | Add_Ovf_Un = 0xd7, 195 | Mul_Ovf = 0xd8, 196 | Mul_Ovf_Un = 0xd9, 197 | Sub_Ovf = 0xda, 198 | Sub_Ovf_Un = 0xdb, 199 | Endfinally = 0xdc, 200 | Leave = 0xdd, 201 | Leave_S = 0xde, 202 | Stind_I = 0xdf, 203 | Conv_U = 0xe0, 204 | Prefix7 = 0xf8, 205 | Prefix6 = 0xf9, 206 | Prefix5 = 0xfa, 207 | Prefix4 = 0xfb, 208 | Prefix3 = 0xfc, 209 | Prefix2 = 0xfd, 210 | Prefix1 = 0xfe, 211 | PrefixRef = 0xff, 212 | Arglist = 0xfe00, 213 | Ceq = 0xfe01, 214 | Cgt = 0xfe02, 215 | Cgt_Un = 0xfe03, 216 | Clt = 0xfe04, 217 | Clt_Un = 0xfe05, 218 | Ldftn = 0xfe06, 219 | Ldvirtftn = 0xfe07, 220 | Ldarg = 0xfe09, 221 | Ldarga = 0xfe0a, 222 | Starg = 0xfe0b, 223 | Ldloc = 0xfe0c, 224 | Ldloca = 0xfe0d, 225 | Stloc = 0xfe0e, 226 | Localloc = 0xfe0f, 227 | Endfilter = 0xfe11, 228 | Unaligned_ = 0xfe12, 229 | Volatile_ = 0xfe13, 230 | Tail_ = 0xfe14, 231 | Initobj = 0xfe15, 232 | Constrained_ = 0xfe16, 233 | Cpblk = 0xfe17, 234 | Initblk = 0xfe18, 235 | Rethrow = 0xfe1a, 236 | Sizeof = 0xfe1c, 237 | Refanytype = 0xfe1d, 238 | Readonly_ = 0xfe1e, 239 | // fake opcodes 240 | #if WHIDBEY 241 | [CLSCompliant(false)] 242 | #endif 243 | _Locals = 0xfef7, 244 | #if WHIDBEY 245 | [CLSCompliant(false)] 246 | #endif 247 | _Try = 0xfef8, 248 | #if WHIDBEY 249 | [CLSCompliant(false)] 250 | #endif 251 | _EndTry = 0xfef9, 252 | #if WHIDBEY 253 | [CLSCompliant(false)] 254 | #endif 255 | _Filter = 0xfefa, 256 | #if WHIDBEY 257 | [CLSCompliant(false)] 258 | #endif 259 | _EndFilter = 0xfefb, 260 | #if WHIDBEY 261 | [CLSCompliant(false)] 262 | #endif 263 | _Catch = 0xfefc, 264 | #if WHIDBEY 265 | [CLSCompliant(false)] 266 | #endif 267 | _Finally = 0xfefd, 268 | #if WHIDBEY 269 | [CLSCompliant(false)] 270 | #endif 271 | _Fault = 0xfefe, 272 | #if WHIDBEY 273 | [CLSCompliant(false)] 274 | #endif 275 | _EndHandler = 0xfeff 276 | } 277 | } 278 | -------------------------------------------------------------------------------- /System.Compiler/PDBreader/BitAccess.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | // See the LICENSE file in the project root for more information. 4 | 5 | using System; 6 | using System.IO; 7 | using System.Text; 8 | 9 | namespace Microsoft.Cci.Pdb 10 | { 11 | internal class BitAccess 12 | { 13 | internal BitAccess(byte[] buffer) 14 | { 15 | this.buffer = buffer; 16 | offset = 0; 17 | } 18 | 19 | internal BitAccess(int capacity) 20 | { 21 | this.buffer = new byte[capacity]; 22 | } 23 | 24 | internal byte[] Buffer 25 | { 26 | get { return buffer; } 27 | } 28 | private byte[] buffer; 29 | 30 | internal void FillBuffer(Stream stream, int capacity) 31 | { 32 | MinCapacity(capacity); 33 | stream.Read(buffer, 0, capacity); 34 | offset = 0; 35 | } 36 | 37 | internal void Append(Stream stream, int count) 38 | { 39 | int newCapacity = offset + count; 40 | if (buffer.Length < newCapacity) 41 | { 42 | byte[] newBuffer = new byte[newCapacity]; 43 | Array.Copy(buffer, newBuffer, buffer.Length); 44 | buffer = newBuffer; 45 | } 46 | stream.Read(buffer, offset, count); 47 | offset += count; 48 | } 49 | 50 | internal int Position 51 | { 52 | get { return offset; } 53 | set { offset = value; } 54 | } 55 | private int offset; 56 | 57 | //internal void WriteBuffer(Stream stream, int count) { 58 | // stream.Write(buffer, 0, count); 59 | //} 60 | 61 | internal void MinCapacity(int capacity) 62 | { 63 | if (buffer.Length < capacity) 64 | { 65 | buffer = new byte[capacity]; 66 | } 67 | offset = 0; 68 | } 69 | 70 | internal void Align(int alignment) 71 | { 72 | while ((offset % alignment) != 0) 73 | { 74 | offset++; 75 | } 76 | } 77 | 78 | //internal void WriteInt32(int value) { 79 | // buffer[offset + 0] = (byte)value; 80 | // buffer[offset + 1] = (byte)(value >> 8); 81 | // buffer[offset + 2] = (byte)(value >> 16); 82 | // buffer[offset + 3] = (byte)(value >> 24); 83 | // offset += 4; 84 | //} 85 | 86 | //internal void WriteInt32(int[] values) { 87 | // for (int i = 0; i < values.Length; i++) { 88 | // WriteInt32(values[i]); 89 | // } 90 | //} 91 | 92 | //internal void WriteBytes(byte[] bytes) { 93 | // for (int i = 0; i < bytes.Length; i++) { 94 | // buffer[offset++] = bytes[i]; 95 | // } 96 | //} 97 | 98 | internal void ReadInt16(out short value) 99 | { 100 | value = (short)((buffer[offset + 0] & 0xFF) | 101 | (buffer[offset + 1] << 8)); 102 | offset += 2; 103 | } 104 | 105 | internal void ReadInt8(out sbyte value) 106 | { 107 | value = (sbyte)buffer[offset]; 108 | offset += 1; 109 | } 110 | 111 | internal void ReadInt32(out int value) 112 | { 113 | value = (int)((buffer[offset + 0] & 0xFF) | 114 | (buffer[offset + 1] << 8) | 115 | (buffer[offset + 2] << 16) | 116 | (buffer[offset + 3] << 24)); 117 | offset += 4; 118 | } 119 | 120 | internal void ReadInt64(out long value) 121 | { 122 | value = (long)(((ulong)buffer[offset + 0] & 0xFF) | 123 | ((ulong)buffer[offset + 1] << 8) | 124 | ((ulong)buffer[offset + 2] << 16) | 125 | ((ulong)buffer[offset + 3] << 24) | 126 | ((ulong)buffer[offset + 4] << 32) | 127 | ((ulong)buffer[offset + 5] << 40) | 128 | ((ulong)buffer[offset + 6] << 48) | 129 | ((ulong)buffer[offset + 7] << 56)); 130 | offset += 8; 131 | } 132 | 133 | internal void ReadUInt16(out ushort value) 134 | { 135 | value = (ushort)((buffer[offset + 0] & 0xFF) | 136 | (buffer[offset + 1] << 8)); 137 | offset += 2; 138 | } 139 | 140 | internal void ReadUInt8(out byte value) 141 | { 142 | value = (byte)((buffer[offset + 0] & 0xFF)); 143 | offset += 1; 144 | } 145 | 146 | internal void ReadUInt32(out uint value) 147 | { 148 | value = (uint)((buffer[offset + 0] & 0xFF) | 149 | (buffer[offset + 1] << 8) | 150 | (buffer[offset + 2] << 16) | 151 | (buffer[offset + 3] << 24)); 152 | offset += 4; 153 | } 154 | 155 | internal void ReadUInt64(out ulong value) 156 | { 157 | value = (ulong)(((ulong)buffer[offset + 0] & 0xFF) | 158 | ((ulong)buffer[offset + 1] << 8) | 159 | ((ulong)buffer[offset + 2] << 16) | 160 | ((ulong)buffer[offset + 3] << 24) | 161 | ((ulong)buffer[offset + 4] << 32) | 162 | ((ulong)buffer[offset + 5] << 40) | 163 | ((ulong)buffer[offset + 6] << 48) | 164 | ((ulong)buffer[offset + 7] << 56)); 165 | offset += 8; 166 | } 167 | 168 | internal void ReadInt32(int[] values) 169 | { 170 | for (int i = 0; i < values.Length; i++) 171 | { 172 | ReadInt32(out values[i]); 173 | } 174 | } 175 | 176 | internal void ReadUInt32(uint[] values) 177 | { 178 | for (int i = 0; i < values.Length; i++) 179 | { 180 | ReadUInt32(out values[i]); 181 | } 182 | } 183 | 184 | internal void ReadBytes(byte[] bytes) 185 | { 186 | for (int i = 0; i < bytes.Length; i++) 187 | { 188 | bytes[i] = buffer[offset++]; 189 | } 190 | } 191 | 192 | internal float ReadFloat() 193 | { 194 | float result = BitConverter.ToSingle(buffer, offset); 195 | offset += 4; 196 | return result; 197 | } 198 | 199 | internal double ReadDouble() 200 | { 201 | double result = BitConverter.ToDouble(buffer, offset); 202 | offset += 8; 203 | return result; 204 | } 205 | 206 | internal decimal ReadDecimal() 207 | { 208 | int[] bits = new int[4]; 209 | this.ReadInt32(bits); 210 | return new decimal(bits[2], bits[3], bits[1], bits[0] < 0, (byte)((bits[0] & 0x00FF0000) >> 16)); 211 | } 212 | 213 | internal void ReadBString(out string value) 214 | { 215 | ushort len; 216 | this.ReadUInt16(out len); 217 | value = Encoding.UTF8.GetString(buffer, offset, len); 218 | offset += len; 219 | } 220 | 221 | internal string ReadBString(int len) 222 | { 223 | var result = Encoding.UTF8.GetString(buffer, offset, len); 224 | offset += len; 225 | return result; 226 | } 227 | 228 | internal void ReadCString(out string value) 229 | { 230 | int len = 0; 231 | while (offset + len < buffer.Length && buffer[offset + len] != 0) 232 | { 233 | len++; 234 | } 235 | value = Encoding.UTF8.GetString(buffer, offset, len); 236 | offset += len + 1; 237 | } 238 | 239 | internal void SkipCString(out string value) 240 | { 241 | int len = 0; 242 | while (offset + len < buffer.Length && buffer[offset + len] != 0) 243 | { 244 | len++; 245 | } 246 | offset += len + 1; 247 | value = null; 248 | } 249 | 250 | internal void ReadGuid(out Guid guid) 251 | { 252 | uint a; 253 | ushort b; 254 | ushort c; 255 | byte d; 256 | byte e; 257 | byte f; 258 | byte g; 259 | byte h; 260 | byte i; 261 | byte j; 262 | byte k; 263 | 264 | ReadUInt32(out a); 265 | ReadUInt16(out b); 266 | ReadUInt16(out c); 267 | ReadUInt8(out d); 268 | ReadUInt8(out e); 269 | ReadUInt8(out f); 270 | ReadUInt8(out g); 271 | ReadUInt8(out h); 272 | ReadUInt8(out i); 273 | ReadUInt8(out j); 274 | ReadUInt8(out k); 275 | 276 | guid = new Guid(a, b, c, d, e, f, g, h, i, j, k); 277 | } 278 | 279 | internal string ReadString() 280 | { 281 | int len = 0; 282 | while (offset + len < buffer.Length && buffer[offset + len] != 0) 283 | { 284 | len += 2; 285 | } 286 | string result = Encoding.Unicode.GetString(buffer, offset, len); 287 | offset += len + 2; 288 | return result; 289 | } 290 | 291 | } 292 | } 293 | -------------------------------------------------------------------------------- /System.Compiler/ExceptionStrings.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | text/microsoft-resx 32 | 33 | 34 | 1.0.0.0 35 | 36 | 37 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 38 | 39 | 40 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 41 | 42 | 43 | Bad blob heap index. 44 | 45 | 46 | Assembly {0} at platform assembly location {1} has version {2} which does not match the target platform version {3}. 47 | 48 | 49 | Unknown virtual address {0}. 50 | 51 | 52 | Unknown constant type. 53 | 54 | 55 | Bad guid heap index. 56 | 57 | 58 | Bad string heap index. 59 | 60 | 61 | Bad user string heap index. 62 | 63 | 64 | No metadata stream. 65 | 66 | 67 | ENCLog Table encountered. 68 | 69 | 70 | ENCMap Table encountered. 71 | 72 | 73 | Unsupported table encountered. 74 | 75 | 76 | Bad CLI header. 77 | 78 | 79 | Bad magic number. 80 | 81 | 82 | Bad metadata header signature. 83 | 84 | 85 | Bad COFF header signature. 86 | 87 | 88 | Bad PE header magic number. 89 | 90 | 91 | File too big. 92 | 93 | 94 | CreateFileMapping returned error code {0}. 95 | 96 | 97 | MapViewOfFile returned error code {0}. 98 | 99 | 100 | The pdb associated with {0} is out of date. 101 | 102 | 103 | GetReaderForFile returned an unexpected HResult: 0x{0}. 104 | 105 | 106 | Invalid module table. 107 | 108 | 109 | Module or assembly depends on a version of core library that is newer than the one the Reader uses to resolve system types. 110 | 111 | 112 | Bad TypeDefOrRef. 113 | 114 | 115 | Assembly reference not resolved: {0}. 116 | 117 | 118 | Malformed signature. 119 | 120 | 121 | Bad security permission set blob. 122 | 123 | 124 | Could not resolve type: {0}. 125 | 126 | 127 | Security attribute type does not have a default constructor: {0}. 128 | 129 | 130 | Unexpected type in custom attribute. 131 | 132 | 133 | Bad serialized type name. 134 | 135 | 136 | Bad constant parent index. 137 | 138 | 139 | Invalid local signature. 140 | 141 | 142 | Bad CustomAttributeType encoded token. 143 | 144 | 145 | Bad member token. 146 | 147 | 148 | Could not resolve member reference: {0}. 149 | 150 | 151 | Invalid base class. 152 | 153 | 154 | Can't load type extension for {0}. Assembly {1} not found. 155 | 156 | 157 | Collection is read-only. 158 | 159 | 160 | Could not resolve type reference: {0}. 161 | 162 | 163 | Could not find referenced module: {0}. 164 | 165 | 166 | Could not find exported type: {0} in module {1}. 167 | 168 | 169 | Bad metadata in export type table: no such assembly reference. 170 | 171 | 172 | Could not find exported type: {0} in assembly. 173 | 174 | 175 | Bad metadata in export type table: no such parent type. 176 | 177 | 178 | Could not find exported nested type: {0} in type {1}. 179 | 180 | 181 | Invalid type table index. 182 | 183 | 184 | Bad type parameter in position {0} for type {1}. 185 | 186 | 187 | Bad method type parameter in position {0}. 188 | 189 | 190 | Invalid fat method header. 191 | 192 | 193 | Bad method header section. 194 | 195 | 196 | Too many method header sections. 197 | 198 | 199 | Bad exception handler type. 200 | 201 | 202 | Bad calli signature. 203 | 204 | 205 | Unknown opcode. 206 | 207 | 208 | Unknown opCode encountered: {0}. 209 | 210 | 211 | Internal compiler error. 212 | 213 | 214 | Unresolved assembly reference not allowed: {0}. 215 | 216 | 217 | Unresolved module reference not allowed. 218 | 219 | 220 | Invalid assembly strong name: {0}. 221 | 222 | 223 | Key needs to be greater than 0. 224 | 225 | 226 | The following error was encountered while reading module '{0}': {1} 227 | 228 | 229 | -------------------------------------------------------------------------------- /System.Compiler/System.Compiler.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Local 6 | 9.0.30729 7 | 2.0 8 | {D7E16B38-3893-4EEF-847F-A3BE807E9546} 9 | 9.0.30729 10 | Debug 11 | 12 | 13 | 14 | 15 | System.Compiler 16 | ..\Common\InterimKey.snk 17 | JScript 18 | Grid 19 | IE50 20 | false 21 | Library 22 | System.Compiler 23 | OnBuildSuccess 24 | 25 | 26 | 27 | 28 | 3.5 29 | 30 | 31 | true 32 | v4.5.2 33 | 6 34 | publish\ 35 | true 36 | Disk 37 | false 38 | Foreground 39 | 7 40 | Days 41 | false 42 | false 43 | true 44 | 0 45 | 1.0.0.%2a 46 | false 47 | false 48 | true 49 | 50 | 0 51 | false 52 | 53 | 54 | true 55 | bin\Debug\ 56 | true 57 | TRACE;DEBUG;WHIDBEY;WHIDBEYwithGenericsAndIEqualityComparer;AllowCsharpConstructorSyntax;ILOFFSETS;NoData;NoRuntimeXml;CodeContracts;CLOUSOT 58 | 0 59 | true 60 | bin\Debug\System.Compiler.xml 61 | 1591;1699 62 | full 63 | AnyCPU 64 | Sdl7.0.ruleset 65 | False 66 | False 67 | True 68 | False 69 | False 70 | False 71 | True 72 | True 73 | True 74 | True 75 | True 76 | True 77 | True 78 | True 79 | False 80 | True 81 | False 82 | False 83 | False 84 | False 85 | False 86 | True 87 | False 88 | True 89 | True 90 | True 91 | False 92 | False 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | True 101 | False 102 | False 103 | True 104 | Full 105 | Build 106 | 0 107 | true 108 | 109 | 110 | true 111 | bin\Release\ 112 | true 113 | WHIDBEY;WHIDBEYwithGenericsAndIEqualityComparer;AllowCsharpConstructorSyntax;ILOFFSETS;NoData;NoRuntimeXml;CodeContracts;CLOUSOT 114 | 0 115 | true 116 | bin\Release\System.Compiler.xml 117 | 1591;1699 118 | full 119 | AnyCPU 120 | 121 | 122 | 123 | System 124 | 125 | 126 | 127 | System.XML 128 | 129 | 130 | 131 | 132 | Code 133 | 134 | 135 | Code 136 | 137 | 138 | 139 | Code 140 | 141 | 142 | Code 143 | 144 | 145 | Code 146 | 147 | 148 | Code 149 | 150 | 151 | Code 152 | 153 | 154 | 155 | 156 | 157 | Code 158 | 159 | 160 | Code 161 | 162 | 163 | Code 164 | 165 | 166 | Code 167 | 168 | 169 | Code 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | Code 196 | 197 | 198 | Code 199 | 200 | 201 | Code 202 | 203 | 204 | Code 205 | 206 | 207 | Code 208 | 209 | 210 | Code 211 | 212 | 213 | Code 214 | 215 | 216 | Code 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | Designer 225 | 226 | 227 | 228 | 229 | InterimKey.snk 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | False 238 | .NET Framework 3.5 SP1 Client Profile 239 | false 240 | 241 | 242 | False 243 | .NET Framework 3.5 SP1 244 | true 245 | 246 | 247 | False 248 | Microsoft Visual Basic PowerPacks 10.0 249 | true 250 | 251 | 252 | False 253 | Windows Installer 3.1 254 | true 255 | 256 | 257 | 258 | 259 | 2.2.13 260 | 261 | 262 | 263 | -------------------------------------------------------------------------------- /System.Compiler/ExceptionStrings.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | // See the LICENSE file in the project root for more information. 4 | 5 | using System; 6 | using System.IO; 7 | using System.Resources; 8 | 9 | #if CCINamespace 10 | namespace Microsoft.Cci{ 11 | #else 12 | namespace System.Compiler{ 13 | #endif 14 | sealed class ExceptionStrings{ 15 | private readonly static WeakReference/*!*/ resMgr = new WeakReference(null); 16 | 17 | private ExceptionStrings(){ 18 | } 19 | 20 | internal static System.Resources.ResourceManager/*!*/ ResourceManager { 21 | get{ 22 | System.Resources.ResourceManager rMgr = ExceptionStrings.resMgr.Target as System.Resources.ResourceManager; 23 | if (rMgr == null){ 24 | #if CCINamespace 25 | rMgr = new System.Resources.ResourceManager("Microsoft.Cci.ExceptionStrings", typeof(ExceptionStrings).Assembly); 26 | #else 27 | rMgr = new System.Resources.ResourceManager("System.Compiler.ExceptionStrings", typeof(ExceptionStrings).Assembly); 28 | #endif 29 | ExceptionStrings.resMgr.Target = rMgr; 30 | } 31 | return rMgr; 32 | } 33 | } 34 | internal static string/*!*/ AssemblyReferenceNotResolved { 35 | get{ 36 | return /*^ (!) ^*/ ResourceManager.GetString("AssemblyReferenceNotResolved", null); 37 | } 38 | } 39 | internal static string/*!*/ BadBlobHeapIndex { 40 | get{ 41 | return /*^ (!) ^*/ ResourceManager.GetString("BadBlobHeapIndex", null); 42 | } 43 | } 44 | internal static string/*!*/ BadCLIHeader { 45 | get{ 46 | return /*^ (!) ^*/ ResourceManager.GetString("BadCLIHeader", null); 47 | } 48 | } 49 | internal static string/*!*/ BadCOFFHeaderSignature { 50 | get{ 51 | return /*^ (!) ^*/ ResourceManager.GetString("BadCOFFHeaderSignature", null); 52 | } 53 | } 54 | internal static string/*!*/ BadConstantParentIndex{ 55 | get{ 56 | return /*^ (!) ^*/ ResourceManager.GetString("BadConstantParentIndex", null); 57 | } 58 | } 59 | internal static string/*!*/ BadCustomAttributeTypeEncodedToken { 60 | get{ 61 | return /*^ (!) ^*/ ResourceManager.GetString("BadCustomAttributeTypeEncodedToken", null); 62 | } 63 | } 64 | internal static string/*!*/ BaddCalliSignature { 65 | get{ 66 | return /*^ (!) ^*/ ResourceManager.GetString("BaddCalliSignature", null); 67 | } 68 | } 69 | internal static string/*!*/ BadExceptionHandlerType{ 70 | get{ 71 | return /*^ (!) ^*/ ResourceManager.GetString("BadExceptionHandlerType", null); 72 | } 73 | } 74 | internal static string/*!*/ BadGuidHeapIndex { 75 | get{ 76 | return /*^ (!) ^*/ ResourceManager.GetString("BadGuidHeapIndex", null); 77 | } 78 | } 79 | internal static string/*!*/ BadMagicNumber{ 80 | get{ 81 | return /*^ (!) ^*/ ResourceManager.GetString("BadMagicNumber", null); 82 | } 83 | } 84 | internal static string/*!*/ BadMemberToken { 85 | get{ 86 | return /*^ (!) ^*/ ResourceManager.GetString("BadMemberToken", null); 87 | } 88 | } 89 | internal static string/*!*/ BadMetadataHeaderSignature { 90 | get{ 91 | return /*^ (!) ^*/ ResourceManager.GetString("BadMetadataHeaderSignature", null); 92 | } 93 | } 94 | internal static string/*!*/ BadMetadataInExportTypeTableNoSuchAssemblyReference { 95 | get{ 96 | return /*^ (!) ^*/ ResourceManager.GetString("BadMetadataInExportTypeTableNoSuchAssemblyReference", null); 97 | } 98 | } 99 | internal static string/*!*/ BadMetadataInExportTypeTableNoSuchParentType { 100 | get{ 101 | return /*^ (!) ^*/ ResourceManager.GetString("BadMetadataInExportTypeTableNoSuchParentType", null); 102 | } 103 | } 104 | internal static string/*!*/ BadMethodHeaderSection{ 105 | get{ 106 | return /*^ (!) ^*/ ResourceManager.GetString("BadMethodHeaderSection", null); 107 | } 108 | } 109 | internal static string/*!*/ BadMethodTypeParameterInPosition { 110 | get{ 111 | return /*^ (!) ^*/ ResourceManager.GetString("BadMethodTypeParameterInPosition", null); 112 | } 113 | } 114 | internal static string/*!*/ BadPEHeaderMagicNumber { 115 | get{ 116 | return /*^ (!) ^*/ ResourceManager.GetString("BadPEHeaderMagicNumber", null); 117 | } 118 | } 119 | internal static string/*!*/ BadSecurityPermissionSetBlob { 120 | get{ 121 | return /*^ (!) ^*/ ResourceManager.GetString("BadSecurityPermissionSetBlob", null); 122 | } 123 | } 124 | internal static string/*!*/ BadSerializedTypeName{ 125 | get{ 126 | return /*^ (!) ^*/ ResourceManager.GetString("BadSerializedTypeName", null); 127 | } 128 | } 129 | internal static string/*!*/ BadStringHeapIndex { 130 | get{ 131 | return /*^ (!) ^*/ ResourceManager.GetString("BadStringHeapIndex", null); 132 | } 133 | } 134 | internal static string BadTargetPlatformLocation { 135 | get{ 136 | return /*^ (!) ^*/ ResourceManager.GetString("BadTargetPlatformLocation", null); 137 | } 138 | } 139 | internal static string BadTypeDefOrRef{ 140 | get{ 141 | return /*^ (!) ^*/ ResourceManager.GetString("BadTypeDefOrRef", null); 142 | } 143 | } 144 | internal static string/*!*/ BadTypeParameterInPositionForType { 145 | get{ 146 | return /*^ (!) ^*/ ResourceManager.GetString("BadTypeParameterInPositionForType", null); 147 | } 148 | } 149 | internal static string/*!*/ BadUserStringHeapIndex { 150 | get{ 151 | return /*^ (!) ^*/ ResourceManager.GetString("BadUserStringHeapIndex", null); 152 | } 153 | } 154 | internal static string/*!*/ CannotLoadTypeExtension { 155 | get{ 156 | return /*^ (!) ^*/ ResourceManager.GetString("CannotLoadTypeExtension", null); 157 | } 158 | } 159 | internal static string/*!*/ CollectionIsReadOnly{ 160 | get{ 161 | return /*^ (!) ^*/ ResourceManager.GetString("CollectionIsReadOnly", null); 162 | } 163 | } 164 | internal static string CouldNotFindExportedNestedTypeInType{ 165 | get{ 166 | return /*^ (!) ^*/ ResourceManager.GetString("CouldNotFindExportedNestedTypeInType", null); 167 | } 168 | } 169 | internal static string/*!*/ CouldNotFindExportedTypeInAssembly { 170 | get{ 171 | return /*^ (!) ^*/ ResourceManager.GetString("CouldNotFindExportedTypeInAssembly", null); 172 | } 173 | } 174 | internal static string CouldNotFindExportedTypeInModule{ 175 | get{ 176 | return /*^ (!) ^*/ ResourceManager.GetString("CouldNotFindExportedTypeInModule", null); 177 | } 178 | } 179 | internal static string/*!*/ CouldNotFindReferencedModule { 180 | get{ 181 | return /*^ (!) ^*/ ResourceManager.GetString("CouldNotFindReferencedModule", null); 182 | } 183 | } 184 | internal static string/*!*/ CouldNotResolveMemberReference { 185 | get{ 186 | return /*^ (!) ^*/ ResourceManager.GetString("CouldNotResolveMemberReference", null); 187 | } 188 | } 189 | internal static string/*!*/ CouldNotResolveType { 190 | get{ 191 | return /*^ (!) ^*/ ResourceManager.GetString("CouldNotResolveType", null); 192 | } 193 | } 194 | internal static string CouldNotResolveTypeReference{ 195 | get{ 196 | return ResourceManager.GetString("CouldNotResolveTypeReference", null); 197 | } 198 | } 199 | internal static string/*!*/ CreateFileMappingReturnedErrorCode { 200 | get{ 201 | return /*^ (!) ^*/ ResourceManager.GetString("CreateFileMappingReturnedErrorCode", null); 202 | } 203 | } 204 | internal static string/*!*/ ENCLogTableEncountered { 205 | get{ 206 | return /*^ (!) ^*/ ResourceManager.GetString("ENCLogTableEncountered", null); 207 | } 208 | } 209 | internal static string/*!*/ ENCMapTableEncountered { 210 | get{ 211 | return /*^ (!) ^*/ ResourceManager.GetString("ENCMapTableEncountered", null); 212 | } 213 | } 214 | internal static string/*!*/ FileTooBig { 215 | get{ 216 | return /*^ (!) ^*/ ResourceManager.GetString("FileTooBig", null); 217 | } 218 | } 219 | internal static string/*!*/ GetReaderForFileReturnedUnexpectedHResult { 220 | get{ 221 | return /*^ (!) ^*/ ResourceManager.GetString("GetReaderForFileReturnedUnexpectedHResult", null); 222 | } 223 | } 224 | internal static string/*!*/ InternalCompilerError { 225 | get{ 226 | return /*^ (!) ^*/ ResourceManager.GetString("InternalCompilerError", null); 227 | } 228 | } 229 | internal static string/*!*/ InvalidBaseClass { 230 | get{ 231 | return /*^ (!) ^*/ ResourceManager.GetString("InvalidBaseClass", null); 232 | } 233 | } 234 | internal static string/*!*/ InvalidFatMethodHeader { 235 | get{ 236 | return /*^ (!) ^*/ ResourceManager.GetString("InvalidFatMethodHeader", null); 237 | } 238 | } 239 | internal static string/*!*/ InvalidLocalSignature { 240 | get{ 241 | return /*^ (!) ^*/ ResourceManager.GetString("InvalidLocalSignature", null); 242 | } 243 | } 244 | internal static string InvalidModuleTable{ 245 | get{ 246 | return /*^ (!) ^*/ ResourceManager.GetString("InvalidModuleTable", null); 247 | } 248 | } 249 | internal static string/*!*/ InvalidTypeTableIndex { 250 | get{ 251 | return /*^ (!) ^*/ ResourceManager.GetString("InvalidTypeTableIndex", null); 252 | } 253 | } 254 | internal static string MalformedSignature{ 255 | get{ 256 | return /*^ (!) ^*/ ResourceManager.GetString("MalformedSignature", null); 257 | } 258 | } 259 | internal static string/*!*/ MapViewOfFileReturnedErrorCode { 260 | get{ 261 | return /*^ (!) ^*/ ResourceManager.GetString("MapViewOfFileReturnedErrorCode", null); 262 | } 263 | } 264 | internal static string/*!*/ ModuleOrAssemblyDependsOnMoreRecentVersionOfCoreLibrary { 265 | get{ 266 | return /*^ (!) ^*/ ResourceManager.GetString("ModuleOrAssemblyDependsOnMoreRecentVersionOfCoreLibrary", null); 267 | } 268 | } 269 | internal static string/*!*/ ModuleError{ 270 | get{ 271 | return /*^ (!) ^*/ ResourceManager.GetString("ModuleError", null); 272 | } 273 | } 274 | internal static string/*!*/ NoMetadataStream { 275 | get{ 276 | return /*^ (!) ^*/ ResourceManager.GetString("NoMetadataStream", null); 277 | } 278 | } 279 | internal static string/*!*/ PdbAssociatedWithFileIsOutOfDate { 280 | get{ 281 | return /*^ (!) ^*/ ResourceManager.GetString("PdbAssociatedWithFileIsOutOfDate", null); 282 | } 283 | } 284 | internal static string/*!*/ SecurityAttributeTypeDoesNotHaveADefaultConstructor { 285 | get{ 286 | return /*^ (!) ^*/ ResourceManager.GetString("SecurityAttributeTypeDoesNotHaveADefaultConstructor", null); 287 | } 288 | } 289 | internal static string/*!*/ TooManyMethodHeaderSections { 290 | get{ 291 | return /*^ (!) ^*/ ResourceManager.GetString("TooManyMethodHeaderSections", null); 292 | } 293 | } 294 | internal static string/*!*/ UnexpectedTypeInCustomAttribute { 295 | get{ 296 | return /*^ (!) ^*/ ResourceManager.GetString("UnexpectedTypeInCustomAttribute", null); 297 | } 298 | } 299 | internal static string/*!*/ UnknownConstantType { 300 | get{ 301 | return /*^ (!) ^*/ ResourceManager.GetString("UnknownConstantType", null); 302 | } 303 | } 304 | internal static string/*!*/ UnknownOpCode { 305 | get{ 306 | return /*^ (!) ^*/ ResourceManager.GetString("UnknownOpCode", null); 307 | } 308 | } 309 | internal static string/*!*/ UnknownOpCodeEncountered { 310 | get{ 311 | return /*^ (!) ^*/ ResourceManager.GetString("UnknownOpCodeEncountered", null); 312 | } 313 | } 314 | internal static string/*!*/ UnknownVirtualAddress { 315 | get{ 316 | return /*^ (!) ^*/ ResourceManager.GetString("UnknownVirtualAddress", null); 317 | } 318 | } 319 | internal static string/*!*/ UnresolvedAssemblyReferenceNotAllowed { 320 | get{ 321 | return /*^ (!) ^*/ ResourceManager.GetString("UnresolvedAssemblyReferenceNotAllowed", null); 322 | } 323 | } 324 | internal static string/*!*/ UnresolvedModuleReferenceNotAllowed { 325 | get{ 326 | return /*^ (!) ^*/ ResourceManager.GetString("UnresolvedModuleReferenceNotAllowed", null); 327 | } 328 | } 329 | internal static string/*!*/ UnsupportedTableEncountered { 330 | get{ 331 | return /*^ (!) ^*/ ResourceManager.GetString("UnsupportedTableEncountered", null); 332 | } 333 | } 334 | internal static string/*!*/ InvalidAssemblyStrongName { 335 | get{ 336 | return /*^ (!) ^*/ ResourceManager.GetString("InvalidAssemblyStrongName", null); 337 | } 338 | } 339 | internal static string/*!*/ KeyNeedsToBeGreaterThanZero { 340 | get{ 341 | return /*^ (!) ^*/ ResourceManager.GetString("KeyNeedsToBeGreaterThanZero", null); 342 | } 343 | } 344 | } 345 | } 346 | -------------------------------------------------------------------------------- /ILMerge/AssemblyResolver.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | // See the LICENSE file in the project root for more information. 4 | 5 | using System; 6 | using System.IO; 7 | using System.Collections; 8 | using System.Compiler; 9 | 10 | namespace AssemblyResolving 11 | { 12 | /// 13 | /// AssemblyResolver is a class that is used for CCI-based applications. 14 | /// When a CCI-based application asks for an assembly to be loaded, CCI 15 | /// first looks in any cache that it has access to (e.g., that was handed 16 | /// to it in a call to GetAssembly). If it cannot find it, then if a 17 | /// resolver has been registered, then it calls the resolver to locate 18 | /// the assembly. 19 | /// If the resolver does not return it, CCI then searches in several 20 | /// standard places (the current working directory, the GAC, etc.). 21 | /// 22 | public class AssemblyResolver 23 | { 24 | private readonly static string[] exts = new string[] { "dll", "exe", "winmd", }; 25 | private string inputDirectory = ""; 26 | private string[] directories = null; 27 | private IDictionary h = null; 28 | private bool log = true; 29 | private string logFile = null; 30 | private bool useGlobalCache = true; 31 | private bool debugInfo = true; 32 | private bool shortB = false; 33 | 34 | /// 35 | /// This object is used to locate an assembly when it is needed to be loaded 36 | /// (i.e., not found in the cache). 37 | /// 38 | public AssemblyResolver() { } 39 | /// 40 | /// This object is used to locate an assembly when it is needed to be loaded 41 | /// (i.e., not found in the cache). 42 | /// 43 | /// Specifies the primary directory in which to look for assemblies. 44 | public AssemblyResolver(string InputDirectory) 45 | { 46 | if ( InputDirectory == null ) 47 | throw new System.ArgumentNullException(); 48 | inputDirectory = InputDirectory; 49 | } 50 | /// 51 | /// This object is used to locate an assembly when it is needed to be loaded 52 | /// (i.e., not found in the cache). 53 | /// 54 | /// A map from assembly names (strings) to AssemblyNode. First 55 | /// place that is looked in for assemblies to be loaded. 56 | public AssemblyResolver(IDictionary AssemblyCache) 57 | { 58 | h = AssemblyCache; 59 | } 60 | /// 61 | /// A map from string names to AssemblyNode. It is used to locate 62 | /// metadata references. 63 | /// 64 | public IDictionary AssemblyCache 65 | { 66 | set { h = value; } 67 | } 68 | /// 69 | /// The set of directory paths that will be searched for assemblies by the 70 | /// assembly resolver. 71 | /// 72 | public string[] SearchDirectories 73 | { 74 | set 75 | { 76 | if ( value == null ) 77 | throw new System.ArgumentNullException(); 78 | else if ( value.Length > 0 ) 79 | { 80 | directories = new string[value.Length]; 81 | value.CopyTo(directories,0); 82 | } 83 | } 84 | } 85 | /// 86 | /// The first directory in which an assembly is searched for if it is not found in the cache. 87 | /// 88 | public string InputDirectory 89 | { 90 | set { 91 | if ( value == null ) 92 | throw new System.ArgumentNullException(); 93 | inputDirectory = value; 94 | } 95 | } 96 | /// 97 | /// Place to send output log messages. Needs to be a full path, e.g., "c:\tmp\foo.log". 98 | /// Can be set at most once. 99 | /// (If the property Log is true and the LogFile is null, then Console.Out is written to.) 100 | /// 101 | public string LogFile 102 | { 103 | get { return logFile; } 104 | set 105 | { 106 | // only allow it to be set once (why?) 107 | if ( logFile == null ) 108 | logFile = value; 109 | else 110 | throw new InvalidOperationException("AssemblyResolver: Can set the log only once."); 111 | } 112 | } 113 | /// 114 | /// Controls whether output log messages are produced during resolving. (default: true) 115 | /// Can be set arbitrarily. 116 | /// (If the property Log is true and the LogFile is null, then Console.Out is written to.) 117 | /// 118 | public bool Log 119 | { 120 | get { return log; } 121 | set { log = value; } 122 | } 123 | /// 124 | /// Controls whether CCI should use its global cache when loading assemblies. (default: true) 125 | /// 126 | public bool UseGlobalCache 127 | { 128 | get { return useGlobalCache; } 129 | set { useGlobalCache = value; } 130 | } 131 | /// 132 | /// Controls whether CCI should read in debug info when loading assemblies. (default: true) 133 | /// 134 | public bool DebugInfo 135 | { 136 | get { return debugInfo; } 137 | set { debugInfo = value; } 138 | } 139 | /// 140 | /// Controls whether CCI should preserve short branches. (default: false) 141 | /// 142 | public bool PreserveShortBranches 143 | { 144 | get { return shortB; } 145 | set { shortB = value; } 146 | } 147 | private void WriteToLog(string s, params object[] args) 148 | { 149 | if ( log ) 150 | { 151 | if ( logFile != null ) 152 | { 153 | StreamWriter writer = new System.IO.StreamWriter(logFile, true); 154 | writer.WriteLine(s,args); 155 | writer.Close(); 156 | } 157 | else 158 | { 159 | Console.WriteLine(s,args); 160 | } 161 | } 162 | } 163 | /// 164 | /// This method is installed as hook so that each assembly that is loaded uses it to resolve 165 | /// any assembly references. 166 | /// 167 | /// The reference that must be chased down to load. 168 | /// The assembly that contains the reference. 169 | /// 170 | public AssemblyNode Resolve(AssemblyReference assemblyReference, Module referencingModule) 171 | { 172 | WriteToLog("AssemblyResolver: Assembly '{0}' is referencing assembly '{1}'.", 173 | referencingModule.Name,assemblyReference.Name); 174 | AssemblyNode a = null; 175 | try 176 | { 177 | // Location Priority (in decreasing order): 178 | // 1. referencing Module's directory 179 | // 2. directory original assembly was in 180 | // 3. list of directories specified by client 181 | // 4. Framework directory 182 | // 183 | // Extension Priority (in decreasing order): 184 | // dll, exe, (any others?) 185 | #region Check referencing module's directory 186 | WriteToLog("\tAssemblyResolver: Attempting referencing assembly's directory."); 187 | if ( referencingModule.Directory != null ) 188 | { 189 | foreach (string ext in exts) 190 | { 191 | bool tempDebugInfo = debugInfo; 192 | string fullName = Path.Combine(referencingModule.Directory, assemblyReference.Name + "." + ext); 193 | if ( File.Exists(fullName) ) { 194 | if (tempDebugInfo) { 195 | // Don't pass the debugInfo flag to GetAssembly unless the PDB file exists. 196 | string pdbFullName = Path.Combine(referencingModule.Directory, assemblyReference.Name + ".pdb"); 197 | if (!File.Exists(pdbFullName)) { 198 | WriteToLog("Can not find PDB file. Debug info will not be available for assembly '{0}'.", 199 | assemblyReference.Name); 200 | tempDebugInfo = false; 201 | } 202 | } 203 | WriteToLog("Resolved assembly reference '{0}' to '{1}'. (Used referencing Module's directory.)", 204 | assemblyReference.Name, 205 | fullName); 206 | a = AssemblyNode.GetAssembly( 207 | fullName, // path to assembly 208 | h, // global cache to use for assemblies 209 | true, // doNotLockFile 210 | tempDebugInfo, // getDebugInfo 211 | useGlobalCache, // useGlobalCache 212 | shortB // preserveShortBranches 213 | ); 214 | break; 215 | } 216 | } 217 | } 218 | else 219 | { 220 | WriteToLog("\t\tAssemblyResolver: Referencing assembly's directory is null."); 221 | } 222 | if ( a == null ) 223 | { 224 | if ( referencingModule.Directory != null ) 225 | { 226 | WriteToLog("\tAssemblyResolver: Did not find assembly in referencing assembly's directory."); 227 | } 228 | } 229 | else 230 | { 231 | goto End; 232 | } 233 | #endregion 234 | #region Check input directory 235 | WriteToLog("\tAssemblyResolver: Attempting input directory."); 236 | foreach ( string ext in exts ) 237 | { 238 | bool tempDebugInfo = debugInfo; 239 | string fullName = Path.Combine(inputDirectory, assemblyReference.Name + "." + ext); 240 | if ( File.Exists(fullName) ) 241 | { 242 | WriteToLog("Resolved assembly reference '{0}' to '{1}'. (Used the original input directory.)", 243 | assemblyReference.Name, 244 | fullName); 245 | if (tempDebugInfo) { 246 | // Don't pass the debugInfo flag to GetAssembly unless the PDB file exists. 247 | string pdbFullName = Path.Combine(referencingModule.Directory, assemblyReference.Name + ".pdb"); 248 | if (!File.Exists(pdbFullName)) { 249 | WriteToLog("Can not find PDB file. Debug info will not be available for assembly '{0}'.", 250 | assemblyReference.Name); 251 | tempDebugInfo = false; 252 | } 253 | } 254 | a = AssemblyNode.GetAssembly( 255 | fullName, // path to assembly 256 | h, // global cache to use for assemblies 257 | true, // doNotLockFile 258 | tempDebugInfo, // getDebugInfo 259 | useGlobalCache, // useGlobalCache 260 | shortB // preserveShortBranches 261 | ); 262 | break; 263 | } 264 | } 265 | if ( a == null ) 266 | { 267 | WriteToLog("\tAssemblyResolver: Did not find assembly in input directory."); 268 | } 269 | else 270 | { 271 | goto End; 272 | } 273 | #endregion 274 | #region Check user-supplied search directories 275 | WriteToLog("\tAssemblyResolver: Attempting user-supplied directories."); 276 | if ( directories != null ) 277 | { 278 | foreach ( string dir in directories ) 279 | { 280 | foreach ( string ext in exts ) 281 | { 282 | string fullName = dir + "\\" + assemblyReference.Name + "." + ext; 283 | if ( File.Exists(fullName) ) 284 | { 285 | bool tempDebugInfo = debugInfo; 286 | WriteToLog("Resolved assembly reference '{0}' to '{1}'. (Used a client-supplied directory.)", 287 | assemblyReference.Name, 288 | fullName); 289 | if (tempDebugInfo) { 290 | // Don't pass the debugInfo flag to GetAssembly unless the PDB file exists. 291 | string pdbFullName = Path.Combine(referencingModule.Directory, assemblyReference.Name + ".pdb"); 292 | if (!File.Exists(pdbFullName)) { 293 | WriteToLog("Can not find PDB file. Debug info will not be available for assembly '{0}'.", 294 | assemblyReference.Name); 295 | tempDebugInfo = false; 296 | } 297 | } 298 | a = AssemblyNode.GetAssembly( //(fullName,h, true, false, true); 299 | fullName, // path to assembly 300 | h, // global cache to use for assemblies 301 | true, // doNotLockFile 302 | tempDebugInfo, // getDebugInfo 303 | useGlobalCache, // useGlobalCache 304 | shortB // preserveShortBranches 305 | ); 306 | break; 307 | } 308 | } 309 | if ( a != null ) 310 | break; 311 | } 312 | } 313 | else 314 | { 315 | WriteToLog("\tAssemblyResolver: No user-supplied directories."); 316 | } 317 | if ( a == null ) 318 | { 319 | if ( directories != null ) 320 | { 321 | WriteToLog("\tAssemblyResolver: Did not find assembly in user-supplied directories."); 322 | } 323 | } 324 | else 325 | { 326 | goto End; 327 | } 328 | #endregion 329 | #region Check framework directory 330 | WriteToLog("\tAssemblyResolver: Attempting framework directory."); 331 | if (TargetPlatform.PlatformAssembliesLocation != null) { 332 | var directory = TargetPlatform.PlatformAssembliesLocation; 333 | foreach (string ext in exts) { 334 | bool tempDebugInfo = debugInfo; 335 | string fullName = Path.Combine(directory, assemblyReference.Name + "." + ext); 336 | if (File.Exists(fullName)) { 337 | if (tempDebugInfo) { 338 | // Don't pass the debugInfo flag to GetAssembly unless the PDB file exists. 339 | string pdbFullName = Path.Combine(directory, assemblyReference.Name + ".pdb"); 340 | if (!File.Exists(pdbFullName)) { 341 | WriteToLog("Can not find PDB file. Debug info will not be available for assembly '{0}'.", 342 | assemblyReference.Name); 343 | tempDebugInfo = false; 344 | } 345 | } 346 | WriteToLog("Resolved assembly reference '{0}' to '{1}'. (Used framework directory.)", 347 | assemblyReference.Name, 348 | fullName); 349 | a = AssemblyNode.GetAssembly( 350 | fullName, // path to assembly 351 | h, // global cache to use for assemblies 352 | true, // doNotLockFile 353 | tempDebugInfo, // getDebugInfo 354 | useGlobalCache, // useGlobalCache 355 | shortB // preserveShortBranches 356 | ); 357 | break; 358 | } 359 | } 360 | } else { 361 | WriteToLog("\t\tAssemblyResolver: Platform assemblies location is null."); 362 | } 363 | if (a == null) { 364 | if (referencingModule.Directory != null) { 365 | WriteToLog("\tAssemblyResolver: Did not find assembly in framework directory."); 366 | } 367 | } else { 368 | goto End; 369 | } 370 | #endregion 371 | End: 372 | if ( a == null ) 373 | WriteToLog("AssemblyResolver: Unable to resolve reference. (It still might be found, e.g., in the GAC.)"); 374 | } 375 | catch (Exception e) 376 | { 377 | WriteToLog("AssemblyResolver: Exception occurred. Unable to resolve reference."); 378 | WriteToLog("Inner exception: " + e.ToString()); 379 | } 380 | return a; 381 | } 382 | } 383 | } 384 | -------------------------------------------------------------------------------- /System.Compiler/Unstacker.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | // See the LICENSE file in the project root for more information. 4 | 5 | #if !MinimalReader && !CodeContracts 6 | using System; 7 | using System.Collections; 8 | using System.Diagnostics; 9 | 10 | #if CCINamespace 11 | namespace Microsoft.Cci{ 12 | #else 13 | namespace System.Compiler{ 14 | #endif 15 | /// 16 | /// Walks a normalized IR, removing push, pop and dup instructions, replacing them with references to local variables. 17 | /// Requires all Blocks to be basic blocks. I.e. any transfer statement is always the last statement in a block. 18 | /// (This precondition is established by Reader but not by Normalizer.) 19 | /// 20 | public class Unstacker : StandardVisitor{ 21 | private TrivialHashtable/*!*/ SucessorBlock = new TrivialHashtable(); 22 | private TrivialHashtable/*!*/ StackLocalsAtEntry = new TrivialHashtable(); 23 | private LocalsStack/*!*/ localsStack = new LocalsStack(); 24 | 25 | public Unstacker(){ 26 | //^ base(); 27 | } 28 | 29 | public override Statement VisitAssignmentStatement(AssignmentStatement assignment){ 30 | if (assignment == null) return null; 31 | assignment.Source = this.VisitExpression(assignment.Source); 32 | assignment.Target = this.VisitTargetExpression(assignment.Target); 33 | return assignment; 34 | } 35 | public override Expression VisitBinaryExpression(BinaryExpression binaryExpression){ 36 | if (binaryExpression == null) return null; 37 | binaryExpression.Operand2 = this.VisitExpression(binaryExpression.Operand2); 38 | binaryExpression.Operand1 = this.VisitExpression(binaryExpression.Operand1); 39 | if (binaryExpression.Type == null) binaryExpression.Type = binaryExpression.Operand1.Type; //Hack: need proper inferencing 40 | return binaryExpression; 41 | } 42 | public override Block VisitBlock(Block block){ 43 | if (block == null) return null; 44 | LocalsStack stackLocalsAtEntry = (LocalsStack)this.StackLocalsAtEntry[block.UniqueKey]; 45 | if (stackLocalsAtEntry == null){ 46 | //Unreachable code, or the very first block 47 | stackLocalsAtEntry = new LocalsStack(); 48 | } 49 | this.localsStack = stackLocalsAtEntry.Clone(); 50 | base.VisitBlock(block); 51 | Block successor = (Block)this.SucessorBlock[block.UniqueKey]; 52 | if (successor != null) { 53 | //Dropping off into successor. 54 | LocalsStack targetStack = (LocalsStack)this.StackLocalsAtEntry[successor.UniqueKey]; 55 | if (targetStack != null && targetStack.top >= 0) { 56 | //Another predecessor block has already decided what the stack for the successor block is going to look like. 57 | //Reconcile the stack from this block with the stack expected by the successor block. 58 | this.localsStack.Transfer(targetStack, block.Statements); 59 | } 60 | else { 61 | this.StackLocalsAtEntry[successor.UniqueKey] = this.localsStack; 62 | } 63 | } 64 | return block; 65 | } 66 | public override Statement VisitBranch(Branch branch){ 67 | if (branch == null) return null; 68 | if (branch.Target == null) return null; 69 | branch.Condition = this.VisitExpression(branch.Condition); 70 | int n = this.localsStack.top+1; 71 | LocalsStack targetStack = (LocalsStack)this.StackLocalsAtEntry[branch.Target.UniqueKey]; 72 | if (targetStack == null){ 73 | this.StackLocalsAtEntry[branch.Target.UniqueKey] = this.localsStack.Clone(); 74 | return branch; 75 | } 76 | //Target block has an entry stack that is different from the current stack. Need to copy stack before branching. 77 | if (n <= 0) return branch; //Empty stack, no need to copy 78 | StatementList statements = new StatementList(n+1); 79 | this.localsStack.Transfer(targetStack, statements); 80 | statements.Add(branch); 81 | return new Block(statements); 82 | } 83 | public override Statement VisitSwitchInstruction(SwitchInstruction switchInstruction) { 84 | if (switchInstruction == null) return null; 85 | switchInstruction.Expression = this.VisitExpression(switchInstruction.Expression); 86 | for (int i = 0, n = switchInstruction.Targets == null ? 0 : switchInstruction.Targets.Count; i < n; i++){ 87 | Block target = switchInstruction.Targets[i]; 88 | if (target == null) continue; 89 | this.StackLocalsAtEntry[target.UniqueKey] = this.localsStack.Clone(); 90 | } 91 | return switchInstruction; 92 | } 93 | public override ExpressionList VisitExpressionList(ExpressionList expressions) { 94 | if (expressions == null) return null; 95 | for (int i = expressions.Count-1; i >= 0; i--) 96 | expressions[i] = this.VisitExpression(expressions[i]); 97 | return expressions; 98 | } 99 | public override Statement VisitExpressionStatement(ExpressionStatement statement){ 100 | if (statement == null) return null; 101 | Expression e = statement.Expression = this.VisitExpression(statement.Expression); 102 | if (e == null || e.Type == CoreSystemTypes.Void) return statement; 103 | if (e.NodeType == NodeType.Dup) return this.localsStack.Dup(); 104 | return this.localsStack.Push(e); 105 | } 106 | public override Expression VisitExpression(Expression expression){ 107 | if (expression == null) return null; 108 | switch(expression.NodeType){ 109 | case NodeType.Dup: 110 | case NodeType.Arglist: 111 | return expression; 112 | case NodeType.Pop: 113 | UnaryExpression uex = expression as UnaryExpression; 114 | if (uex != null){ 115 | Expression e = uex.Operand = this.VisitExpression(uex.Operand); 116 | if (e == null) return null; 117 | uex.Type = CoreSystemTypes.Void; 118 | return uex; 119 | } 120 | return this.localsStack.Pop(); 121 | default: 122 | return (Expression)this.Visit(expression); 123 | } 124 | } 125 | public override Expression VisitIndexer(Indexer indexer){ 126 | if (indexer == null) return null; 127 | indexer.Operands = this.VisitExpressionList(indexer.Operands); 128 | indexer.Object = this.VisitExpression(indexer.Object); 129 | return indexer; 130 | } 131 | public override Method VisitMethod(Method method){ 132 | // body might not have been materialized, so make sure we do that first! 133 | Block body = method.Body; 134 | 135 | if (method == null) return null; 136 | BlockSorter blockSorter = new BlockSorter(); 137 | BlockList sortedBlocks = blockSorter.SortedBlocks; 138 | this.SucessorBlock = blockSorter.SuccessorBlock; 139 | this.StackLocalsAtEntry = new TrivialHashtable(); 140 | this.localsStack = new LocalsStack(); 141 | ExceptionHandlerList ehandlers = method.ExceptionHandlers; 142 | for (int i = 0, n = ehandlers == null ? 0 : ehandlers.Count; i < n; i++){ 143 | ExceptionHandler ehandler = ehandlers[i]; 144 | if (ehandler == null) continue; 145 | Block handlerStart = ehandler.HandlerStartBlock; 146 | if (handlerStart == null) continue; 147 | LocalsStack lstack = new LocalsStack(); 148 | this.StackLocalsAtEntry[handlerStart.UniqueKey] = lstack; 149 | if (ehandler.HandlerType == NodeType.Catch) { 150 | lstack.exceptionHandlerType = CoreSystemTypes.Object; 151 | if (ehandler.FilterType != null) lstack.exceptionHandlerType = ehandler.FilterType; 152 | } else if (ehandler.HandlerType == NodeType.Filter) { 153 | lstack.exceptionHandlerType = CoreSystemTypes.Object; 154 | if (ehandler.FilterExpression != null) { 155 | lstack = new LocalsStack(); 156 | lstack.exceptionHandlerType = CoreSystemTypes.Object; 157 | this.StackLocalsAtEntry[ehandler.FilterExpression.UniqueKey] = lstack; 158 | } 159 | } 160 | } 161 | blockSorter.VisitMethodBody(body); 162 | for (int i = 0, n = sortedBlocks.Count; i < n; i++) { 163 | Block b = sortedBlocks[i]; 164 | if (b == null) { Debug.Assert(false); continue; } 165 | this.VisitBlock(b); 166 | } 167 | return method; 168 | } 169 | public override Expression VisitMethodCall(MethodCall call){ 170 | if (call == null) return null; 171 | call.Operands = this.VisitExpressionList(call.Operands); 172 | call.Callee = this.VisitExpression(call.Callee); 173 | return call; 174 | } 175 | public override Expression VisitTernaryExpression(TernaryExpression expression){ 176 | if (expression == null) return null; 177 | expression.Operand3 = this.VisitExpression(expression.Operand3); 178 | expression.Operand2 = this.VisitExpression(expression.Operand2); 179 | expression.Operand1 = this.VisitExpression(expression.Operand1); 180 | return expression; 181 | } 182 | 183 | private class LocalsStack{ 184 | private Local[]/*!*/ elements; 185 | internal int top = -1; 186 | internal TypeNode exceptionHandlerType; 187 | 188 | private void Grow(){ 189 | int n = this.elements.Length; 190 | Local[] newElements = new Local[n+8]; 191 | for (int i = 0; i < n; i++) newElements[i] = this.elements[i]; 192 | this.elements = newElements; 193 | } 194 | internal LocalsStack(){ 195 | this.elements = new Local[8]; 196 | //^ base(); 197 | } 198 | private LocalsStack(LocalsStack/*!*/ other) { 199 | this.top = other.top; 200 | this.exceptionHandlerType = other.exceptionHandlerType; 201 | Local[] otherElements = other.elements; 202 | int n = otherElements.Length; 203 | Local[] elements = this.elements = new Local[n]; 204 | //^ base(); 205 | n = this.top+1; 206 | for (int i = 0; i < n; i++) 207 | elements[i] = otherElements[i]; 208 | } 209 | internal LocalsStack/*!*/ Clone(){ 210 | return new LocalsStack(this); 211 | } 212 | internal AssignmentStatement Dup(){ 213 | int i = this.top; 214 | Expression topVal; 215 | if (this.top == -1 && this.exceptionHandlerType != null) { 216 | topVal = new Expression(NodeType.Dup, this.exceptionHandlerType); 217 | }else{ 218 | Debug.Assert(i >= 0 && i < this.elements.Length); 219 | topVal = this.elements[i]; 220 | //^ assume topVal != null; 221 | } 222 | Local dup = new Local(topVal.Type); 223 | if ((i = ++this.top) >= this.elements.Length) this.Grow(); 224 | this.elements[i] = dup; 225 | return new AssignmentStatement(dup, topVal); 226 | } 227 | internal AssignmentStatement Push(Expression/*!*/ expr) { 228 | //Debug.Assert(expr != null && expr.Type != null); 229 | int i = ++this.top; 230 | Debug.Assert(i >= 0); 231 | if (i >= this.elements.Length) this.Grow(); 232 | Local loc = this.elements[i]; 233 | if (loc == null || loc.Type != expr.Type) 234 | this.elements[i] = loc = new Local(expr.Type); 235 | return new AssignmentStatement(loc, expr); 236 | } 237 | internal Expression Pop(){ 238 | if (this.top == -1 && this.exceptionHandlerType != null){ 239 | TypeNode t = this.exceptionHandlerType; 240 | this.exceptionHandlerType = null; 241 | return new Expression(NodeType.Pop, t); 242 | } 243 | int i = this.top--; 244 | Debug.Assert(i >= 0 && i < this.elements.Length); 245 | return this.elements[i]; 246 | } 247 | internal void Transfer(LocalsStack/*!*/ targetStack, StatementList/*!*/ statements) { 248 | Debug.Assert(targetStack != null); 249 | if (targetStack == this) return; 250 | int n = this.top; 251 | Debug.Assert(n == targetStack.top); 252 | for (int i = 0; i <= n; i++){ 253 | Local sloc = this.elements[i]; 254 | Local tloc = targetStack.elements[i]; 255 | if (sloc == tloc) continue; 256 | Debug.Assert(sloc != null && tloc != null); 257 | statements.Add(new AssignmentStatement(tloc, sloc)); 258 | } 259 | } 260 | } 261 | private class BlockSorter : StandardVisitor{ 262 | private TrivialHashtable/*!*/ VisitedBlocks = new TrivialHashtable(); 263 | private TrivialHashtable/*!*/ BlocksThatDropThrough = new TrivialHashtable(); 264 | private bool lastBranchWasUnconditional = false; 265 | internal BlockList/*!*/ SortedBlocks = new BlockList(); 266 | internal TrivialHashtable/*!*/ SuccessorBlock = new TrivialHashtable(); 267 | 268 | internal BlockSorter(){ 269 | //^ base(); 270 | } 271 | 272 | internal void VisitMethodBody(Block body) { 273 | if (body == null) return; 274 | StatementList statements = body.Statements; 275 | if (statements == null) return; 276 | Block previousBlock = null; 277 | for (int i = 0, n = statements.Count; i < n; i++) { 278 | Block b = statements[i] as Block; 279 | if (b == null) { Debug.Assert(false); continue; } 280 | if (previousBlock != null && this.BlocksThatDropThrough[previousBlock.UniqueKey] != null) { 281 | this.SuccessorBlock[previousBlock.UniqueKey] = b; 282 | } 283 | this.VisitBlock(b); 284 | previousBlock = b; 285 | } 286 | } 287 | public override Block VisitBlock(Block block) { 288 | if (block == null) return null; 289 | if (this.VisitedBlocks[block.UniqueKey] != null) { 290 | return block; 291 | } 292 | this.VisitedBlocks[block.UniqueKey] = block; 293 | this.SortedBlocks.Add(block); 294 | this.lastBranchWasUnconditional = false; 295 | base.VisitBlock(block); 296 | if (!this.lastBranchWasUnconditional) 297 | this.BlocksThatDropThrough[block.UniqueKey] = block; 298 | return block; 299 | } 300 | public override Statement VisitBranch(Branch branch){ 301 | if (branch == null) return null; 302 | if (branch.Target == null) return null; 303 | this.VisitBlock(branch.Target); 304 | this.lastBranchWasUnconditional = branch.Condition == null; 305 | return branch; 306 | } 307 | public override Statement VisitEndFilter(EndFilter endFilter) { 308 | endFilter.Value = this.VisitExpression(endFilter.Value); 309 | this.lastBranchWasUnconditional = true; 310 | return endFilter; 311 | } 312 | public override Statement VisitEndFinally(EndFinally endFinally) { 313 | this.lastBranchWasUnconditional = true; 314 | return endFinally; 315 | } 316 | public override Statement VisitReturn(Return ret) { 317 | this.lastBranchWasUnconditional = true; 318 | return ret; 319 | } 320 | public override Statement VisitSwitchInstruction(SwitchInstruction switchInstruction) { 321 | if (switchInstruction == null) return null; 322 | switchInstruction.Expression = this.VisitExpression(switchInstruction.Expression); 323 | for (int i = 0, n = switchInstruction.Targets == null ? 0 : switchInstruction.Targets.Count; i < n; i++){ 324 | Block target = switchInstruction.Targets[i]; 325 | if (target == null) continue; 326 | this.VisitBlock(target); 327 | } 328 | return switchInstruction; 329 | } 330 | public override Statement VisitThrow(Throw Throw) { 331 | this.lastBranchWasUnconditional = true; 332 | return Throw; 333 | } 334 | } 335 | } 336 | } 337 | #endif 338 | -------------------------------------------------------------------------------- /System.Compiler/AssemblyCache.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | // See the LICENSE file in the project root for more information. 4 | 5 | #if !ROTOR 6 | using System; 7 | using System.Collections; 8 | using System.Diagnostics; 9 | using System.IO; 10 | using System.Runtime.InteropServices; 11 | using System.Text; 12 | 13 | #if CCINamespace 14 | namespace Microsoft.Cci{ 15 | #else 16 | namespace System.Compiler{ 17 | #endif 18 | #if !FxCop 19 | public 20 | #endif 21 | class GlobalAssemblyCache{ 22 | private GlobalAssemblyCache(){} 23 | private static readonly object Lock = new object(); 24 | private static bool FusionLoaded; 25 | #if CodeContracts 26 | public static bool probeGAC = true; 27 | #endif 28 | 29 | /// Uri pointing to the assembly 30 | public static bool Contains(Uri codeBaseUri){ 31 | if (codeBaseUri == null) { Debug.Fail("codeBaseUri == null"); return false; } 32 | lock(GlobalAssemblyCache.Lock){ 33 | if (!GlobalAssemblyCache.FusionLoaded){ 34 | GlobalAssemblyCache.FusionLoaded = true; 35 | System.Reflection.Assembly systemAssembly = typeof(object).Assembly; 36 | //^ assume systemAssembly != null && systemAssembly.Location != null; 37 | string dir = Path.GetDirectoryName(systemAssembly.Location); 38 | //^ assume dir != null; 39 | GlobalAssemblyCache.LoadLibrary(Path.Combine(dir, "fusion.dll")); 40 | } 41 | IAssemblyEnum assemblyEnum; 42 | int rc = GlobalAssemblyCache.CreateAssemblyEnum(out assemblyEnum, null, null, ASM_CACHE.GAC, 0); 43 | if (rc < 0 || assemblyEnum == null) return false; 44 | IApplicationContext applicationContext; 45 | IAssemblyName currentName; 46 | while (assemblyEnum.GetNextAssembly(out applicationContext, out currentName, 0) == 0){ 47 | //^ assume currentName != null; 48 | AssemblyName assemblyName = new AssemblyName(currentName); 49 | string scheme = codeBaseUri.Scheme; 50 | if (scheme != null && assemblyName.CodeBase.StartsWith(scheme)){ 51 | try{ 52 | Uri foundUri = new Uri(assemblyName.CodeBase); 53 | if (codeBaseUri.Equals(foundUri)) return true; 54 | #if !FxCop 55 | }catch(Exception){ 56 | #else 57 | }finally{ 58 | #endif 59 | } 60 | } 61 | } 62 | return false; 63 | } 64 | } 65 | /// 66 | /// Returns the original location of the corresponding assembly if available, otherwise returns the location of the shadow copy. 67 | /// If the corresponding assembly is not in the GAC, null is returned. 68 | /// 69 | public static string GetLocation(AssemblyReference assemblyReference){ 70 | #if CodeContracts 71 | if (!probeGAC) return null; 72 | #endif 73 | if (assemblyReference == null) { Debug.Fail("assemblyReference == null"); return null; } 74 | lock(GlobalAssemblyCache.Lock){ 75 | if (!GlobalAssemblyCache.FusionLoaded){ 76 | GlobalAssemblyCache.FusionLoaded = true; 77 | System.Reflection.Assembly systemAssembly = typeof(object).Assembly; 78 | //^ assume systemAssembly != null && systemAssembly.Location != null; 79 | string dir = Path.GetDirectoryName(systemAssembly.Location); 80 | //^ assume dir != null; 81 | GlobalAssemblyCache.LoadLibrary(Path.Combine(dir, "fusion.dll")); 82 | } 83 | IAssemblyEnum assemblyEnum; 84 | CreateAssemblyEnum(out assemblyEnum, null, null, ASM_CACHE.GAC, 0); 85 | if (assemblyEnum == null) return null; 86 | IApplicationContext applicationContext; 87 | IAssemblyName currentName; 88 | while (assemblyEnum.GetNextAssembly(out applicationContext, out currentName, 0) == 0){ 89 | //^ assume currentName != null; 90 | AssemblyName aName = new AssemblyName(currentName); 91 | if (assemblyReference.Matches(aName.Name, aName.Version, aName.Culture, aName.PublicKeyToken)){ 92 | string codeBase = aName.CodeBase; 93 | if (codeBase != null && codeBase.StartsWith("file:///")) 94 | return codeBase.Substring(8); 95 | return aName.GetLocation(); 96 | } 97 | } 98 | return null; 99 | } 100 | } 101 | 102 | [DllImport("kernel32.dll", CharSet=CharSet.Ansi, BestFitMapping = false, ThrowOnUnmappableChar = true)] 103 | private static extern IntPtr LoadLibrary(string lpFileName); 104 | [DllImport("fusion.dll", CharSet=CharSet.Auto, BestFitMapping = false, ThrowOnUnmappableChar = true)] 105 | private static extern int CreateAssemblyEnum(out IAssemblyEnum ppEnum, IApplicationContext pAppCtx, IAssemblyName pName, uint dwFlags, int pvReserved); 106 | private class ASM_CACHE{ 107 | private ASM_CACHE(){} 108 | public const uint ZAP = 1; 109 | public const uint GAC = 2; 110 | public const uint DOWNLOAD = 4; 111 | } 112 | } 113 | internal class AssemblyName{ 114 | readonly IAssemblyName/*!*/ assemblyName; 115 | 116 | internal AssemblyName(IAssemblyName/*!*/ assemblyName) { 117 | this.assemblyName = assemblyName; 118 | //^ base(); 119 | } 120 | 121 | internal string/*!*/ Name { 122 | //set {this.WriteString(ASM_NAME.NAME, value);} 123 | get {return this.ReadString(ASM_NAME.NAME);} 124 | } 125 | internal Version Version{ 126 | //set{ 127 | // if (value == null) throw new ArgumentNullException(); 128 | // this.WriteUInt16(ASM_NAME.MAJOR_VERSION, (ushort)value.Major); 129 | // this.WriteUInt16(ASM_NAME.MINOR_VERSION, (ushort)value.Minor); 130 | // this.WriteUInt16(ASM_NAME.BUILD_NUMBER, (ushort)value.Build); 131 | // this.WriteUInt16(ASM_NAME.REVISION_NUMBER, (ushort)value.Revision); 132 | //} 133 | get{ 134 | int major = this.ReadUInt16(ASM_NAME.MAJOR_VERSION); 135 | int minor = this.ReadUInt16(ASM_NAME.MINOR_VERSION); 136 | int build = this.ReadUInt16(ASM_NAME.BUILD_NUMBER); 137 | int revision = this.ReadUInt16(ASM_NAME.REVISION_NUMBER); 138 | return new Version(major, minor, build, revision); 139 | } 140 | } 141 | internal string/*!*/ Culture { 142 | //set {this.WriteString(ASM_NAME.CULTURE, value);} 143 | get {return this.ReadString(ASM_NAME.CULTURE);} 144 | } 145 | internal byte[]/*!*/ PublicKeyToken { 146 | //set {this.WriteBytes(ASM_NAME.PUBLIC_KEY_TOKEN, value); } 147 | get {return this.ReadBytes(ASM_NAME.PUBLIC_KEY_TOKEN); } 148 | } 149 | internal string StrongName{ 150 | get{ 151 | uint size = 0; 152 | this.assemblyName.GetDisplayName(null, ref size, (uint)AssemblyNameDisplayFlags.ALL); 153 | if (size == 0) return ""; 154 | StringBuilder strongName = new StringBuilder((int)size); 155 | this.assemblyName.GetDisplayName(strongName, ref size, (uint)AssemblyNameDisplayFlags.ALL); 156 | return strongName.ToString(); 157 | } 158 | } 159 | internal string/*!*/ CodeBase { 160 | //set {this.WriteString(ASM_NAME.CODEBASE_URL, value);} 161 | get {return this.ReadString(ASM_NAME.CODEBASE_URL);} 162 | } 163 | public override string ToString(){ 164 | return this.StrongName; 165 | } 166 | internal string GetLocation(){ 167 | IAssemblyCache assemblyCache; 168 | CreateAssemblyCache(out assemblyCache, 0); 169 | if (assemblyCache == null) return null; 170 | ASSEMBLY_INFO assemblyInfo = new ASSEMBLY_INFO(); 171 | assemblyInfo.cbAssemblyInfo = (uint)Marshal.SizeOf(typeof(ASSEMBLY_INFO)); 172 | assemblyCache.QueryAssemblyInfo(ASSEMBLYINFO_FLAG.VALIDATE | ASSEMBLYINFO_FLAG.GETSIZE, this.StrongName, ref assemblyInfo); 173 | if (assemblyInfo.cbAssemblyInfo == 0) return null; 174 | assemblyInfo.pszCurrentAssemblyPathBuf = new string(new char[assemblyInfo.cchBuf]); 175 | assemblyCache.QueryAssemblyInfo(ASSEMBLYINFO_FLAG.VALIDATE | ASSEMBLYINFO_FLAG.GETSIZE, this.StrongName, ref assemblyInfo); 176 | String value = assemblyInfo.pszCurrentAssemblyPathBuf; 177 | return value; 178 | } 179 | private string/*!*/ ReadString(uint assemblyNameProperty) { 180 | uint size = 0; 181 | this.assemblyName.GetProperty(assemblyNameProperty, IntPtr.Zero, ref size); 182 | if (size == 0 || size > Int16.MaxValue) return String.Empty; 183 | IntPtr ptr = Marshal.AllocHGlobal((int) size); 184 | this.assemblyName.GetProperty(assemblyNameProperty, ptr, ref size); 185 | String str = Marshal.PtrToStringUni(ptr); 186 | //^ assume str != null; 187 | Marshal.FreeHGlobal(ptr); 188 | return str; 189 | } 190 | private ushort ReadUInt16(uint assemblyNameProperty){ 191 | uint size = 0; 192 | this.assemblyName.GetProperty(assemblyNameProperty, IntPtr.Zero, ref size); 193 | IntPtr ptr = Marshal.AllocHGlobal((int) size); 194 | this.assemblyName.GetProperty(assemblyNameProperty, ptr, ref size); 195 | ushort value = (ushort)Marshal.ReadInt16(ptr); 196 | Marshal.FreeHGlobal(ptr); 197 | return value; 198 | } 199 | private byte[]/*!*/ ReadBytes(uint assemblyNameProperty) { 200 | uint size = 0; 201 | this.assemblyName.GetProperty(assemblyNameProperty, IntPtr.Zero, ref size); 202 | IntPtr ptr = Marshal.AllocHGlobal((int) size); 203 | this.assemblyName.GetProperty(assemblyNameProperty, ptr, ref size); 204 | byte[] value = new byte[(int) size]; 205 | Marshal.Copy(ptr, value, 0, (int) size); 206 | Marshal.FreeHGlobal(ptr); 207 | return value; 208 | } 209 | //private void WriteString(uint assemblyNameProperty, string/*!*/ value){ 210 | // IntPtr ptr = Marshal.StringToHGlobalUni(value); 211 | // this.assemblyName.SetProperty(assemblyNameProperty, ptr, (uint)((value.Length + 1) * 2)); 212 | // Marshal.FreeHGlobal(ptr); 213 | //} 214 | //private void WriteUInt16(uint assemblyNameProperty, ushort value){ 215 | // IntPtr ptr = Marshal.AllocHGlobal(2); 216 | // Marshal.WriteInt16(ptr, (short)value); 217 | // this.assemblyName.SetProperty(assemblyNameProperty, ptr, 2); 218 | // Marshal.FreeHGlobal(ptr); 219 | //} 220 | //private void WriteBytes(uint assemblyNameProperty, Byte[]/*!*/ value) { 221 | // int size = value.Length; 222 | // IntPtr ptr = Marshal.AllocHGlobal(size); 223 | // Marshal.Copy(value, 0, ptr, size); 224 | // this.assemblyName.SetProperty(assemblyNameProperty, ptr, (uint)size); 225 | // Marshal.FreeHGlobal(ptr); 226 | //} 227 | 228 | [DllImport("fusion.dll", CharSet=CharSet.Auto)] 229 | private static extern int CreateAssemblyCache(out IAssemblyCache ppAsmCache, uint dwReserved); 230 | private class CREATE_ASM_NAME_OBJ_FLAGS{ 231 | private CREATE_ASM_NAME_OBJ_FLAGS(){} 232 | public const uint CANOF_PARSE_DISPLAY_NAME = 0x1; 233 | public const uint CANOF_SET_DEFAULT_VALUES = 0x2; 234 | } 235 | private class ASM_NAME{ 236 | private ASM_NAME(){} 237 | public const uint PUBLIC_KEY = 0; 238 | public const uint PUBLIC_KEY_TOKEN = 1; 239 | public const uint HASH_VALUE = 2; 240 | public const uint NAME = 3; 241 | public const uint MAJOR_VERSION = 4; 242 | public const uint MINOR_VERSION = 5; 243 | public const uint BUILD_NUMBER = 6; 244 | public const uint REVISION_NUMBER = 7; 245 | public const uint CULTURE = 8; 246 | public const uint PROCESSOR_ID_ARRAY = 9; 247 | public const uint OSINFO_ARRAY = 10; 248 | public const uint HASH_ALGID = 11; 249 | public const uint ALIAS = 12; 250 | public const uint CODEBASE_URL = 13; 251 | public const uint CODEBASE_LASTMOD = 14; 252 | public const uint NULL_PUBLIC_KEY = 15; 253 | public const uint NULL_PUBLIC_KEY_TOKEN = 16; 254 | public const uint CUSTOM = 17; 255 | public const uint NULL_CUSTOM = 18; 256 | public const uint MVID = 19; 257 | public const uint _32_BIT_ONLY = 20; 258 | } 259 | [Flags] 260 | internal enum AssemblyNameDisplayFlags{ 261 | VERSION=0x01, 262 | CULTURE=0x02, 263 | PUBLIC_KEY_TOKEN=0x04, 264 | PROCESSORARCHITECTURE=0x20, 265 | RETARGETABLE=0x80, 266 | ALL=VERSION | CULTURE | PUBLIC_KEY_TOKEN | PROCESSORARCHITECTURE | RETARGETABLE 267 | } 268 | private class ASSEMBLYINFO_FLAG { 269 | private ASSEMBLYINFO_FLAG(){} 270 | public const uint VALIDATE = 1; 271 | public const uint GETSIZE = 2; 272 | } 273 | [StructLayout(LayoutKind.Sequential)] 274 | private struct ASSEMBLY_INFO{ 275 | public uint cbAssemblyInfo; 276 | public uint dwAssemblyFlags; 277 | public ulong uliAssemblySizeInKB; 278 | [MarshalAs(UnmanagedType.LPWStr)] 279 | public string pszCurrentAssemblyPathBuf; 280 | public uint cchBuf; 281 | } 282 | [ComImport(), Guid("E707DCDE-D1CD-11D2-BAB9-00C04F8ECEAE"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 283 | private interface IAssemblyCache{ 284 | [PreserveSig()] 285 | int UninstallAssembly(uint dwFlags, [MarshalAs(UnmanagedType.LPWStr)] string pszAssemblyName, IntPtr pvReserved, int pulDisposition); 286 | [PreserveSig()] 287 | int QueryAssemblyInfo(uint dwFlags, [MarshalAs(UnmanagedType.LPWStr)] string pszAssemblyName, ref ASSEMBLY_INFO pAsmInfo); 288 | [PreserveSig()] 289 | int CreateAssemblyCacheItem(uint dwFlags, IntPtr pvReserved, out object ppAsmItem, [MarshalAs(UnmanagedType.LPWStr)] string pszAssemblyName); 290 | [PreserveSig()] 291 | int CreateAssemblyScavenger(out object ppAsmScavenger); 292 | [PreserveSig()] 293 | int InstallAssembly(uint dwFlags, [MarshalAs(UnmanagedType.LPWStr)] string pszManifestFilePath, IntPtr pvReserved); 294 | } 295 | } 296 | [ComImport(), Guid("CD193BC0-B4BC-11D2-9833-00C04FC31D2E"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 297 | interface IAssemblyName{ 298 | [PreserveSig()] 299 | int SetProperty(uint PropertyId, IntPtr pvProperty, uint cbProperty); 300 | [PreserveSig()] 301 | int GetProperty(uint PropertyId, IntPtr pvProperty, ref uint pcbProperty); 302 | [PreserveSig()] 303 | int Finalize(); 304 | [PreserveSig()] 305 | int GetDisplayName(StringBuilder szDisplayName, ref uint pccDisplayName, uint dwDisplayFlags); 306 | [PreserveSig()] 307 | int BindToObject(object refIID, object pAsmBindSink, IApplicationContext pApplicationContext, [MarshalAs(UnmanagedType.LPWStr)] string szCodeBase, long llFlags, int pvReserved, uint cbReserved, out int ppv); 308 | [PreserveSig()] 309 | int GetName(out uint lpcwBuffer, out int pwzName); 310 | [PreserveSig()] 311 | int GetVersion(out uint pdwVersionHi, out uint pdwVersionLow); 312 | [PreserveSig()] 313 | int IsEqual(IAssemblyName pName, uint dwCmpFlags); 314 | [PreserveSig()] 315 | int Clone(out IAssemblyName pName); 316 | } 317 | [ComImport(), Guid("7C23FF90-33AF-11D3-95DA-00A024A85B51"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 318 | interface IApplicationContext{ 319 | void SetContextNameObject(IAssemblyName pName); 320 | void GetContextNameObject(out IAssemblyName ppName); 321 | void Set([MarshalAs(UnmanagedType.LPWStr)] string szName, int pvValue, uint cbValue, uint dwFlags); 322 | void Get([MarshalAs(UnmanagedType.LPWStr)] string szName, out int pvValue, ref uint pcbValue, uint dwFlags); 323 | void GetDynamicDirectory(out int wzDynamicDir, ref uint pdwSize); 324 | } 325 | [ComImport(), Guid("21B8916C-F28E-11D2-A473-00C04F8EF448"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 326 | interface IAssemblyEnum{ 327 | [PreserveSig()] 328 | int GetNextAssembly(out IApplicationContext ppAppCtx, out IAssemblyName ppName, uint dwFlags); 329 | [PreserveSig()] 330 | int Reset(); 331 | [PreserveSig()] 332 | int Clone(out IAssemblyEnum ppEnum); 333 | } 334 | } 335 | #else 336 | //TODO: provide a way to query ROTOR GAC 337 | #endif 338 | -------------------------------------------------------------------------------- /System.Compiler/MemoryMappedFile.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | // See the LICENSE file in the project root for more information. 4 | 5 | using System; 6 | #if CCINamespace 7 | using Microsoft.Cci; 8 | #else 9 | using System.Compiler; 10 | #endif 11 | using System.Diagnostics; 12 | using System.IO; 13 | using System.Globalization; 14 | using System.Runtime.InteropServices; 15 | using System.Text; 16 | using System.Diagnostics.Contracts; 17 | 18 | #if CCINamespace 19 | namespace Microsoft.Cci.Metadata{ 20 | #else 21 | namespace System.Compiler.Metadata{ 22 | #endif 23 | unsafe internal sealed class MemoryCursor{ 24 | private byte* buffer, pb; 25 | readonly internal int Length; 26 | 27 | #if !ROTOR 28 | internal MemoryCursor(MemoryMappedFile/*!*/ memoryMap) 29 | :this(memoryMap.Buffer, memoryMap.Length){ 30 | } 31 | #endif 32 | internal MemoryCursor(byte* buffer, int length, int position){ 33 | this.buffer = buffer; 34 | this.pb = buffer+position; 35 | this.Length = length; 36 | } 37 | internal MemoryCursor(byte *buffer, int length) 38 | : this(buffer, length, 0){ 39 | } 40 | internal MemoryCursor(MemoryCursor/*!*/ c) { 41 | this.buffer = c.buffer; 42 | this.pb = c.pb; 43 | this.Length = c.Length; 44 | } 45 | 46 | internal byte* GetBuffer(){ 47 | return this.buffer; 48 | } 49 | 50 | internal int Position{ 51 | get{ return (int)(this.pb-this.buffer); } 52 | set{ this.pb = this.buffer+value; } 53 | } 54 | internal void Align(int size){ 55 | Contract.Requires(size == 2 || size == 4 || size == 8 || size == 16 || size == 32 || size == 64); 56 | int remainder = Position & (size-1); 57 | if (remainder != 0) 58 | pb += size-remainder; 59 | } 60 | 61 | //internal System.Char Char(int i){ return *(System.Char*)(this.pb+i*sizeof(System.Char)); } 62 | //internal System.SByte SByte(int i){ return *(System.SByte*)(this.pb+i*sizeof(System.SByte)); } 63 | internal System.Int16 Int16(int i){ return *(System.Int16*)(this.pb+i*sizeof(System.Int16)); } 64 | internal System.Int32 Int32(int i){ return *(System.Int32*)(this.pb+i*sizeof(System.Int32)); } 65 | //internal System.Int64 Int64(int i){ return *(System.Int64*)(this.pb+i*sizeof(System.Int64)); } 66 | internal System.Byte Byte(int i){ return *(System.Byte*)(this.pb+i*sizeof(System.Byte)); } 67 | internal System.UInt16 UInt16(int i){ return *(System.UInt16*)(this.pb+i*sizeof(System.UInt16)); } 68 | //internal System.UInt32 UInt32(int i){ return *(System.UInt32*)(this.pb+i*sizeof(System.UInt32)); } 69 | //internal System.UInt64 UInt64(int i){ return *(System.UInt64*)(this.pb+i*sizeof(System.UInt64)); } 70 | //internal System.Boolean Boolean(int i){ return *(System.Boolean*)(this.pb+i*sizeof(System.Boolean)); } 71 | //internal System.Single Single(int i){ return *(System.Single*)(this.pb+i*sizeof(System.Single)); } 72 | //internal System.Double Double(int i){ return *(System.Double*)(this.pb+i*sizeof(System.Double)); } 73 | 74 | //internal void SkipChar(int c){ this.pb += c*sizeof(System.Char); } 75 | //internal void SkipSByte(int c){ this.pb += c*sizeof(System.SByte); } 76 | internal void SkipInt16(int c){ this.pb += c*sizeof(System.Int16); } 77 | internal void SkipInt32(int c){ this.pb += c*sizeof(System.Int32); } 78 | //internal void SkipInt64(int c){ this.pb += c*sizeof(System.Int64); } 79 | internal void SkipByte(int c){ this.pb += c*sizeof(System.Byte); } 80 | internal void SkipUInt16(int c){ this.pb += c*sizeof(System.UInt16); } 81 | //internal void SkipUInt32(int c){ this.pb += c*sizeof(System.UInt32); } 82 | //internal void SkipUInt64(int c){ this.pb += c*sizeof(System.UInt64); } 83 | //internal void SkipBoolean(int c){ this.pb += c*sizeof(System.Boolean); } 84 | //internal void SkipSingle(int c){ this.pb += c*sizeof(System.Single); } 85 | //internal void SkipDouble(int c){ this.pb += c*sizeof(System.Double); } 86 | 87 | internal System.Char ReadChar(){ byte *pb = this.pb; System.Char v = *(System.Char*)pb; this.pb = pb+sizeof(System.Char); return v; } 88 | internal System.SByte ReadSByte(){ byte *pb = this.pb; System.SByte v = *(System.SByte*)pb; this.pb = pb+sizeof(System.SByte); return v; } 89 | internal System.Int16 ReadInt16(){ byte *pb = this.pb; System.Int16 v = *(System.Int16*)pb; this.pb = pb+sizeof(System.Int16); return v; } 90 | internal System.Int32 ReadInt32(){ byte *pb = this.pb; System.Int32 v = *(System.Int32*)pb; this.pb = pb+sizeof(System.Int32); return v; } 91 | internal System.Int64 ReadInt64(){ byte *pb = this.pb; System.Int64 v = *(System.Int64*)pb; this.pb = pb+sizeof(System.Int64); return v; } 92 | internal System.Byte ReadByte(){ byte *pb = this.pb; System.Byte v = *(System.Byte*)pb; this.pb = pb+sizeof(System.Byte); return v; } 93 | internal System.UInt16 ReadUInt16(){ byte *pb = this.pb; System.UInt16 v = *(System.UInt16*)pb; this.pb = pb+sizeof(System.UInt16); return v; } 94 | internal System.UInt32 ReadUInt32(){ byte *pb = this.pb; System.UInt32 v = *(System.UInt32*)pb; this.pb = pb+sizeof(System.UInt32); return v; } 95 | internal System.UInt64 ReadUInt64(){ byte *pb = this.pb; System.UInt64 v = *(System.UInt64*)pb; this.pb = pb+sizeof(System.UInt64); return v; } 96 | internal System.Boolean ReadBoolean(){ byte *pb = this.pb; System.Boolean v = *(System.Boolean*)pb; this.pb = pb+sizeof(System.Boolean); return v; } 97 | internal System.Single ReadSingle(){ byte *pb = this.pb; System.Single v = *(System.Single*)pb; this.pb = pb+sizeof(System.Single); return v; } 98 | internal System.Double ReadDouble(){ byte *pb = this.pb; System.Double v = *(System.Double*)pb; this.pb = pb+sizeof(System.Double); return v; } 99 | 100 | internal System.Int32 ReadReference(int refSize){ 101 | if (refSize == 2) return ReadUInt16(); 102 | return ReadInt32(); 103 | } 104 | 105 | internal int ReadCompressedInt(){ 106 | byte headerByte = ReadByte(); 107 | int result; 108 | if ((headerByte & 0x80) == 0x00) 109 | result = headerByte; 110 | else if ((headerByte & 0x40) == 0x00) 111 | result = ((headerByte & 0x3f) << 8) | ReadByte(); 112 | else if (headerByte == 0xFF) 113 | result = -1; 114 | else 115 | result = ((headerByte & 0x3f) << 24) | (ReadByte() << 16) | (ReadByte() << 8) | ReadByte(); 116 | return result; 117 | } 118 | 119 | internal byte[]/*!*/ ReadBytes(int c){ 120 | byte[] result = new byte[c]; 121 | byte *pb = this.pb; 122 | for (int i = 0; i < c; i++) 123 | result[i] = *pb++; 124 | this.pb = pb; 125 | return result; 126 | } 127 | 128 | internal unsafe Identifier/*!*/ ReadIdentifierFromSerString() { 129 | byte *pb = this.pb; 130 | byte headerByte = *pb++; 131 | uint length = 0; 132 | if ((headerByte & 0x80) == 0x00) 133 | length = headerByte; 134 | else if ((headerByte & 0x40) == 0x00) 135 | length = (uint)((headerByte & 0x3f) << 8) | *pb++; 136 | else 137 | length = (uint)((headerByte & 0x3f) << 24) | (uint)(*pb++ << 16) | (uint)(*pb++ << 8) | (*pb++); 138 | this.pb = pb+length; 139 | return Identifier.For(pb, length/*, this.KeepAlive*/); 140 | } 141 | 142 | internal string/*!*/ ReadUTF8(int bytesToRead) { 143 | char[] buffer = new char[bytesToRead]; 144 | byte *pb = this.pb; 145 | this.pb += bytesToRead; 146 | int j = 0; 147 | while (bytesToRead > 0){ 148 | byte b = *pb++; bytesToRead--; 149 | if ((b & 0x80) == 0 || bytesToRead == 0){ 150 | buffer[j++] = (char)b; 151 | continue; 152 | } 153 | char ch; 154 | byte b1 = *pb++; bytesToRead--; 155 | if ((b & 0x20) == 0) 156 | ch = (char)(((b&0x1F)<<6) | (b1&0x3F)); 157 | else{ 158 | if (bytesToRead == 0){ //Dangling lead bytes, do not decompose 159 | buffer[j++] = (char)((b << 8) | b1); 160 | break; 161 | } 162 | byte b2 = *pb++; bytesToRead--; 163 | uint ch32; 164 | if ((b & 0x10) == 0) 165 | ch32 = (uint)(((b&0x0F)<<12) | ((b1&0x3F)<<6) | (b2&0x3F)); 166 | else{ 167 | if (bytesToRead == 0){ //Dangling lead bytes, do not decompose 168 | buffer[j++] = (char)((b << 8) | b1); 169 | buffer[j++] = (char)b2; 170 | break; 171 | } 172 | byte b3 = *pb++; bytesToRead--; 173 | ch32 = (uint)(((b&0x07)<<18) | ((b1&0x3F)<<12) | ((b2&0x3F)<<6) | (b3&0x3F)); 174 | } 175 | if ((ch32 & 0xFFFF0000) == 0) 176 | ch = (char)ch32; 177 | else{ //break up into UTF16 surrogate pair 178 | buffer[j++] = (char)((ch32 >> 10) | 0xD800); 179 | ch = (char)((ch32 & 0x3FF) | 0xDC00); 180 | } 181 | } 182 | buffer[j++] = ch; 183 | } 184 | if (j > 0 && buffer[j-1] == 0) j--; 185 | return new String(buffer, 0, j); 186 | } 187 | 188 | internal string/*!*/ ReadUTF8(){ 189 | byte *pb = this.pb; 190 | StringBuilder sb = new StringBuilder(); 191 | byte b = 0; 192 | for(;;){ 193 | b = *pb++; 194 | if (b == 0) break; 195 | if ((b & 0x80) == 0){ 196 | sb.Append((char)b); 197 | continue; 198 | } 199 | char ch; 200 | byte b1 = *pb++; 201 | if (b1 == 0){ //Dangling lead byte, do not decompose 202 | sb.Append((char)b); 203 | break; 204 | } 205 | if ((b & 0x20) == 0){ 206 | ch = (char)(((b&0x1F)<<6) | (b1&0x3F)); 207 | }else{ 208 | byte b2 = *pb++; 209 | if (b2 == 0){ //Dangling lead bytes, do not decompose 210 | sb.Append((char)((b << 8)|b1)); 211 | break; 212 | } 213 | uint ch32; 214 | if ((b & 0x10) == 0) 215 | ch32 = (uint)(((b&0x0F)<<12) | ((b1&0x3F)<<6) | (b2&0x3F)); 216 | else{ 217 | byte b3 = *pb++; 218 | if (b3 == 0){ //Dangling lead bytes, do not decompose 219 | sb.Append((char)((b << 8)|b1)); 220 | sb.Append((char)b2); 221 | break; 222 | } 223 | ch32 = (uint)(((b&0x07)<<18) | ((b1&0x3F)<<12) | ((b2&0x3F)<<6) | (b3&0x3F)); 224 | } 225 | if ((ch32 & 0xFFFF0000) == 0) 226 | ch = (char)ch32; 227 | else{ //break up into UTF16 surrogate pair 228 | sb.Append((char)((ch32 >> 10) | 0xD800)); 229 | ch = (char)((ch32 & 0x3FF) | 0xDC00); 230 | } 231 | } 232 | sb.Append(ch); 233 | } 234 | this.pb = pb; 235 | return sb.ToString(); 236 | } 237 | 238 | internal string/*!*/ ReadUTF16(int charsToRead){ 239 | char *pc = (char*)this.pb; 240 | char[] buffer = new char[charsToRead]; 241 | for (int i = 0; i < charsToRead; i++) 242 | buffer[i] = *pc++; 243 | this.pb = (byte*)pc; 244 | return new String(buffer, 0, charsToRead); 245 | } 246 | 247 | internal string/*!*/ ReadUTF16() { 248 | string result = new string((char*)this.pb); 249 | this.pb += (result.Length+1)*2; 250 | return result; 251 | } 252 | 253 | internal string/*!*/ ReadASCII(int bytesToRead) { 254 | int c = bytesToRead; 255 | if (bytesToRead == -1) c = 128; //buffer size 256 | byte *pb = this.pb; 257 | char[] buffer = new char[c]; 258 | int j = 0; 259 | byte b = 0; 260 | Restart: 261 | while (j < c){ 262 | b = *pb++; 263 | if (b == 0) break; 264 | buffer[j++] = (char)b; 265 | } 266 | if (bytesToRead == -1){ 267 | if (b != 0){ 268 | char[] newBuffer = new char[c *= 2]; 269 | for (int copy = 0; copy < j; copy++) 270 | newBuffer[copy] = buffer[copy]; 271 | buffer = newBuffer; 272 | goto Restart; 273 | } 274 | this.pb = pb; 275 | }else 276 | this.pb += bytesToRead; 277 | return new String(buffer, 0, j); 278 | } 279 | 280 | internal string/*!*/ ReadASCII() { return ReadASCII(-1); } 281 | } 282 | 283 | #if !ROTOR 284 | #if !FxCop 285 | /// 286 | /// Public only for use by the Framework. Do not use this class. 287 | /// Well, if you really really must, use it only if you can tolerate keeping the file locked for at least as long as any Identifier 288 | /// derived from the file stays alive. 289 | /// 290 | unsafe public sealed class MemoryMappedFile : IDisposable, ISourceTextBuffer{ 291 | #else 292 | unsafe sealed class MemoryMappedFile : IDisposable{ 293 | #endif 294 | private byte* buffer; 295 | private int length; 296 | 297 | public MemoryMappedFile(string fileName){ 298 | this.OpenMap(fileName); 299 | } 300 | ~MemoryMappedFile(){ 301 | this.CloseMap(); 302 | } 303 | public void Dispose(){ 304 | this.CloseMap(); 305 | GC.SuppressFinalize(this); 306 | } 307 | 308 | public byte *Buffer{ 309 | get { 310 | Debug.Assert(this.buffer != null); 311 | return this.buffer; 312 | } 313 | } 314 | public int Length { 315 | get { 316 | Debug.Assert(this.buffer != null); 317 | return this.length; 318 | } 319 | } 320 | #if !FxCop 321 | string ISourceText.Substring(int start, int length){ 322 | Debug.Assert(false, "Can't use Substring on memory mapped files"); 323 | return null; 324 | } 325 | char ISourceText.this[int index]{ 326 | get{ 327 | Debug.Assert(false, "Can't access memory mapped files via an indexer, use Buffer"); 328 | return ' '; 329 | } 330 | } 331 | #endif 332 | private void OpenMap(string filename){ 333 | IntPtr hmap; 334 | int length; 335 | using (FileStream stream = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read)){ 336 | if (stream.Length > Int32.MaxValue) 337 | throw new FileLoadException(ExceptionStrings.FileTooBig, filename); 338 | length = unchecked((int)stream.Length); 339 | #if WHIDBEY && !OldWhidbey 340 | hmap = CreateFileMapping(stream.SafeFileHandle.DangerousGetHandle(), IntPtr.Zero, PageAccess.PAGE_READONLY, 0, length, null); 341 | #else 342 | hmap = CreateFileMapping(stream.Handle, IntPtr.Zero, PageAccess.PAGE_READONLY, 0, length, null); 343 | #endif 344 | if (hmap == IntPtr.Zero){ 345 | int rc = Marshal.GetLastWin32Error(); 346 | throw new FileLoadException(String.Format(CultureInfo.CurrentCulture, 347 | ExceptionStrings.CreateFileMappingReturnedErrorCode, rc.ToString()), filename); 348 | } 349 | } 350 | this.buffer = (byte *)MapViewOfFile(hmap, FileMapAccess.FILE_MAP_READ, 0, 0, (IntPtr)length); 351 | MemoryMappedFile.CloseHandle(hmap); 352 | if (this.buffer == null){ 353 | int rc = Marshal.GetLastWin32Error(); 354 | throw new FileLoadException(String.Format(CultureInfo.CurrentCulture, 355 | ExceptionStrings.MapViewOfFileReturnedErrorCode, rc.ToString()), filename); 356 | } 357 | this.length = length; 358 | } 359 | private void CloseMap(){ 360 | if (buffer != null){ 361 | UnmapViewOfFile(buffer); 362 | buffer = null; 363 | } 364 | } 365 | #if !FxCop 366 | void ISourceText.MakeCollectible(){ 367 | } 368 | #endif 369 | 370 | private enum PageAccess : int { PAGE_READONLY = 0x02 }; 371 | private enum FileMapAccess : int { FILE_MAP_READ = 0x0004 }; 372 | 373 | [DllImport("kernel32.dll", CharSet=CharSet.Auto, SetLastError=true, BestFitMapping =false, ThrowOnUnmappableChar = true)] 374 | private static extern IntPtr CreateFileMapping( 375 | IntPtr hFile, // handle to file 376 | IntPtr lpAttributes, // security 377 | PageAccess flProtect, // protection 378 | int dwMaximumSizeHigh, // high-order DWORD of size 379 | int dwMaximumSizeLow, // low-order DWORD of size 380 | string lpName // object name 381 | ); 382 | 383 | [DllImport("kernel32.dll", CharSet=CharSet.Auto, SetLastError=true)] 384 | private static extern void* MapViewOfFile( 385 | IntPtr hFileMappingObject, // handle to file-mapping object 386 | FileMapAccess dwDesiredAccess, // access mode 387 | int dwFileOffsetHigh, // high-order DWORD of offset 388 | int dwFileOffsetLow, // low-order DWORD of offset 389 | IntPtr dwNumberOfBytesToMap // number of bytes to map 390 | ); 391 | 392 | [DllImport("kernel32.dll", CharSet=CharSet.Auto, SetLastError=true)] 393 | [return: MarshalAs(UnmanagedType.Bool)] 394 | private static extern bool UnmapViewOfFile( 395 | void* lpBaseAddress // starting address 396 | ); 397 | 398 | [DllImport("kernel32.dll", CharSet=CharSet.Auto, SetLastError=true)] 399 | [return: MarshalAs(UnmanagedType.Bool)] 400 | private static extern bool CloseHandle( 401 | IntPtr hObject // handle to object 402 | ); 403 | } 404 | #endif 405 | } 406 | --------------------------------------------------------------------------------