<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/60599>60599</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[lld][ELF] Memory region overflow reported before merging .ARM.exidx sections
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
fdischner
</td>
</tr>
</table>
<pre>
When compiling only C sources, clang will generate a cantunwind .ARM.exidx section for each function and these will all be merged to a single entry in the final binary. However, lld will initially use the sum of all input sections when calculating the output section size. This may lead to a memory region overflow error even if the output section would fit after merging.
The issue seems to manifest here:
https://github.com/llvm/llvm-project/blob/981218e0f88c78fbf83e45abbae65d09b787f2c1/lld/ELF/Writer.cpp#L1614-L1621
Specifically, the call to `assignAddresses()` on line 1614 will check the sizes of the output sections against the memory region, but the exidx sections are not merged until the call to `finalizeSynthetic()` on line 1620.
Since we need to know the relative order of executable sections in order to perform the exidx merging, I think the only real solution is to somehow ignore the size of the .ARM.exidx output section on the first call to `assignAddresses()`. I've tested this by changing line 3371 to `size = 8` here:
https://github.com/llvm/llvm-project/blob/472393eff45002f60826f04fcc9261eeaa9f8691/lld/ELF/SyntheticSections.cpp#L3364-L3374
This essentially sets the size estimate to zero if no exidx sections are present and exactly 8 if one or more are present. I don't know whether this is an acceptable fix, because I'm not sure exactly what the initial size estimate is needed for or whether making it a fixed number has other unintended consequences. However, this change did allow me to link a project where lld previously reported an overflow of ~800 bytes, because there were over 100 cantunwind sections that all got merged into one.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJyslk1v4zYTxz-NfBmsIVG2Xg4-ZDeP8SyQvTQL7JkihxIbilRJyopz6GcvhrITJ82hBXpxEGs0b__fzJiHoHuLeMj2X7P9_YbPcXD-oKQOYrDoN52T58OvAS0IN07aaNuDs-YM3yC42QsMGfsGwnDbw6KNgR4teh4ROAhu42wXbSVs7377scVnLZ8hoIjaWVDOA3IxgJrt-g23EuKAAVdP3BjoEEb0PUqIDjgEbXuDgDb6M2hL1qC05QY6bbk_b-H_bsETekrKGLk60lZHzY05wxwwvRPmEZxKEbSd5nhNKsCSSuVGzIZHKpbM3RxvjCDoF9zCz0EHGPkZDPJLeiOOzp_BY09m7oReGbcAek-1ntCCVp85XNxsJCgdgauIPpWsbb_N8vssv1s_fw4IOoQZISCOgQKO3GqFIcKAHrPy7tZ8iHEK9B07ZuzY6zjM3Va4MWNHY07XP18m735HETN27IzrMnZsm4IVDeaqaUTdqE41Je72vOs4VnuZt13d1IqJIjmQGTv-74EC_PI6ot-KacpY-VBUxe7LQ1Gx4jalxwmFVlqQEqQPNYL-oVKyKl9RvJPSYwiEVZOxNqtycBaMtgjkdRVUDCieViH1CwaS8u9dDcB7rm2I6dk7aSh6N68P3kEZgHsE6-KVutlGbT5mmojTL_h4tnHAqMVnubL8nXyP2gqEBcHiCvOTdUty7JFIOyE4L9FTLfiMYo68M_iWl7aX59HBhF45P96kfwGG6voOcdB27U4aVI_cQHBmTqjpRE5wIw5uAd1b5_G1k9dG3kzrB1LddeZ8iP9EvC18z1h9QogYIhVOQ9OdQQzcUsZrt8qyLi6OUhpZeQ8NtfM_BHtXs7ItUandPs-ZqvKGVSrfKSFaVhWInLeqqdqPYL9q_HhR4sp4WVa7Lw9lWe_eT6kOQC2wl40TMIa3_mKIeqTlGB28oHe0D6z7jMHJIzlJOxGfuYjmDA2ZO0ukwEi63Rhu4TtIIruOK1rLgHEgXigjHYBb4ELgtHKl9HMaAhScdiKJNCbuw-zxNeAy8HVILhv0QxE6JJpRpl3u_GvMkT-RtrTPKBJKsPPYoYeBB3DJZLbaRrT0snA24B8zWoHh3QJPqSdSEKSWtK7dAmPqniHGOVxkpsge08afPJ60m0Mif3KeqOM3y9gp-LPJc-jOcb1d1x7E5GKhDzKGIs9vL9irOpGaQuT3b2tC2-hImXcjv5GHUrZlyzd4KKp637C2zevNcGgLyaq6K2RdlNjlTdlVbaNk3UiVd9W-2-gDy1mZs7zJd0XD6i3nNWvaXS2bSvKi7LJdjiPXZkusb53vN-k0HKp837Ybwzs0IZ10xiwu693IGKML7w9pPrq5D9kuNzrE8OYl6mjSbwEagf19tv9KU7C_hx-fX7bXDneoCMjLHvrk3IfN7M3hXw9vyjxk7Jgq-ysAAP__xBT0HA">