Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions Cpp2IL.Core/Model/Contexts/ApplicationAnalysisContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,17 @@ private void PopulateMethodsByAddressTable()

return ConcreteGenericMethodsByRef.TryGetValue(methodReference, out var context) ? context : new(methodReference, this);
}

[return: NotNullIfNotNull(nameof(methodReference))]
public MethodAnalysisContext? ResolveContextForMethod(MetadataUsage? methodReference)
{
return methodReference?.Type switch
{
null => null,
MetadataUsageType.MethodDef => ResolveContextForMethod(methodReference.AsMethod()),
MetadataUsageType.MethodRef => ResolveContextForMethod(methodReference.AsGenericMethodRef()),
};
}

public FieldAnalysisContext? ResolveContextForField(Il2CppFieldDefinition? field)
{
Expand Down
7 changes: 7 additions & 0 deletions Cpp2IL.Core/Model/Contexts/AssemblyAnalysisContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ public class AssemblyAnalysisContext : HasCustomAttributesAndName
/// </summary>
public IEnumerable<TypeAnalysisContext> TopLevelTypes => Types.Where(t => t.DeclaringType == null);

/// <summary>
/// The analysis context object for the manifest module of the assembly.
/// </summary>
public ModuleAnalysisContext ManifestModule { get; }

/// <summary>
/// The analysis context objects for all types exported by this assembly.
/// </summary>
Expand Down Expand Up @@ -185,6 +190,8 @@ public AssemblyAnalysisContext(Il2CppAssemblyDefinition? assemblyDefinition, App

Definition = assemblyDefinition;

ManifestModule = new(this);

if (AppContext.MetadataVersion >= 24.2f)
CodeGenModule = AppContext.Binary.GetCodegenModuleByName(Definition.Image.Name!);

Expand Down
9 changes: 3 additions & 6 deletions Cpp2IL.Core/Model/Contexts/HasCustomAttributes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -279,23 +279,20 @@ private void AnalyzeCustomAttributeDataV29()

//Diagnostic data
var startOfData = blobStream.Position;
var perAttributeStartOffsets = new Dictionary<Il2CppMethodDefinition, long>();
var perAttributeStartOffsets = new Dictionary<MethodAnalysisContext, long>();

CustomAttributes = [];
foreach (var constructor in constructors)
{
perAttributeStartOffsets[constructor] = blobStream.Position;

var attributeTypeContext = AppContext.ResolveContextForType(constructor.DeclaringType!) ?? throw new($"Unable to find type {constructor.DeclaringType!.FullName}");
var attributeMethodContext = attributeTypeContext.GetMethod(constructor) ?? throw new($"Unable to find method {constructor.Name} in type {attributeTypeContext.Definition?.FullName}");

try
{
CustomAttributes.Add(V29AttributeUtils.ReadAttribute(blobStream, attributeMethodContext, AppContext));
CustomAttributes.Add(V29AttributeUtils.ReadAttribute(blobStream, constructor, AppContext));
}
catch (Exception e)
{
Logger.ErrorNewline($"Failed to read attribute data for {constructor}, which has parameters {string.Join(", ", constructor.Parameters!.Select(p => p.Type))}", "CA Restore");
Logger.ErrorNewline($"Failed to read attribute data for {constructor}, which has parameters {string.Join(", ", constructor.Parameters.Select(p => p.ParameterType))}", "CA Restore");
Logger.ErrorNewline($"This member ({ToString()}) has {RawIl2CppCustomAttributeData.Length} bytes of data starting at 0x{GetV29BlobOffsets()!.Value.blobStart:X}", "CA Restore");
Logger.ErrorNewline($"The post-constructor data started at 0x{startOfData:X} bytes into our blob", "CA Restore");
Logger.ErrorNewline($"Data for this constructor started at 0x{perAttributeStartOffsets[constructor]:X} bytes into our blob, we are now 0x{blobStream.Position:X} bytes into the blob", "CA Restore");
Expand Down
23 changes: 23 additions & 0 deletions Cpp2IL.Core/Model/Contexts/ModuleAnalysisContext.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
namespace Cpp2IL.Core.Model.Contexts;

/// <summary>
/// Represents a single Module that was converted using IL2CPP.
/// </summary>
public class ModuleAnalysisContext : HasCustomAttributesAndName
{
private AssemblyAnalysisContext _assemblyContext;

/// <inheritdoc />
override protected int CustomAttributeIndex => -1;
/// <inheritdoc />
public override AssemblyAnalysisContext CustomAttributeAssembly => _assemblyContext;
/// <inheritdoc />
public override string DefaultName => _assemblyContext.Definition!.Image.Name!;

public ModuleAnalysisContext(AssemblyAnalysisContext asmCtx) : base(asmCtx.Definition?.ModuleToken ?? 1, asmCtx.AppContext)
{
_assemblyContext = asmCtx;

InitCustomAttributeData();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,12 @@ public override void Process(ApplicationAnalysisContext appContext, Action<int,
{
var total = appContext.Assemblies.Count + appContext.AllTypes.Select(t => 1 + t.Events.Count + t.Fields.Count + t.Methods.Count + t.Properties.Count).Sum();

int count = 0;
appContext.Assemblies.ForEach(a => AnalyzeAndRaise(a, ref count, total, progressCallback));
var count = 0;
foreach (var a in appContext.Assemblies)
{
AnalyzeAndRaise(a, ref count, total, progressCallback);
AnalyzeAndRaise(a.ManifestModule, ref count, total, progressCallback);
}

//TODO look into making this parallel
foreach (var type in appContext.AllTypes)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,9 @@ public static void PopulateCustomAttributes(AssemblyAnalysisContext asmContext)
try
#endif
{
CopyCustomAttributes(asmContext, asmContext.GetExtraData<AssemblyDefinition>("AsmResolverAssembly")!.CustomAttributes);
var assembly = asmContext.GetExtraData<AssemblyDefinition>("AsmResolverAssembly")!;
CopyCustomAttributes(asmContext, assembly.CustomAttributes);
CopyCustomAttributes(asmContext.ManifestModule, assembly.ManifestModule!.CustomAttributes);

foreach (var type in asmContext.Types)
{
Expand Down
17 changes: 13 additions & 4 deletions Cpp2IL.Core/Utils/V29AttributeUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ namespace Cpp2IL.Core.Utils;

public static class V29AttributeUtils
{
public static Il2CppMethodDefinition[] ReadConstructors(Stream stream, uint count, ApplicationAnalysisContext context)
public static MethodAnalysisContext[] ReadConstructors(Stream stream, uint count, ApplicationAnalysisContext context)
{
using var reader = new BinaryReader(stream, Encoding.UTF8, true);
var indices = new uint[count];
Expand All @@ -25,7 +25,10 @@ public static Il2CppMethodDefinition[] ReadConstructors(Stream stream, uint coun
if (ClassReadingBinaryReader.EnableReadableSizeInformation)
context.Metadata.TrackRead<AnalyzedCustomAttribute>((int)(4 * count), trackIfFinishedReading: true);

return indices.Select(i => context.Metadata.methodDefs[i]).ToArray(); //TODO DynWidth: Validate against v105 CA blob once we have one.
if (context.Metadata.MetadataVersion >= 104)
return indices.Select(i => context.ResolveContextForMethod(MetadataUsage.DecodeMetadataUsage(i, 0, context.LibCpp2IlContext)!)).ToArray();
else
return indices.Select(i => context.ResolveContextForMethod(context.Metadata.methodDefs[i])!).ToArray();
}

public static AnalyzedCustomAttribute ReadAttribute(Stream stream, MethodAnalysisContext constructor, ApplicationAnalysisContext context)
Expand Down Expand Up @@ -83,8 +86,14 @@ private static T ResolveMemberFromIndex<T>(Stream stream, MethodAnalysisContext
memberIndex = -(memberIndex + 1);

//Resolve type
var typeDef = context.Metadata.GetTypeDefinitionFromIndex(Il2CppVariableWidthIndex<Il2CppTypeDefinition>.MakeTemporaryForFixedWidthUsage((int)typeIndex)); //DynWidth: typeIndex is already compressed, they didn't make it dynamic
var typeContext = context.ResolveContextForType(typeDef) ?? throw new("Unable to find type " + typeDef);
TypeAnalysisContext typeContext;
if (context.Metadata.MetadataVersion >= 104)
typeContext = constructor.DeclaringType!.DeclaringAssembly.ResolveIl2CppType(context.Binary.GetType(Il2CppVariableWidthIndex<Il2CppType>.MakeTemporaryForFixedWidthUsage((int)typeIndex)));
else
{
var typeDef = context.Metadata.GetTypeDefinitionFromIndex(Il2CppVariableWidthIndex<Il2CppTypeDefinition>.MakeTemporaryForFixedWidthUsage((int)typeIndex)); //DynWidth: typeIndex is already compressed, they didn't make it dynamic
typeContext = context.ResolveContextForType(typeDef) ?? throw new("Unable to find type " + typeDef);
}

//Get member
member = memberListGetter(typeContext)[memberIndex];
Expand Down
Loading