Skip to content
This repository has been archived by the owner on Apr 23, 2020. It is now read-only.

Commit

Permalink
X86: swap EBP, ESP on !APPLE
Browse files Browse the repository at this point in the history
Restore the `libunwind.h` enumeration values back to the inverted
values.  This diverges from the DWARF definition of the register values.
However, this allows our header to be compatible with other unwind
implementations (e.g. HP, GNU Savannah, GCC).

The register IDs are only swapped in the header and need to be unswapped
when accessing the unwind register file.  The flipped EBP and ESP only
applies on non-Apple x86 targets.

When optimizations were enabled, EBP and ESP would no longer be
equivalent.  As a result, the incorrect access on Linux would manifest
as a failure to unwind the stack.  We can now unwind the stack with and
without FPO on Linux x86.

Resolves PR30879!

git-svn-id: https://llvm.org/svn/llvm-project/libunwind/trunk@292723 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
compnerd committed Jan 21, 2017
1 parent e1d4b2e commit aa805e4
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 5 deletions.
5 changes: 0 additions & 5 deletions include/libunwind.h
Original file line number Diff line number Diff line change
Expand Up @@ -165,13 +165,8 @@ enum {
UNW_X86_ECX = 1,
UNW_X86_EDX = 2,
UNW_X86_EBX = 3,
#if defined(__CloudABI__) || defined(__FreeBSD__)
UNW_X86_ESP = 4,
UNW_X86_EBP = 5,
#else
UNW_X86_EBP = 4,
UNW_X86_ESP = 5,
#endif
UNW_X86_ESI = 6,
UNW_X86_EDI = 7
};
Expand Down
16 changes: 16 additions & 0 deletions src/Registers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,9 +122,17 @@ inline uint32_t Registers_x86::getRegister(int regNum) const {
return _registers.__edx;
case UNW_X86_EBX:
return _registers.__ebx;
#if !defined(__APPLE__)
case UNW_X86_ESP:
#else
case UNW_X86_EBP:
#endif
return _registers.__ebp;
#if !defined(__APPLE__)
case UNW_X86_EBP:
#else
case UNW_X86_ESP:
#endif
return _registers.__esp;
case UNW_X86_ESI:
return _registers.__esi;
Expand Down Expand Up @@ -154,10 +162,18 @@ inline void Registers_x86::setRegister(int regNum, uint32_t value) {
case UNW_X86_EBX:
_registers.__ebx = value;
return;
#if !defined(__APPLE__)
case UNW_X86_ESP:
#else
case UNW_X86_EBP:
#endif
_registers.__ebp = value;
return;
#if !defined(__APPLE__)
case UNW_X86_EBP:
#else
case UNW_X86_ESP:
#endif
_registers.__esp = value;
return;
case UNW_X86_ESI:
Expand Down

0 comments on commit aa805e4

Please sign in to comment.