Skip to content

Commit

Permalink
Split dummydll into 4 separate output formats
Browse files Browse the repository at this point in the history
  • Loading branch information
ds5678 committed Jan 1, 2024
1 parent 0e1b3dc commit a35868c
Show file tree
Hide file tree
Showing 7 changed files with 134 additions and 58 deletions.
5 changes: 4 additions & 1 deletion Cpp2IL.Core/Cpp2IlCorePlugin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,10 @@ public override void OnLoad()

Logger.VerboseNewline("\tRegistering built-in output formats...", "Core Plugin");

OutputFormatRegistry.Register<AsmResolverDummyDllOutputFormat>();
OutputFormatRegistry.Register<AsmResolverDllOutputFormatDefault>();
OutputFormatRegistry.Register<AsmResolverDllOutputFormatEmpty>();
OutputFormatRegistry.Register<AsmResolverDllOutputFormatThrowNull>();
OutputFormatRegistry.Register<AsmResolverDllOutputFormatIlRecovery>();
OutputFormatRegistry.Register<DiffableCsOutputFormat>();
OutputFormatRegistry.Register<IsilDumpOutputFormat>();
OutputFormatRegistry.Register<WasmMappingOutputFormat>();
Expand Down
17 changes: 17 additions & 0 deletions Cpp2IL.Core/OutputFormats/AsmResolverDllOutputFormatDefault.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using AsmResolver.DotNet;
using AssetRipper.CIL;
using Cpp2IL.Core.Model.Contexts;

namespace Cpp2IL.Core.OutputFormats;

public class AsmResolverDllOutputFormatDefault : AsmResolverDllOutputFormat
{
public override string OutputFormatId => "dll_default";

public override string OutputFormatName => "DLL files with default method bodies";

protected override void FillMethodBody(MethodDefinition methodDefinition, MethodAnalysisContext methodContext)
{
methodDefinition.FillMethodBodyWithStub();
}
}
18 changes: 18 additions & 0 deletions Cpp2IL.Core/OutputFormats/AsmResolverDllOutputFormatEmpty.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using AsmResolver.DotNet;
using Cpp2IL.Core.Model.Contexts;
using Cpp2IL.Core.Utils.AsmResolver;

namespace Cpp2IL.Core.OutputFormats;

public class AsmResolverDllOutputFormatEmpty : AsmResolverDllOutputFormat
{
public override string OutputFormatId => "dll_empty";

public override string OutputFormatName => "DLL files with empty method bodies";

protected override void FillMethodBody(MethodDefinition methodDefinition, MethodAnalysisContext methodContext)
{
if (methodDefinition.IsManagedMethodWithBody())
methodDefinition.CilMethodBody = new(methodDefinition);
}
}
24 changes: 24 additions & 0 deletions Cpp2IL.Core/OutputFormats/AsmResolverDllOutputFormatIlRecovery.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using AsmResolver.DotNet;
using AsmResolver.PE.DotNet.Cil;
using Cpp2IL.Core.Model.Contexts;
using Cpp2IL.Core.Utils.AsmResolver;

namespace Cpp2IL.Core.OutputFormats;

public class AsmResolverDllOutputFormatIlRecovery : AsmResolverDllOutputFormat
{
public override string OutputFormatId => "dll_il_recovery";

public override string OutputFormatName => "DLL files with IL Recovery";

protected override void FillMethodBody(MethodDefinition methodDefinition, MethodAnalysisContext methodContext)
{
if (methodDefinition.IsManagedMethodWithBody())
{
methodDefinition.CilMethodBody = new(methodDefinition);
var instructions = methodDefinition.CilMethodBody.Instructions;
instructions.Add(CilOpCodes.Ldnull);
instructions.Add(CilOpCodes.Throw);
}
}
}
24 changes: 24 additions & 0 deletions Cpp2IL.Core/OutputFormats/AsmResolverDllOutputFormatThrowNull.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using AsmResolver.DotNet;
using AsmResolver.PE.DotNet.Cil;
using Cpp2IL.Core.Model.Contexts;
using Cpp2IL.Core.Utils.AsmResolver;

