[riscv] Workaround for undef-weak symbol relocations with clang+lld

When building with clang -mcmodel=medany and linking with ld.lld, we get
out-of-range relocation errors for undefined __start_<section> symbols
since 0 cannot be represented as a PC-relative offset). This is not a
problem with ld.bfd since ld.bfd rewrites the instructions to avoid the
out-of-range PC-relative relocation. For now, the simplest workaround is
to build with -fpie -mcmodel=medany (thus indirecting these symbols via
the GOT). This will be done automatically once clang includes
https://reviews.llvm.org/D107280.

Without this change I get the following linker errors:
ld.lld: error: dev/driver.c:21:(.text+0x1E): relocation R_RISCV_PCREL_HI20 out of range: -524295 is not in [-524288, 524287]; references __start_devices

See https://github.com/riscv-non-isa/riscv-elf-psabi-doc/issues/126 and
https://github.com/riscv-non-isa/riscv-elf-psabi-doc/pull/201.
This commit is contained in:
Alex Richardson
2021-12-09 04:05:29 -08:00
parent 69111c40f5
commit bf6ab93088

View File

@@ -224,6 +224,18 @@ ifeq ($(ARCH),riscv)
# TODO: This is no longer true as of LLVM 15, so should add a version check
ifeq ($(LINKER_TYPE),lld)
ARCH_COMPILEFLAGS += -mno-relax
# Work around out-of-range undef-weak relocations when building with clang and
# linking with ld.lld. This is not a problem with ld.bfd since ld.bfd rewrites
# the instructions to avoid the out-of-range PC-relative relocation
# See https://github.com/riscv-non-isa/riscv-elf-psabi-doc/issues/126 for more
# details. For now, the simplest workaround is to build with -fpie when using
# a version of clang that does not include https://reviews.llvm.org/D107280.
# TODO: Add a clang 17 version check now that the review has been merged.
ifeq ($(COMPILER_TYPE),clang)
# We also add the -fdirect-access-external-data flag is added to avoid the
# majority of the performance overhead caused by -fPIE.
ARCH_COMPILEFLAGS += -fPIE -fdirect-access-external-data
endif
endif
endif