@@ -6,49 +6,51 @@ namespace Cpp2IL.InstructionSets.ArmV8;
66
77internal static class ArmV8Utils
88{
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 )
1010 {
1111 if ( managed )
1212 {
13- var startOfNext = MiscUtils . GetAddressOfNextFunctionStart ( virtAddress ) ;
13+ var startOfNext = MiscUtils . GetAddressOfNextFunctionStart ( virtualAddress ) ;
1414
1515 //We have to fall through to default behavior for the last method because we cannot accurately pinpoint its end
1616 if ( startOfNext > 0 )
1717 {
1818 var rawStartOfNextMethod = LibCpp2IlMain . Binary ! . MapVirtualAddressToRaw ( startOfNext ) ;
1919
20- var rawStart = LibCpp2IlMain . Binary . MapVirtualAddressToRaw ( virtAddress ) ;
20+ var rawStart = LibCpp2IlMain . Binary . MapVirtualAddressToRaw ( virtualAddress ) ;
2121 if ( rawStartOfNextMethod < rawStart )
2222 rawStartOfNextMethod = LibCpp2IlMain . Binary . RawLength ;
2323
24- var bytes = LibCpp2IlMain . Binary . GetRawBinaryContent ( ) . AsSpan ( ( int ) rawStart , ( int ) ( rawStartOfNextMethod - rawStart ) ) ;
24+ var bytes = LibCpp2IlMain . Binary . GetRawBinaryContent ( ) . AsMemory ( ( int ) rawStart , ( int ) ( rawStartOfNextMethod - rawStart ) ) ;
2525
26- return Disassemble ( bytes , virtAddress ) ;
26+ return Disassemble ( bytes , virtualAddress , out endVirtualAddress ) ;
2727 }
2828 }
2929
3030 //Unmanaged function, look for first b
31- var pos = ( int ) LibCpp2IlMain . Binary ! . MapVirtualAddressToRaw ( virtAddress ) ;
31+ var pos = ( int ) LibCpp2IlMain . Binary ! . MapVirtualAddressToRaw ( virtualAddress ) ;
3232 var allBytes = LibCpp2IlMain . Binary . GetRawBinaryContent ( ) ;
33- var span = allBytes . AsSpan ( pos , 4 ) ;
34- Arm64DisassemblyResult ret = new ( ) ;
33+
34+ var instructions = new List < Arm64Instruction > ( ) ;
3535
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 ) )
3738 {
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 ;
4243 }
4344
44- return ret ;
45+ return instructions ;
4546 }
4647
47- private static Arm64DisassemblyResult Disassemble ( Span < byte > bytes , ulong virtAddress )
48+ private static IEnumerable < Arm64Instruction > Disassemble ( ReadOnlyMemory < byte > bytes , ulong virtualAddress , out ulong endVirtualAddress )
4849 {
4950 try
5051 {
51- return Disassembler . Disassemble ( bytes , virtAddress ) ;
52+ endVirtualAddress = virtualAddress + ( ulong ) bytes . Length ;
53+ return Disassembler . Disassemble ( bytes , virtualAddress , Disassembler . Options . IgnoreErrors ) ;
5254 }
5355 catch ( Exception e )
5456 {
0 commit comments