Skip to content

Commit

Permalink
Make VersionAwareSizeOf trimmable
Browse files Browse the repository at this point in the history
  • Loading branch information
ds5678 committed Dec 28, 2023
1 parent ef427a9 commit 9a63bf7
Show file tree
Hide file tree
Showing 8 changed files with 66 additions and 57 deletions.
1 change: 1 addition & 0 deletions Cpp2IL.Core/Cpp2IL.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
<!--Plugins make this non-trimmable-->

<ContinuousIntegrationBuild Condition="'$(GITHUB_ACTIONS)' == 'true'">true</ContinuousIntegrationBuild>
<PolySharpIncludeRuntimeSupportedAttributes>true</PolySharpIncludeRuntimeSupportedAttributes>
</PropertyGroup>

<ItemGroup>
Expand Down
3 changes: 2 additions & 1 deletion Cpp2IL.Core/Utils/MiscUtils.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Text;
using Cpp2IL.Core.Extensions;
Expand Down Expand Up @@ -153,7 +154,7 @@ public static int GetPointerSizeBytes()
return LibCpp2IlMain.Binary!.is32Bit ? 4 : 8;
}

public static IConvertible ReinterpretBytes(IConvertible original, Type desired)
public static IConvertible ReinterpretBytes(IConvertible original, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] Type desired)
{
if (desired is null)
throw new ArgumentNullException(nameof(desired), "Destination type is null");
Expand Down
9 changes: 6 additions & 3 deletions Cpp2IL/Cpp2IL.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,17 @@
<LangVersion>10</LangVersion>
<Nullable>enable</Nullable>
<OutputType>Exe</OutputType>
<PublishSingleFile Condition="'$(TargetFramework)'!='net472' and '$(GITHUB_ACTIONS)' == 'true'">true</PublishSingleFile>
<PublishTrimmed>true</PublishTrimmed>
<TargetFrameworks>net7.0;net472</TargetFrameworks>
<TrimMode>partial</TrimMode>
<VersionPrefix>2022.1.0</VersionPrefix>
<ServerGarbageCollection>true</ServerGarbageCollection>
</PropertyGroup>

<PropertyGroup Condition=" '$(TargetFramework)'!='net472' ">
<TrimMode>partial</TrimMode>
<PublishTrimmed>true</PublishTrimmed>
<PublishSingleFile Condition="'$(GITHUB_ACTIONS)' == 'true'">true</PublishSingleFile>
</PropertyGroup>

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
<OutputPath>bin\x64\Debug\</OutputPath>
</PropertyGroup>
Expand Down
6 changes: 3 additions & 3 deletions LibCpp2IL/BinarySearcher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ internal ulong FindCodeRegistrationPost2019()

//We have pCodegenModules which *should* be x-reffed in the last pointer of Il2CppCodeRegistration.
//So, subtract the size of one pointer from that...
var bytesToGoBack = (ulong) LibCpp2ILUtils.VersionAwareSizeOf(typeof(Il2CppCodeRegistration)) - ptrSize;
var bytesToGoBack = (ulong) LibCpp2ILUtils.VersionAwareSizeOf<Il2CppCodeRegistration>() - ptrSize;

LibLogger.VerboseNewline($"\t\t\tpCodegenModules is the second-to-last field of the codereg struct. Therefore on this version and architecture, we need to subtract {bytesToGoBack} bytes from its address to get pCodeReg");

Expand Down Expand Up @@ -285,7 +285,7 @@ public static bool ValidateCodeRegistration(Il2CppCodeRegistration codeReg, Dict
public ulong FindMetadataRegistrationPre24_5()
{
//We're looking for TypeDefinitionsSizesCount, which is the 4th-to-last field
var sizeOfMr = (ulong) LibCpp2ILUtils.VersionAwareSizeOf(typeof(Il2CppMetadataRegistration));
var sizeOfMr = (ulong) LibCpp2ILUtils.VersionAwareSizeOf<Il2CppMetadataRegistration>();
var ptrSize = _binary.is32Bit ? 4ul : 8ul;

var bytesToSubtract = sizeOfMr - ptrSize * 4;
Expand Down Expand Up @@ -315,7 +315,7 @@ public ulong FindMetadataRegistrationPre24_5()
public ulong FindMetadataRegistrationPost24_5()
{
var ptrSize = _binary.is32Bit ? 4ul : 8ul;
var sizeOfMr = (uint) LibCpp2ILUtils.VersionAwareSizeOf(typeof(Il2CppMetadataRegistration));
var sizeOfMr = (uint) LibCpp2ILUtils.VersionAwareSizeOf<Il2CppMetadataRegistration>();

LibLogger.VerboseNewline($"\t\t\tLooking for the number of type definitions, 0x{_typeDefinitionsCount:X}");
var ptrsToNumberOfTypes = FindAllMappedWords((ulong) _typeDefinitionsCount).ToList();
Expand Down
4 changes: 2 additions & 2 deletions LibCpp2IL/Elf/ElfFile.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
Expand Down Expand Up @@ -269,7 +269,7 @@ private void ProcessRelocations()
}
}

var sizeOfRelocationStruct = (ulong) (is32Bit ? LibCpp2ILUtils.VersionAwareSizeOf(typeof(ElfDynamicSymbol32), true, false) : LibCpp2ILUtils.VersionAwareSizeOf(typeof(ElfDynamicSymbol64), true, false));
var sizeOfRelocationStruct = (ulong) (is32Bit ? LibCpp2ILUtils.VersionAwareSizeOf<ElfDynamicSymbol32>(true, false) : LibCpp2ILUtils.VersionAwareSizeOf<ElfDynamicSymbol64>(true, false));

LibLogger.Verbose($"\t-Now Processing {rels.Count} relocations...");

Expand Down
3 changes: 2 additions & 1 deletion LibCpp2IL/LibCpp2IL.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,17 @@
<Configurations>Debug;Release</Configurations>
<TargetFrameworks>net7.0;net6.0;netstandard2.0</TargetFrameworks>
<IsTrimmable>true</IsTrimmable>
<PolySharpIncludeRuntimeSupportedAttributes>true</PolySharpIncludeRuntimeSupportedAttributes>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="AssetRipper.Primitives" Version="2.0.0" />
<PackageReference Include="PolySharp" Version="1.12.1" PrivateAssets="all" IncludeAssets="runtime; build; native; contentfiles; analyzers; buildtransitive" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' != 'net6.0'">
<PackageReference Include="IndexRange" Version="1.0.2" />
<PackageReference Include="System.Memory" Version="4.5.5" />
<PackageReference Include="Nullable" Version="1.3.1" PrivateAssets="all" IncludeAssets="runtime; build; native; contentfiles; analyzers; buildtransitive" />
</ItemGroup>

<ItemGroup>
Expand Down
92 changes: 47 additions & 45 deletions LibCpp2IL/LibCpp2IlUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,22 +35,22 @@ public static class LibCpp2ILUtils
{28, "object"}
};

private static readonly Dictionary<string, ulong> PrimitiveSizes = new()
private static readonly Dictionary<Type, byte> PrimitiveSizes = new()
{
{"Byte", 1},
{"SByte", 1},
{"Boolean", 1},
{"Int16", 2},
{"UInt16", 2},
{"Char", 2},
{"Int32", 4},
{"UInt32", 4},
{"Single", 4},
{"Int64", 8},
{"UInt64", 8},
{"Double", 8},
{"IntPtr", 8},
{"UIntPtr", 8},
{typeof(byte), 1},
{typeof(sbyte), 1},
{typeof(bool), 1},
{typeof(short), 2},
{typeof(ushort), 2},
{typeof(char), 2},
{typeof(int), 4},
{typeof(uint), 4},
{typeof(float), 4},
{typeof(long), 8},
{typeof(ulong), 8},
{typeof(double), 8},
{typeof(IntPtr), 8},
{typeof(UIntPtr), 8},
};

private static Dictionary<FieldInfo, VersionAttribute[]> _cachedVersionAttributes = new();
Expand Down Expand Up @@ -393,18 +393,24 @@ public static Il2CppTypeReflectionData GetTypeReflectionData(Il2CppType forWhat)
throw new ArgumentException($"Unknown type {forWhat.Type}");
}

