; The initial code for this file was generated using clang: ; ; clang -c testfile -otestfile.s -arch arm64 -S -O -fverbose-asm ; ; Relevant and helpful documentation: ; * https://github.com/ARM-software/abi-aa/blob/main/aapcs64/aapcs64.rst ; * https://github.com/ARM-software/abi-aa/blob/main/cppabi64/cppabi64.rst ; .section __TEXT,__text,regular,pure_instructions .globl OBJCMSGFUNC ; -- Begin function xamarin_dyn_objc_msgSend[Super] .p2align 2 OBJCMSGFUNC: ; @xamarin_dyn_objc_msgSend[Super] Lfunc_begin2: .cfi_startproc .cfi_personality 155, ___objc_personality_v0 .cfi_lsda 16, Lexception0 stp x20, x19, [sp, #-32]! ; 16-byte Folded Spill stp x29, x30, [sp, #16] ; 16-byte Folded Spill add x29, sp, #16 .cfi_def_cfa w29, 16 .cfi_offset w30, -8 .cfi_offset w29, -16 .cfi_offset w19, -24 .cfi_offset w20, -32 Lbeforeinvoke: ; calculate the amount of stack space we need sub sp, sp, #400 ; we need to preserve: ; x0-x8, x16, x19 ; q0-q7 stp x0, x1, [sp, #0x00] stp x2, x3, [sp, #0x10] stp x4, x5, [sp, #0x20] stp x6, x7, [sp, #0x30] stp x8,x16, [sp, #0x40] stp x21,x22, [sp, #0x50] stp q0, q1, [sp, #0x60] stp q2, q3, [sp, #0x80] stp q4, q5, [sp, #0xa0] stp q6, q7, [sp, #0xc0] ; potentially resolve objc_super* [handle, class_handle] to the actual instance RESOLVESUPER ; figure out how much stack space we need bl _xamarin_get_frame_length ; x0 holds the amount of stack space we need ; first align stack requirement to 16 bytes add x0, x0, #15 lsr x0, x0, #4 lsl x0, x0, #4 ; save the current stack location mov x22, sp ; save how much space we need mov x21, x0 ; then make space for the arguments sub sp, sp, x0 ; copy arguments from old location in the stack to new location in the stack ; x2 will hold the amount of bytes left to copy. This will be a multiple of 8. ; x1 the current src location ; x0 the current dst location mov x2, x0 ; x2 = frame_length add x1, x29, #16 ; x1 = address of first argument we got mov x0, sp ; x0 = address of the bottom of the stack L_start: cmp x2, #0 ; b.eq L_end ; while (left != 0) { sub x2, x2, #8 ; len -= 8 x2 -= 8 ldr x3, [x1, x2] ; tmp = src [len] x3 = x1 [x2] str x3, [x0, x2] ; dst [len] = tmp x0 [x2] = x3 b L_start ; } L_end: ; restore original input registers, except x21 and x22, which we're still using ldp x0, x1, [x22, #0x00] ldp x2, x3, [x22, #0x10] ldp x4, x5, [x22, #0x20] ldp x6, x7, [x22, #0x30] ldp x8,x16, [x22, #0x40] ldp q0, q1, [x22, #0x60] ldp q2, q3, [x22, #0x80] ldp q4, q5, [x22, #0xa0] ldp q6, q7, [x22, #0xc0] bl OBJCMSGCALL Lafterinvoke: ; restore the stack to it's previous value add sp, sp, x21 ; now restore x21 and x22 ldp x21, x22, [sp, #0x50] add sp, sp, #400 ldp x29, x30, [sp, #16] ; 16-byte Folded Reload ldp x20, x19, [sp], #32 ; 16-byte Folded Reload ret Lcatchhandler: mov x19, x0 cmp w1, #1 ; =1 b.ne Lnomatchexception ; check if xamarin_marshal_objectivec_exception_mode == disable, if so, just don't handle the exception Lloh0: adrp x8, _xamarin_marshal_objectivec_exception_mode@GOTPAGE Lloh1: ldr x8, [x8, _xamarin_marshal_objectivec_exception_mode@GOTPAGEOFF] Lloh2: ldr w0, [x8] cmp w0, #4 b.eq Lnomatchexception mov x0, x19 bl _objc_begin_catch Lcatchbegin: mov w1, #0 mov x2, #0 bl _xamarin_process_nsexception_using_mode Lcatchend: bl _objc_end_catch ; xamarin_process_nsexception_using_mode might have set a pending managed exception, which means we end up executing more code here ; in theory, any pending managed exceptions should be thrown automatically upon returning to managed code. ; however, things may go wrong, and if the pending managed exception isn't thrown, then make sure we don't return some random value. ; returning a constant NULL/0 is at least consistent behavior, and is less likely to crash the process than any other value. mov x0, #0 b Lafterinvoke Lcatchcatchhandler: mov x19, x0 bl _objc_end_catch Lnomatchexception: mov x0, x19 bl __Unwind_Resume brk #0x1 Lfunc_end2: .loh AdrpLdrGotLdr Lloh0, Lloh1, Lloh2 .cfi_endproc .section __TEXT,__gcc_except_tab .p2align 2 GCC_except_table0: Lexception0: .byte 255 ; @LPStart Encoding = omit .byte 155 ; @TType Encoding = indirect pcrel sdata4 .uleb128 Lttbase0-Lttbaseref0 Lttbaseref0: .byte 1 ; Call site Encoding = uleb128 .uleb128 Lcst_end0-Lcst_begin0 Lcst_begin0: .uleb128 Lbeforeinvoke-Lfunc_begin2 ; >> Call Site 1 << .uleb128 Lafterinvoke-Lbeforeinvoke ; Call between Lbeforeinvoke and Lafterinvoke .uleb128 Lcatchhandler-Lfunc_begin2 ; jumps to Lcatchhandler .byte 3 ; On action: 2 .uleb128 Lafterinvoke-Lfunc_begin2 ; >> Call Site 2 << .uleb128 Lcatchbegin-Lafterinvoke ; Call between Lafterinvoke and Lcatchbegin .byte 0 ; has no landing pad .byte 0 ; On action: cleanup .uleb128 Lcatchbegin-Lfunc_begin2 ; >> Call Site 3 << .uleb128 Lcatchend-Lcatchbegin ; Call between Lcatchbegin and Lcatchend .uleb128 Lcatchcatchhandler-Lfunc_begin2 ; jumps to Lcatchcatchhandler .byte 0 ; On action: cleanup .uleb128 Lcatchend-Lfunc_begin2 ; >> Call Site 4 << .uleb128 Lfunc_end2-Lcatchend ; Call between Lcatchend and Lfunc_end2 .byte 0 ; has no landing pad .byte 0 ; On action: cleanup Lcst_end0: .byte 0 ; >> Action Record 1 << ; Cleanup .byte 0 ; No further actions .byte 1 ; >> Action Record 2 << ; Catch TypeInfo 1 .byte 125 ; Continue to action 1 .p2align 2 ; >> Catch TypeInfos << Ltmp8: ; TypeInfo 1 .long _OBJC_EHTYPE_$_NSException@GOT-Ltmp8 Lttbase0: .p2align 2 ; -- End function .section __DATA,__objc_imageinfo,regular,no_dead_strip L_OBJC_IMAGE_INFO: .long 0 .long 64 .subsections_via_symbols