//! 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>
//!  * <http://monoinfinito.wordpress.com/series/exception-handling-in-c/>
//!  * <http://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.

use alloc::boxed::Box;
use core::any::Any;

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

#[repr(C)]
struct Exception {
    _uwe: uw::_Unwind_Exception,
    cause: Box<dyn Any + Send>,
}

pub unsafe fn panic(data: Box<dyn Any + Send>) -> u32 {
    let exception = Box::new(Exception {
        _uwe: uw::_Unwind_Exception {
            exception_class: rust_exception_class(),
            exception_cleanup,
            private: [0; uw::unwinder_private_data_size],
        },
        cause: data,
    });
    let exception_param = Box::into_raw(exception) as *mut uw::_Unwind_Exception;
    return uw::_Unwind_RaiseException(exception_param) as u32;

    extern "C" fn exception_cleanup(
        _unwind_code: uw::_Unwind_Reason_Code,
        exception: *mut uw::_Unwind_Exception,
    ) {
        unsafe {
            let _: Box<Exception> = Box::from_raw(exception as *mut Exception);
            super::__rust_drop_panic();
        }
    }
}

pub unsafe fn cleanup(ptr: *mut u8) -> Box<dyn Any + Send> {
    let exception = ptr as *mut uw::_Unwind_Exception;
    if (*exception).exception_class != rust_exception_class() {
        uw::_Unwind_DeleteException(exception);
        super::__rust_foreign_exception();
    } else {
        let exception = Box::from_raw(exception as *mut Exception);
        exception.cause
    }
}

// Rust's exception class identifier.  This is used by personality routines to
// determine whether the exception was thrown by their own runtime.
fn rust_exception_class() -> uw::_Unwind_Exception_Class {
    // M O Z \0  R U S T -- vendor, language
    0x4d4f5a_00_52555354
}

// 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 http://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(any(target_arch = "mips", target_arch = "mips64"))]
const UNWIND_DATA_REG: (i32, i32) = (4, 5); // A0, A1

#[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

// 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(target_os = "ios"), not(target_os = "netbsd")))] {
        // ARM EHABI personality routine.
        // http://infocenter.arm.com/help/topic/com.arm.doc.ihi0038b/IHI0038B_ehabi.pdf
        //
        // iOS uses the default routine instead since it uses SjLj unwinding.
        #[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 {
            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(_) => {
                        // 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::Cleanup(lpad) |
                    EHAction::Catch(lpad) => {
                        uw::_Unwind_SetGR(context, UNWIND_DATA_REG.0,
                                          exception_object as uintptr_t);
                        uw::_Unwind_SetGR(context, UNWIND_DATA_REG.1, 0);
                        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 {
                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 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 {
            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(_) => uw::_URC_HANDLER_FOUND,
                    EHAction::Terminate => uw::_URC_FATAL_PHASE1_ERROR,
                }
            } else {
                match eh_action {
                    EHAction::None => uw::_URC_CONTINUE_UNWIND,
                    EHAction::Cleanup(lpad) |
                    EHAction::Catch(lpad) => {
                        uw::_Unwind_SetGR(context, UNWIND_DATA_REG.0,
                            exception_object as uintptr_t);
                        uw::_Unwind_SetGR(context, UNWIND_DATA_REG.1, 0);
                        uw::_Unwind_SetIP(context, lpad);
                        uw::_URC_INSTALL_CONTEXT
                    }
                    EHAction::Terminate => uw::_URC_FATAL_PHASE2_ERROR,
                }
            }
        }

        cfg_if::cfg_if! {
            if #[cfg(all(windows, target_arch = "x86_64", target_env = "gnu"))] {
                // On x86_64 MinGW targets, the unwinding mechanism is SEH however the unwind
                // handler data (aka LSDA) uses GCC-compatible encoding.
                #[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 {
                    uw::_GCC_specific_handler(exceptionRecord,
                                             establisherFrame,
                                             contextRecord,
                                             dispatcherContext,
                                             rust_eh_personality_impl)
                }
            } else {
                // The personality routine for most of our targets.
                #[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 {
                    rust_eh_personality_impl(version,
                                             actions,
                                             exception_class,
                                             exception_object,
                                             context)
                }
            }
        }
    }
}

unsafe fn find_eh_action(context: *mut uw::_Unwind_Context) -> Result<EHAction, ()> {
    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: if ip_before_instr != 0 { ip } else { ip - 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)
}

// Frame unwind info registration
//
// Each module's image contains a frame unwind info section (usually
// ".eh_frame").  When a module is loaded/unloaded into the process, the
// unwinder must be informed about the location of this section in memory. The
// methods of achieving that vary by the platform.  On some (e.g., Linux), the
// unwinder can discover unwind info sections on its own (by dynamically
// enumerating currently loaded modules via the dl_iterate_phdr() API and
// finding their ".eh_frame" sections); Others, like Windows, require modules
// to actively register their unwind info sections via unwinder API.
//
// This module defines two symbols which are referenced and called from
// rsbegin.rs to register our information with the GCC runtime. The
// implementation of stack unwinding is (for now) deferred to libgcc_eh, however
// Rust crates use these Rust-specific entry points to avoid potential clashes
// with any GCC runtime.
#[cfg(all(target_os = "windows", target_arch = "x86", target_env = "gnu"))]
pub mod eh_frame_registry {
    extern "C" {
        fn __register_frame_info(eh_frame_begin: *const u8, object: *mut u8);
        fn __deregister_frame_info(eh_frame_begin: *const u8, object: *mut u8);
    }

    #[rustc_std_internal_symbol]
    pub unsafe extern "C" fn rust_eh_register_frames(eh_frame_begin: *const u8, object: *mut u8) {
        __register_frame_info(eh_frame_begin, object);
    }

    #[rustc_std_internal_symbol]
    pub unsafe extern "C" fn rust_eh_unregister_frames(eh_frame_begin: *const u8, object: *mut u8) {
        __deregister_frame_info(eh_frame_begin, object);
    }
}
