mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-10-09 20:34:54 +00:00
unwind: Fix libc++abi and libgcc build.
To build libc++abi without libunwind, we should make sure that all function calls to _Unwind_{Get,Set}{GR,IP}() are inlined as function calls to _Unwind_VRS_{Get,Set}(). Otherwise, libc++abi.so will fail to link since libgcc does not provide these symbol at all. This commit fixes the problem by providing both the inlined version and exported version. llvm-svn: 243073
This commit is contained in:
parent
b1e77a3642
commit
ff8fbf9f90
@ -204,12 +204,55 @@ _Unwind_VRS_Pop(_Unwind_Context *context, _Unwind_VRS_RegClass regclass,
|
||||
_Unwind_VRS_DataRepresentation representation);
|
||||
#endif
|
||||
|
||||
#if !_LIBUNWIND_ARM_EHABI
|
||||
|
||||
extern uintptr_t _Unwind_GetGR(struct _Unwind_Context *context, int index);
|
||||
extern void _Unwind_SetGR(struct _Unwind_Context *context, int index,
|
||||
uintptr_t new_value);
|
||||
extern uintptr_t _Unwind_GetIP(struct _Unwind_Context *context);
|
||||
extern void _Unwind_SetIP(struct _Unwind_Context *, uintptr_t new_value);
|
||||
|
||||
#else // _LIBUNWIND_ARM_EHABI
|
||||
|
||||
#if defined(_LIBUNWIND_UNWIND_LEVEL1_EXTERNAL_LINKAGE)
|
||||
#define _LIBUNWIND_EXPORT_UNWIND_LEVEL1 extern
|
||||
#else
|
||||
#define _LIBUNWIND_EXPORT_UNWIND_LEVEL1 static __inline__
|
||||
#endif
|
||||
|
||||
// These are de facto helper functions for ARM, which delegate the function
|
||||
// calls to _Unwind_VRS_Get/Set(). These are not a part of ARM EHABI
|
||||
// specification, thus these function MUST be inlined. Please don't replace
|
||||
// these with the "extern" function declaration; otherwise, the program
|
||||
// including this <unwind.h> header won't be ABI compatible and will result in
|
||||
// link error when we are linking the program with libgcc.
|
||||
|
||||
_LIBUNWIND_EXPORT_UNWIND_LEVEL1
|
||||
uintptr_t _Unwind_GetGR(struct _Unwind_Context *context, int index) {
|
||||
uintptr_t value = 0;
|
||||
_Unwind_VRS_Get(context, _UVRSC_CORE, (uint32_t)index, _UVRSD_UINT32, &value);
|
||||
return value;
|
||||
}
|
||||
|
||||
_LIBUNWIND_EXPORT_UNWIND_LEVEL1
|
||||
void _Unwind_SetGR(struct _Unwind_Context *context, int index,
|
||||
uintptr_t value) {
|
||||
_Unwind_VRS_Set(context, _UVRSC_CORE, (uint32_t)index, _UVRSD_UINT32, &value);
|
||||
}
|
||||
|
||||
_LIBUNWIND_EXPORT_UNWIND_LEVEL1
|
||||
uintptr_t _Unwind_GetIP(struct _Unwind_Context *context) {
|
||||
// remove the thumb-bit before returning
|
||||
return _Unwind_GetGR(context, 15) & (~(uintptr_t)0x1);
|
||||
}
|
||||
|
||||
_LIBUNWIND_EXPORT_UNWIND_LEVEL1
|
||||
void _Unwind_SetIP(struct _Unwind_Context *context, uintptr_t value) {
|
||||
uintptr_t thumb_bit = _Unwind_GetGR(context, 15) & ((uintptr_t)0x1);
|
||||
_Unwind_SetGR(context, 15, value | thumb_bit);
|
||||
}
|
||||
#endif // _LIBUNWIND_ARM_EHABI
|
||||
|
||||
extern uintptr_t _Unwind_GetRegionStart(struct _Unwind_Context *context);
|
||||
extern uintptr_t
|
||||
_Unwind_GetLanguageSpecificData(struct _Unwind_Context *context);
|
||||
|
@ -12,6 +12,13 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// ARM EHABI does not specify _Unwind_{Get,Set}{GR,IP}(). Thus, we are
|
||||
// defining inline functions to delegate the function calls to
|
||||
// _Unwind_VRS_{Get,Set}(). However, some applications might declare the
|
||||
// function protetype directly (instead of including <unwind.h>), thus we need
|
||||
// to export these functions from libunwind.so as well.
|
||||
#define _LIBUNWIND_UNWIND_LEVEL1_EXTERNAL_LINKAGE 1
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
@ -496,39 +503,4 @@ _LIBUNWIND_EXPORT void _Unwind_SetIP(struct _Unwind_Context *context,
|
||||
unw_set_reg(cursor, UNW_REG_IP, value);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
_LIBUNWIND_EXPORT uintptr_t
|
||||
_Unwind_GetGR(struct _Unwind_Context *context, int index) {
|
||||
uintptr_t value = 0;
|
||||
_Unwind_VRS_Get(context, _UVRSC_CORE, (uint32_t)index, _UVRSD_UINT32, &value);
|
||||
_LIBUNWIND_TRACE_API("_Unwind_GetGR(context=%p, reg=%d) => 0x%" PRIx64 "\n",
|
||||
(void *)context, index, (uint64_t)value);
|
||||
return value;
|
||||
}
|
||||
|
||||
_LIBUNWIND_EXPORT void _Unwind_SetGR(struct _Unwind_Context *context, int index,
|
||||
uintptr_t value) {
|
||||
_LIBUNWIND_TRACE_API("_Unwind_SetGR(context=%p, reg=%d, value=0x%0"PRIx64")\n",
|
||||
(void *)context, index, (uint64_t)value);
|
||||
_Unwind_VRS_Set(context, _UVRSC_CORE, (uint32_t)index, _UVRSD_UINT32, &value);
|
||||
}
|
||||
|
||||
_LIBUNWIND_EXPORT uintptr_t _Unwind_GetIP(struct _Unwind_Context *context) {
|
||||
// remove the thumb-bit before returning
|
||||
uintptr_t value = _Unwind_GetGR(context, 15) & (~(uintptr_t)0x1);
|
||||
_LIBUNWIND_TRACE_API("_Unwind_GetIP(context=%p) => 0x%" PRIx64 "\n",
|
||||
(void *)context, (uint64_t)value);
|
||||
return value;
|
||||
}
|
||||
|
||||
_LIBUNWIND_EXPORT void _Unwind_SetIP(struct _Unwind_Context *context,
|
||||
uintptr_t value) {
|
||||
_LIBUNWIND_TRACE_API("_Unwind_SetIP(context=%p, value=0x%0" PRIx64 ")\n",
|
||||
(void *)context, (uint64_t)value);
|
||||
uintptr_t thumb_bit = _Unwind_GetGR(context, 15) & ((uintptr_t)0x1);
|
||||
_Unwind_SetGR(context, 15, value | thumb_bit);
|
||||
}
|
||||
|
||||
#endif // !_LIBUNWIND_ARM_EHABI
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user