<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/54753>54753</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
"error: fixup value out of range" for aarch64-windows, for symbol references with a large offset
</td>
</tr>
<tr>
<th>Labels</th>
<td>
backend:AArch64,
platform:windows
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
mstorsjo
</td>
</tr>
</table>
<pre>
CC @efriedma-quic
In https://github.com/llvm/llvm-project/issues/51720 we fixed issues where relocations against temporary symbols could end up with a too large offset. This is an issue as the ADRP relocations can store a 21 bit immediate (+/- 1 MB) offset against the symbol it points at. For those cases, we inserted extra temp symbols for large sections, to allow relocations against a temporary symbol to use these extra symbols instead of using the start of the section and a large offset.
The same issue can crop up elsewhere too, in code with references to symbols with large offsets.
```c
#define MAX_MEM_HANDLES 0x10000
struct mem_entry {
void *ptr1, *ptr2;
};
//extern struct mem_entry mem_entries[];
static struct mem_entry mem_entries[MAX_MEM_HANDLES];
void *getPtr(void) {
return mem_entries + MAX_MEM_HANDLES;
}
```
```
$ bin/clang -target aarch64-windows -c aarch64-symbol-offset.c -O2
error: fixup value out of range
1 error generated.
```
```
$ bin/clang -target aarch64-windows -S -o - aarch64-symbol-offset.c -O2
[...]
getPtr: // @getPtr
adrp x0, mem_entries+1048576
add x0, x0, :lo12:mem_entries+1048576
ret
```
(In this reduced case, it only triggers when built with `-O2`, but in the original case, it also triggered without `-O2`.)
For references to symbols in the current object file, we could potentially try to rewrite references to use the extra symbols that we've emitted with 1 MB intervals, but that's not correct if the symbol isn't static (and such rewrites aren't necessarily correct e.g. if the symbol can be weak and overridden by another symbol at link time), and clearly doesn't work if the symbol isn't defined in the current object file.
Curiously, if uncommenting the other declaration of `mem_entries`, `extern struct mem_entry mem_entries[];`, it does generate this code instead:
```
getPtr: // @getPtr
adrp x8, mem_entries
add x8, x8, :lo12:mem_entries
add x0, x8, #256, lsl #12 // =1048576
ret
```
Therefore, it seems like the best solution would be to avoid forming address expressions in the form `symbol+offset`, if the offset is too large, and just add the offset as a separate operation instead. Where in the code is that decision taken, for how to form an address expression, deciding between an imediate symbol offset or a separate addition?
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJytV99v2zYQ_mvsF8KGTP_Mgx_spMUGLFuxFujeCko62Wwo0SOpOPnv9x0pJYqbphtWw5Al8e743d13x3Nuy8ft9bUYLTKqnKayVpO_W12IUXYzynbp-msjjiGc_Gi-G8n3-B50OLb5tLA1Hoy5738mJ2e_UhHwqL1vyeNmOVvLTJxJVPqBSpHei_ORHAlHxhYqaNt4oQ5KNz6IQPXJOuUehX-sc2u8KGxrSkFNKdqTOGNroUSwVhjlDiRsVXkKU_HpqD2sC9WkPYTyIhxJ7G7-_PBiowISPlhsr4SciVwHoeuaSq0CiZHcjOQesCdiJm5xc9Vt8IwPNhMyAc2T1U3ApgDw3josWk_YwbPr1-w1dMgFOE4Pwano3ZNjFTSSEx5BY3CsFKxQxtjzq9FR38SH5VtsCly4pl36DViFVAkXIKKbQwIflAv8Kj6kjRG1ErZfRHTIgE8sqmrqQsshLJw9cULIeErZRE4Yv8aaLSllylGFpaZAyoGzxxWXhpv5frdVlr5F9yznJVW6IXG7--vL7bvbL7_sfr_57d1HIbKHWYZPkvPBtUUQNdVfqAmIzWi9TytC3FtdIq-7U3Azxpdu5Wi-70m-vsHD0N3EcsSSHHPlwnZ_p5Hk5X60fNZGaANq5wcaF64MDaRrj_hA4UNwoCS_YCoOvHIUWoAbWIbG_jJMz4bh48sIv_D34qVcoCwahKAwCqyZBE4VyKdccVwtJmfdlPbsxaR4epUyO-moU4jJH7KLLjlnHToH1z_ocq8MCGTbyEAH65TEZiIKigM15FCJ5SUjfgbej2JixeQt0J3B5X46nXJi4mOXB_jwo08iDnfTTqfLVvqo0p349yFjHg5JIfezbLFZrleXCqV4VkhXwDB2Bvru_oUBsOStMMoNWnvgxumobAt0KW5dsYiRn8Y8Clg_HMjFht2IvNUmpOqFKQ7XKmLKkU7dxIZioaAbZYaWlPG2t4Q9WJ8J8GRiCm4PcXEnfb1xdJsUrcMaIOZ82oBZhrp2m86Kkw1Y1mij7MEjW3B0djrQhd2ucV60zXBU8BIm1_dYqnUIHep4JgAE-gJ47HvXWR7CXjQ2AAGwAZSuXhwVHvRcB9F1CESeO65vi2OPDD0euKJQQ4DnldOA35uj6WF6YZO7cI4-S-ou9m97jxLSZcmJesQbC1nXC8Mjo5s7EXRNHG5AZ53CkHLYprTUITxbd_cd8KkVl29k4cWhcd06bVtvHiMNcAQ1GBhqTkx3EiWAJaFqXTznuCeAD0NiJ4Lh5z9146QF6rFfTz0lUT0eTt3JyBPNa_Xx0yt-c1nxr9d5FEvX1-v8rfaQ1ORcLld8Z7zhp5l8Be385nvtIol9v2d84qMeg0tf256o9qDWXSqknDCkeGvamM5zrMac4kwTTzVo1px-QHfgOArvxL9xxuloxSKc8EQ-dLbUn_ucJmZ2Q5n2z5NgT-mvLc9JCM1ADrMgyptOKtLAnqjjW0eDqfgcJ5ie2JEhXR8APTXjE0HdcX1ex7HtiPkMTkWsKMNv3WFBVi3Z25zCmaiJs2k_aXa11QGEyQFAmNOMbzR_Py638_JqfqXGQQdD25GUPz5RpYwgL86_Hnu386ATdkP1cCIbt85s_8fUv1gv5-PjdlbJJc2zrFiWajZflYssW-RFUVVys8qrrBoblWOC3HLpSpmrAjHmqtztInS8S6SWJ6MCRxtrT-5IVPtYb2UmZbbIlqD01Xw2lfPqarnZLNBiZZmrGf-1qZU2U8Y6te4wdtsIO28PHotGe8yfT4sK6Ts0RNvUTcaqxWnltjX_ZfBf7Ti6uI3-_QPsyzVW">