1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 11:02:59 +02:00

[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
This commit is contained in:
Jordan Rupprecht 2019-04-17 07:42:31 +00:00
parent 782ab36562
commit 1313ac2770
4 changed files with 145 additions and 48 deletions

View File

@ -3,6 +3,11 @@
# RUN: not llvm-objcopy -O xyz %t.o %t.2.o 2>&1 \
# RUN: | FileCheck %s --check-prefix=BAD-OUTPUT-FORMAT
# FreeBSD has some special output format parsing that looks up the name without
# the trailing "-freebsd". Make sure we include the full output format name.
# RUN: not llvm-objcopy -O xyz-freebsd %t.o %t.2.o 2>&1 \
# RUN: | FileCheck %s --check-prefix=BAD-OUTPUT-FORMAT-BSD
!ELF
FileHeader:
Class: ELFCLASS32
@ -11,3 +16,4 @@ FileHeader:
Machine: EM_386
# BAD-OUTPUT-FORMAT: Invalid output format: 'xyz'
# BAD-OUTPUT-FORMAT-BSD: Invalid output format: 'xyz-freebsd'

View File

@ -6,36 +6,88 @@
# Without --output-format, the format should match the input.
# RUN: llvm-objcopy %t.o %t.default.o --split-dwo=%t.default.dwo
# RUN: llvm-readobj --file-headers %t.default.o | FileCheck %s --check-prefixes=CHECK,DEFAULT,32
# RUN: llvm-readobj --file-headers %t.default.dwo | FileCheck %s --check-prefixes=CHECK,DEFAULT,32
# RUN: llvm-readobj --file-headers %t.default.o | FileCheck %s --check-prefixes=CHECK,LE,DEFAULT,32
# RUN: llvm-readobj --file-headers %t.default.dwo | FileCheck %s --check-prefixes=CHECK,LE,DEFAULT,32
# RUN: llvm-objcopy %t.o -O elf32-i386 %t.elf32_i386.o --split-dwo=%t.elf32_i386.dwo
# RUN: llvm-readobj --file-headers %t.elf32_i386.o | FileCheck %s --check-prefixes=CHECK,I386,32,SYSV
# RUN: llvm-readobj --file-headers %t.elf32_i386.dwo | FileCheck %s --check-prefixes=CHECK,I386,32,SYSV
# RUN: llvm-readobj --file-headers %t.elf32_i386.o | FileCheck %s --check-prefixes=CHECK,LE,I386,32,SYSV
# RUN: llvm-readobj --file-headers %t.elf32_i386.dwo | FileCheck %s --check-prefixes=CHECK,LE,I386,32,SYSV
# RUN: llvm-objcopy %t.o -O elf32-i386-freebsd %t.elf32_i386_freebsd.o --split-dwo=%t.elf32_i386_freebsd.dwo
# RUN: llvm-readobj --file-headers %t.elf32_i386_freebsd.o | FileCheck %s --check-prefixes=CHECK,I386,32,FREEBSD
# RUN: llvm-readobj --file-headers %t.elf32_i386_freebsd.dwo | FileCheck %s --check-prefixes=CHECK,I386,32,FREEBSD
# RUN: llvm-readobj --file-headers %t.elf32_i386_freebsd.o | FileCheck %s --check-prefixes=CHECK,LE,I386,32,FREEBSD
# RUN: llvm-readobj --file-headers %t.elf32_i386_freebsd.dwo | FileCheck %s --check-prefixes=CHECK,LE,I386,32,FREEBSD
# RUN: llvm-objcopy %t.o -O elf32-iamcu %t.elf32_iamcu.o --split-dwo=%t.elf32_iamcu.dwo
# RUN: llvm-readobj --file-headers %t.elf32_iamcu.o | FileCheck %s --check-prefixes=CHECK,LE,IAMCU,32,SYSV
# RUN: llvm-readobj --file-headers %t.elf32_iamcu.dwo | FileCheck %s --check-prefixes=CHECK,LE,IAMCU,32,SYSV
# RUN: llvm-objcopy %t.o -O elf32-littlearm %t.elf32_littlearm.o --split-dwo=%t.elf32_littlearm.dwo
# RUN: llvm-readobj --file-headers %t.elf32_littlearm.o | FileCheck %s --check-prefixes=CHECK,LE,ARM,32,SYSV
# RUN: llvm-readobj --file-headers %t.elf32_littlearm.dwo | FileCheck %s --check-prefixes=CHECK,LE,ARM,32,SYSV
# RUN: llvm-objcopy %t.o -O elf64-aarch64 %t.elf64_aarch64.o --split-dwo=%t.elf64_aarch64.dwo
# RUN: llvm-readobj --file-headers %t.elf64_aarch64.o | FileCheck %s --check-prefixes=CHECK,LE,AARCH,64,SYSV
# RUN: llvm-readobj --file-headers %t.elf64_aarch64.dwo | FileCheck %s --check-prefixes=CHECK,LE,AARCH,64,SYSV
# RUN: llvm-objcopy %t.o -O elf64-littleaarch64 %t.elf64_littleaarch64.o --split-dwo=%t.elf64_littleaarch64.dwo
# RUN: llvm-readobj --file-headers %t.elf64_littleaarch64.o | FileCheck %s --check-prefixes=CHECK,LE,AARCH,64,SYSV
# RUN: llvm-readobj --file-headers %t.elf64_littleaarch64.dwo | FileCheck %s --check-prefixes=CHECK,LE,AARCH,64,SYSV
# RUN: llvm-objcopy %t.o -O elf32-powerpc %t.elf32_powerpc.o --split-dwo=%t.elf32_powerpc.dwo
# RUN: llvm-readobj --file-headers %t.elf32_powerpc.o | FileCheck %s --check-prefixes=CHECK,BE,PPC,32,SYSV
# RUN: llvm-readobj --file-headers %t.elf32_powerpc.dwo | FileCheck %s --check-prefixes=CHECK,BE,PPC,32,SYSV
# RUN: llvm-objcopy %t.o -O elf64-powerpc %t.elf64_powerpc.o --split-dwo=%t.elf64_powerpc.dwo
# RUN: llvm-readobj --file-headers %t.elf64_powerpc.o | FileCheck %s --check-prefixes=CHECK,BE,PPC64BE,64,SYSV
# RUN: llvm-readobj --file-headers %t.elf64_powerpc.dwo | FileCheck %s --check-prefixes=CHECK,BE,PPC64BE,64,SYSV
# RUN: llvm-objcopy %t.o -O elf32-powerpcle %t.elf32_ppcle.o --split-dwo=%t.elf32_ppcle.dwo
# RUN: llvm-readobj --file-headers %t.elf32_ppcle.o | FileCheck %s --check-prefixes=CHECK,PPC,32,SYSV
# RUN: llvm-readobj --file-headers %t.elf32_ppcle.dwo | FileCheck %s --check-prefixes=CHECK,PPC,32,SYSV
# RUN: llvm-readobj --file-headers %t.elf32_ppcle.o | FileCheck %s --check-prefixes=CHECK,LE,PPC,32,SYSV
# RUN: llvm-readobj --file-headers %t.elf32_ppcle.dwo | FileCheck %s --check-prefixes=CHECK,LE,PPC,32,SYSV
# RUN: llvm-objcopy %t.o -O elf32-x86-64 %t.elf32_x86_64.o --split-dwo=%t.elf32_x86_64.dwo
# RUN: llvm-readobj --file-headers %t.elf32_x86_64.o | FileCheck %s --check-prefixes=CHECK,X86-64,32,SYSV
# RUN: llvm-readobj --file-headers %t.elf32_x86_64.dwo | FileCheck %s --check-prefixes=CHECK,X86-64,32,SYSV
# RUN: llvm-readobj --file-headers %t.elf32_x86_64.o | FileCheck %s --check-prefixes=CHECK,LE,X86-64,32,SYSV
# RUN: llvm-readobj --file-headers %t.elf32_x86_64.dwo | FileCheck %s --check-prefixes=CHECK,LE,X86-64,32,SYSV
# RUN: llvm-objcopy %t.o -O elf64-powerpcle %t.elf64_ppcle.o --split-dwo=%t.elf64_ppcle.dwo
# RUN: llvm-readobj --file-headers %t.elf64_ppcle.o | FileCheck %s --check-prefixes=CHECK,PPC64,64,SYSV
# RUN: llvm-readobj --file-headers %t.elf64_ppcle.dwo | FileCheck %s --check-prefixes=CHECK,PPC64,64,SYSV
# RUN: llvm-readobj --file-headers %t.elf64_ppcle.o | FileCheck %s --check-prefixes=CHECK,LE,PPC64LE,64,SYSV
# RUN: llvm-readobj --file-headers %t.elf64_ppcle.dwo | FileCheck %s --check-prefixes=CHECK,LE,PPC64LE,64,SYSV
# RUN: llvm-objcopy %t.o -O elf64-x86-64 %t.elf64_x86_64.o --split-dwo=%t.elf64_x86_64.dwo
# RUN: llvm-readobj --file-headers %t.elf64_x86_64.o | FileCheck %s --check-prefixes=CHECK,X86-64,64,SYSV
# RUN: llvm-readobj --file-headers %t.elf64_x86_64.dwo | FileCheck %s --check-prefixes=CHECK,X86-64,64,SYSV
# RUN: llvm-readobj --file-headers %t.elf64_x86_64.o | FileCheck %s --check-prefixes=CHECK,LE,X86-64,64,SYSV
# RUN: llvm-readobj --file-headers %t.elf64_x86_64.dwo | FileCheck %s --check-prefixes=CHECK,LE,X86-64,64,SYSV
# RUN: llvm-objcopy %t.o -O elf64-x86-64-freebsd %t.elf64_x86_64_freebsd.o --split-dwo=%t.elf64_x86_64_freebsd.dwo
# RUN: llvm-readobj --file-headers %t.elf64_x86_64_freebsd.o | FileCheck %s --check-prefixes=CHECK,X86-64,64,FREEBSD
# RUN: llvm-readobj --file-headers %t.elf64_x86_64_freebsd.dwo | FileCheck %s --check-prefixes=CHECK,X86-64,64,FREEBSD
# RUN: llvm-readobj --file-headers %t.elf64_x86_64_freebsd.o | FileCheck %s --check-prefixes=CHECK,LE,X86-64,64,FREEBSD
# RUN: llvm-readobj --file-headers %t.elf64_x86_64_freebsd.dwo | FileCheck %s --check-prefixes=CHECK,LE,X86-64,64,FREEBSD
# RUN: llvm-objcopy %t.o -O elf32-tradbigmips %t.elf32_tradbigmips.o --split-dwo=%t.elf32_tradbigmips.dwo
# RUN: llvm-readobj --file-headers %t.elf32_tradbigmips.o | FileCheck %s --check-prefixes=CHECK,BE,MIPS,MIPSBE,32,SYSV
# RUN: llvm-readobj --file-headers %t.elf32_tradbigmips.dwo | FileCheck %s --check-prefixes=CHECK,BE,MIPS,MIPSBE,32,SYSV
# RUN: llvm-objcopy %t.o -O elf32-bigmips %t.elf32_bigmips.o --split-dwo=%t.elf32_bigmips.dwo
# RUN: llvm-readobj --file-headers %t.elf32_bigmips.o | FileCheck %s --check-prefixes=CHECK,BE,MIPS,MIPSBE,32,SYSV
# RUN: llvm-readobj --file-headers %t.elf32_bigmips.dwo | FileCheck %s --check-prefixes=CHECK,BE,MIPS,MIPSBE,32,SYSV
# RUN: llvm-objcopy %t.o -O elf32-ntradbigmips %t.elf32_ntradbigmips.o --split-dwo=%t.elf32_ntradbigmips.dwo
# RUN: llvm-readobj --file-headers %t.elf32_ntradbigmips.o | FileCheck %s --check-prefixes=CHECK,BE,MIPS,MIPSBE,32,SYSV
# RUN: llvm-readobj --file-headers %t.elf32_ntradbigmips.dwo | FileCheck %s --check-prefixes=CHECK,BE,MIPS,MIPSBE,32,SYSV
# RUN: llvm-objcopy %t.o -O elf32-tradlittlemips %t.elf32_tradlittlemips.o --split-dwo=%t.elf32_tradlittlemips.dwo
# RUN: llvm-readobj --file-headers %t.elf32_tradlittlemips.o | FileCheck %s --check-prefixes=CHECK,LE,MIPS,MIPSLE,32,SYSV
# RUN: llvm-readobj --file-headers %t.elf32_tradlittlemips.dwo | FileCheck %s --check-prefixes=CHECK,LE,MIPS,MIPSLE,32,SYSV
# RUN: llvm-objcopy %t.o -O elf32-ntradlittlemips %t.elf32_ntradlittlemips.o --split-dwo=%t.elf32_ntradlittlemips.dwo
# RUN: llvm-readobj --file-headers %t.elf32_ntradlittlemips.o | FileCheck %s --check-prefixes=CHECK,LE,MIPS,MIPSLE,32,SYSV
# RUN: llvm-readobj --file-headers %t.elf32_ntradlittlemips.dwo | FileCheck %s --check-prefixes=CHECK,LE,MIPS,MIPSLE,32,SYSV
# RUN: llvm-objcopy %t.o -O elf64-tradbigmips %t.elf64_tradbigmips.o --split-dwo=%t.elf64_tradbigmips.dwo
# RUN: llvm-readobj --file-headers %t.elf64_tradbigmips.o | FileCheck %s --check-prefixes=CHECK,BE,MIPS,MIPS64BE,64,SYSV
# RUN: llvm-readobj --file-headers %t.elf64_tradbigmips.dwo | FileCheck %s --check-prefixes=CHECK,BE,MIPS,MIPS64BE,64,SYSV
# RUN: llvm-objcopy %t.o -O elf64-tradlittlemips %t.elf64_tradlittlemips.o --split-dwo=%t.elf64_tradlittlemips.dwo
# RUN: llvm-readobj --file-headers %t.elf64_tradlittlemips.o | FileCheck %s --check-prefixes=CHECK,LE,MIPS,MIPS64LE,64,SYSV
# RUN: llvm-readobj --file-headers %t.elf64_tradlittlemips.dwo | FileCheck %s --check-prefixes=CHECK,LE,MIPS,MIPS64LE,64,SYSV
!ELF
FileHeader:
@ -68,29 +120,47 @@ Symbols:
# 32-SAME: ELF32-
# 64-SAME: ELF64-
# I386-SAME: i386
# IAMCU-SAME: iamcu
# AARCH-SAME: aarch64
# ARM-SAME: arm-little
# MIPS-SAME: mips
# PPC-SAME: ppc{{$}}
# PPC64-SAME: ppc64
# PPC64BE-SAME: ppc64{{$}}
# PPC64LE-SAME: ppc64{{$}}
# X86-64-SAME: x86-64
# DEFAULT-SAME: unknown
# I386-NEXT: Arch: i386
# PPC-NEXT: Arch: powerpc{{$}}
# PPC64-NEXT: Arch: powerpc64le
# X86-64-NEXT: Arch: x86_64
# DEFAULT-NEXT: Arch: unknown
# I386-NEXT: Arch: i386
# IAMCU-NEXT: Arch: i386
# AARCH-NEXT: Arch: aarch64
# ARM-NEXT: Arch: arm
# MIPSBE-NEXT: Arch: mips{{$}}
# MIPSLE-NEXT: Arch: mipsel{{$}}
# MIPS64BE-NEXT: Arch: mips64{{$}}
# MIPS64LE-NEXT: Arch: mips64el{{$}}
# PPC-NEXT: Arch: powerpc{{$}}
# PPC64BE-NEXT: Arch: powerpc64{{$}}
# PPC64LE-NEXT: Arch: powerpc64le
# X86-64-NEXT: Arch: x86_64
# DEFAULT-NEXT: Arch: unknown
# 32-NEXT: AddressSize: 32bit
# 64-NEXT: AddressSize: 64bit
# 32: Class: 32-bit
# 64: Class: 64-bit
# CHECK: DataEncoding: LittleEndian
# 32: Class: 32-bit
# 64: Class: 64-bit
# LE: DataEncoding: LittleEndian
# BE: DataEncoding: BigEndian
# SYSV: OS/ABI: SystemV (0x0)
# FREEBSD: OS/ABI: FreeBSD (0x9)
# DEFAULT: OS/ABI: Standalone (0xFF)
# AARCH: Machine: EM_AARCH64 (0xB7)
# ARM: Machine: EM_ARM (0x28)
# I386: Machine: EM_386 (0x3)
# IAMCU: Machine: EM_IAMCU (0x6)
# MIPS: Machine: EM_MIPS (0x8)
# PPC: Machine: EM_PPC (0x14)
# PPC64: Machine: EM_PPC64 (0x15)
# X86-64: Machine: EM_X86_64 (0x3E)

View File

@ -253,14 +253,14 @@ static Expected<NewSymbolInfo> parseNewSymbolInfo(StringRef FlagValue) {
}
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 @@ static Expected<const MachineInfo &> getMachineInfo(StringRef Arch) {
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 @@ Expected<DriverConfig> parseObjcopyOptions(ArrayRef<const char *> ArgsArr) {
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;

View File

@ -30,6 +30,13 @@ namespace objcopy {
// 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;