-
Notifications
You must be signed in to change notification settings - Fork 14.5k
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
--target
argument 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)