This is an archive of the discontinued LLVM Phabricator instance.

Handle flags such as -m32 when computing the prefix for programs/runtime libs
Changes PlannedPublic

Authored by arichardson on Apr 7 2021, 11:18 AM.

Details

Summary

I was trying to use -DLLVM_ENABLE_RUNTIMES=compiler-rt on FreeBSD and this
failed since the 32-bit build ended up linking against the 64-bit ASAN
runtime and linking with "/usr/local/bin/x86_64-unknown-freebsd12.2-ld".
Looking at the driver code shows that the triple used as a prefix for tools
and libaries is always the raw value passed to -target and is not affected
by flags such as -m32/-march/etc.

While the 64-bit linker can usually link 32-bit programs just fine, the real
problem here is that search paths for the compiler-rt builtins/sanitizer
runtimes use the raw target triple and we can therefore end up linking
against the 64-bit runtime instead of the 32-bit one. In my case the build
of compiler-rt failed because "--whole-archive" "....llvm-project-build/./lib/clang/13.0.0/lib/x86_64-unknown-freebsd12.2/libclang_rt.asan_cxx.a"
was being passed to the linker instead of using the 32-bit library that
can be found in ".../lib/clang/13.0.0/lib/i386-unknown-freebsd12.2/".

This commit uses computeTargetTriple() to update the triple used as a
prefix for tools such as the linker. If computeTargetTriple() results in
a different triple, we update the RawTargetTriple and now search for
i386-unknown-freebsd12.2-ld when -m32 is passed. It is important to note
that we do not normalize the triple passed to -target since adding
additional could result in an unexpected behaviour change. For example,
clang -target x86_64-freebsd13 should search for x86_64-freebsd13-ld
and not the normalized x86_64-unknown-freebsd13-ld and
clang -target x86_64-freebsd13 -m32 tries to find i386-unknown-freebsd13-ld.

Diff Detail

Event Timeline

arichardson created this revision.Apr 7 2021, 11:18 AM
arichardson requested review of this revision.Apr 7 2021, 11:18 AM
Herald added a project: Restricted Project. · View Herald TranscriptApr 7 2021, 11:18 AM
Herald added a subscriber: cfe-commits. · View Herald Transcript
joerg added a subscriber: joerg.Apr 7 2021, 2:12 PM

This sounds wrong. If you are using 'x86_64-freebsd' as triple and -m32, it should still call 'x86_64-freebsd-ld', but it is the responsibility of the driver to ensure that also the right set of linker flags are passed as well. Compare netbsd::Linker::ConstructJob for one way to handle this.

arichardson planned changes to this revision.Apr 7 2021, 2:38 PM

This sounds wrong. If you are using 'x86_64-freebsd' as triple and -m32, it should still call 'x86_64-freebsd-ld', but it is the responsibility of the driver to ensure that also the right set of linker flags are passed as well. Compare netbsd::Linker::ConstructJob for one way to handle this.

Good point. The real problem was that clang was passing the 64-bit asan runtime library to the linker, not so much that it tried to invoke the x86_64-prefixed linker. I'll see if I can limit this to the library paths.

arichardson retitled this revision from Handle flags such as -m32 when computing the triple prefix for programs to Handle flags such as -m32 when computing the prefix for programs/runtime libs.Apr 8 2021, 4:40 AM
arichardson edited the summary of this revision. (Show Details)
arichardson added a reviewer: joerg.

Add the raw triple prefix for programs (but prefer the adjusted triple) and always use the adjusted triple for libraries.
Should hopefully address the feedback from @joerg.

Also improve tests to check that we don't insert additional empty/"-unknown" triple components.

Drop chunk that is no longer necessary

  • Fix Windows path regex
phosek added inline comments.Apr 9 2021, 10:54 AM
clang/lib/Driver/Driver.cpp
1176–1210

I think this should be handled by each toolchain. For example Linux toolchain already has getMultiarchTriple which takes into account target handling on various existing platforms like Debian.

What I've been thinking of doing is to move that method to the ToolChain class as virtual so it could be overriden and customized by each toolchain, and then use it in getRuntimePath.