<html>
<head>
<base href="https://bugs.llvm.org/">
</head>
<body><table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Bug ID</th>
<td><a class="bz_bug_link
bz_status_NEW "
title="NEW - Exception unwinding fails with shadow call stack"
href="https://bugs.llvm.org/show_bug.cgi?id=45875">45875</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>Exception unwinding fails with shadow call stack
</td>
</tr>
<tr>
<th>Product</th>
<td>Runtime Libraries
</td>
</tr>
<tr>
<th>Version</th>
<td>trunk
</td>
</tr>
<tr>
<th>Hardware</th>
<td>Other
</td>
</tr>
<tr>
<th>OS</th>
<td>other
</td>
</tr>
<tr>
<th>Status</th>
<td>NEW
</td>
</tr>
<tr>
<th>Severity</th>
<td>normal
</td>
</tr>
<tr>
<th>Priority</th>
<td>P
</td>
</tr>
<tr>
<th>Component</th>
<td>libunwind
</td>
</tr>
<tr>
<th>Assignee</th>
<td>unassignedbugs@nondot.org
</td>
</tr>
<tr>
<th>Reporter</th>
<td>ambre@google.com
</td>
</tr>
<tr>
<th>CC</th>
<td>compnerd@compnerd.org, jgorbe@google.com, llvm-bugs@lists.llvm.org, saugustine@google.com
</td>
</tr></table>
<p>
<div>
<pre>With a version of libunwind built for aarch64-unknown-fuchsia (which enables
the shadow call stack by default), the unwinding information generated for
_Unwind_RaiseException does not adjust x18. This breaks exception handling: the
function that catches the exception returns to the wrong place.
Here's an example, using the version of llvm shipped in the fuchsia tree:
Source:
#include <iostream>
int main() {
void* x18;
try {
asm volatile("mov %0, x18" : "=r"(x18) : :);
std::cerr << "will throw, x18=" << x18 << std::endl;
throw "something";
} catch (...) {
asm volatile("mov %0, x18" : "=r"(x18) : :);
std::cerr << "caught, x18=" << x18 << std::endl;
}
return 0;
}
Actual output:
will throw, x18=0x779ed45010
caught, x18=0x779ed45018
<CRASH>
Expected output:
will throw, x18=0x779ed45010
caught, x18=0x779ed45010
Looking at the library, _Unwind_RaiseException starts with the shadow call
stack prolog:
0000000000000000 <_Unwind_RaiseException>:
0: 5e 86 00 f8 str x30, [x18], #8
4: fd 7b bd a9 stp x29, x30, [sp, #-48]!
but it is omitted by its unwind information. I'm not sure how to compile
libunwind for fuchsia myself, but the compiled version I used can be found
under lib/aarch64-unknown-fuchsia/c++/libc++.a in the archive here:
<a href="https://chrome-infra-packages.appspot.com/p/fuchsia/third_party/clang/linux-amd64/+/RJTCpB4rJ4IkRZuUWvaLtgjL6zz1HcitXQOIG47dvh8C">https://chrome-infra-packages.appspot.com/p/fuchsia/third_party/clang/linux-amd64/+/RJTCpB4rJ4IkRZuUWvaLtgjL6zz1HcitXQOIG47dvh8C</a>
This seems to be fixed by compiling UnwindLevel1.c with -fexceptions. I'm not
sure of what the difference should be between using -fexceptions or just
-funwind-tables, but it seems that the dwarf instruction to update x18 is not
emitted when a function is marked nounwind
(<a href="https://github.com/llvm/llvm-project/blob/2481f26ac3f228cc085d4d68ee72dadc07afa48f/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp#L2147">https://github.com/llvm/llvm-project/blob/2481f26ac3f228cc085d4d68ee72dadc07afa48f/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp#L2147</a>).</pre>
</div>
</p>
<hr>
<span>You are receiving this mail because:</span>
<ul>
<li>You are on the CC list for the bug.</li>
</ul>
</body>
</html>