With -fno-plt, global value references can use GOTPCREL and RIP must be used.
A simple example that breaks with -fno-plt:
extern "C"
{
attribute((weak)) int weakfunc();
int fp_weakfunc() {
if (&weakfunc) return 1; return 0;
}
}
$ clang -O2 -fno-plt -S file.cc
$ cat file.s
...
fp_weakfunc: # @fp_weakfunc
.cfi_startproc
%bb.0:
xorl %eax, %eax
cmpq $0, weakfunc@GOTPCREL
...
That's a GOTPCREL reference without %rip. This will force the linker to only patch it with the offset in the GOT and will get the exact opposite program behavior at run-time. This patch fixes it.