// Copyright 2015 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #if defined(__x86_64__) || defined(__aarch64__) // base::apple::CallWithEHFrame(void () block_pointer) #define CALL_WITH_EH_FRAME __ZN4base5apple15CallWithEHFrameEU13block_pointerFvvE .section __TEXT,__text,regular,pure_instructions #if !defined(COMPONENT_BUILD) .private_extern CALL_WITH_EH_FRAME #endif .globl CALL_WITH_EH_FRAME .p2align 2 CALL_WITH_EH_FRAME: .cfi_startproc // Configure the C++ exception handler personality routine. Normally the // compiler would emit ___gxx_personality_v0 here. The purpose of this // function is to use a custom personality routine. .cfi_personality 155, __ZN4base5apple21CxxPersonalityRoutineEi14_Unwind_ActionyP17_Unwind_ExceptionP15_Unwind_Context .cfi_lsda 16, CallWithEHFrame_exception_table #if defined(__x86_64__) Lfunction_start: pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset %rbp, -16 movq %rsp, %rbp .cfi_def_cfa_register %rbp // Load the function pointer from the block descriptor. movq 16(%rdi), %rax // Execute the block in the context of a C++ try{}. Ltry_start: callq *%rax Ltry_end: popq %rbp ret // Landing pad for the exception handler. This should never be called, since // the personality routine will stop the search for an exception handler, // which will cause the runtime to invoke the default terminate handler. Lcatch: movq %rax, %rdi callq ___cxa_begin_catch // The ABI requires a call to the catch handler. ud2 // In the event this is called, make it fatal. #elif defined(__aarch64__) Lfunction_start: stp x29, x30, [sp, #-16]! mov x29, sp .cfi_def_cfa w29, 16 .cfi_offset w30, -8 .cfi_offset w29, -16 // Load the function pointer from the block descriptor. ldr x8, [x0, #16] // Execute the block in the context of a C++ try{}. Ltry_start: blr x8 Ltry_end: ldp x29, x30, [sp], #16 ret // Landing pad for the exception handler. This should never be called, since // the personality routine will stop the search for an exception handler, // which will cause the runtime to invoke the default terminate handler. Lcatch: bl ___cxa_begin_catch // The ABI requires a call to the catch handler. brk #0x1 // In the event this is called, make it fatal. #endif Lfunction_end: .cfi_endproc // The C++ exception table that is used to identify this frame as an // exception handler. See https://llvm.org/docs/ExceptionHandling.html, // https://itanium-cxx-abi.github.io/cxx-abi/exceptions.pdf and // https://www.airs.com/blog/archives/464. .section __TEXT,__gcc_except_tab .p2align 2 CallWithEHFrame_exception_table: .byte 255 // DW_EH_PE_omit .byte 155 // DW_EH_PE_indirect | DW_EH_PE_pcrel | DW_EH_PE_sdata4 // The number of bytes in this table .uleb128 Ltypes_table_base - Ltypes_table_ref_base Ltypes_table_ref_base: .byte 1 // DW_EH_PE_uleb128 // Callsite table length. .uleb128 Lcall_site_table_end - Lcall_site_table_start Lcall_site_table_start: // First callsite. CS1_begin = Ltry_start - Lfunction_start .uleb128 CS1_begin CS1_end = Ltry_end - Ltry_start .uleb128 CS1_end // First landing pad. LP1 = Lcatch - Lfunction_start .uleb128 LP1 .uleb128 1 // Action record. // Second callsite. CS2_begin = Ltry_end - Lfunction_start .uleb128 CS2_begin CS2_end = Lfunction_end - Ltry_end .uleb128 CS2_end // Second landing pad (none). .uleb128 0 .uleb128 0 // No action. Lcall_site_table_end: // Action table. // Action record 1. .uleb128 1 // Type filter -1. .uleb128 0 // No further action to take. // Types table. .p2align 2 .long 0 // Type filter -1: no type filter for this catch(){} clause. Ltypes_table_base: .p2align 2 #endif // defined(__x86_64__) || defined(__aarch64__)