From 6429392003af42655271598543cd4d55e482cae2 Mon Sep 17 00:00:00 2001 From: Mike Barnett Date: Thu, 28 Apr 2016 16:16:54 -0700 Subject: [PATCH 1/2] Correctly propagate the imagebase and sizeofStackReserve for 64-bit assemblies. --- System.Compiler/Metadata.cs | 22 ++++++++++++++-------- System.Compiler/Nodes.cs | 2 ++ System.Compiler/Reader.cs | 2 ++ System.Compiler/Writer.cs | 2 ++ 4 files changed, 20 insertions(+), 8 deletions(-) diff --git a/System.Compiler/Metadata.cs b/System.Compiler/Metadata.cs index 4c24ab01..843b0c0d 100644 --- a/System.Compiler/Metadata.cs +++ b/System.Compiler/Metadata.cs @@ -318,7 +318,7 @@ internal class NTHeader { internal int addressOfEntryPoint; internal int baseOfCode; internal int baseOfData; - internal long imageBase; + internal ulong imageBase; internal int sectionAlignment; internal int fileAlignment; internal ushort majorOperatingSystemVersion; @@ -365,7 +365,7 @@ internal NTHeader(){ this.magic = 0x10B; this.majorLinkerVersion = 6; this.baseOfCode = 0x2000; - this.imageBase = 0x400000; //TODO: make this settable + this.imageBase = 0x400000; this.sectionAlignment = 8192; this.fileAlignment = 512; this.majorOperatingSystemVersion = 4; @@ -523,6 +523,8 @@ unsafe internal class MetadataReader : IDisposable{ readonly private MemoryCursor/*!*/ cursor; internal int entryPointToken; internal int fileAlignment; + internal ulong baseAddress; + internal long sizeOfStackReserve; internal ModuleKindFlags moduleKind; internal PEKindFlags peKind; internal bool TrackDebugData; @@ -924,6 +926,8 @@ private void ReadHeader(){ //TODO: break up this method this.linkerMajorVersion = ntHeader.majorLinkerVersion; this.linkerMinorVersion = ntHeader.minorLinkerVersion; this.fileAlignment = ntHeader.fileAlignment; + this.baseAddress = ntHeader.imageBase; + this.sizeOfStackReserve = ntHeader.sizeOfStackReserve; if ((ntHeader.characteristics & 0x2000) != 0) this.moduleKind = ModuleKindFlags.DynamicallyLinkedLibrary; else @@ -2058,10 +2062,10 @@ internal static void ReadDOSHeader(MemoryCursor/*!*/ c) { header.baseOfCode = c.ReadInt32(); if (header.magic == 0x10B){ header.baseOfData = c.ReadInt32(); - header.imageBase = c.ReadInt32(); + header.imageBase = c.ReadUInt32(); }else{ header.baseOfData = 0; - header.imageBase = c.ReadInt64(); + header.imageBase = c.ReadUInt64(); } header.sectionAlignment = c.ReadInt32(); header.fileAlignment = c.ReadInt32(); @@ -2208,6 +2212,8 @@ internal class MetadataWriter{ internal TypeSpecRow[] typeSpecTable; internal int entryPointToken; internal int fileAlignment; + internal ulong baseAddress; + internal long sizeOfStackReserve; internal ModuleKindFlags moduleKind; internal ushort dllCharacteristics; internal PEKindFlags peKind; @@ -3414,9 +3420,9 @@ private void WriteNTHeader(BinaryWriter/*!*/ writer) writer.Write(this.sectionHeaders[1].virtualAddress); //baseOfData else writer.Write((int)0); - writer.Write((int)ntHeader.imageBase); + writer.Write((int)this.baseAddress); // imageBase }else{ - writer.Write(ntHeader.imageBase); + writer.Write(this.baseAddress); // imageBase } writer.Write(ntHeader.sectionAlignment); writer.Write(this.fileAlignment); @@ -3435,12 +3441,12 @@ private void WriteNTHeader(BinaryWriter/*!*/ writer) writer.Write(ntHeader.subsystem); writer.Write(ntHeader.dllCharacteristics); if (ntHeader.magic == 0x10B){ - writer.Write((int)ntHeader.sizeOfStackReserve); + writer.Write((int)this.sizeOfStackReserve); writer.Write((int)ntHeader.sizeOfStackCommit); writer.Write((int)ntHeader.sizeOfHeapReserve); writer.Write((int)ntHeader.sizeOfHeapCommit); }else{ - writer.Write(ntHeader.sizeOfStackReserve); + writer.Write(this.sizeOfStackReserve); writer.Write(ntHeader.sizeOfStackCommit); writer.Write(ntHeader.sizeOfHeapReserve); writer.Write(ntHeader.sizeOfHeapCommit); diff --git a/System.Compiler/Nodes.cs b/System.Compiler/Nodes.cs index ff5ebc07..a19d2fea 100644 --- a/System.Compiler/Nodes.cs +++ b/System.Compiler/Nodes.cs @@ -5452,6 +5452,8 @@ public class Module : Node, IDisposable{ public bool UsePublicKeyTokensForAssemblyReferences = true; #endif internal int FileAlignment = 512; + internal ulong BaseAddress; + internal long SizeOfStackReserve; internal readonly static object GlobalLock = new object(); #if !NoWriter public bool StripOptionalModifiersFromLocals = true; diff --git a/System.Compiler/Reader.cs b/System.Compiler/Reader.cs index 7dbbde9b..b95ad1d4 100644 --- a/System.Compiler/Reader.cs +++ b/System.Compiler/Reader.cs @@ -639,6 +639,8 @@ private void ReadModuleProperties(Module/*!*/ module){ module.reader = this; module.DllCharacteristics = this.tables.dllCharacteristics; module.FileAlignment = this.tables.fileAlignment; + module.BaseAddress = this.tables.baseAddress; + module.SizeOfStackReserve = this.tables.sizeOfStackReserve; module.HashValue = this.tables.HashValue; module.Kind = this.tables.moduleKind; module.Location = this.fileName; diff --git a/System.Compiler/Writer.cs b/System.Compiler/Writer.cs index 9b43e5cb..da8217bd 100644 --- a/System.Compiler/Writer.cs +++ b/System.Compiler/Writer.cs @@ -556,6 +556,8 @@ private void SetupMetadataWriter(string debugSymbolsLocation){ writer.peKind = module.PEKind; writer.TrackDebugData = module.TrackDebugData; writer.fileAlignment = module.FileAlignment; + writer.baseAddress = module.BaseAddress; + writer.sizeOfStackReserve = module.SizeOfStackReserve; if (writer.fileAlignment < 512) writer.fileAlignment = 512; writer.PublicKey = this.PublicKey; writer.SignatureKeyLength = this.SignatureKeyLength; From b1f94fb43e66b965e00f5c39a2571717ac596631 Mon Sep 17 00:00:00 2001 From: Mike Barnett Date: Mon, 2 May 2016 07:35:09 -0700 Subject: [PATCH 2/2] Fro 32-bit assemblies, use the default imageBase, because doing otherwise causes bad assemblies if the module's imageBase is bigger than 0x400000. --- System.Compiler/Metadata.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/System.Compiler/Metadata.cs b/System.Compiler/Metadata.cs index 843b0c0d..eba7112a 100644 --- a/System.Compiler/Metadata.cs +++ b/System.Compiler/Metadata.cs @@ -365,7 +365,7 @@ internal NTHeader(){ this.magic = 0x10B; this.majorLinkerVersion = 6; this.baseOfCode = 0x2000; - this.imageBase = 0x400000; + this.imageBase = 0x400000; //TODO: make this settable this.sectionAlignment = 8192; this.fileAlignment = 512; this.majorOperatingSystemVersion = 4; @@ -3420,7 +3420,7 @@ private void WriteNTHeader(BinaryWriter/*!*/ writer) writer.Write(this.sectionHeaders[1].virtualAddress); //baseOfData else writer.Write((int)0); - writer.Write((int)this.baseAddress); // imageBase + writer.Write((int)ntHeader.imageBase); // don't use the imageBase read in from the input assembly: it creates bad modules. }else{ writer.Write(this.baseAddress); // imageBase }