crossgen2: Add --imagebase option (#65567)
authort-mustafin <66252296+t-mustafin@users.noreply.github.com>
Wed, 27 Apr 2022 22:48:12 +0000 (01:48 +0300)
committerGleb Balykov <g.balykov@samsung.com>
Tue, 27 Sep 2022 12:50:22 +0000 (15:50 +0300)
--imagebase option set preferable ImageBase field to output PE-file

src/coreclr/tools/aot/ILCompiler.ReadyToRun/CodeGen/ReadyToRunObjectWriter.cs
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRunCodegenNodeFactory.cs
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilation.cs
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilationBuilder.cs
src/coreclr/tools/aot/ILCompiler.ReadyToRun/ObjectWriter/R2RPEBuilder.cs
src/coreclr/tools/aot/crossgen2/CommandLineOptions.cs
src/coreclr/tools/aot/crossgen2/Program.cs
src/coreclr/tools/aot/crossgen2/Properties/Resources.resx

index d704579efd766119e9a26dcc5c95098d3d927172..1d97b0bbd15e9435815da6b231b3de2968f492fc 100644 (file)
@@ -206,7 +206,7 @@ namespace ILCompiler.DependencyAnalysis
 
                 if (_nodeFactory.CompilationModuleGroup.IsCompositeBuildMode && _componentModule == null)
                 {
-                    headerBuilder = PEHeaderProvider.Create(Subsystem.Unknown, _nodeFactory.Target);
+                    headerBuilder = PEHeaderProvider.Create(Subsystem.Unknown, _nodeFactory.Target, _nodeFactory.ImageBase);
                     peIdProvider = new Func<IEnumerable<Blob>, BlobContentId>(content => BlobContentId.FromHash(CryptographicHashProvider.ComputeSourceHash(content)));
                     timeDateStamp = null;
                     r2rHeaderExportSymbol = _nodeFactory.Header;
@@ -214,7 +214,7 @@ namespace ILCompiler.DependencyAnalysis
                 else
                 {
                     PEReader inputPeReader = (_componentModule != null ? _componentModule.PEReader : _nodeFactory.CompilationModuleGroup.CompilationModuleSet.First().PEReader);
-                    headerBuilder = PEHeaderProvider.Create(inputPeReader.PEHeaders.PEHeader.Subsystem, _nodeFactory.Target);
+                    headerBuilder = PEHeaderProvider.Create(inputPeReader.PEHeaders.PEHeader.Subsystem, _nodeFactory.Target, _nodeFactory.ImageBase);
                     timeDateStamp = inputPeReader.PEHeaders.CoffHeader.TimeDateStamp;
                     r2rHeaderExportSymbol = null;
                 }
index da9c4592b549a6ff87328d4312f4ef1c36fe5dcd..3629ab5ce0e9afb8709b4e63d7ccf3f84d4471db 100644 (file)
@@ -63,6 +63,8 @@ namespace ILCompiler.DependencyAnalysis
 
         public CompositeImageSettings CompositeImageSettings { get; set; }
 
+        public ulong ImageBase;
+
         public bool MarkingComplete => _markingComplete;
 
         public void SetMarkingComplete()
@@ -155,7 +157,8 @@ namespace ILCompiler.DependencyAnalysis
             CopiedCorHeaderNode corHeaderNode,
             DebugDirectoryNode debugDirectoryNode,
             ResourceData win32Resources,
-            ReadyToRunFlags flags)
+            ReadyToRunFlags flags,
+            ulong imageBase)
         {
             TypeSystemContext = context;
             CompilationModuleGroup = compilationModuleGroup;
@@ -167,6 +170,7 @@ namespace ILCompiler.DependencyAnalysis
             DebugDirectoryNode = debugDirectoryNode;
             Resolver = compilationModuleGroup.Resolver;
             Header = new GlobalHeaderNode(Target, flags);
+            ImageBase = imageBase;
             if (!win32Resources.IsEmpty)
                 Win32ResourcesNode = new Win32ResourcesNode(win32Resources);
 
index a5c7359a048b045ba65085fbfb7d709b244981ef..472f90e8e8ee745fa1ffd65bd608ed90e8fa0433 100644 (file)
@@ -411,7 +411,8 @@ namespace ILCompiler
                 copiedCorHeader,
                 debugDirectory,
                 win32Resources: new Win32Resources.ResourceData(inputModule),
-                flags);
+                flags,
+                _nodeFactory.ImageBase);
 
             IComparer<DependencyNodeCore<NodeFactory>> comparer = new SortableDependencyNode.ObjectNodeComparer(new CompilerComparer());
             DependencyAnalyzerBase<NodeFactory> componentGraph = new DependencyAnalyzer<NoLogStrategy<NodeFactory>, NodeFactory>(componentFactory, comparer);
index 34aced76b44b01ce343dc87b8ec19fef2c5d2ff8..109b3819b87324a81417e712ae14ec55b05ec012 100644 (file)
@@ -42,6 +42,7 @@ namespace ILCompiler
         private int _customPESectionAlignment;
         private bool _verifyTypeAndFieldLayout;
         private CompositeImageSettings _compositeImageSettings;
+        private ulong _imageBase;
 
         private string _jitPath;
         private string _outputFile;
@@ -212,6 +213,12 @@ namespace ILCompiler
             return this;
         }
 
