The current rule is loose: !Sym.IsPreemptible || Expr == R_GOT.
When the symbol is non-preemptable, this allows absolute relocation
types with smaller numbers of bits, e.g. R_X86_64_{8,16,32}. They are
disallowed by ld.bfd and gold, e.g.
ld.bfd: a.o: relocation R_X86_64_8 against `.text' can not be used when making a shared object; recompile with -fPIC
This patch:
a) Add TargetInfo::SymbolicRel to represent relocation types that resolve to a
symbol value (e.g. R_AARCH_ABS64, R_386_32, R_X86_64_64).
As a side benefit, we currently (ab)use GotRel (R_*_GLOB_DAT) to resolve GOT slots that are link-time constants. Since we now use Target->SymbolRel to do the job, we can remove R_*_GLOB_DAT from relocateOne() for all targets. R_*_GLOB_DAT cannot be used as static relocation types.
b) Change the condition to !Sym.IsPreemptible && Type != Target->SymbolicRel || Expr == R_GOT.
Some tests are caught by the improved error checking (ld.bfd/gold also
issue errors on them). Many misuse .long where .quad should be used
instead.
I'm not sure that there is always just one relocation per Target that is a SymbolicRel. On Arm there are a few implementation defined relocations like R_ARM_TARGET1 that can be R_ARM_ABS32 or R_ARM_REL32 depending on the platform. I think that this needs to be a callback to Target so that more than one relocation can apply.