//===--------------------- Unwind_AppleExtras.cpp -------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//
//===----------------------------------------------------------------------===//

#include "config.h"
#include "AddressSpace.hpp"
#include "DwarfParser.hpp"


// private keymgr stuff
#define KEYMGR_GCC3_DW2_OBJ_LIST 302
extern "C" {
 extern void _keymgr_set_and_unlock_processwide_ptr(int key, void *ptr);
 extern void *_keymgr_get_and_lock_processwide_ptr(int key);
}

// undocumented libgcc "struct object"
struct libgcc_object {
  void          *start;
  void          *unused1;
  void          *unused2;
  void          *fde;
  unsigned long  encoding;
  void          *fde_end;
  libgcc_object *next;
};

// undocumented libgcc "struct km_object_info" referenced by
// KEYMGR_GCC3_DW2_OBJ_LIST
struct libgcc_object_info {
  libgcc_object   *seen_objects;
  libgcc_object   *unseen_objects;
  unsigned         spare[2];
};


// static linker symbols to prevent wrong two level namespace for _Unwind symbols
#if defined(__arm__)
   #define NOT_HERE_BEFORE_5_0(sym)     \
       extern const char sym##_tmp30 __asm("$ld$hide$os3.0$_" #sym ); \
       __attribute__((visibility("default"))) const char sym##_tmp30 = 0; \
       extern const char sym##_tmp31 __asm("$ld$hide$os3.1$_" #sym ); \
          __attribute__((visibility("default"))) const char sym##_tmp31 = 0; \
       extern const char sym##_tmp32 __asm("$ld$hide$os3.2$_" #sym );\
           __attribute__((visibility("default"))) const char sym##_tmp32 = 0; \
       extern const char sym##_tmp40 __asm("$ld$hide$os4.0$_" #sym ); \
          __attribute__((visibility("default"))) const char sym##_tmp40 = 0; \
       extern const char sym##_tmp41 __asm("$ld$hide$os4.1$_" #sym ); \
          __attribute__((visibility("default"))) const char sym##_tmp41 = 0; \
       extern const char sym##_tmp42 __asm("$ld$hide$os4.2$_" #sym ); \
          __attribute__((visibility("default"))) const char sym##_tmp42 = 0; \
       extern const char sym##_tmp43 __asm("$ld$hide$os4.3$_" #sym ); \
          __attribute__((visibility("default"))) const char sym##_tmp43 = 0;
#elif defined(__aarch64__)
  #define NOT_HERE_BEFORE_10_6(sym)
  #define NEVER_HERE(sym)
#else
  #define NOT_HERE_BEFORE_10_6(sym) \
    extern const char sym##_tmp4 __asm("$ld$hide$os10.4$_" #sym ); \
          __attribute__((visibility("default"))) const char sym##_tmp4 = 0; \
    extern const char sym##_tmp5 __asm("$ld$hide$os10.5$_" #sym ); \
          __attribute__((visibility("default"))) const char sym##_tmp5 = 0;
  #define NEVER_HERE(sym) \
    extern const char sym##_tmp4 __asm("$ld$hide$os10.4$_" #sym ); \
          __attribute__((visibility("default"))) const char sym##_tmp4 = 0; \
    extern const char sym##_tmp5 __asm("$ld$hide$os10.5$_" #sym ); \
          __attribute__((visibility("default"))) const char sym##_tmp5 = 0; \
    extern const char sym##_tmp6 __asm("$ld$hide$os10.6$_" #sym ); \
          __attribute__((visibility("default"))) const char sym##_tmp6 = 0;
#endif


#if defined(_LIBUNWIND_BUILD_ZERO_COST_APIS)

//
// symbols in libSystem.dylib in 10.6 and later, but are in libgcc_s.dylib in
// earlier versions
//
NOT_HERE_BEFORE_10_6(_Unwind_DeleteException)
NOT_HERE_BEFORE_10_6(_Unwind_Find_FDE)
NOT_HERE_BEFORE_10_6(_Unwind_ForcedUnwind)
NOT_HERE_BEFORE_10_6(_Unwind_GetGR)
NOT_HERE_BEFORE_10_6(_Unwind_GetIP)
NOT_HERE_BEFORE_10_6(_Unwind_GetLanguageSpecificData)
NOT_HERE_BEFORE_10_6(_Unwind_GetRegionStart)
NOT_HERE_BEFORE_10_6(_Unwind_RaiseException)
NOT_HERE_BEFORE_10_6(_Unwind_Resume)
NOT_HERE_BEFORE_10_6(_Unwind_SetGR)
NOT_HERE_BEFORE_10_6(_Unwind_SetIP)
NOT_HERE_BEFORE_10_6(_Unwind_Backtrace)
NOT_HERE_BEFORE_10_6(_Unwind_FindEnclosingFunction)
NOT_HERE_BEFORE_10_6(_Unwind_GetCFA)
NOT_HERE_BEFORE_10_6(_Unwind_GetDataRelBase)
NOT_HERE_BEFORE_10_6(_Unwind_GetTextRelBase)
NOT_HERE_BEFORE_10_6(_Unwind_Resume_or_Rethrow)
NOT_HERE_BEFORE_10_6(_Unwind_GetIPInfo)
NOT_HERE_BEFORE_10_6(__register_frame)
NOT_HERE_BEFORE_10_6(__deregister_frame)

