This is an archive of the discontinued LLVM Phabricator instance.

[Driver] Pass --target2= to linker from baremetal toolchain
ClosedPublic

Authored by miyuki on Apr 28 2023, 9:25 AM.

Details

Summary

According to the GNU ld manual
https://sourceware.org/binutils/docs/ld/ARM.html#ARM the R_ARM_TARGET2
relocation (used in exception handling tables) is treated differently
depending on the target. By default, LLD treats R_ARM_TARGET2 as
R_ARM_GOT_PREL (--target2=got-rel), which is correct for Linux but not
for embedded targets.

This patch adds --target2=rel to linker options in the baremetal
toolchain driver so that on baremetal targets, R_ARM_TARGET2 is
treated as R_ARM_REL32. Such behavior is compatible with GNU ld and
unwinding libraries (e.g., libuwind).

Diff Detail

Event Timeline

miyuki created this revision.Apr 28 2023, 9:25 AM
Herald added a project: Restricted Project. · View Herald TranscriptApr 28 2023, 9:25 AM
miyuki requested review of this revision.Apr 28 2023, 9:25 AM
Herald added a project: Restricted Project. · View Herald TranscriptApr 28 2023, 9:25 AM
peter.smith accepted this revision.Apr 28 2023, 9:34 AM

LGTM. This is consistent with the target2 support that I added to LLD several years ago in https://reviews.llvm.org/D25684 will be good to give some time for other reviewers to add any comments/objections before committing.

Other references:

The latter states that ABS is the right value for bare-metal, but I think it ended up being implemented as REL for the GNU bare-metal personality routines.

This revision is now accepted and ready to land.Apr 28 2023, 9:34 AM
phosek accepted this revision.Apr 28 2023, 9:52 AM

LGTM

This revision was landed with ongoing or failed builds.Apr 28 2023, 10:31 AM
This revision was automatically updated to reflect the committed changes.
AlexYzhov added a subscriber: AlexYzhov.EditedSep 23 2023, 10:18 AM

Add command without backend wrapper destroys the compatibility to different linkers.
Some people will use gcc driver instead of ld/lld itself as linker, a "-Wl," prefix is needed in this situation.

i've met familiar issue that corrupts the link step:

/opt/homebrew/opt/llvm@17/bin/clang-17 -Wl,--verbose --verbose --target=arm-none-eabi -nostdlib -z noexecstack -fuse-ld=/opt/homebrew/bin/arm-none-eabi-gcc -mthread-model single -Wl,-mcpu=cortex-m7 -Wl,-mfloat-abi=hard -Wl,-mfpu=fpv5-sp-d16 -Wl,--specs=nano.specs -Wl,--specs=nosys.specs -Wl,-nostartfiles -Wl,-u -Wl,printf_float -Wl,-u -Wl,sprintf_float -Wl,-u -Wl,snprintf_float -Wl,-u -Wl,vsnprintf_float -Wl,-Xlinker -Wl,-EL -Wl,-Xlinker -Wl,--target2=rel -Wl,-Xlinker -Wl,--check-sections -Wl,-Xlinker -Wl,--gc-sections -Wl,-Xlinker -Wl,--print-memory-usage -Wl,-Xlinker -Wl,--reduce-memory-overheads -Wl,-Xlinker -Wl,--relax -Wl,-Xlinker -Wl,--no-undefined -Wl,-Xlinker -Wl,--unresolved-symbols=report-all -Wl,-Xlinker -Wl,--script -Wl,-Xlinker -Wl,repo/source/bsp/stm32h750/toolchain/clang/linker/STM32H750.ld -Wl,-Xlinker -Wl,-Map -Wl,-Xlinker -Wl,out/artpi/obj/firmware.map -Wl,-Lout/artpi/obj/repo/ -Wl,-Lout/artpi/obj/demo/ -Wl,-Xlinker -Wl,--whole-archive -Wl,-lrepo -Wl,-ldemo -lm -lgcc  -Wl,-Xlinker -Wl,--no-whole-archive -o out/artpi/obj/firmware.elf
Homebrew clang version 17.0.1
Target: arm-none-unknown-eabi
Thread model: single
InstalledDir: /opt/homebrew/opt/llvm@17/bin
 "/opt/homebrew/bin/arm-none-eabi-gcc" --verbose -z noexecstack -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-sp-d16 --specs=nano.specs --specs=nosys.specs -nostartfiles -u printf_float -u sprintf_float -u snprintf_float -u vsnprintf_float -Xlinker -EL -Xlinker --target2=rel -Xlinker --check-sections -Xlinker --gc-sections -Xlinker --print-memory-usage -Xlinker --reduce-memory-overheads -Xlinker --relax -Xlinker --no-undefined -Xlinker --unresolved-symbols=report-all -Xlinker --script -Xlinker repo/source/bsp/stm32h750/toolchain/clang/linker/STM32H750.ld -Xlinker -Map -Xlinker out/artpi/obj/firmware.map -Lout/artpi/obj/repo/ -Lout/artpi/obj/demo/ -Xlinker --whole-archive -lrepo -ldemo -lm -lgcc -Xlinker --no-whole-archive -Bstatic -EL -L/Library/Developer/CommandLineTools/SDKs/MacOSX13.sdk/lib -L/Library/Developer/CommandLineTools/SDKs/MacOSX13.sdk/lib -L/opt/homebrew/Cellar/llvm/17.0.1/lib/clang/17/lib/baremetal --target2=rel -o out/artpi/obj/firmware.elf
