//! Implementation of panics backed by libgcc/libunwind (in some form).
//!
//! For background on exception handling and stack unwinding please see
//! "Exception Handling in LLVM" (llvm.org/docs/ExceptionHandling.html) and
//! documents linked from it.
//! These are also good reads:
//!  * <https://itanium-cxx-abi.github.io/cxx-abi/abi-eh.html>
//!  * <https://monoinfinito.wordpress.com/series/exception-handling-in-c/>
//!  * <https://www.airs.com/blog/index.php?s=exception+frames>
//!
//! ## A brief summary
//!
//! Exception handling happens in two phases: a search phase and a cleanup
//! phase.
//!
//! In both phases the unwinder walks stack frames from top to bottom using
//! information from the stack frame unwind sections of the current process's
//! modules ("module" here refers to an OS module, i.e., an executable or a
//! dynamic library).
//!
//! For each stack frame, it invokes the associated "personality routine", whose
//! address is also stored in the unwind info section.
//!
//! In the search phase, the job of a personality routine is to examine
//! exception object being thrown, and to decide whether it should be caught at
//! that stack frame. Once the handler frame has been identified, cleanup phase
//! begins.
//!
//! In the cleanup phase, the unwinder invokes each personality routine again.
//! This time it decides which (if any) cleanup code needs to be run for
//! the current stack frame. If so, the control is transferred to a special
//! branch in the function body, the "landing pad", which invokes destructors,
//! frees memory, etc. At the end of the landing pad, control is transferred
//! back to the unwinder and unwinding resumes.
//!
//! Once stack has been unwound down to the handler frame level, unwinding stops
//! and the last personality routine transfers control to the catch block.
#![forbid(unsafe_op_in_unsafe_fn)]

use super::dwarf::eh::{self, EHAction, EHContext};
use crate::ffi::c_int;
use unwind as uw;

// Register ids were lifted from LLVM's TargetLowering::getExceptionPointerRegister()
// and TargetLowering::getExceptionSelectorRegister() for each architecture,
// then mapped to DWARF register numbers via register definition tables
// (typically <arch>RegisterInfo.td, search for "DwarfRegNum").
// See also https://llvm.org/docs/WritingAnLLVMBackend.html#defining-a-register.

#[cfg(target_arch = "x86")]
const UNWIND_DATA_REG: (i32, i32) = (0, 2); // EAX, EDX

#[cfg(target_arch = "x86_64")]
const UNWIND_DATA_REG: (i32, i32) = (0, 1); // RAX, RDX

#[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
const UNWIND_DATA_REG: (i32, i32) = (0, 1); // R0, R1 / X0, X1

#[cfg(target_arch = "m68k")]
const UNWIND_DATA_REG: (i32, i32) = (0, 1); // D0, D1

#[cfg(any(
    target_arch = "mips",
    target_arch = "mips32r6",
    target_arch = "mips64",
    target_arch = "mips64r6"
))]
const UNWIND_DATA_REG: (i32, i32) = (4, 5); // A0, A1

#[cfg(target_arch = "csky")]
const UNWIND_DATA_REG: (i32, i32) = (0, 1); // R0, R1

#[cfg(any(target_arch = "powerpc", target_arch = "powerpc64"))]
const UNWIND_DATA_REG: (i32, i32) = (3, 4); // R3, R4 / X3, X4

#[cfg(target_arch = "s390x")]
const UNWIND_DATA_REG: (i32, i32) = (6, 7); // R6, R7

#[cfg(any(target_arch = "sparc", target_arch = "sparc64"))]
const UNWIND_DATA_REG: (i32, i32) = (24, 25); // I0, I1

#[cfg(target_arch = "hexagon")]
const UNWIND_DATA_REG: (i32, i32) = (0, 1); // R0, R1

#[cfg(any(target_arch = "riscv64", target_arch = "riscv32"))]
const UNWIND_DATA_REG: (i32, i32) = (10, 11); // x10, x11

#[cfg(target_arch = "loongarch64")]
const UNWIND_DATA_REG: (i32, i32) = (4, 5); // a0, a1

// The following code is based on GCC's C and C++ personality routines.  For reference, see:
// https://github.com/gcc-mirror/gcc/blob/master/libstdc++-v3/libsupc++/eh_personality.cc
// https://github.com/gcc-mirror/gcc/blob/trunk/libgcc/unwind-c.c

