<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/99660>99660</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
IFunc is not working properly when RISC-V relaxations are enabled
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
sc-clulzze
</td>
</tr>
</table>
<pre>
**Example:**
```
#include <stdio.h>
#include <stdlib.h>
extern void foo();
void foo1() { printf("impl1\n"); }
void foo2() { printf("impl2\n"); }
int cpu_has_rvv(void) { return 0; }
void foo() __attribute__((ifunc ("resolve_foo")));
static void *resolve_foo(void) {
return cpu_has_rvv() ? foo2 : foo1;
}
int main() {
foo();
return 0;
}
```
This test is crashing when compiled with: `clang --target=riscv64-unknown-linux-gnu -fuse-ld=lld test.c`. The same test compiled with `-Wl,--no-relax` or using GNU LD prints "impl1" as expected.
**Investigation:**
The reason of crash is incorrect address of resolve_foo in .rela.dyn. The address of resolve_foo after relaxation is 0x185a (in my case), while the address in R_RISCV_IRELATIVE relocation is 0x1862 (the old resolve_foo adress before relaxation). The dynamic linker enters resolve_foo function at the middle of its body and that's why it crashes later.
```
llvm-objdump -d a.out
...
000000000000185a <resolve_foo>:
185a: 1101 addi sp,sp,-32
185c: ec06 sd ra,24(sp)
185e: e822 sd s0,16(sp)
1860: 1000 addi s0,sp,32
1862: fe7ff0ef jal 1848 <cpu_has_rvv>
...
```
```
llvm-objdump -R a.out
0000000000003b18 R_RISCV_IRELATIVE *ABS*+0x0000000000001862
```
After looking into handleNonPreemptibleIfunc function I noticed that we allocate and store a copy of symbol which represents foo ifunc. This happens before relaxation so the address of foo inside dynamic relocs vector is not being updated.
I couldn't come up with the proper fix. I have several ideas, but everything looks bad, so I will appreciate any help.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJx8Vt2OozwSfRrnpgQCkxBykYt0unsV6dNo1TM7exkZuwiecWxkm_zM069s9w_pTQ-KaIGpU1XH55SbOScPGnFNFg9k8Thjo--NXTuecTWqP39w1hpxXRO6IXTzdGHHQSGpNumZFI-k2JC6eP2lR1pJzdUoEEi1dV5Ik_ekevpiVcl2uhzvePFoNZyMFNAZQ2hD6IpUD9Nv3hbLtApk-QCDldp38QWVx0GVZLHVhNIUDWT5eBtL_xJLv4hNd6k98GHc98zt7elEaBMw37As-tFqKO4E3vYE-z3z3sp29Ljfx3eN7EbNIRVi0Rl1wn0MiKWk3y0VzjMveaKL0M1N0LSu9DW8lXdbf_ymeo60AKk2idv3RP_f_pFJ_cHfGzbc2bApH5_hbrXzo5cOPDoP0gG3zPVSH-DcowZujoNUKOAsfR_qI3XBFdMHyDLP7AE9qR6tdPxUz7NR_9bmrDMl9XjJDnqErBsdZkqQ6lEpEXPknNRFDj96BMeOmPLepAk5sv8qQrdZpk1mUbELqQswFkYXKvvXt__AP49JOw7eVUcpMAd4GZB7FPmUuWScnT6h8_LAvDT6k51CPRaZMxpMl0gIbEjNjbXIPTAhLDoXVidbDVJDHirMxVWnrr74kHUeLcRmYv6AXlzKZsGC6qSG4xU4cxi1toVzLxWCn-BJDS_7l9337c_97uXpn82P3c-ngGf4DV5NA14INErcVpBwWuyMxUklhK5S5eKq2VFyUFL_RguoPVp3AxFMEpMxH2s7SiEUhlaldxBmFjAtwPfME7p0cO6vIH2iEx0o5tHmdzWo1OmYmfaXGI8DZAJYbkaflvL8NaSYXIm4aju1XfUUNvXdEuGTINl0lWVRBi5leHADodt4yyp6E8E_IpAXNdy5nADLCN3SOaFNAFndIOAEoaH0CwRXELot63sIdTGpuiiKewjvjRRvjbz3ESTwAdDhsusK7D4D_GIqJWjmTeBxOpbejoV34j-fNX_bupfp1k13rGrL5o6CCd1sHr5HKz4Ul9strundhJtoJWXM7zANpPYGeqaFwm9G_9siHgcvW4W7ONLfJbsDbbzkmOQJZwSmonkwatb54AoG3AzXIGh3PbZGBR_yHiwOFh2GcRNNH0CDZ6SDng0D6ju2Amdu_Gu6FKudFB9eiwZ2cELujQ0e1sZDi6GxcRDs8yDbATejEprQZZyaCOOQhmZINVgzoIVOXnLYQc9OCA5PaJkCKZC5MFja0UN4d_VxygcWHbRMhDVnYAdnqRSwYbDIZSLnCj2qIZ-JdSVW1YrNcF0uaTkv5lWzmPXrpuWrZdGIrl229byp2Lziy3K-6qp22WCBM7mmBZ0Xy3JVLhZVschZV9arsunq1UKwctGReYFHJlUetJQbe5hJ50Zcr1Z1XcwUa1G5-L8SpRrPEBfD0bx4nNl11F87HhyZF0o67z5QvPQK17vnIIRXbs_GRtkkrtQ1nXNBldnPye45YBYBNWsVitlo1br3fnDx1Hgm9PkgfT-2OTdHQp9Dvtc_2WDNL-Se0OdYpSP0OXVxWtP_BQAA__9yAPt5">