Skip to content

Commit

Permalink
[libunwind] Convert x86, x86_64, arm64 register restore functions to …
Browse files Browse the repository at this point in the history
…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
  • Loading branch information
mstorsjo committed Aug 26, 2020
1 parent 642cb78 commit e524daa
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 14 deletions.
12 changes: 9 additions & 3 deletions libunwind/src/Registers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -56,7 +58,7 @@ class _LIBUNWIND_HIDDEN Registers_x86 {
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; }

Expand Down Expand Up @@ -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();
Expand All @@ -263,7 +267,7 @@ class _LIBUNWIND_HIDDEN Registers_x86_64 {
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; }

Expand Down Expand Up @@ -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();
Expand All @@ -1786,7 +1792,7 @@ class _LIBUNWIND_HIDDEN Registers_arm64 {
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; }

Expand Down
17 changes: 6 additions & 11 deletions libunwind/src/UnwindRegistersRestore.S
Original file line number Diff line number Diff line change
Expand Up @@ -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:
# + +
# +-----------------------+
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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]
Expand Down

0 comments on commit e524daa

Please sign in to comment.