#pragma warning disable IL2070 //'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicFields'
public static int VersionAwareSizeOf<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] T>(
bool dontCheckVersionAttributes = false,
bool downsize = true)
{
return VersionAwareSizeOf(typeof(T), dontCheckVersionAttributes, downsize);
}

public static int VersionAwareSizeOf(
Type type,
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] Type type,
bool dontCheckVersionAttributes = false,
bool downsize = true
)
{
if (type.IsEnum)
type = type.GetEnumUnderlyingType();
return PrimitiveSizes[type.GetEnumUnderlyingType()];

if (type.IsPrimitive)
return (int) PrimitiveSizes[type.Name];
return PrimitiveSizes[type];

var shouldDownsize = downsize && LibCpp2IlMain.Binary!.is32Bit;

Expand All @@ -418,36 +424,32 @@ public static int VersionAwareSizeOf(
continue;
}

switch (field.FieldType.Name)
{
case "Int64":
case "UInt64":
size += shouldDownsize ? 4 : 8;
break;
case "Int32":
case "UInt32":
size += 4;
break;
case "Int16":
case "UInt16":
size += 2;
break;
case "Byte":
case "SByte":
size += 1;
break;
default:
if (field.FieldType == type)
throw new Exception($"Infinite recursion is not allowed. Field {field} of type {type} has the same type as its parent.");

size += VersionAwareSizeOf(field.FieldType, dontCheckVersionAttributes, downsize);
break;
}
if (field.FieldType == typeof(long) || field.FieldType == typeof(ulong))
size += shouldDownsize ? 4 : 8;
else if (field.FieldType == typeof(int) || field.FieldType == typeof(uint))
size += 4;
else if (field.FieldType == typeof(short) || field.FieldType == typeof(ushort))
size += 2;
else if (field.FieldType == typeof(byte) || field.FieldType == typeof(sbyte))
size += 1;
else if (field.FieldType.IsEnum)
size += PrimitiveSizes[field.FieldType.GetEnumUnderlyingType()];
else if (field.FieldType.IsPrimitive)
size += PrimitiveSizes[field.FieldType];
else if (field.FieldType == type)
throw new Exception($"Infinite recursion is not allowed. Field {field} of type {type} has the same type as its parent.");
else if (field.FieldType == typeof(Il2CppGenericContext))
size += VersionAwareSizeOf(typeof(Il2CppGenericContext), dontCheckVersionAttributes, downsize);
else if (field.FieldType == typeof(Il2CppGenericMethodIndices))
size += VersionAwareSizeOf(typeof(Il2CppGenericMethodIndices), dontCheckVersionAttributes, downsize);
else if (field.FieldType == typeof(Il2CppAssemblyNameDefinition))
size += VersionAwareSizeOf(typeof(Il2CppAssemblyNameDefinition), dontCheckVersionAttributes, downsize);
else
throw new Exception($"Custom field type '{field.FieldType}' has no special case.");
}

return size;
}
#pragma warning restore IL2070

internal static IEnumerable<int> Range(int start, int count)
{
Expand Down
5 changes: 3 additions & 2 deletions LibCpp2IL/Metadata/Il2CppMetadata.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Reflection;
Expand Down Expand Up @@ -286,9 +287,9 @@ private Il2CppMetadata(MemoryStream stream) : base(stream)
}
#pragma warning restore 8618

private T[] ReadMetadataClassArray<T>(int offset, int length) where T : ReadableClass, new()
private T[] ReadMetadataClassArray<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] T>(int offset, int length) where T : ReadableClass, new()
{
return ReadReadableArrayAtRawAddr<T>(offset, length / LibCpp2ILUtils.VersionAwareSizeOf(typeof(T), downsize: false));
return ReadReadableArrayAtRawAddr<T>(offset, length / LibCpp2ILUtils.VersionAwareSizeOf<T>(downsize: false));
}

private void DecipherMetadataUsage()
Expand Down

0 comments on commit 9a63bf7

Please sign in to comment.