[libunwind] Convert x86, x86_64, arm64 register restore functions to C calling convention and name mangling

Currently, the assembly functions for restoring register state have
been direct implementations of the Registers_*::jumpto() method
(contrary to the functions for saving register state, which are
implementations of the extern C function __unw_getcontext). This has
included having the assembly function name match the C++ mangling of
that method name (and having the function match the C++ member
function calling convention). To simplify the interface of the assembly
implementations, make the functions have C calling conventions and
name mangling.

This fixes building the library in with a MSVC C++ ABI with clang-cl,
which uses a significantly different method name mangling scheme.
(The library might not be of much use as C++ exception unwinder in such
an environment, but the libunwind.h interface for stepwise unwinding
still is usable, as is the _Unwind_Backtrace function.)

Differential Revision: https://reviews.llvm.org/D86041
This commit is contained in:
Martin Storsjö 2020-08-16 15:12:55 +03:00
parent 642cb7865f
commit e524daa7e8
2 changed files with 15 additions and 14 deletions

View File

@ -39,6 +39,8 @@ enum {
};
#if defined(_LIBUNWIND_TARGET_I386)
class _LIBUNWIND_HIDDEN Registers_x86;
extern "C" void __libunwind_Registers_x86_jumpto(Registers_x86 *);
/// Registers_x86 holds the register state of a thread in a 32-bit intel
/// process.
class _LIBUNWIND_HIDDEN Registers_x86 {
@ -56,7 +58,7 @@ public:
v128 getVectorRegister(int num) const;
void setVectorRegister(int num, v128 value);
static const char *getRegisterName(int num);
void jumpto();
void jumpto() { __libunwind_Registers_x86_jumpto(this); }
static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86; }
static int getArch() { return REGISTERS_X86; }
@ -248,6 +250,8 @@ inline void Registers_x86::setVectorRegister(int, v128) {
#if defined(_LIBUNWIND_TARGET_X86_64)
/// Registers_x86_64 holds the register state of a thread in a 64-bit intel
/// process.
class _LIBUNWIND_HIDDEN Registers_x86_64;
extern "C" void __libunwind_Registers_x86_64_jumpto(Registers_x86_64 *);
class _LIBUNWIND_HIDDEN Registers_x86_64 {
public:
Registers_x86_64();
@ -263,7 +267,7 @@ public:
v128 getVectorRegister(int num) const;
void setVectorRegister(int num, v128 value);
static const char *getRegisterName(int num);
void jumpto();
void jumpto() { __libunwind_Registers_x86_64_jumpto(this); }
static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86_64; }
static int getArch() { return REGISTERS_X86_64; }
@ -1771,6 +1775,8 @@ inline const char *Registers_ppc64::getRegisterName(int regNum) {
#if defined(_LIBUNWIND_TARGET_AARCH64)
/// Registers_arm64 holds the register state of a thread in a 64-bit arm
/// process.
class _LIBUNWIND_HIDDEN Registers_arm64;
extern "C" void __libunwind_Registers_arm64_jumpto(Registers_arm64 *);
class _LIBUNWIND_HIDDEN Registers_arm64 {
public:
Registers_arm64();
@ -1786,7 +1792,7 @@ public:
v128 getVectorRegister(int num) const;
void setVectorRegister(int num, v128 value);
static const char *getRegisterName(int num);
void jumpto();
void jumpto() { __libunwind_Registers_arm64_jumpto(this); }
static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM64; }
static int getArch() { return REGISTERS_ARM64; }

View File

@ -13,14 +13,10 @@
#if !defined(__USING_SJLJ_EXCEPTIONS__)
#if defined(__i386__)
DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_x866jumptoEv)
DEFINE_LIBUNWIND_FUNCTION(__libunwind_Registers_x86_jumpto)
#
# void libunwind::Registers_x86::jumpto()
# extern "C" void __libunwind_Registers_x86_jumpto(Registers_x86 *);
#
#if defined(_WIN32)
# On windows, the 'this' pointer is passed in ecx instead of on the stack
movl %ecx, %eax
#else
# On entry:
# + +
# +-----------------------+
@ -30,7 +26,6 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_x866jumptoEv)
# +-----------------------+ <-- SP
# + +
movl 4(%esp), %eax
#endif
# set up eax and ret on new stack location
movl 28(%eax), %edx # edx holds new stack pointer
subl $8,%edx
@ -60,9 +55,9 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind13Registers_x866jumptoEv)
#elif defined(__x86_64__)
DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind16Registers_x86_646jumptoEv)
DEFINE_LIBUNWIND_FUNCTION(__libunwind_Registers_x86_64_jumpto)
#
# void libunwind::Registers_x86_64::jumpto()
# extern "C" void __libunwind_Registers_x86_64_jumpto(Registers_x86_64 *);
#
#if defined(_WIN64)
# On entry, thread_state pointer is in rcx; move it into rdi
@ -560,13 +555,13 @@ Lnovec:
#elif defined(__aarch64__)
//
// void libunwind::Registers_arm64::jumpto()
// extern "C" void __libunwind_Registers_arm64_jumpto(Registers_arm64 *);
//
// On entry:
// thread_state pointer is in x0
//
.p2align 2
DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_arm646jumptoEv)
DEFINE_LIBUNWIND_FUNCTION(__libunwind_Registers_arm64_jumpto)
// skip restore of x0,x1 for now
ldp x2, x3, [x0, #0x010]
ldp x4, x5, [x0, #0x020]