Using built-in specs.
Reading specs from /opt/homebrew/Cellar/arm-none-eabi-gcc/10-2020q4/bin/../lib/gcc/arm-none-eabi/10.2.1/../../../../arm-none-eabi/lib/nano.specs
rename spec link to nano_link
rename spec link_gcc_c_sequence to nano_link_gcc_c_sequence
rename spec cpp_unique_options to nano_cpp_unique_options
Reading specs from /opt/homebrew/Cellar/arm-none-eabi-gcc/10-2020q4/bin/../lib/gcc/arm-none-eabi/10.2.1/../../../../arm-none-eabi/lib/nosys.specs
rename spec link_gcc_c_sequence to nosys_link_gcc_c_sequence
COLLECT_GCC=/opt/homebrew/bin/arm-none-eabi-gcc
COLLECT_LTO_WRAPPER=/opt/homebrew/Cellar/arm-none-eabi-gcc/10-2020q4/bin/../lib/gcc/arm-none-eabi/10.2.1/lto-wrapper
arm-none-eabi-gcc: error: unrecognized command-line option '-EL'; did you mean '-E'?
arm-none-eabi-gcc: error: unrecognized command-line option '--target2=rel'; did you mean '--target-help'?
Target: arm-none-eabi
Configured with: /tmp/jenkins-GCC-10-pipeline-48_20201124_1606180639/src/gcc/configure --target=arm-none-eabi --prefix=/tmp/jenkins-GCC-10-pipeline-48_20201124_1606180639/install-native --libexecdir=/tmp/jenkins-GCC-10-pipeline-48_20201124_1606180639/install-native/lib --infodir=/tmp/jenkins-GCC-10-pipeline-48_20201124_1606180639/install-native/share/doc/gcc-arm-none-eabi/info --mandir=/tmp/jenkins-GCC-10-pipeline-48_20201124_1606180639/install-native/share/doc/gcc-arm-none-eabi/man --htmldir=/tmp/jenkins-GCC-10-pipeline-48_20201124_1606180639/install-native/share/doc/gcc-arm-none-eabi/html --pdfdir=/tmp/jenkins-GCC-10-pipeline-48_20201124_1606180639/install-native/share/doc/gcc-arm-none-eabi/pdf --enable-languages=c,c++ --enable-plugins --disable-decimal-float --disable-libffi --disable-libgomp --disable-libmudflap --disable-libquadmath --disable-libssp --disable-libstdcxx-pch --disable-nls --disable-shared --disable-threads --disable-tls --with-gnu-as --with-gnu-ld --with-newlib --with-headers=yes --with-python-dir=share/gcc-arm-none-eabi --with-sysroot=/tmp/jenkins-GCC-10-pipeline-48_20201124_1606180639/install-native/arm-none-eabi --build=x86_64-apple-darwin10 --host=x86_64-apple-darwin10 --with-gmp=/tmp/jenkins-GCC-10-pipeline-48_20201124_1606180639/build-native/host-libs/usr --with-mpfr=/tmp/jenkins-GCC-10-pipeline-48_20201124_1606180639/build-native/host-libs/usr --with-mpc=/tmp/jenkins-GCC-10-pipeline-48_20201124_1606180639/build-native/host-libs/usr --with-isl=/tmp/jenkins-GCC-10-pipeline-48_20201124_1606180639/build-native/host-libs/usr --with-libelf=/tmp/jenkins-GCC-10-pipeline-48_20201124_1606180639/build-native/host-libs/usr --with-host-libstdcxx='-static-libgcc -Wl,-lstdc++ -lm' --with-pkgversion='GNU Arm Embedded Toolchain 10-2020-q4-major' --with-multilib-list=rmprofile,aprofile
Thread model: single
Supported LTO compression algorithms: zlib
gcc version 10.2.1 20201103 (release) (GNU Arm Embedded Toolchain 10-2020-q4-major) 
clang-17: error: ld.lld command failed with exit code 1 (use -v to see invocation)