cfg_if::cfg_if! {
    if #[cfg(all(
            target_arch = "arm",
            not(all(target_vendor = "apple", not(target_os = "watchos"))),
            not(target_os = "netbsd"),
        ))] {
        /// personality fn called by [ARM EHABI][armeabi-eh]
        ///
        /// Apple 32-bit ARM (but not watchOS) uses the default routine instead
        /// since it uses "setjmp-longjmp" unwinding.
        ///
        /// [armeabi-eh]: https://web.archive.org/web/20190728160938/https://infocenter.arm.com/help/topic/com.arm.doc.ihi0038b/IHI0038B_ehabi.pdf
        #[lang = "eh_personality"]
        unsafe extern "C" fn rust_eh_personality(
            state: uw::_Unwind_State,
            exception_object: *mut uw::_Unwind_Exception,
            context: *mut uw::_Unwind_Context,
        ) -> uw::_Unwind_Reason_Code {
            unsafe {
                let state = state as c_int;
                let action = state & uw::_US_ACTION_MASK as c_int;
                let search_phase = if action == uw::_US_VIRTUAL_UNWIND_FRAME as c_int {
                    // Backtraces on ARM will call the personality routine with
                    // state == _US_VIRTUAL_UNWIND_FRAME | _US_FORCE_UNWIND. In those cases
                    // we want to continue unwinding the stack, otherwise all our backtraces
                    // would end at __rust_try
                    if state & uw::_US_FORCE_UNWIND as c_int != 0 {
                        return continue_unwind(exception_object, context);
                    }
                    true
                } else if action == uw::_US_UNWIND_FRAME_STARTING as c_int {
                    false
                } else if action == uw::_US_UNWIND_FRAME_RESUME as c_int {
                    return continue_unwind(exception_object, context);
                } else {
                    return uw::_URC_FAILURE;
                };

                // The DWARF unwinder assumes that _Unwind_Context holds things like the function
                // and LSDA pointers, however ARM EHABI places them into the exception object.
                // To preserve signatures of functions like _Unwind_GetLanguageSpecificData(), which
                // take only the context pointer, GCC personality routines stash a pointer to
                // exception_object in the context, using location reserved for ARM's
                // "scratch register" (r12).
                uw::_Unwind_SetGR(context, uw::UNWIND_POINTER_REG, exception_object as uw::_Unwind_Ptr);
                // ...A more principled approach would be to provide the full definition of ARM's
                // _Unwind_Context in our libunwind bindings and fetch the required data from there
                // directly, bypassing DWARF compatibility functions.

                let eh_action = match find_eh_action(context) {
                    Ok(action) => action,
                    Err(_) => return uw::_URC_FAILURE,
                };
                if search_phase {
                    match eh_action {
                        EHAction::None | EHAction::Cleanup(_) => {
                            return continue_unwind(exception_object, context);
                        }
                        EHAction::Catch(_) | EHAction::Filter(_) => {
                            // EHABI requires the personality routine to update the
                            // SP value in the barrier cache of the exception object.
                            (*exception_object).private[5] =
                                uw::_Unwind_GetGR(context, uw::UNWIND_SP_REG);
                            return uw::_URC_HANDLER_FOUND;
                        }
                        EHAction::Terminate => return uw::_URC_FAILURE,
                    }
                } else {
                    match eh_action {
                        EHAction::None => return continue_unwind(exception_object, context),
                        EHAction::Filter(_) if state & uw::_US_FORCE_UNWIND as c_int != 0 => return continue_unwind(exception_object, context),
                        EHAction::Cleanup(lpad) | EHAction::Catch(lpad) | EHAction::Filter(lpad) => {
                            uw::_Unwind_SetGR(
                                context,
                                UNWIND_DATA_REG.0,
                                exception_object as uw::_Unwind_Ptr,
                            );
                            uw::_Unwind_SetGR(context, UNWIND_DATA_REG.1, core::ptr::null());
                            uw::_Unwind_SetIP(context, lpad);
                            return uw::_URC_INSTALL_CONTEXT;
                        }
                        EHAction::Terminate => return uw::_URC_FAILURE,
                    }
                }

                // On ARM EHABI the personality routine is responsible for actually
                // unwinding a single stack frame before returning (ARM EHABI Sec. 6.1).
                unsafe fn continue_unwind(
                    exception_object: *mut uw::_Unwind_Exception,
                    context: *mut uw::_Unwind_Context,
                ) -> uw::_Unwind_Reason_Code {
                    unsafe {
                        if __gnu_unwind_frame(exception_object, context) == uw::_URC_NO_REASON {
                            uw::_URC_CONTINUE_UNWIND
                        } else {
                            uw::_URC_FAILURE
                        }
                    }
                }
                // defined in libgcc
                extern "C" {
                    fn __gnu_unwind_frame(
                        exception_object: *mut uw::_Unwind_Exception,
                        context: *mut uw::_Unwind_Context,
                    ) -> uw::_Unwind_Reason_Code;
                }
            }
        }
    } else {
        /// Default personality routine, which is used directly on most targets
        /// and indirectly on Windows x86_64 and AArch64 via SEH.
        unsafe extern "C" fn rust_eh_personality_impl(
            version: c_int,
            actions: uw::_Unwind_Action,
            _exception_class: uw::_Unwind_Exception_Class,
            exception_object: *mut uw::_Unwind_Exception,
            context: *mut uw::_Unwind_Context,
        ) -> uw::_Unwind_Reason_Code {
            unsafe {
                if version != 1 {
                    return uw::_URC_FATAL_PHASE1_ERROR;
                }
                let eh_action = match find_eh_action(context) {
                    Ok(action) => action,
                    Err(_) => return uw::_URC_FATAL_PHASE1_ERROR,
                };
                if actions as i32 & uw::_UA_SEARCH_PHASE as i32 != 0 {
                    match eh_action {
                        EHAction::None | EHAction::Cleanup(_) => uw::_URC_CONTINUE_UNWIND,
                        EHAction::Catch(_) | EHAction::Filter(_) => uw::_URC_HANDLER_FOUND,
                        EHAction::Terminate => uw::_URC_FATAL_PHASE1_ERROR,
                    }
                } else {
                    match eh_action {
                        EHAction::None => uw::_URC_CONTINUE_UNWIND,
                        // Forced unwinding hits a terminate action.
                        EHAction::Filter(_) if actions as i32 & uw::_UA_FORCE_UNWIND as i32 != 0 => uw::_URC_CONTINUE_UNWIND,
                        EHAction::Cleanup(lpad) | EHAction::Catch(lpad) | EHAction::Filter(lpad) => {
                            uw::_Unwind_SetGR(
                                context,
                                UNWIND_DATA_REG.0,
                                exception_object.cast(),
                            );
                            uw::_Unwind_SetGR(context, UNWIND_DATA_REG.1, core::ptr::null());
                            uw::_Unwind_SetIP(context, lpad);
                            uw::_URC_INSTALL_CONTEXT
                        }
                        EHAction::Terminate => uw::_URC_FATAL_PHASE2_ERROR,
                    }
                }
            }
        }

        cfg_if::cfg_if! {
            if #[cfg(all(windows, any(target_arch = "aarch64", target_arch = "x86_64"), target_env = "gnu"))] {
                /// personality fn called by [Windows Structured Exception Handling][windows-eh]
                ///
                /// On x86_64 and AArch64 MinGW targets, the unwinding mechanism is SEH,
                /// however the unwind handler data (aka LSDA) uses GCC-compatible encoding
                ///
                /// [windows-eh]: https://learn.microsoft.com/en-us/cpp/cpp/structured-exception-handling-c-cpp?view=msvc-170
                #[lang = "eh_personality"]
                #[allow(nonstandard_style)]
                unsafe extern "C" fn rust_eh_personality(
                    exceptionRecord: *mut uw::EXCEPTION_RECORD,
                    establisherFrame: uw::LPVOID,
                    contextRecord: *mut uw::CONTEXT,
                    dispatcherContext: *mut uw::DISPATCHER_CONTEXT,
                ) -> uw::EXCEPTION_DISPOSITION {
                    // SAFETY: the cfg is still target_os = "windows" and target_env = "gnu",
                    // which means that this is the correct function to call, passing our impl fn
                    // as the callback which gets actually used
                    unsafe {
                        uw::_GCC_specific_handler(
                            exceptionRecord,
                            establisherFrame,
                            contextRecord,
                            dispatcherContext,
                            rust_eh_personality_impl,
                        )
                    }
                }
            } else {
                /// personality fn called by [Itanium C++ ABI Exception Handling][itanium-eh]
                ///
                /// The personality routine for most non-Windows targets. This will be called by
                /// the unwinding library:
                /// - "In the search phase, the framework repeatedly calls the personality routine,
                ///   with the _UA_SEARCH_PHASE flag as described below, first for the current PC
                ///   and register state, and then unwinding a frame to a new PC at each step..."
                /// - "If the search phase reports success, the framework restarts in the cleanup
                ///    phase. Again, it repeatedly calls the personality routine, with the
                ///   _UA_CLEANUP_PHASE flag as described below, first for the current PC and
                ///   register state, and then unwinding a frame to a new PC at each step..."i
                ///
                /// [itanium-eh]: https://itanium-cxx-abi.github.io/cxx-abi/abi-eh.html
                #[lang = "eh_personality"]
                unsafe extern "C" fn rust_eh_personality(
                    version: c_int,
                    actions: uw::_Unwind_Action,
                    exception_class: uw::_Unwind_Exception_Class,
                    exception_object: *mut uw::_Unwind_Exception,
                    context: *mut uw::_Unwind_Context,
                ) -> uw::_Unwind_Reason_Code {
                    // SAFETY: the platform support must modify the cfg for the inner fn
                    // if it needs something different than what is currently invoked.
                    unsafe {
                        rust_eh_personality_impl(
                            version,
                            actions,
                            exception_class,
                            exception_object,
                            context,
                        )
                    }
                }
            }
        }
    }
}

unsafe fn find_eh_action(context: *mut uw::_Unwind_Context) -> Result<EHAction, ()> {
    unsafe {
        let lsda = uw::_Unwind_GetLanguageSpecificData(context) as *const u8;
        let mut ip_before_instr: c_int = 0;
        let ip = uw::_Unwind_GetIPInfo(context, &mut ip_before_instr);
        let eh_context = EHContext {
            // The return address points 1 byte past the call instruction,
            // which could be in the next IP range in LSDA range table.
            //
            // `ip = -1` has special meaning, so use wrapping sub to allow for that
            ip: if ip_before_instr != 0 { ip } else { ip.wrapping_sub(1) },
            func_start: uw::_Unwind_GetRegionStart(context),
            get_text_start: &|| uw::_Unwind_GetTextRelBase(context),
            get_data_start: &|| uw::_Unwind_GetDataRelBase(context),
        };
        eh::find_eh_action(lsda, &eh_context)
    }
}
