[PATCH] D112349: [Verifier] Add verification logic for GlobalIFuncs
Fangrui Song via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Thu Nov 4 15:35:57 PDT 2021
MaskRay added a comment.
Sorry for being late to the party. Itay's explanation is correct to me.
I don't know much about multiversioned functions. My reply below if for ifunc.
- On ELF, an alias is just a symbol sharing st_shndx/st_value with another symbol. It is not by name. The target symbol can be overridden (say STB_WEAK overridden by STB_GLOBAL) while the alias itself remains unchanged.
- GNU indirect function is an ELF specific feature. Mach-O has a similar feature `N_SYMBOL_RESOLVER` but it is not modeled by an LLVM IR construct.
- While an assembler can create an "undefined ifunc" (`{st_shndx=0, st_info=STB_GLOBAL<<4 | STT_GNU_IFUNC}`), it is no different from a regular undefined symbol (`{st_shndx=0, st_info=STB_GLOBAL<<4 | STT_NOTYPE}`). You can check that the linker just ignore the STT_GNU_IFUNC type when replacing it with a definition. [1]
- For the GNU function attribute `__attribute__((ifunc(...)))`, GCC requires that the target is defined. The LLVM IR construct models the C/C++ syntax, so it makes sense to enforce the same requirement.
[1]:
echo '.type foo, @gnu_indirect_function' > a.s
echo '.globl foo; .type foo, @function; foo: ret' > b.s
gcc -c a.s b.s
ld a.o b.o
readelf -Ws a.out
> ... If no translation unit in the EXE/DSO had an ifunc with the same name and a defined resolver, you'd end up with a peculiar undefined symbol of type ifunc in the EXE/DSO (same as the .o).
This is the ld.lld behavior.
GNU ld appears to leave a STT_FUNC undefined symbol. The idea may be that when cross-DSO, STT_GNU_IFUNC loses meaning.
In this case using "undefined ifunc" in the first place is a user error.
---
GNU indirect functions are largely under-specified. glibc implemented it and FreeBSD adopted it.
Few years ago, glibc folks wrote https://sourceware.org/glibc/wiki/GNU_IFUNC to specify some behaviors they expected to work.
You can see
> Requirement (a): Resolver must be defined in the same translation unit as the implementations.
An undefined STT_GNU_IFUNC violates this requirement.
The second requirement says
> Requirement (b): Cannot be weakly defined functions.
It mostly wants to warn you that STB_GLOBAL overriding STB_WEAK can have weird behaviors, so users should move away that.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D112349/new/
https://reviews.llvm.org/D112349
More information about the llvm-commits
mailing list