summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSaleem Abdulrasool <compnerd@compnerd.org>2017-01-21 16:22:59 +0000
committerSaleem Abdulrasool <compnerd@compnerd.org>2017-01-21 16:22:59 +0000
commitb64d3273a331e40bfbd9c76b7d40e45b92ea3217 (patch)
tree0bd409c6f929a9ab294fcd4a608a080f27c3cb76
parentc06f0cf88c7697fc015934a3629025934d5523e8 (diff)
downloadbcm5719-llvm-b64d3273a331e40bfbd9c76b7d40e45b92ea3217.tar.gz
bcm5719-llvm-b64d3273a331e40bfbd9c76b7d40e45b92ea3217.zip
X86: swap EBP, ESP on !APPLE
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! llvm-svn: 292723
-rw-r--r--libunwind/include/libunwind.h5
-rw-r--r--libunwind/src/Registers.hpp16
2 files changed, 16 insertions, 5 deletions
diff --git a/libunwind/include/libunwind.h b/libunwind/include/libunwind.h
index 9d72d48d206..fef72bfdc9e 100644
--- a/libunwind/include/libunwind.h
+++ b/libunwind/include/libunwind.h
@@ -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
};
diff --git a/libunwind/src/Registers.hpp b/libunwind/src/Registers.hpp
index 8066b808c63..ff57c6076fe 100644
--- a/libunwind/src/Registers.hpp
+++ b/libunwind/src/Registers.hpp
@@ -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;
@@ -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:
OpenPOWER on IntegriCloud