[llvm-branch-commits] [lld] ELF: Only rewrite non-preemptible IFUNCs to IPLT functions if a non-IRELATIVE relocation is needed. (PR #133531)
Peter Smith via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Thu Apr 10 09:38:31 PDT 2025
https://github.com/smithp35 commented:
How does this work in the non-PIE (PDE) case when we take the address of an ifunc and pass it to a function in a shared library, which then compares the argument with its own global address take of the ifunc?
For example:
shared lib
```
typedef void Fptr(void);
extern void ifn(void);
// take address of ifunc ifn defined in application
Fptr* ifp = &ifn;
// compare address of ifn we have calculated in ifp vs
// address calculated by application, passed in fp1.
int compare(Fptr* fp1) {
return fp1 == ifp;
}
```
App
```
typedef void Fptr(void);
extern int compare(Fptr* fp1);
int val = 0;
static void impl(void) { val = 42; }
static void *resolver(void) { return impl; }
__attribute__((ifunc("resolver"))) void *ifn();
extern Fptr* fp;
int main(void) {
return compare(fp);
}
// separate file so compiler is unaware ifn is an ifunc.
typedef void Fptr(void);
extern void ifn(void);
Fptr* fp = &ifn;
```
Right now in the application lld produces an iPLT entry for `ifn`, with `fp` pointing to the iPLT entry. The dynamic symbol table contains the address of the iPLT entry with type STT_FUNC . The shared library and the argument compare equal.
As I understand it, this patch will change `fp` to point directly to the result of the ifunc resolver. So unless we also change the value put into the dynamic symbol table we'll stop comparing equal.
I don't think there's a STT_FUNC symbol we can put in the dynamic symbol table that holds the result of the ifunc resolver. GNU ld, puts the address of the resolver function with a STT_GNU_IFUNC symbol type in the dynamic symbol table. If that causes the dynamic loader to call the resolver and replace the value with the result then that would work. I haven't had time to check what glibc does though.
I'll put some more general comments below. Didn't want to make this one too long.
https://github.com/llvm/llvm-project/pull/133531
More information about the llvm-branch-commits
mailing list