@@ -6,49 +6,51 @@ namespace Cpp2IL.InstructionSets.ArmV8;
6
6
7
7
internal static class ArmV8Utils
8
8
{
9
- public static Arm64DisassemblyResult GetArm64MethodBodyAtVirtualAddress ( ulong virtAddress , bool managed = true , int count = - 1 )
9
+ public static IEnumerable < Arm64Instruction > GetArm64MethodBodyAtVirtualAddress ( ulong virtualAddress , out ulong endVirtualAddress , bool managed = true , int count = - 1 )
10
10
{
11
11
if ( managed )
12
12
{
13
- var startOfNext = MiscUtils . GetAddressOfNextFunctionStart ( virtAddress ) ;
13
+ var startOfNext = MiscUtils . GetAddressOfNextFunctionStart ( virtualAddress ) ;
14
14
15
15
//We have to fall through to default behavior for the last method because we cannot accurately pinpoint its end
16
16
if ( startOfNext > 0 )
17
17
{
18
18
var rawStartOfNextMethod = LibCpp2IlMain . Binary ! . MapVirtualAddressToRaw ( startOfNext ) ;
19
19
20
- var rawStart = LibCpp2IlMain . Binary . MapVirtualAddressToRaw ( virtAddress ) ;
20
+ var rawStart = LibCpp2IlMain . Binary . MapVirtualAddressToRaw ( virtualAddress ) ;
21
21
if ( rawStartOfNextMethod < rawStart )
22
22
rawStartOfNextMethod = LibCpp2IlMain . Binary . RawLength ;
23
23
24
- var bytes = LibCpp2IlMain . Binary . GetRawBinaryContent ( ) . AsSpan ( ( int ) rawStart , ( int ) ( rawStartOfNextMethod - rawStart ) ) ;
24
+ var bytes = LibCpp2IlMain . Binary . GetRawBinaryContent ( ) . AsMemory ( ( int ) rawStart , ( int ) ( rawStartOfNextMethod - rawStart ) ) ;
25
25
26
- return Disassemble ( bytes , virtAddress ) ;
26
+ return Disassemble ( bytes , virtualAddress , out endVirtualAddress ) ;
27
27
}
28
28
}
29
29
30
30
//Unmanaged function, look for first b
31
- var pos = ( int ) LibCpp2IlMain . Binary ! . MapVirtualAddressToRaw ( virtAddress ) ;
31
+ var pos = ( int ) LibCpp2IlMain . Binary ! . MapVirtualAddressToRaw ( virtualAddress ) ;
32
32
var allBytes = LibCpp2IlMain . Binary . GetRawBinaryContent ( ) ;
33
- var span = allBytes . AsSpan ( pos , 4 ) ;
34
- Arm64DisassemblyResult ret = new ( ) ;
33
+
34
+ var instructions = new List < Arm64Instruction > ( ) ;
35
35
36
- while ( ( count == - 1 || ret . Instructions . Count < count ) && ! ret . Instructions . Any ( i => i . Mnemonic is Arm64Mnemonic . B ) )
36
+ endVirtualAddress = virtualAddress ;
37
+ foreach ( var instruction in Disassembler . Disassemble ( allBytes . AsSpan ( pos ) , virtualAddress , Disassembler . Options . IgnoreErrors ) )
37
38
{
38
- ret = Disassemble ( span , virtAddress ) ;
39
-
40
- //All arm64 instructions are 4 bytes
41
- span = allBytes . AsSpan ( pos , span . Length + 4 ) ;
39
+ instructions . Add ( instruction ) ;
40
+ endVirtualAddress = instruction . Address ;
41
+ if ( instruction . Mnemonic == Arm64Mnemonic . B ) break ;
42
+ if ( count != - 1 && instructions . Count >= count ) break ;
42
43
}
43
44
44
- return ret ;
45
+ return instructions ;
45
46
}
46
47
47
- private static Arm64DisassemblyResult Disassemble ( Span < byte > bytes , ulong virtAddress )
48
+ private static IEnumerable < Arm64Instruction > Disassemble ( ReadOnlyMemory < byte > bytes , ulong virtualAddress , out ulong endVirtualAddress )
48
49
{
49
50
try
50
51
{
51
- return Disassembler . Disassemble ( bytes , virtAddress ) ;
52
+ endVirtualAddress = virtualAddress + ( ulong ) bytes . Length ;
53
+ return Disassembler . Disassemble ( bytes , virtualAddress , Disassembler . Options . IgnoreErrors ) ;
52
54
}
53
55
catch ( Exception e )
54
56
{
0 commit comments