namespace Cpp2IL.Core.OutputFormats;

public class AsmResolverDllOutputFormatThrowNull : AsmResolverDllOutputFormat
{
public override string OutputFormatId => "dll_throw_null";

public override string OutputFormatName => "DLL files with method bodies containing throw null";

protected override void FillMethodBody(MethodDefinition methodDefinition, MethodAnalysisContext methodContext)
{
if (methodDefinition.IsManagedMethodWithBody())
{
methodDefinition.CilMethodBody = new(methodDefinition);
var instructions = methodDefinition.CilMethodBody.Instructions;
instructions.Add(CilOpCodes.Ldnull);
instructions.Add(CilOpCodes.Throw);
}
}
}
68 changes: 47 additions & 21 deletions Cpp2IL.Core/OutputFormats/AsmResolverDummyDllOutputFormat.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,16 @@

namespace Cpp2IL.Core.OutputFormats;

public class AsmResolverDummyDllOutputFormat : Cpp2IlOutputFormat
public abstract class AsmResolverDllOutputFormat : Cpp2IlOutputFormat
{
public override string OutputFormatId => "dummydll";

public override string OutputFormatName => "Stub (\"Dummy\") DLL Files";

private AssemblyDefinition? MostRecentCorLib { get; set; }

public override void DoOutput(ApplicationAnalysisContext context, string outputRoot)
public sealed override void DoOutput(ApplicationAnalysisContext context, string outputRoot)
{
var ret = BuildAssemblies(context);

var start = DateTime.Now;
Logger.Verbose("Generating PE images...", "DummyDllOutput");
Logger.Verbose("Generating PE images...", "DllOutput");

if (!Directory.Exists(outputRoot))
Directory.CreateDirectory(outputRoot);
Expand All @@ -42,10 +38,10 @@ public override void DoOutput(ApplicationAnalysisContext context, string outputR
.Select(a => (image: a.ManifestModule!.ToPEImage(new ManagedPEImageBuilder()), name: a.ManifestModule.Name!))
.ToList();

Logger.VerboseNewline($"{(DateTime.Now - start).TotalMilliseconds:F1}ms", "DummyDllOutput");
Logger.VerboseNewline($"{(DateTime.Now - start).TotalMilliseconds:F1}ms", "DllOutput");

start = DateTime.Now;
Logger.Verbose("Building and writing managed PE files to disk...", "DummyDllOutput");
Logger.Verbose("Building and writing managed PE files to disk...", "DllOutput");

//Save them
var fileBuilder = new ManagedPEFileBuilder();
Expand All @@ -55,7 +51,7 @@ public override void DoOutput(ApplicationAnalysisContext context, string outputR
fileBuilder.CreateFile(image).Write(dllPath);
}

Logger.VerboseNewline($"{(DateTime.Now - start).TotalMilliseconds:F1}ms", "DummyDllOutput");
Logger.VerboseNewline($"{(DateTime.Now - start).TotalMilliseconds:F1}ms", "DllOutput");
}

public List<AssemblyDefinition> BuildAssemblies(ApplicationAnalysisContext context)
Expand All @@ -72,46 +68,76 @@ public List<AssemblyDefinition> BuildAssemblies(ApplicationAnalysisContext conte
//Build the stub assemblies
var start = DateTime.Now;
#if VERBOSE_LOGGING
Logger.Verbose($"Building stub assemblies ({asmCount} assemblies, {typeCount} types)...", "DummyDllOutput");
Logger.Verbose($"Building stub assemblies ({asmCount} assemblies, {typeCount} types)...", "DllOutput");
#else
Logger.Verbose($"Building stub assemblies...", "DummyDllOutput");
Logger.Verbose($"Building stub assemblies...", "DllOutput");
#endif
List<AssemblyDefinition> ret = BuildStubAssemblies(context);
Logger.VerboseNewline($"{(DateTime.Now - start).TotalMilliseconds:F1}ms", "DummyDllOutput");
Logger.VerboseNewline($"{(DateTime.Now - start).TotalMilliseconds:F1}ms", "DllOutput");

start = DateTime.Now;
Logger.Verbose("Configuring inheritance and generics...", "DummyDllOutput");
Logger.Verbose("Configuring inheritance and generics...", "DllOutput");

Parallel.ForEach(context.Assemblies, AsmResolverAssemblyPopulator.ConfigureHierarchy);

Logger.VerboseNewline($"{(DateTime.Now - start).TotalMilliseconds:F1}ms", "DummyDllOutput");
Logger.VerboseNewline($"{(DateTime.Now - start).TotalMilliseconds:F1}ms", "DllOutput");

//Populate them
start = DateTime.Now;

#if VERBOSE_LOGGING
Logger.Verbose($"Adding {fieldCount} fields, {methodCount} methods, {propertyCount} properties, and {eventCount} events (in parallel)...", "DummyDllOutput");
Logger.Verbose($"Adding {fieldCount} fields, {methodCount} methods, {propertyCount} properties, and {eventCount} events (in parallel)...", "DllOutput");
#else
Logger.Verbose($"Adding fields, methods, properties, and events (in parallel)...", "DummyDllOutput");
Logger.Verbose($"Adding fields, methods, properties, and events (in parallel)...", "DllOutput");
#endif

MiscUtils.ExecuteParallel(context.Assemblies, AsmResolverAssemblyPopulator.CopyDataFromIl2CppToManaged);
MiscUtils.ExecuteParallel(context.Assemblies, AsmResolverMethodFiller.FillManagedMethodBodies);
MiscUtils.ExecuteParallel(context.Assemblies, FillMethodBodies);

Logger.VerboseNewline($"{(DateTime.Now - start).TotalMilliseconds:F1}ms", "DummyDllOutput");
Logger.VerboseNewline($"{(DateTime.Now - start).TotalMilliseconds:F1}ms", "DllOutput");

//Populate custom attributes
start = DateTime.Now;
Logger.Verbose("Adding custom attributes to all of the above...", "DummyDllOutput");
Logger.Verbose("Adding custom attributes to all of the above...", "DllOutput");
MiscUtils.ExecuteParallel(context.Assemblies, AsmResolverAssemblyPopulator.PopulateCustomAttributes);

Logger.VerboseNewline($"{(DateTime.Now - start).TotalMilliseconds:F1}ms", "DummyDllOutput");
Logger.VerboseNewline($"{(DateTime.Now - start).TotalMilliseconds:F1}ms", "DllOutput");

TypeDefinitionsAsmResolver.Reset();

return ret;
}

protected abstract void FillMethodBody(MethodDefinition methodDefinition, MethodAnalysisContext methodContext);

protected virtual void FillMethodBodies(AssemblyAnalysisContext context)
{
foreach (var typeContext in context.Types)
{
if (AsmResolverAssemblyPopulator.IsTypeContextModule(typeContext))
continue;

#if !DEBUG
try
#endif
{
foreach (var methodCtx in typeContext.Methods)
{
var managedMethod = methodCtx.GetExtraData<MethodDefinition>("AsmResolverMethod") ?? throw new($"AsmResolver method not found in method analysis context for {typeContext.Definition?.FullName}.{methodCtx.Definition?.Name}");

FillMethodBody(managedMethod, methodCtx);
}
}
#if !DEBUG
catch (System.Exception e)
{
var managedType = typeContext.GetExtraData<TypeDefinition>("AsmResolverType") ?? throw new($"AsmResolver type not found in type analysis context for {typeContext.Definition?.FullName}");
throw new($"Failed to process type {managedType.FullName} (module {managedType.Module?.Name}, declaring type {managedType.DeclaringType?.FullName}) in {asmContext.Definition.AssemblyName.Name}", e);

Check failure on line 135 in Cpp2IL.Core/OutputFormats/AsmResolverDummyDllOutputFormat.cs

View workflow job for this annotation

GitHub Actions / Build Single-File Artifact (osx-x64, Cpp2IL.Gui)

The name 'asmContext' does not exist in the current context

Check failure on line 135 in Cpp2IL.Core/OutputFormats/AsmResolverDummyDllOutputFormat.cs

View workflow job for this annotation

GitHub Actions / Build Single-File Artifact (win-x64, Cpp2IL.Gui)

The name 'asmContext' does not exist in the current context

Check failure on line 135 in Cpp2IL.Core/OutputFormats/AsmResolverDummyDllOutputFormat.cs

View workflow job for this annotation

GitHub Actions / Build Single-File Artifact (osx-x64, Cpp2IL)

The name 'asmContext' does not exist in the current context

Check failure on line 135 in Cpp2IL.Core/OutputFormats/AsmResolverDummyDllOutputFormat.cs

View workflow job for this annotation

GitHub Actions / Build Single-File Artifact (linux-x64, Cpp2IL)

The name 'asmContext' does not exist in the current context

Check failure on line 135 in Cpp2IL.Core/OutputFormats/AsmResolverDummyDllOutputFormat.cs

View workflow job for this annotation

GitHub Actions / Build Single-File Artifact (win-x64, Cpp2IL)

The name 'asmContext' does not exist in the current context

Check failure on line 135 in Cpp2IL.Core/OutputFormats/AsmResolverDummyDllOutputFormat.cs

View workflow job for this annotation

GitHub Actions / Build Single-File Artifact (linux-x64, Cpp2IL.Gui)

The name 'asmContext' does not exist in the current context

Check failure on line 135 in Cpp2IL.Core/OutputFormats/AsmResolverDummyDllOutputFormat.cs

View workflow job for this annotation

GitHub Actions / Build - Windows .NET Framework Zip

The name 'asmContext' does not exist in the current context

Check failure on line 135 in Cpp2IL.Core/OutputFormats/AsmResolverDummyDllOutputFormat.cs

View workflow job for this annotation

GitHub Actions / Run Tests & Publish Dev Package

The name 'asmContext' does not exist in the current context

Check failure on line 135 in Cpp2IL.Core/OutputFormats/AsmResolverDummyDllOutputFormat.cs

View workflow job for this annotation

GitHub Actions / Run Tests & Publish Dev Package

The name 'asmContext' does not exist in the current context

Check failure on line 135 in Cpp2IL.Core/OutputFormats/AsmResolverDummyDllOutputFormat.cs

View workflow job for this annotation

GitHub Actions / Run Tests & Publish Dev Package

The name 'asmContext' does not exist in the current context

Check failure on line 135 in Cpp2IL.Core/OutputFormats/AsmResolverDummyDllOutputFormat.cs

View workflow job for this annotation

GitHub Actions / Run Tests & Publish Dev Package

The name 'asmContext' does not exist in the current context

Check failure on line 135 in Cpp2IL.Core/OutputFormats/AsmResolverDummyDllOutputFormat.cs

View workflow job for this annotation

GitHub Actions / Run Tests & Publish Dev Package

The name 'asmContext' does not exist in the current context

Check failure on line 135 in Cpp2IL.Core/OutputFormats/AsmResolverDummyDllOutputFormat.cs

View workflow job for this annotation

GitHub Actions / Run Tests & Publish Dev Package

The name 'asmContext' does not exist in the current context

Check failure on line 135 in Cpp2IL.Core/OutputFormats/AsmResolverDummyDllOutputFormat.cs

View workflow job for this annotation

GitHub Actions / Run Tests & Publish Dev Package

The name 'asmContext' does not exist in the current context

Check failure on line 135 in Cpp2IL.Core/OutputFormats/AsmResolverDummyDllOutputFormat.cs

View workflow job for this annotation

GitHub Actions / Run Tests & Publish Dev Package

The name 'asmContext' does not exist in the current context
}
#endif
}
}

private List<AssemblyDefinition> BuildStubAssemblies(ApplicationAnalysisContext context)
{
var assemblyResolver = new Il2CppAssemblyResolver();
Expand Down
36 changes: 0 additions & 36 deletions Cpp2IL.Core/Utils/AsmResolver/AsmResolverMethodFiller.cs

This file was deleted.

0 comments on commit a35868c

Please sign in to comment.