smaller tweaks, hack around loops in cpp type layouting
This commit is contained in:
@@ -228,6 +228,14 @@ namespace Il2CppInspector.Cpp
|
||||
ns.ReserveName("_");
|
||||
fieldType = types.Struct(name + "__Fields");
|
||||
var baseFieldType = types[TypeNamer.GetName(ti.BaseType) + "__Fields"];
|
||||
|
||||
if (baseFieldType == null)
|
||||
{
|
||||
// if we end up here, there is a loop in the type generation.
|
||||
// this is not currently supported, so we throw an exception.
|
||||
throw new InvalidOperationException($"Failed to generate type for {ti}");
|
||||
}
|
||||
|
||||
fieldType.AddField("_", baseFieldType);
|
||||
GenerateFieldList(fieldType, ns, ti);
|
||||
}
|
||||
@@ -437,17 +445,31 @@ namespace Il2CppInspector.Cpp
|
||||
/// <returns>A string containing C type declarations</returns>
|
||||
public List<(TypeInfo ilType, CppComplexType valueType, CppComplexType referenceType, CppComplexType fieldsType,
|
||||
CppComplexType vtableType, CppComplexType staticsType)> GenerateRemainingTypeDeclarations() {
|
||||
try
|
||||
{
|
||||
var decl = GenerateVisitedFieldStructs().Select(s =>
|
||||
(s.ilType, s.valueType, s.referenceType, s.fieldsType, (CppComplexType) null, (CppComplexType) null)).ToList();
|
||||
(s.ilType, s.valueType, s.referenceType, s.fieldsType, (CppComplexType)null,
|
||||
(CppComplexType)null))
|
||||
.ToList();
|
||||
|
||||
foreach (var ti in TodoTypeStructs) {
|
||||
foreach (var ti in TodoTypeStructs)
|
||||
{
|
||||
var (cls, statics, vtable) = GenerateTypeStruct(ti);
|
||||
decl.Add((ti, null, cls, null, vtable, statics));
|
||||
}
|
||||
TodoTypeStructs.Clear();
|
||||
|
||||
return decl;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
finally
|
||||
{
|
||||
TodoTypeStructs.Clear();
|
||||
TodoFieldStructs.Clear();
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Method Generation
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
using System;
|
||||
|
||||
namespace Il2CppInspector.Cpp
|
||||
{
|
||||
// A field in a C++ type
|
||||
|
||||
@@ -337,7 +337,15 @@ namespace Il2CppInspector
|
||||
}
|
||||
|
||||
// Read method invoker pointer indices - one per method
|
||||
MethodInvokerIndices.Add(module, Image.ReadMappedPrimitiveArray<int>(module.InvokerIndices, (int) module.MethodPointerCount));
|
||||
try
|
||||
{
|
||||
MethodInvokerIndices.Add(module,
|
||||
Image.ReadMappedPrimitiveArray<int>(module.InvokerIndices, (int)module.MethodPointerCount));
|
||||
}
|
||||
catch (InvalidOperationException)
|
||||
{
|
||||
MethodInvokerIndices.Add(module, [..new int[(int)module.MethodPointerCount]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -398,12 +406,21 @@ namespace Il2CppInspector
|
||||
var type = TypeReferences[i];
|
||||
if (type.Type.IsTypeDefinitionEnum())
|
||||
{
|
||||
if (type.Data.Type.PointerValue >= baseDefinitionPtr)
|
||||
type.Data.Value = (type.Data.Type.PointerValue - baseDefinitionPtr) / definitionSize;
|
||||
|
||||
Debug.Assert(Metadata!.Types.Length > type.Data.KlassIndex);
|
||||
}
|
||||
else if (type.Type.IsGenericParameterEnum())
|
||||
{
|
||||
if (type.Data.Type.PointerValue >= baseGenericPtr)
|
||||
type.Data.Value = (type.Data.Type.PointerValue - baseGenericPtr) / genericParameterSize;
|
||||
|
||||
Debug.Assert(Metadata!.GenericParameters.Length > type.Data.KlassIndex);
|
||||
}
|
||||
|
||||
Debug.Assert((long)type.Data.Value >= 0);
|
||||
|
||||
builder.Add(type);
|
||||
}
|
||||
TypeReferences = builder.MoveToImmutable();
|
||||
|
||||
@@ -236,7 +236,17 @@ namespace Il2CppInspector.Model
|
||||
break;
|
||||
case MetadataUsageType.MethodDef or MetadataUsageType.MethodRef:
|
||||
var method = TypeModel.GetMetadataUsageMethod(usage);
|
||||
|
||||
declarationGenerator.IncludeMethod(method);
|
||||
var definitions = declarationGenerator.GenerateRemainingTypeDeclarations();
|
||||
if (definitions == null)
|
||||
{
|
||||
// if we end up here, type generation has failed
|
||||
// todo: this try/catch is a massive hack to sidestep the original issue of generation failing,
|
||||
// todo: this needs to be improved.
|
||||
break;
|
||||
}
|
||||
|
||||
AddTypes(declarationGenerator.GenerateRemainingTypeDeclarations());
|
||||
|
||||
// Any method here SHOULD already be in the Methods list
|
||||
@@ -247,6 +257,7 @@ namespace Il2CppInspector.Model
|
||||
Methods.Add(method, fnPtr, new AppMethod(method, fnPtr) { Group = Group });
|
||||
}
|
||||
Methods[method].MethodInfoPtrAddress = address;
|
||||
|
||||
break;
|
||||
|
||||
// FieldInfo is used for array initializers.
|
||||
|
||||
@@ -430,7 +430,7 @@ namespace Il2CppInspector.Outputs
|
||||
if (method.VirtualAddress.HasValue) {
|
||||
var args = new List<(string,object)> {
|
||||
("RVA", (method.VirtualAddress.Value.Start - model.Package.BinaryImage.ImageBase).ToAddressString()),
|
||||
("Offset", string.Format("0x{0:X}", model.Package.BinaryImage.MapVATR(method.VirtualAddress.Value.Start))),
|
||||
("Offset", $"0x{model.Package.BinaryImage.MapVATR(method.VirtualAddress.Value.Start):X}"),
|
||||
("VA", method.VirtualAddress.Value.Start.ToAddressString())
|
||||
};
|
||||
if (method.Definition.Slot != ushort.MaxValue)
|
||||
@@ -470,7 +470,7 @@ namespace Il2CppInspector.Outputs
|
||||
return def.AddAttribute(module, attributeAttribute,
|
||||
("Name", ca.AttributeType.Name),
|
||||
("RVA", (ca.VirtualAddress.Start - model.Package.BinaryImage.ImageBase).ToAddressString()),
|
||||
("Offset", string.Format("0x{0:X}", model.Package.BinaryImage.MapVATR(ca.VirtualAddress.Start)))
|
||||
("Offset", $"0x{model.Package.BinaryImage.MapVATR(ca.VirtualAddress.Start):X}")
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -165,10 +165,9 @@ namespace Il2CppInspector.Reflection
|
||||
// Generic type definitions have an invoker index of -1
|
||||
foreach (var method in MethodsByDefinitionIndex) {
|
||||
var index = package.GetInvokerIndex(method.DeclaringType.Assembly.ModuleDefinition, method.Definition);
|
||||
if (index != -1) {
|
||||
if (MethodInvokers[index] == null)
|
||||
MethodInvokers[index] = new MethodInvoker(method, index);
|
||||
|
||||
if (index != -1)
|
||||
{
|
||||
MethodInvokers[index] ??= new MethodInvoker(method, index);
|
||||
method.Invoker = MethodInvokers[index];
|
||||
}
|
||||
}
|
||||
@@ -176,12 +175,13 @@ namespace Il2CppInspector.Reflection
|
||||
// Create method invokers sourced from generic method invoker indices
|
||||
foreach (var spec in GenericMethods.Keys) {
|
||||
if (package.GenericMethodInvokerIndices.TryGetValue(spec, out var index)) {
|
||||
if (MethodInvokers[index] == null)
|
||||
MethodInvokers[index] = new MethodInvoker(GenericMethods[spec], index);
|
||||
|
||||
if (index != -1)
|
||||
{
|
||||
MethodInvokers[index] ??= new MethodInvoker(GenericMethods[spec], index);
|
||||
GenericMethods[spec].Invoker = MethodInvokers[index];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Post-processing hook
|
||||
PluginHooks.PostProcessTypeModel(this);
|
||||
|
||||
Reference in New Issue
Block a user