<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>