+        public ReadyToRunCodegenCompilationBuilder UseImageBase(ulong imageBase)
+        {
+            _imageBase = imageBase;
+            return this;
+        }
+
         public override ICompilation ToCompilation()
         {
             // TODO: only copy COR headers for single-assembly build and for composite build with embedded MSIL
@@ -254,7 +261,9 @@ namespace ILCompiler
                 corHeaderNode,
                 debugDirectoryNode,
                 win32Resources,
-                flags);
+                flags,
+                _imageBase
+                );
 
             factory.CompositeImageSettings = _compositeImageSettings;
 
index c7212368ace07aeed63a04d1e2dce5d1c738b409..e1fb041c4af9cf5f98a9f399b3ac497d0036eb89 100644 (file)
@@ -673,15 +673,13 @@ namespace ILCompiler.PEWriter
         /// </summary>
         /// <param name="subsystem">Targeting subsystem</param>
         /// <param name="target">Target architecture to set in the header</param>
-        public static PEHeaderBuilder Create(Subsystem subsystem, TargetDetails target)
+        public static PEHeaderBuilder Create(Subsystem subsystem, TargetDetails target, ulong imageBase)
         {
             bool is64BitTarget = target.PointerSize == sizeof(long);
 
             Characteristics imageCharacteristics = Characteristics.ExecutableImage | Characteristics.Dll;
             imageCharacteristics |= is64BitTarget ? Characteristics.LargeAddressAware : Characteristics.Bit32Machine;
 
-            ulong imageBase = is64BitTarget ? PE64HeaderConstants.DllImageBase : PE32HeaderConstants.ImageBase;
-
             int fileAlignment = 0x200;
             if (!target.IsWindows && !is64BitTarget)
             {
index c34c7ad7bf3c34e7ff60d74975fc8c20da4c2026..9afe893b17caf96b823e33e9064ad476688a3273 100644 (file)
@@ -69,6 +69,7 @@ namespace ILCompiler
         public string FileLayout;
         public bool VerifyTypeAndFieldLayout;
         public string CallChainProfileFile;
+        public string ImageBase;
 
         public string SingleMethodTypeName;
         public string SingleMethodName;
@@ -147,6 +148,7 @@ namespace ILCompiler
                 syntax.DefineOption("waitfordebugger", ref WaitForDebugger, SR.WaitForDebuggerOption);
                 syntax.DefineOptionList("codegenopt|codegen-options", ref CodegenOptions, SR.CodeGenOptions);
                 syntax.DefineOption("resilient", ref Resilient, SR.ResilientOption);
+                syntax.DefineOption("imagebase", ref ImageBase, SR.ImageBase);
 
                 syntax.DefineOption("targetarch", ref TargetArch, SR.TargetArchOption);
                 syntax.DefineOption("targetos", ref TargetOS, SR.TargetOSOption);
index f25fa36e5c80305987ea3e875a7f34becda0460a..4912905fbbe4a6b0b98c492679b1c31a73848d17 100644 (file)
@@ -26,6 +26,7 @@ namespace ILCompiler
         public TargetArchitecture _targetArchitecture;
         private bool _armelAbi = false;
         public OptimizationMode _optimizationMode;
+        private ulong _imageBase;
 
         // File names as strings in args
         private Dictionary<string, string> _inputFilePaths = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
@@ -311,6 +312,16 @@ namespace ILCompiler
                                                                   _targetArchitecture);
         }
 
+        private void ConfigureImageBase(TargetDetails targetDetails)
+        {
+            bool is64BitTarget = targetDetails.PointerSize == sizeof(long);
+
+            if (_commandLineOptions.ImageBase != null)
+                _imageBase = is64BitTarget ? Convert.ToUInt64(_commandLineOptions.ImageBase, 16) : Convert.ToUInt32(_commandLineOptions.ImageBase, 16);
+            else
+                _imageBase = is64BitTarget ? PEWriter.PE64HeaderConstants.DllImageBase : PEWriter.PE32HeaderConstants.ImageBase;
+        }
+
         private int Run(string[] args)
         {
             InitializeDefaultOptions();
@@ -336,6 +347,8 @@ namespace ILCompiler
 
             var targetDetails = new TargetDetails(_targetArchitecture, _targetOS, _armelAbi ? TargetAbi.CoreRTArmel : TargetAbi.CoreRT, instructionSetSupport.GetVectorTSimdVector());
 
+            ConfigureImageBase(targetDetails);
+
             bool versionBubbleIncludesCoreLib = false;
             if (_commandLineOptions.InputBubble)
             {
@@ -732,6 +745,7 @@ namespace ILCompiler
                         .UseCustomPESectionAlignment(_commandLineOptions.CustomPESectionAlignment)
                         .UseVerifyTypeAndFieldLayout(_commandLineOptions.VerifyTypeAndFieldLayout)
                         .GenerateOutputFile(outFile)
+                        .UseImageBase(_imageBase)
                         .UseILProvider(ilProvider)
                         .UseBackendOptions(_commandLineOptions.CodegenOptions)
                         .UseLogger(logger)
index 7a272037fd14f7113e4ce71d14696a03024efa6e..a65ea2c2ae38e2d658027eea11f89d67b5710433 100644 (file)
   <data name="UnsupportedInputFileExtension" xml:space="preserve">
     <value>Input file with '{0}' extension not supported</value>
   </data>
+  <data name="ImageBase" xml:space="preserve">
+    <value>Hexademical value to set target PE-file ImageBase field</value>
+  </data>
 </root>