On Tue, Jun 2, 2020 at 12:25 PM Nathan Chancellor <natechancellor@xxxxxxxxx> wrote: > > Currently, the VDSO is being linked through $(CC). This does not match > how the rest of the kernel links objects, which is through the $(LD) > variable. > > When clang is built in a default configuration, it first attempts to use > the target triple's default linker, which is just ld. However, the user > can override this through the CLANG_DEFAULT_LINKER cmake define so that > clang uses another linker by default, such as LLVM's own linker, ld.lld. > This can be useful to get more optimized links across various different > projects. > > However, this is problematic for the s390 vDSO because ld.lld does not > have any s390 emulatiom support: > > https://github.com/llvm/llvm-project/blob/llvmorg-10.0.1-rc1/lld/ELF/Driver.cpp#L132-L150 > > Thus, if a user is using a toolchain with ld.lld as the default, they > will see an error, even if they have specified ld.bfd through the LD > make variable: > > $ make -j"$(nproc)" -s ARCH=s390 CROSS_COMPILE=s390x-linux-gnu- LLVM=1 \ > LD=s390x-linux-gnu-ld \ > defconfig arch/s390/kernel/vdso64/ > ld.lld: error: unknown emulation: elf64_s390 > clang-11: error: linker command failed with exit code 1 (use -v to see invocation) > > Normally, '-fuse-ld=bfd' could be used to get around this; however, this > can be fragile, depending on paths and variable naming. The cleaner > solution for the kernel is to take advantage of the fact that $(LD) can > be invoked directly, which bypasses the heuristics of $(CC) and respects > the user's choice. Similar changes have been done for ARM, ARM64, and > MIPS. > > Link: https://github.com/ClangBuiltLinux/linux/issues/1041 > Signed-off-by: Nathan Chancellor <natechancellor@xxxxxxxxx> Thanks, with this, I'm more confident that the linker flags don't change. Reviewed-by: Nick Desaulniers <ndesaulniers@xxxxxxxxxx> > --- > > v1 -> v2: > > * Add -fPIC per GCC's documentation, as pointed out by Nick. > > arch/s390/kernel/vdso64/Makefile | 10 ++++------ > 1 file changed, 4 insertions(+), 6 deletions(-) > > diff --git a/arch/s390/kernel/vdso64/Makefile b/arch/s390/kernel/vdso64/Makefile > index bec19e7e6e1c..67c14732c304 100644 > --- a/arch/s390/kernel/vdso64/Makefile > +++ b/arch/s390/kernel/vdso64/Makefile > @@ -18,8 +18,8 @@ KBUILD_AFLAGS_64 += -m64 -s > > KBUILD_CFLAGS_64 := $(filter-out -m64,$(KBUILD_CFLAGS)) > KBUILD_CFLAGS_64 += -m64 -fPIC -shared -fno-common -fno-builtin > -KBUILD_CFLAGS_64 += -nostdlib -Wl,-soname=linux-vdso64.so.1 \ > - -Wl,--hash-style=both > +ldflags-y := -fPIC -shared -nostdlib -soname=linux-vdso64.so.1 \ > + --hash-style=both -T > > $(targets:%=$(obj)/%.dbg): KBUILD_CFLAGS = $(KBUILD_CFLAGS_64) > $(targets:%=$(obj)/%.dbg): KBUILD_AFLAGS = $(KBUILD_AFLAGS_64) > @@ -37,8 +37,8 @@ KASAN_SANITIZE := n > $(obj)/vdso64_wrapper.o : $(obj)/vdso64.so > > # link rule for the .so file, .lds has to be first > -$(obj)/vdso64.so.dbg: $(src)/vdso64.lds $(obj-vdso64) FORCE > - $(call if_changed,vdso64ld) > +$(obj)/vdso64.so.dbg: $(obj)/vdso64.lds $(obj-vdso64) FORCE > + $(call if_changed,ld) > > # strip rule for the .so file > $(obj)/%.so: OBJCOPYFLAGS := -S > @@ -50,8 +50,6 @@ $(obj-vdso64): %.o: %.S FORCE > $(call if_changed_dep,vdso64as) > > # actual build commands > -quiet_cmd_vdso64ld = VDSO64L $@ > - cmd_vdso64ld = $(CC) $(c_flags) -Wl,-T $(filter %.lds %.o,$^) -o $@ > quiet_cmd_vdso64as = VDSO64A $@ > cmd_vdso64as = $(CC) $(a_flags) -c -o $@ $< > > > base-commit: e1750a3d9abbea2ece29cac8dc5a6f5bc19c1492 > -- > 2.27.0.rc2 > -- Thanks, ~Nick Desaulniers