//
// symbols in libSystem.dylib for compatibility, but we don't want any new code
// using them
//
NEVER_HERE(__register_frame_info_bases)
NEVER_HERE(__register_frame_info)
NEVER_HERE(__register_frame_info_table_bases)
NEVER_HERE(__register_frame_info_table)
NEVER_HERE(__register_frame_table)
NEVER_HERE(__deregister_frame_info)
NEVER_HERE(__deregister_frame_info_bases)

#endif // defined(_LIBUNWIND_BUILD_ZERO_COST_APIS)




#if defined(_LIBUNWIND_BUILD_SJLJ_APIS)
//
// symbols in libSystem.dylib in iOS 5.0 and later, but are in libgcc_s.dylib in
// earlier versions
//
NOT_HERE_BEFORE_5_0(_Unwind_GetLanguageSpecificData)
NOT_HERE_BEFORE_5_0(_Unwind_GetRegionStart)
NOT_HERE_BEFORE_5_0(_Unwind_GetIP)
NOT_HERE_BEFORE_5_0(_Unwind_SetGR)
NOT_HERE_BEFORE_5_0(_Unwind_SetIP)
NOT_HERE_BEFORE_5_0(_Unwind_DeleteException)
NOT_HERE_BEFORE_5_0(_Unwind_SjLj_Register)
NOT_HERE_BEFORE_5_0(_Unwind_GetGR)
NOT_HERE_BEFORE_5_0(_Unwind_GetIPInfo)
NOT_HERE_BEFORE_5_0(_Unwind_GetCFA)
NOT_HERE_BEFORE_5_0(_Unwind_SjLj_Resume)
NOT_HERE_BEFORE_5_0(_Unwind_SjLj_RaiseException)
NOT_HERE_BEFORE_5_0(_Unwind_SjLj_Resume_or_Rethrow)
NOT_HERE_BEFORE_5_0(_Unwind_SjLj_Unregister)

#endif // defined(_LIBUNWIND_BUILD_SJLJ_APIS)


namespace libunwind {

_LIBUNWIND_HIDDEN
bool checkKeyMgrRegisteredFDEs(uintptr_t pc, void *&fde) {
#if __MAC_OS_X_VERSION_MIN_REQUIRED
  // lastly check for old style keymgr registration of dynamically generated
  // FDEs acquire exclusive access to libgcc_object_info
  libgcc_object_info *head = (libgcc_object_info *)
                _keymgr_get_and_lock_processwide_ptr(KEYMGR_GCC3_DW2_OBJ_LIST);
  if (head != NULL) {
    // look at each FDE in keymgr
    for (libgcc_object *ob = head->unseen_objects; ob != NULL; ob = ob->next) {
      CFI_Parser<LocalAddressSpace>::FDE_Info fdeInfo;
      CFI_Parser<LocalAddressSpace>::CIE_Info cieInfo;
      const char *msg = CFI_Parser<LocalAddressSpace>::decodeFDE(
                                      LocalAddressSpace::sThisAddressSpace,
                                      (uintptr_t)ob->fde, &fdeInfo, &cieInfo);
      if (msg == NULL) {
        // Check if this FDE is for a function that includes the pc
        if ((fdeInfo.pcStart <= pc) && (pc < fdeInfo.pcEnd)) {
          fde = (void*)fdeInfo.pcStart;
          _keymgr_set_and_unlock_processwide_ptr(KEYMGR_GCC3_DW2_OBJ_LIST,
                                                 head);
          return true;
        }
      }
    }
  }
  // release libgcc_object_info
  _keymgr_set_and_unlock_processwide_ptr(KEYMGR_GCC3_DW2_OBJ_LIST, head);
#else
  (void)pc;
  (void)fde;
#endif
  return false;
}

}

