[llvm-objcopy] Support full list of bfd targets that lld uses.
Summary:
This change takes the full list of bfd targets that lld supports (see `ScriptParser.cpp`), including generic handling for `*-freebsd` targets (which uses the same settings but with a FreeBSD OSABI). In particular this adds mips support for `--output-target` (but not yet via `--binary-architecture`).
lld and llvm-objcopy use their own different custom data structures, so I'd prefer to check this in as-is (add support directly in llvm-objcopy, including all the test coverage) and do a separate NFC patch(s) that consolidate the two by putting this mapping into libobject.
See [[ https://bugs.llvm.org/show_bug.cgi?id=41462 | PR41462 ]].
Reviewers: jhenderson, jakehehrlich, espindola, alexshap, arichardson
Reviewed By: arichardson
Subscribers: fedor.sergeev, emaste, sdardis, krytarowski, atanasyan, llvm-commits, MaskRay, arichardson
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D60773
llvm-svn: 358562
diff --git a/llvm/tools/llvm-objcopy/CopyConfig.cpp b/llvm/tools/llvm-objcopy/CopyConfig.cpp
index e2d3d45..1e6aa40 100644
--- a/llvm/tools/llvm-objcopy/CopyConfig.cpp
+++ b/llvm/tools/llvm-objcopy/CopyConfig.cpp
@@ -253,14 +253,14 @@
}
static const StringMap<MachineInfo> ArchMap{
- // Name, {EMachine, OS/ABI, 64bit, LittleEndian}
- {"aarch64", {ELF::EM_AARCH64, ELF::ELFOSABI_NONE, true, true}},
- {"arm", {ELF::EM_ARM, ELF::ELFOSABI_NONE, false, true}},
- {"i386", {ELF::EM_386, ELF::ELFOSABI_NONE, false, true}},
- {"i386:x86-64", {ELF::EM_X86_64, ELF::ELFOSABI_NONE, true, true}},
- {"powerpc:common64", {ELF::EM_PPC64, ELF::ELFOSABI_NONE, true, true}},
- {"sparc", {ELF::EM_SPARC, ELF::ELFOSABI_NONE, false, true}},
- {"x86-64", {ELF::EM_X86_64, ELF::ELFOSABI_NONE, true, true}},
+ // Name, {EMachine, 64bit, LittleEndian}
+ {"aarch64", {ELF::EM_AARCH64, true, true}},
+ {"arm", {ELF::EM_ARM, false, true}},
+ {"i386", {ELF::EM_386, false, true}},
+ {"i386:x86-64", {ELF::EM_X86_64, true, true}},
+ {"powerpc:common64", {ELF::EM_PPC64, true, true}},
+ {"sparc", {ELF::EM_SPARC, false, true}},
+ {"x86-64", {ELF::EM_X86_64, true, true}},
};
static Expected<const MachineInfo &> getMachineInfo(StringRef Arch) {
@@ -271,26 +271,41 @@
return Iter->getValue();
}
+// FIXME: consolidate with the bfd parsing used by lld.
static const StringMap<MachineInfo> OutputFormatMap{
- // Name, {EMachine, OSABI, 64bit, LittleEndian}
- {"elf32-i386", {ELF::EM_386, ELF::ELFOSABI_NONE, false, true}},
- {"elf32-i386-freebsd", {ELF::EM_386, ELF::ELFOSABI_FREEBSD, false, true}},
- {"elf32-powerpcle", {ELF::EM_PPC, ELF::ELFOSABI_NONE, false, true}},
- {"elf32-x86-64", {ELF::EM_X86_64, ELF::ELFOSABI_NONE, false, true}},
- {"elf64-powerpcle", {ELF::EM_PPC64, ELF::ELFOSABI_NONE, true, true}},
- {"elf64-x86-64", {ELF::EM_X86_64, ELF::ELFOSABI_NONE, true, true}},
- {"elf64-x86-64-freebsd",
- {ELF::EM_X86_64, ELF::ELFOSABI_FREEBSD, true, true}},
+ // Name, {EMachine, 64bit, LittleEndian}
+ {"elf32-i386", {ELF::EM_386, false, true}},
+ {"elf32-iamcu", {ELF::EM_IAMCU, false, true}},
+ {"elf32-littlearm", {ELF::EM_ARM, false, true}},
+ {"elf32-x86-64", {ELF::EM_X86_64, false, true}},
+ {"elf64-aarch64", {ELF::EM_AARCH64, true, true}},
+ {"elf64-littleaarch64", {ELF::EM_AARCH64, true, true}},
+ {"elf32-powerpc", {ELF::EM_PPC, false, false}},
+ {"elf32-powerpcle", {ELF::EM_PPC, false, true}},
+ {"elf64-powerpc", {ELF::EM_PPC64, true, false}},
+ {"elf64-powerpcle", {ELF::EM_PPC64, true, true}},
+ {"elf64-x86-64", {ELF::EM_X86_64, true, true}},
+ {"elf32-tradbigmips", {ELF::EM_MIPS, false, false}},
+ {"elf32-bigmips", {ELF::EM_MIPS, false, false}},
+ {"elf32-ntradbigmips", {ELF::EM_MIPS, false, false}},
+ {"elf32-tradlittlemips", {ELF::EM_MIPS, false, true}},
+ {"elf32-ntradlittlemips", {ELF::EM_MIPS, false, true}},
+ {"elf64-tradbigmips", {ELF::EM_MIPS, true, false}},
+ {"elf64-tradlittlemips", {ELF::EM_MIPS, true, true}},
};
-static Expected<const MachineInfo &>
-getOutputFormatMachineInfo(StringRef Format) {
+static Expected<MachineInfo> getOutputFormatMachineInfo(StringRef Format) {
+ StringRef OriginalFormat = Format;
+ bool IsFreeBSD = Format.consume_back("-freebsd");
auto Iter = OutputFormatMap.find(Format);
if (Iter == std::end(OutputFormatMap))
return createStringError(errc::invalid_argument,
"Invalid output format: '%s'",
- Format.str().c_str());
- return Iter->getValue();
+ OriginalFormat.str().c_str());
+ MachineInfo MI = Iter->getValue();
+ if (IsFreeBSD)
+ MI.OSABI = ELF::ELFOSABI_FREEBSD;
+ return {MI};
}
static Error addSymbolsFromFile(std::vector<NameOrRegex> &Symbols,
@@ -431,8 +446,7 @@
Config.BinaryArch = *MI;
}
if (!Config.OutputFormat.empty() && Config.OutputFormat != "binary") {
- Expected<const MachineInfo &> MI =
- getOutputFormatMachineInfo(Config.OutputFormat);
+ Expected<MachineInfo> MI = getOutputFormatMachineInfo(Config.OutputFormat);
if (!MI)
return MI.takeError();
Config.OutputArch = *MI;
diff --git a/llvm/tools/llvm-objcopy/CopyConfig.h b/llvm/tools/llvm-objcopy/CopyConfig.h
index 3fe4ab4..8c025eb 100644
--- a/llvm/tools/llvm-objcopy/CopyConfig.h
+++ b/llvm/tools/llvm-objcopy/CopyConfig.h
@@ -30,6 +30,13 @@
// lets us map architecture names to ELF types and the e_machine value of the
// ELF file.
struct MachineInfo {
+ MachineInfo(uint16_t EM, uint8_t ABI, bool Is64, bool IsLittle)
+ : EMachine(EM), OSABI(ABI), Is64Bit(Is64), IsLittleEndian(IsLittle) {}
+ // Alternative constructor that defaults to NONE for OSABI.
+ MachineInfo(uint16_t EM, bool Is64, bool IsLittle)
+ : MachineInfo(EM, ELF::ELFOSABI_NONE, Is64, IsLittle) {}
+ // Default constructor for unset fields.
+ MachineInfo() : MachineInfo(0, 0, false, false) {}
uint16_t EMachine;
uint8_t OSABI;
bool Is64Bit;