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

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to