<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/112943>112943</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
Landing pad accesses corrupted register
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
purplesyringa
</td>
</tr>
</table>
<pre>
LLVM currently assumes that if a function preserves the value of a register, this register can be safely accessed from a landing pad even if the function unwinds.
For example (x86_64):
```cpp
#include <stdio.h>
__attribute__((ms_abi, noinline)) void f() { throw 1; }
struct Dropper {
int x;
~Dropper() { printf("Dropper{%d}\n", x); }
};
__attribute__((noinline)) void test(int arg) {
Dropper dropper{arg};
f();
}
int main() try { test(1); } catch (...) {
}
```
`f()` is marked as `ms_abi`, where `rdi` is callee-saved, so the value of `arg` can be read out from `rdi` after invoking `f()`. That's what LLVM does both if `f()` returns and in `test`'s cleanup pad.
Unfortunately, that's incorrect behavior. According to [the Itanium C++ ABI](https://itanium-cxx-abi.github.io/cxx-abi/abi-eh.html#landing), the landing pad can only rely on the registers that are *callee-saved by the base ABI*. For Linux, "base ABI" is the SysV ABI, where `rdi` is caller-saved, so the unwinding library is not required to restore `rdi`.
While LLVM's libunwind goes beyond the EH ABI requirements and restores `rdi`, libgcc indeed doesn't (which I'd argue is compliant with the standard). When compiled against libgcc, the above code produces `Dropper{random garbage}` instead of `Dropper{1}`.
---
I've tested this on clang 18.1.8 from the Arch repos, built against libgcc. It compiles the `test` function from above to
```
│ test(int)
1200 │ 53 push rbx
1201 │ 48 83 ec 20 sub rsp, 0x20
1205 │ 89 fe mov esi, edi
1207 │ e8 84 ff ff ff call f()
120c │ 48 89 c3 mov rbx, rax
120f │ 48 8d 3d ee 0d 00 00 lea rdi, [rel _IO_stdin_used+0x4]
1216 │ 31 c0 xor eax, eax
1218 │ e8 13 fe ff ff call printf@plt
121d │ 48 89 df mov rdi, rbx
1220 │ e8 5b fe ff ff call _Unwind_Resume@plt
1225 │ 66 66 2e 0f 1f 84 00 data16 cs nop word [rax+rax]
│ 00 00 00 00
```
which erroneously assumes `rsi` is retained rather than `rdi`, but it's the same bug anyway.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJx8Vl2Ps7oR_jXOzSgITAjkIhebzbvqSm9Vqe055zIyeAjuAZvaJh83_e3VGLIhebMHoaDY45lnnvmycE4dNeKWZTuW7Rdi8I2x236wfYvuapU-ikVp5HX78-fvf4dqsBa1b68gnBs6dOAb4UHVIKAedOWV0dBbdGhPYRPhJNoBwZCExaNyHi3j7-Ab5b4WoBIaSgQnaiTdVYXOoYTamg4EtEJLpY_QCwl4Qk32SPWXxUGflZYuYvGexW_j74exgBfR9S0C48WlWB_WK8Y3LH2bi7F1PL5V308rPFW6ageJwNJ356UyUcPSH_NTh4Pw3qpy8Hg4MF4wXnTuIEpFrmmjdKs0kjG-gZNREuogtAGW78A31pwhYekOWL6fq3XeDpWHvTV9j5aEx3UApT1cWPr1_3-TzExtb5X2ox1-2813jGeSrGTvmnFO8C6BhLntfP-l-Vv3Xjnl0XnGC8Im7HHCcUN4c0J-QSGZmSm4kXI3_sgG6e2E0pOP3l5H-karyd0NqISvGopyFEUPMO4ab2F-iv0NwjoG5aAT9k-UIBywdTwFdB0TaecGLdKqlWoSrkTbIi6dOKEkEWce852tY_J4Hd-y26KQYAY_pvVdl6ipBJQ-mT8pyx9QRfDvRnjGcwdnqrRQhdKgg9L4hgrh0QmLfrDagdASlKbNQBc5kTuoWhR66KmQHmrlN10b6wctPLbXsTono0pXxlqsPJTYiJMyNoK3qjI2FKQ3wLIdef3phVZDB--M7xjfwdvuk2V7xovG-95RzfEPxj_UKLasLpelKFV0VL4ZykgZxj-mNcY_RKmW2ESN71rG06n6Q-K9B4rn_YC4Nbq9gqXOYXQQuPWVqT0JCh1_mwcMymuQLIXDAJa_RUAt46fSw4UMMc7vm5wCTvL_urrfx6Xvc8L-khNjfyLIrSqtsFeS1caDxf8OyqIkJi06b-YKH0L0R6NaDOEPcWlVOSqFY0gGvBotg60ffyN8N80daj9mw6Te3fUTwFaVx6oCpSWiDImlGc891dK5UVUDn4znksp7wOCg6fpWCe3hrHwTDDovtBRWMr6J4I8GdRBSLRXSUSjt_GTlFj5RmhNCZSRCb40cqhHUvWdZoaXp4ChsKY5INUzsaudDAdWPwsm4_0DWcrmc_yUfThgaB1FNk8doqFqhj5AUURIVY0kSuDdbNWCxN47gloNq_ZMbEXz6m4tjUtyr7D6SxtEVPPXm5cC5dcHwsB-cbVas4LOmShk_ySQ8jmcy9GQpvHz6wTUAYMvL7HDydHhVQJECVsDjh8NuKOljXU_exxcez5RkT0qKDdT4AkFnTvRBF6YhSjXTkT_pwAKKFdT19H49VEhwnxB3BdULTzZQ_ULGBIJo4O9gxZyN-oUOCakERIglxDG9ANCiCDpkcIRlO4stHD7_caBLgT4Mjop8F19WLNvf7N7NJOsnM2kCVfyCr4uxgQoRoOIcalL8yleSEu2v-ZruAKu4b_1Mi3xJmqy_I210-CGF-HP-YQFZ-T2Sw2-hPR3-iXRPfEbEn3NpvaaXI8Q1JDXlxBgCKbxI1lBRu-zhbKwMcSCqwm-2_6aM6BkDGd6_uAWMfQ6tNRrN4GZ3W-qU7tbaLXqhNEqwwjdoabLox15aDh7UODZDXxQdQjkcQejrWVyjhdymcpNuxAK3Sc43PE9jni2abZLLvFzVVZqs1nlRx1mdl3GWppt0XcbxplioLY_5KomTIsnTPM4iHmd5VuSreFVsCrEp2SrGTqg2attTFxl7XCjnBtwmCd-s0kUrSmxduOJzrvEMYZeug9l-Ybd0aFkOR8dWcaucd3c1XvkWtz9n83a6m9MksHboqaHepu1isO32cd5P870yHeMfpHX6LHtr_oOVpysBYXGMf0xgT1v-_wAAAP__5U-gBQ">