[PATCH] D112349: [Verifier] Add verification logic for GlobalIFuncs

Fangrui Song via Phabricator via cfe-commits cfe-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 cfe-commits mailing list