x86-64 (and many other archs)
cat > b.s <<e
.long foo - . - 4
as b.s -o b.o
ld.bfd b.o -shared # relocation R_X86_64_PC32 against symbol `foo' can not be used when making a shared object; recompile with -fPIC
cat > a.s <<e
addi 9,9, (__kernel_datapage_offset - (.-4))@l
powerpc-linux-gnu-as a.s -o a.o
powerpc-linux-gnu-ld -shared a.o # no error
powerpc64le-linux-gnu-as a.s -o a.o
powerpc64le-linux-gnu-ld -shared a.o # no error
This is incorrect. STB_DEFAULT STV_DEFAULT __kernel_datapage_offset is preemptible in a shared object. If __kernel_datapage_offset binds to another component at runtime, the patched instruction will be wrong.
Many relocations should not use global symbols in shared libraries, but there is a lot of powerpc assembly out there that works well enough in the way it is used. I'm not inclined to break the powerpc/powerpc64 linux kernel without good reason..
Incidentally, using @l on a sequence that doesn't also have an instruction with @h or @ha is asking for trouble too: Relocation overflow won't be reported.