-
Notifications
You must be signed in to change notification settings - Fork 15.1k
Description
LLD's frontends are currently very faithful to the linkers they are based on. But that means the target-selection mechanisms they have are rather underpowered. I think would be good to have modern flags that would allow us to set the EM_* choice, ELFOSABI_* choice, and ELFKind independently (for valid combinations)
A good use for this would be better handling of the "OSABI" field. For example:
Problems
FreeBSD existing hacks
llvm-project/lld/ELF/Driver.cpp
Lines 174 to 177 in 9572388
| if (s.ends_with("_fbsd")) { | |
| s = s.drop_back(5); | |
| osabi = ELFOSABI_FREEBSD; | |
| } |
is an ad-hoc hack for FreeBSD. The corresponding code in Clang to use it is even uglier:
llvm-project/clang/lib/Driver/ToolChains/FreeBSD.cpp
Lines 174 to 218 in 9572388
| // Explicitly set the linker emulation for platforms that might not | |
| // be the default emulation for the linker. | |
| switch (Arch) { | |
| case llvm::Triple::x86: | |
| CmdArgs.push_back("-m"); | |
| CmdArgs.push_back("elf_i386_fbsd"); | |
| break; | |
| case llvm::Triple::ppc: | |
| CmdArgs.push_back("-m"); | |
| CmdArgs.push_back("elf32ppc_fbsd"); | |
| break; | |
| case llvm::Triple::ppcle: | |
| CmdArgs.push_back("-m"); | |
| // Use generic -- only usage is for freestanding. | |
| CmdArgs.push_back("elf32lppc"); | |
| break; | |
| case llvm::Triple::mips: | |
| CmdArgs.push_back("-m"); | |
| CmdArgs.push_back("elf32btsmip_fbsd"); | |
| break; | |
| case llvm::Triple::mipsel: | |
| CmdArgs.push_back("-m"); | |
| CmdArgs.push_back("elf32ltsmip_fbsd"); | |
| break; | |
| case llvm::Triple::mips64: | |
| CmdArgs.push_back("-m"); | |
| if (tools::mips::hasMipsAbiArg(Args, "n32")) | |
| CmdArgs.push_back("elf32btsmipn32_fbsd"); | |
| else | |
| CmdArgs.push_back("elf64btsmip_fbsd"); | |
| break; | |
| case llvm::Triple::mips64el: | |
| CmdArgs.push_back("-m"); | |
| if (tools::mips::hasMipsAbiArg(Args, "n32")) | |
| CmdArgs.push_back("elf32ltsmipn32_fbsd"); | |
| else | |
| CmdArgs.push_back("elf64ltsmip_fbsd"); | |
| break; | |
| case llvm::Triple::riscv64: | |
| CmdArgs.push_back("-m"); | |
| CmdArgs.push_back("elf64lriscv"); | |
| break; | |
| default: | |
| break; | |
| } |
If Clang could use "regular" code to transform the CPU into a -m flag, and then separately tell LLD that the ELFOSABI_* is ELFOSABI_FREEBSD, that would be much cleaner.
OpenBSD has similar needs
As discussed in #92675, we ought to have CI for OpenBSD, but OpenBSD has some outstanding downstream changes that need to be upstreamed before upstream-tool-produced binaries will work, and many of those changes today assume OpenBSD->OpenBSD native compilation and so are unfit to upstream as is
#97122 is the first such patch I've rebased. This is a somewhat borderline case, as there is already blanket handling to .openbsd.random regardless of the ELFOSABI_* in use. Still, "stealing names" from all ELF usages of LLD doesn't seem very elegant, even if the .openbsd.random case is grandfathered in --- I much rather start requiring ELFOSABI_OPENBSD with the .openbsd.random case deprecated with a warning. That said, if doing this would require a _obsd hack like FreeBSD's _fbsd, I can't help but think the medicine is as almost as bad is the disease.
Solutions
Proposal A: --target flag
Add a flag for "regular" LLVM triples --- like Clang's --target or LLVM's -mtriple --- so we have more expressive power. Those triples should be mostly possible to map to the choices above, and -m flags could still be used to fill in the gaps.
Advantages:
- "no new syntax"
- tools like Clang can just forward their
--targetargument as-is and hope for the best
Disadvantages:
LLVM triples can both say to much and too little
Proposal B: New greenfield flags
Add multiple new flags for specifying the these parts independently. Certainly ELFOSABI_ needs one. -m does the EM_ and ELFKind residual alright, perhaps, or perhaps they get fresh new flags too.
Advantages: No syntax vs semantics mismatch / friction / corner cases.
Disadvantage: Greenfield new flags for other tooling to have to learn about.
CC @brad0 because OpenBSD
C @mstorsjo because I am curious if Windows stuff has similar needs / not sure what to do about lld-link (clang-cl takes --target and many other GNU-style flags, but lld-link only takes /flag MS-style-flags)