[llvm] r350541 - [llvm-objcopy] Handle -O <format> flag.
Jordan Rupprecht via llvm-commits
llvm-commits at lists.llvm.org
Mon Jan 7 08:59:13 PST 2019
Author: rupprecht
Date: Mon Jan 7 08:59:12 2019
New Revision: 350541
URL: http://llvm.org/viewvc/llvm-project?rev=350541&view=rev
Log:
[llvm-objcopy] Handle -O <format> flag.
Summary:
The -O flag is currently being mostly ignored; it's only checked whether or not the output format is "binary". This adds support for a few formats (e.g. elf64-x86-64), so that when specified, the output can change between 32/64 bit and sizes/alignments are updated accordingly.
This fixes PR39135
Reviewers: jakehehrlich, jhenderson, alexshap, espindola
Reviewed By: jhenderson
Subscribers: emaste, arichardson, llvm-commits
Differential Revision: https://reviews.llvm.org/D53667
Added:
llvm/trunk/test/tools/llvm-objcopy/ELF/bad-output-format.test
llvm/trunk/test/tools/llvm-objcopy/ELF/binary-input-with-arch.test
llvm/trunk/test/tools/llvm-objcopy/ELF/cross-arch-headers.test
llvm/trunk/test/tools/llvm-objcopy/ELF/cross-arch-sections-symbols.test
Modified:
llvm/trunk/tools/llvm-objcopy/CopyConfig.cpp
llvm/trunk/tools/llvm-objcopy/CopyConfig.h
llvm/trunk/tools/llvm-objcopy/ELF/ELFObjcopy.cpp
Added: llvm/trunk/test/tools/llvm-objcopy/ELF/bad-output-format.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/ELF/bad-output-format.test?rev=350541&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-objcopy/ELF/bad-output-format.test (added)
+++ llvm/trunk/test/tools/llvm-objcopy/ELF/bad-output-format.test Mon Jan 7 08:59:12 2019
@@ -0,0 +1,13 @@
+# RUN: yaml2obj %s > %t.o
+
+# RUN: not llvm-objcopy -O xyz %t.o %t.2.o 2>&1 \
+# RUN: | FileCheck %s --check-prefix=BAD-OUTPUT-FORMAT
+
+!ELF
+FileHeader:
+ Class: ELFCLASS32
+ Data: ELFDATA2LSB
+ Type: ET_EXEC
+ Machine: EM_386
+
+# BAD-OUTPUT-FORMAT: Invalid output format: 'xyz'.
Added: llvm/trunk/test/tools/llvm-objcopy/ELF/binary-input-with-arch.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/ELF/binary-input-with-arch.test?rev=350541&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-objcopy/ELF/binary-input-with-arch.test (added)
+++ llvm/trunk/test/tools/llvm-objcopy/ELF/binary-input-with-arch.test Mon Jan 7 08:59:12 2019
@@ -0,0 +1,20 @@
+# RUN: echo -n abcd > %t.x-txt
+# Preserve input to verify it is not modified.
+# RUN: cp %t.x-txt %t-copy.txt
+# RUN: llvm-objcopy -I binary -B i386 -O elf64-x86-64 %t.x-txt %t.o
+# RUN: llvm-readobj --file-headers %t.o | FileCheck %s
+# RUN: cmp %t.x-txt %t-copy.txt
+
+# Many uses of objcopy use no spaces in the flags, make sure that also works.
+# RUN: llvm-objcopy -Ibinary -Bi386 -Oelf64-x86-64 %t.x-txt %t-no-spaces.o
+# RUN: cmp %t.o %t-no-spaces.o
+
+# CHECK: Format: ELF64-x86-64
+# CHECK-NEXT: Arch: x86_64
+# CHECK-NEXT: AddressSize: 64bit
+
+# CHECK: Class: 64-bit
+# CHECK: DataEncoding: LittleEndian
+# CHECK: Machine: EM_X86_64
+# CHECK: HeaderSize: 64
+# CHECK: SectionHeaderEntrySize: 64
Added: llvm/trunk/test/tools/llvm-objcopy/ELF/cross-arch-headers.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/ELF/cross-arch-headers.test?rev=350541&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-objcopy/ELF/cross-arch-headers.test (added)
+++ llvm/trunk/test/tools/llvm-objcopy/ELF/cross-arch-headers.test Mon Jan 7 08:59:12 2019
@@ -0,0 +1,71 @@
+# RUN: yaml2obj %s > %t.o
+
+# RUN: llvm-objcopy %t.o -O elf32-i386 %t.elf32_i386.o
+# RUN: llvm-readobj --file-headers %t.elf32_i386.o | FileCheck %s --check-prefixes=CHECK,I386,32
+
+# RUN: llvm-objcopy %t.o -O elf32-powerpcle %t.elf32_ppcle.o
+# RUN: llvm-readobj --file-headers %t.elf32_ppcle.o | FileCheck %s --check-prefixes=CHECK,PPC,32
+
+# RUN: llvm-objcopy %t.o -O elf32-x86-64 %t.elf32_x86_64.o
+# RUN: llvm-readobj --file-headers %t.elf32_x86_64.o | FileCheck %s --check-prefixes=CHECK,X86-64,32
+
+# RUN: llvm-objcopy %t.o -O elf64-powerpcle %t.elf64_ppcle.o
+# RUN: llvm-readobj --file-headers %t.elf64_ppcle.o | FileCheck %s --check-prefixes=CHECK,PPC64,64
+
+# RUN: llvm-objcopy %t.o -O elf64-x86-64 %t.elf64_x86_64.o
+# RUN: llvm-readobj --file-headers %t.elf64_x86_64.o | FileCheck %s --check-prefixes=CHECK,X86-64,64
+
+!ELF
+FileHeader:
+ Class: ELFCLASS32
+ Data: ELFDATA2LSB
+ Type: ET_EXEC
+ Machine: EM_386
+Sections:
+ - Name: .text
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ - Name: .data
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC ]
+Symbols:
+ Global:
+ - Name: foo
+ Type: STT_FUNC
+ Section: .text
+ Value: 0x1234
+ - Name: bar
+ Type: STT_OBJECT
+ Section: .data
+ Value: 0xabcd
+
+# CHECK: Format:
+# 32-SAME: ELF32-
+# 64-SAME: ELF64-
+# I386-SAME: i386
+# PPC-SAME: ppc
+# PPC64-SAME: ppc64
+# X86-64-SAME: x86-64
+
+# I386-NEXT: Arch: i386
+# PPC-NEXT: Arch: powerpc
+# PPC64-NEXT: Arch: powerpc64le
+# X86-64-NEXT: Arch: x86_64
+
+# 32-NEXT: AddressSize: 32bit
+# 64-NEXT: AddressSize: 64bit
+
+# 32: Class: 32-bit
+# 64: Class: 64-bit
+# CHECK: DataEncoding: LittleEndian
+
+# I386: Machine: EM_386
+# PPC: Machine: EM_PPC
+# PPC64: Machine: EM_PPC64
+# X86-64: Machine: EM_X86_64
+
+# 32: HeaderSize: 52
+# 64: HeaderSize: 64
+
+# 32: SectionHeaderEntrySize: 40
+# 64: SectionHeaderEntrySize: 64
Added: llvm/trunk/test/tools/llvm-objcopy/ELF/cross-arch-sections-symbols.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/ELF/cross-arch-sections-symbols.test?rev=350541&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-objcopy/ELF/cross-arch-sections-symbols.test (added)
+++ llvm/trunk/test/tools/llvm-objcopy/ELF/cross-arch-sections-symbols.test Mon Jan 7 08:59:12 2019
@@ -0,0 +1,153 @@
+# RUN: yaml2obj %s > %t.o
+# Preserve input to verify it is not modified.
+# RUN: cp %t.o %t-copy.o
+# RUN: llvm-objcopy %t.o -O elf64-x86-64 %t.2.o
+# RUN: llvm-readobj --sections --symbols %t.2.o | FileCheck %s
+# RUN: cmp %t.o %t-copy.o
+
+!ELF
+FileHeader:
+ Class: ELFCLASS32
+ Data: ELFDATA2LSB
+ Type: ET_EXEC
+ Machine: EM_386
+Sections:
+ - Name: .text
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ Size: 32
+ - Name: .data
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC ]
+ Content: DEADBEEF
+ Size: 16
+Symbols:
+ Global:
+ - Name: foo
+ Type: STT_FUNC
+ Section: .text
+ Value: 16
+ Size: 8
+ - Name: bar
+ Type: STT_OBJECT
+ Section: .data
+ Size: 16
+
+# CHECK: Sections [
+# CHECK-NEXT: Section {
+# CHECK-NEXT: Index: 0
+# CHECK-NEXT: Name: (0)
+# CHECK-NEXT: Type: SHT_NULL (0x0)
+# CHECK-NEXT: Flags [ (0x0)
+# CHECK-NEXT: ]
+# CHECK-NEXT: Address:
+# CHECK-NEXT: Offset:
+# CHECK-NEXT: Size: 0
+# CHECK-NEXT: Link: 0
+# CHECK-NEXT: Info: 0
+# CHECK-NEXT: AddressAlignment: 0
+# CHECK-NEXT: EntrySize: 0
+# CHECK-NEXT: }
+# CHECK-NEXT: Section {
+# CHECK-NEXT: Index: 1
+# CHECK-NEXT: Name: .text
+# CHECK-NEXT: Type: SHT_PROGBITS (0x1)
+# CHECK-NEXT: Flags [ (0x6)
+# CHECK-NEXT: SHF_ALLOC (0x2)
+# CHECK-NEXT: SHF_EXECINSTR (0x4)
+# CHECK-NEXT: ]
+# CHECK-NEXT: Address:
+# CHECK-NEXT: Offset:
+# CHECK-NEXT: Size: 32
+# CHECK-NEXT: Link: 0
+# CHECK-NEXT: Info: 0
+# CHECK-NEXT: AddressAlignment: 0
+# CHECK-NEXT: EntrySize: 0
+# CHECK-NEXT: }
+# CHECK-NEXT: Section {
+# CHECK-NEXT: Index: 2
+# CHECK-NEXT: Name: .data
+# CHECK-NEXT: Type: SHT_PROGBITS (0x1)
+# CHECK-NEXT: Flags [ (0x2)
+# CHECK-NEXT: SHF_ALLOC (0x2)
+# CHECK-NEXT: ]
+# CHECK-NEXT: Address:
+# CHECK-NEXT: Offset:
+# CHECK-NEXT: Size: 16
+# CHECK-NEXT: Link: 0
+# CHECK-NEXT: Info: 0
+# CHECK-NEXT: AddressAlignment: 0
+# CHECK-NEXT: EntrySize: 0
+# CHECK-NEXT: }
+# CHECK-NEXT: Section {
+# CHECK-NEXT: Index: 3
+# CHECK-NEXT: Name: .symtab
+# CHECK-NEXT: Type: SHT_SYMTAB (0x2)
+# CHECK-NEXT: Flags [ (0x0)
+# CHECK-NEXT: ]
+# CHECK-NEXT: Address:
+# CHECK-NEXT: Offset:
+# CHECK-NEXT: Size: 72
+# CHECK-NEXT: Link: 4
+# CHECK-NEXT: Info: 1
+# CHECK-NEXT: AddressAlignment: 8
+# CHECK-NEXT: EntrySize: 24
+# CHECK-NEXT: }
+# CHECK-NEXT: Section {
+# CHECK-NEXT: Index: 4
+# CHECK-NEXT: Name: .strtab
+# CHECK-NEXT: Type: SHT_STRTAB (0x3)
+# CHECK-NEXT: Flags [ (0x0)
+# CHECK-NEXT: ]
+# CHECK-NEXT: Address:
+# CHECK-NEXT: Offset:
+# CHECK-NEXT: Size: 10
+# CHECK-NEXT: Link: 0
+# CHECK-NEXT: Info: 0
+# CHECK-NEXT: AddressAlignment: 1
+# CHECK-NEXT: EntrySize: 0
+# CHECK-NEXT: }
+# CHECK-NEXT: Section {
+# CHECK-NEXT: Index: 5
+# CHECK-NEXT: Name: .shstrtab
+# CHECK-NEXT: Type: SHT_STRTAB (0x3)
+# CHECK-NEXT: Flags [ (0x0)
+# CHECK-NEXT: ]
+# CHECK-NEXT: Address:
+# CHECK-NEXT: Offset:
+# CHECK-NEXT: Size: 39
+# CHECK-NEXT: Link: 0
+# CHECK-NEXT: Info: 0
+# CHECK-NEXT: AddressAlignment: 1
+# CHECK-NEXT: EntrySize: 0
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+# CHECK-NEXT: Symbols [
+# CHECK-NEXT: Symbol {
+# CHECK-NEXT: Name:
+# CHECK-NEXT: Value: 0x0
+# CHECK-NEXT: Size: 0
+# CHECK-NEXT: Binding: Local (0x0)
+# CHECK-NEXT: Type: None (0x0)
+# CHECK-NEXT: Other: 0
+# CHECK-NEXT: Section: Undefined
+# CHECK-NEXT: }
+# CHECK-NEXT: Symbol {
+# CHECK-NEXT: Name: foo
+# CHECK-NEXT: Value: 0x10
+# CHECK-NEXT: Size: 8
+# CHECK-NEXT: Binding: Global (0x1)
+# CHECK-NEXT: Type: Function (0x2)
+# CHECK-NEXT: Other: 0
+# CHECK-NEXT: Section: .text
+# CHECK-NEXT: }
+# CHECK-NEXT: Symbol {
+# CHECK-NEXT: Name: bar
+# CHECK-NEXT: Value: 0x0
+# CHECK-NEXT: Size: 16
+# CHECK-NEXT: Binding: Global (0x1)
+# CHECK-NEXT: Type: Object (0x1)
+# CHECK-NEXT: Other: 0
+# CHECK-NEXT: Section: .data
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
Modified: llvm/trunk/tools/llvm-objcopy/CopyConfig.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/CopyConfig.cpp?rev=350541&r1=350540&r2=350541&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-objcopy/CopyConfig.cpp (original)
+++ llvm/trunk/tools/llvm-objcopy/CopyConfig.cpp Mon Jan 7 08:59:12 2019
@@ -189,6 +189,22 @@ static const MachineInfo &getMachineInfo
return Iter->getValue();
}
+static const StringMap<MachineInfo> OutputFormatMap{
+ // Name, {EMachine, 64bit, LittleEndian}
+ {"elf32-i386", {ELF::EM_386, false, true}},
+ {"elf32-powerpcle", {ELF::EM_PPC, false, true}},
+ {"elf32-x86-64", {ELF::EM_X86_64, false, true}},
+ {"elf64-powerpcle", {ELF::EM_PPC64, true, true}},
+ {"elf64-x86-64", {ELF::EM_X86_64, true, true}},
+};
+
+static const MachineInfo &getOutputFormatMachineInfo(StringRef Format) {
+ auto Iter = OutputFormatMap.find(Format);
+ if (Iter == std::end(OutputFormatMap))
+ error("Invalid output format: '" + Format + "'");
+ return Iter->getValue();
+}
+
static void addGlobalSymbolsFromFile(std::vector<std::string> &Symbols,
StringRef Filename) {
SmallVector<StringRef, 16> Lines;
@@ -266,6 +282,8 @@ DriverConfig parseObjcopyOptions(ArrayRe
error("Specified binary input without specifiying an architecture");
Config.BinaryArch = getMachineInfo(BinaryArch);
}
+ if (!Config.OutputFormat.empty() && Config.OutputFormat != "binary")
+ Config.OutputArch = getOutputFormatMachineInfo(Config.OutputFormat);
if (auto Arg = InputArgs.getLastArg(OBJCOPY_compress_debug_sections,
OBJCOPY_compress_debug_sections_eq)) {
Modified: llvm/trunk/tools/llvm-objcopy/CopyConfig.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/CopyConfig.h?rev=350541&r1=350540&r2=350541&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-objcopy/CopyConfig.h (original)
+++ llvm/trunk/tools/llvm-objcopy/CopyConfig.h Mon Jan 7 08:59:12 2019
@@ -46,8 +46,10 @@ struct CopyConfig {
StringRef OutputFilename;
StringRef OutputFormat;
- // Only applicable for --input-format=Binary
+ // Only applicable for --input-format=binary
MachineInfo BinaryArch;
+ // Only applicable when --output-format!=binary (e.g. elf64-x86-64).
+ Optional<MachineInfo> OutputArch;
// Advanced options
StringRef AddGnuDebugLink;
Modified: llvm/trunk/tools/llvm-objcopy/ELF/ELFObjcopy.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/ELF/ELFObjcopy.cpp?rev=350541&r1=350540&r2=350541&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-objcopy/ELF/ELFObjcopy.cpp (original)
+++ llvm/trunk/tools/llvm-objcopy/ELF/ELFObjcopy.cpp Mon Jan 7 08:59:12 2019
@@ -173,6 +173,8 @@ static void splitDWOToFile(const CopyCon
auto DWOFile = Reader.create();
DWOFile->removeSections(
[&](const SectionBase &Sec) { return onlyKeepDWOPred(*DWOFile, Sec); });
+ if (Config.OutputArch)
+ DWOFile->Machine = Config.OutputArch.getValue().EMachine;
FileBuffer FB(File);
auto Writer = createWriter(Config, *DWOFile, FB, OutputElfType);
Writer->finalize();
@@ -261,6 +263,8 @@ static void handleArgs(const CopyConfig
if (!Config.SplitDWO.empty()) {
splitDWOToFile(Config, Reader, Config.SplitDWO, OutputElfType);
}
+ if (Config.OutputArch)
+ Obj.Machine = Config.OutputArch.getValue().EMachine;
// TODO: update or remove symbols only if there is an option that affects
// them.
@@ -528,7 +532,10 @@ void executeObjcopyOnRawBinary(const Cop
BinaryReader Reader(Config.BinaryArch, &In);
std::unique_ptr<Object> Obj = Reader.create();
- const ElfType OutputElfType = getOutputElfType(Config.BinaryArch);
+ // Prefer OutputArch (-O<format>) if set, otherwise fallback to BinaryArch
+ // (-B<arch>).
+ const ElfType OutputElfType = getOutputElfType(
+ Config.OutputArch ? Config.OutputArch.getValue() : Config.BinaryArch);
handleArgs(Config, *Obj, Reader, OutputElfType);
std::unique_ptr<Writer> Writer =
createWriter(Config, *Obj, Out, OutputElfType);
@@ -540,7 +547,10 @@ void executeObjcopyOnBinary(const CopyCo
object::ELFObjectFileBase &In, Buffer &Out) {
ELFReader Reader(&In);
std::unique_ptr<Object> Obj = Reader.create();
- const ElfType OutputElfType = getOutputElfType(In);
+ // Prefer OutputArch (-O<format>) if set, otherwise infer it from the input.
+ const ElfType OutputElfType =
+ Config.OutputArch ? getOutputElfType(Config.OutputArch.getValue())
+ : getOutputElfType(In);
ArrayRef<uint8_t> BuildIdBytes;
if (!Config.BuildIdLinkDir.empty()) {
More information about the llvm-commits
mailing list