Index: llvm/trunk/test/tools/llvm-objcopy/ELF/binary-input-and-output.test =================================================================== --- llvm/trunk/test/tools/llvm-objcopy/ELF/binary-input-and-output.test +++ llvm/trunk/test/tools/llvm-objcopy/ELF/binary-input-and-output.test @@ -3,13 +3,21 @@ # Preserve input to verify it is not modified # RUN: cp %t.txt %t-copy.txt -# -I binary -O binary preserves payload through in-memory representation -# RUN: llvm-objcopy -I binary -B i386:x86-64 -O binary %t.txt %t.2.txt +## -I binary -O binary preserves payload through in-memory representation. +# RUN: llvm-objcopy -I binary -O binary %t.txt %t.2.txt # RUN: cmp %t.txt %t.2.txt # RUN: cmp %t.txt %t-copy.txt -# -I binary -O binary preserves payload through an intermediate object file -# RUN: llvm-objcopy -I binary -B i386:x86-64 %t.txt %t.o -# RUN: llvm-objcopy -O binary %t.o %t.3.txt +## If -O is not specified, it defaults to -I, i.e. "binary". +# RUN: llvm-objcopy -I binary %t.txt %t.3.txt # RUN: cmp %t.txt %t.3.txt -# RUN: cmp %t.txt %t-copy.txt + +## -I binary -O elf* creates an ELF. -O binary transforms it back to the +## original file. +# RUN: llvm-objcopy -I binary -O elf64-x86-64 %t.txt %t.o +# RUN: llvm-objcopy -O binary %t.o %t.4.txt +# RUN: cmp %t.txt %t.4.txt + +## -B is ignored. +# RUN: llvm-objcopy -I binary -B i386:x86-64 -O binary %t.txt %t.5.txt +# RUN: cmp %t.txt %t.5.txt Index: llvm/trunk/test/tools/llvm-objcopy/ELF/binary-input-arch.test =================================================================== --- llvm/trunk/test/tools/llvm-objcopy/ELF/binary-input-arch.test +++ llvm/trunk/test/tools/llvm-objcopy/ELF/binary-input-arch.test @@ -1,102 +0,0 @@ -# RUN: echo abcd > %t.txt - -# RUN: llvm-objcopy -I binary -B aarch64 %t.txt %t.aarch64.o -# RUN: llvm-readobj --file-headers %t.aarch64.o | FileCheck %s --check-prefixes=CHECK,LE,AARCH64,64 - -# RUN: llvm-objcopy -I binary -B arm %t.txt %t.arm.o -# RUN: llvm-readobj --file-headers %t.arm.o | FileCheck %s --check-prefixes=CHECK,LE,ARM,32 - -# RUN: llvm-objcopy -I binary -B i386 %t.txt %t.i386.o -# RUN: llvm-readobj --file-headers %t.i386.o | FileCheck %s --check-prefixes=CHECK,LE,I386,32 - -# RUN: llvm-objcopy -I binary -B i386:x86-64 %t.txt %t.i386_x86-64.o -# RUN: llvm-readobj --file-headers %t.i386_x86-64.o | FileCheck %s --check-prefixes=CHECK,LE,X86-64,64 - -# RUN: llvm-objcopy -I binary -B mips %t.txt %t.mips.o -# RUN: llvm-readobj --file-headers %t.mips.o | FileCheck %s --check-prefixes=CHECK,BE,MIPS,32 - -# RUN: llvm-objcopy -I binary -B powerpc:common64 %t.txt %t.powerpc_common64.o -# RUN: llvm-readobj --file-headers %t.powerpc_common64.o | FileCheck %s --check-prefixes=CHECK,LE,PPC,64 - -# RUN: llvm-objcopy -I binary -B riscv:rv32 %t.txt %t.rv32.o -# RUN: llvm-readobj --file-headers %t.rv32.o | FileCheck %s --check-prefixes=CHECK,LE,RISCV32,32 - -# RUN: llvm-objcopy -I binary -B riscv:rv64 %t.txt %t.rv64.o -# RUN: llvm-readobj --file-headers %t.rv64.o | FileCheck %s --check-prefixes=CHECK,LE,RISCV64,64 - -# RUN: llvm-objcopy -I binary -B sparc %t.txt %t.sparc.o -# RUN: llvm-readobj --file-headers %t.sparc.o | FileCheck %s --check-prefixes=CHECK,BE,SPARC,32 - -# RUN: llvm-objcopy -I binary -B sparcel %t.txt %t.sparcel.o -# RUN: llvm-readobj --file-headers %t.sparcel.o | FileCheck %s --check-prefixes=CHECK,LE,SPARCEL,32 - -# RUN: llvm-objcopy -I binary -B x86-64 %t.txt %t.x86-64.o -# RUN: llvm-readobj --file-headers %t.x86-64.o | FileCheck %s --check-prefixes=CHECK,LE,X86-64,64 - -# CHECK: Format: -# 32-SAME: ELF32- -# 64-SAME: ELF64- -# AARCH64-SAME: aarch64-little -# ARM-SAME: arm-little -# I386-SAME: i386 -# MIPS-SAME: mips{{$}} -# RISCV32-SAME: riscv{{$}} -# RISCV64-SAME: riscv{{$}} -# PPC-SAME: ppc64 -# SPARC-SAME: sparc -# SPARCEL-SAME: sparc -# X86-64-SAME: x86-64 - -# AARCH64-NEXT: Arch: aarch64 -# ARM-NEXT: Arch: arm -# I386-NEXT: Arch: i386 -# MIPS-NEXT: Arch: mips{{$$}} -# PPC-NEXT: Arch: powerpc64le -# RISCV32-NEXT: Arch: riscv32 -# RISCV64-NEXT: Arch: riscv64 -# SPARC-NEXT: Arch: sparc{{$}} -# SPARCEL-NEXT: Arch: sparcel -# X86-64-NEXT: Arch: x86_64 - -# 32-NEXT: AddressSize: 32bit -# 64-NEXT: AddressSize: 64bit - -# CHECK: ElfHeader { -# CHECK-NEXT: Ident { -# CHECK-NEXT: Magic: (7F 45 4C 46) -# 32-NEXT: Class: 32-bit (0x1) -# 64-NEXT: Class: 64-bit (0x2) -# LE-NEXT: DataEncoding: LittleEndian (0x1) -# BE-NEXT: DataEncoding: BigEndian (0x2) -# CHECK-NEXT: FileVersion: 1 -# CHECK-NEXT: OS/ABI: SystemV (0x0) -# CHECK-NEXT: ABIVersion: 0 -# CHECK-NEXT: Unused: (00 00 00 00 00 00 00) -# CHECK-NEXT: } -# CHECK-NEXT: Type: Relocatable (0x1) -# AARCH64-NEXT: Machine: EM_AARCH64 (0xB7) -# ARM-NEXT: Machine: EM_ARM (0x28) -# I386-NEXT: Machine: EM_386 (0x3) -# MIPS-NEXT: Machine: EM_MIPS (0x8) -# PPC-NEXT: Machine: EM_PPC64 (0x15) -# RISCV32-NEXT: Machine: EM_RISCV (0xF3) -# RISCV64-NEXT: Machine: EM_RISCV (0xF3) -# SPARC-NEXT: Machine: EM_SPARC (0x2) -# SPARCEL-NEXT: Machine: EM_SPARC (0x2) -# X86-64-NEXT: Machine: EM_X86_64 (0x3E) -# CHECK-NEXT: Version: 1 -# CHECK-NEXT: Entry: 0x0 -# CHECK-NEXT: ProgramHeaderOffset: -# CHECK-NEXT: SectionHeaderOffset: -# CHECK-NEXT: Flags [ (0x0) -# CHECK-NEXT: ] -# 32-NEXT: HeaderSize: 52 -# 64-NEXT: HeaderSize: 64 -# 32-NEXT: ProgramHeaderEntrySize: 0 -# 64-NEXT: ProgramHeaderEntrySize: 0 -# CHECK-NEXT: ProgramHeaderCount: 0 -# 32-NEXT: SectionHeaderEntrySize: 40 -# 64-NEXT: SectionHeaderEntrySize: 64 -# CHECK-NEXT: SectionHeaderCount: 4 -# CHECK-NEXT: StringTableSectionIndex: -# CHECK-NEXT: } Index: llvm/trunk/test/tools/llvm-objcopy/ELF/binary-input-error.test =================================================================== --- llvm/trunk/test/tools/llvm-objcopy/ELF/binary-input-error.test +++ llvm/trunk/test/tools/llvm-objcopy/ELF/binary-input-error.test @@ -1,10 +1,6 @@ # RUN: echo abcd > %t.txt -# RUN: not llvm-objcopy -I binary %t.txt %t.o 2>&1 \ -# RUN: | FileCheck %s --check-prefix=MISSING-BINARY-ARCH - # RUN: not llvm-objcopy -I binary -B xyz %t.txt %t.o 2>&1 \ # RUN: | FileCheck %s --check-prefix=BAD-BINARY-ARCH -# MISSING-BINARY-ARCH: specified binary input without specifiying an architecture # BAD-BINARY-ARCH: invalid architecture: 'xyz' Index: llvm/trunk/test/tools/llvm-objcopy/ELF/binary-input.test =================================================================== --- llvm/trunk/test/tools/llvm-objcopy/ELF/binary-input.test +++ llvm/trunk/test/tools/llvm-objcopy/ELF/binary-input.test @@ -1,7 +1,7 @@ # 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:x86-64 %t.x-txt %t.o +# RUN: llvm-objcopy -I binary -O elf64-x86-64 %t.x-txt %t.o # RUN: llvm-readobj --sections --symbols %t.o | FileCheck %s # RUN: cmp %t.x-txt %t-copy.txt Index: llvm/trunk/test/tools/llvm-objcopy/ELF/binary-output-target.test =================================================================== --- llvm/trunk/test/tools/llvm-objcopy/ELF/binary-output-target.test +++ llvm/trunk/test/tools/llvm-objcopy/ELF/binary-output-target.test @@ -0,0 +1,107 @@ +# RUN: echo abcd > %t.txt + +# RUN: llvm-objcopy -I binary -O elf64-littleaarch64 %t.txt %t.aarch64.o +# RUN: llvm-readobj --file-headers %t.aarch64.o | FileCheck %s --check-prefixes=CHECK,LE,AARCH64,64 + +# RUN: llvm-objcopy -I binary -O elf32-littlearm %t.txt %t.arm.o +# RUN: llvm-readobj --file-headers %t.arm.o | FileCheck %s --check-prefixes=CHECK,LE,ARM,32 + +# RUN: llvm-objcopy -I binary -O elf32-i386 %t.txt %t.i386.o +# RUN: llvm-readobj --file-headers %t.i386.o | FileCheck %s --check-prefixes=CHECK,LE,I386,32 + +# RUN: llvm-objcopy -I binary -O elf64-x86-64 %t.txt %t.x86-64.o +# RUN: llvm-readobj --file-headers %t.x86-64.o | FileCheck %s --check-prefixes=CHECK,LE,X86-64,64 + +# RUN: llvm-objcopy -I binary -O elf32-bigmips %t.txt %t.mips.o +# RUN: llvm-readobj --file-headers %t.mips.o | FileCheck %s --check-prefixes=CHECK,BE,MIPS,32 + +# RUN: llvm-objcopy -I binary -O elf64-powerpcle %t.txt %t.ppc64le.o +# RUN: llvm-readobj --file-headers %t.ppc64le.o | FileCheck %s --check-prefixes=CHECK,LE,PPC64,64 + +# RUN: llvm-objcopy -I binary -O elf32-littleriscv %t.txt %t.rv32.o +# RUN: llvm-readobj --file-headers %t.rv32.o | FileCheck %s --check-prefixes=CHECK,LE,RISCV32,32 + +# RUN: llvm-objcopy -I binary -O elf64-littleriscv %t.txt %t.rv64.o +# RUN: llvm-readobj --file-headers %t.rv64.o | FileCheck %s --check-prefixes=CHECK,LE,RISCV64,64 + +# RUN: llvm-objcopy -I binary -O elf32-sparc %t.txt %t.sparc.o +# RUN: llvm-readobj --file-headers %t.sparc.o | FileCheck %s --check-prefixes=CHECK,BE,SPARC,32 + +# RUN: llvm-objcopy -I binary -O elf32-sparcel %t.txt %t.sparcel.o +# RUN: llvm-readobj --file-headers %t.sparcel.o | FileCheck %s --check-prefixes=CHECK,LE,SPARCEL,32 + +# CHECK: Format: +# 32-SAME: ELF32- +# 64-SAME: ELF64- +# AARCH64-SAME: aarch64-little +# ARM-SAME: arm-little +# I386-SAME: i386 +# MIPS-SAME: mips{{$}} +# RISCV32-SAME: riscv{{$}} +# RISCV64-SAME: riscv{{$}} +# PPC-SAME: ppc{{$}} +# PPC64le-SAME: ppc64 +# SPARC-SAME: sparc +# SPARCEL-SAME: sparc +# X86-64-SAME: x86-64 + +# AARCH64-NEXT: Arch: aarch64 +# ARM-NEXT: Arch: arm +# I386-NEXT: Arch: i386 +# MIPS-NEXT: Arch: mips{{$}} +# PPC-NEXT: Arch: powerpc{{$}} +# PPC64-NEXT: Arch: powerpc64le +# RISCV32-NEXT: Arch: riscv32 +# RISCV64-NEXT: Arch: riscv64 +# SPARC-NEXT: Arch: sparc{{$}} +# SPARCEL-NEXT: Arch: sparcel +# X86-64-NEXT: Arch: x86_64 + +# 32-NEXT: AddressSize: 32bit +# 64-NEXT: AddressSize: 64bit + +# CHECK: ElfHeader { +# CHECK-NEXT: Ident { +# CHECK-NEXT: Magic: (7F 45 4C 46) +# 32-NEXT: Class: 32-bit (0x1) +# 64-NEXT: Class: 64-bit (0x2) +# LE-NEXT: DataEncoding: LittleEndian (0x1) +# BE-NEXT: DataEncoding: BigEndian (0x2) +# CHECK-NEXT: FileVersion: 1 +# CHECK-NEXT: OS/ABI: SystemV (0x0) +# CHECK-NEXT: ABIVersion: 0 +# CHECK-NEXT: Unused: (00 00 00 00 00 00 00) +# CHECK-NEXT: } +# CHECK-NEXT: Type: Relocatable (0x1) + +## In GNU objcopy, e_machine is EM_NONE unless -B is specifid. +## It is not very clear why it behaves this way. +## We fill in the field regardless of -B. +# AARCH64-NEXT: Machine: EM_AARCH64 (0xB7) +# ARM-NEXT: Machine: EM_ARM (0x28) +# I386-NEXT: Machine: EM_386 (0x3) +# MIPS-NEXT: Machine: EM_MIPS (0x8) +# PPC-NEXT: Machine: EM_PPC (0x14) +# PPC64-NEXT: Machine: EM_PPC64 (0x15) +# RISCV32-NEXT: Machine: EM_RISCV (0xF3) +# RISCV64-NEXT: Machine: EM_RISCV (0xF3) +# SPARC-NEXT: Machine: EM_SPARC (0x2) +# SPARCEL-NEXT: Machine: EM_SPARC (0x2) +# X86-64-NEXT: Machine: EM_X86_64 (0x3E) + +# CHECK-NEXT: Version: 1 +# CHECK-NEXT: Entry: 0x0 +# CHECK-NEXT: ProgramHeaderOffset: +# CHECK-NEXT: SectionHeaderOffset: +# CHECK-NEXT: Flags [ (0x0) +# CHECK-NEXT: ] +# 32-NEXT: HeaderSize: 52 +# 64-NEXT: HeaderSize: 64 +# 32-NEXT: ProgramHeaderEntrySize: 0 +# 64-NEXT: ProgramHeaderEntrySize: 0 +# CHECK-NEXT: ProgramHeaderCount: 0 +# 32-NEXT: SectionHeaderEntrySize: 40 +# 64-NEXT: SectionHeaderEntrySize: 64 +# CHECK-NEXT: SectionHeaderCount: 4 +# CHECK-NEXT: StringTableSectionIndex: +# CHECK-NEXT: } Index: llvm/trunk/test/tools/llvm-objcopy/ELF/new-symbol-visibility.test =================================================================== --- llvm/trunk/test/tools/llvm-objcopy/ELF/new-symbol-visibility.test +++ llvm/trunk/test/tools/llvm-objcopy/ELF/new-symbol-visibility.test @@ -1,22 +1,22 @@ ## Ensure that the visibility of the start, end and size symbols created when ## using binary input can be specified with the --new-symbol-visibility switch. -# RUN: llvm-objcopy -I binary -B i386:x86-64 %s %t.unspecified +# RUN: llvm-objcopy -I binary -O elf64-x86-64 %s %t.unspecified # RUN: llvm-readelf -s %t.unspecified | FileCheck %s --check-prefix=BINARY -DVISIBILITY=DEFAULT -# RUN: llvm-objcopy --new-symbol-visibility default -I binary -B i386:x86-64 %s %t.default +# RUN: llvm-objcopy --new-symbol-visibility default -I binary -O elf64-x86-64 %s %t.default # RUN: llvm-readelf -s %t.default | FileCheck %s --check-prefix=BINARY -DVISIBILITY=DEFAULT -# RUN: llvm-objcopy --new-symbol-visibility hidden -I binary -B i386:x86-64 %s %t.hidden +# RUN: llvm-objcopy --new-symbol-visibility hidden -I binary -O elf64-x86-64 %s %t.hidden # RUN: llvm-readelf -s %t.hidden | FileCheck %s --check-prefix=BINARY -DVISIBILITY=HIDDEN -# RUN: llvm-objcopy --new-symbol-visibility protected -I binary -B i386:x86-64 %s %t.protected +# RUN: llvm-objcopy --new-symbol-visibility protected -I binary -O elf64-x86-64 %s %t.protected # RUN: llvm-readelf -s %t.protected | FileCheck %s --check-prefix=BINARY -DVISIBILITY=PROTECTED -# RUN: llvm-objcopy --new-symbol-visibility internal -I binary -B i386:x86-64 %s %t.internal +# RUN: llvm-objcopy --new-symbol-visibility internal -I binary -O elf64-x86-64 %s %t.internal # RUN: llvm-readelf -s %t.internal | FileCheck %s --check-prefix=BINARY -DVISIBILITY=INTERNAL # BINARY: [[VISIBILITY]] {{.*}} _binary{{.*}}_start # BINARY-NEXT: [[VISIBILITY]] {{.*}} _binary{{.*}}_end # BINARY-NEXT: [[VISIBILITY]] {{.*}} _binary{{.*}}_size -# RUN: not llvm-objcopy --new-symbol-visibility fluff -I binary -B i386:x86-64 %s %t.error 2>&1 \ -# RUN: | FileCheck %s --check-prefix=ERR +# RUN: not llvm-objcopy --new-symbol-visibility fluff -I binary -O elf64-x86-64 \ +# RUN: %s %t.error 2>&1 | FileCheck %s --check-prefix=ERR # ERR: error: 'fluff' is not a valid symbol visibility Index: llvm/trunk/tools/llvm-objcopy/CopyConfig.cpp =================================================================== --- llvm/trunk/tools/llvm-objcopy/CopyConfig.cpp +++ llvm/trunk/tools/llvm-objcopy/CopyConfig.cpp @@ -491,14 +491,12 @@ .Default(FileFormat::Unspecified); if (Config.InputFormat == FileFormat::Binary) { auto BinaryArch = InputArgs.getLastArgValue(OBJCOPY_binary_architecture); - if (BinaryArch.empty()) - return createStringError( - errc::invalid_argument, - "specified binary input without specifiying an architecture"); - Expected MI = getMachineInfo(BinaryArch); - if (!MI) - return MI.takeError(); - Config.BinaryArch = *MI; + if (!BinaryArch.empty()) { + Expected MI = getMachineInfo(BinaryArch); + if (!MI) + return MI.takeError(); + Config.BinaryArch = *MI; + } } if (opt::Arg *A = InputArgs.getLastArg(OBJCOPY_new_symbol_visibility)) { @@ -520,12 +518,17 @@ .Case("binary", FileFormat::Binary) .Case("ihex", FileFormat::IHex) .Default(FileFormat::Unspecified); - if (Config.OutputFormat == FileFormat::Unspecified && !OutputFormat.empty()) { - Expected Target = getOutputTargetInfoByTargetName(OutputFormat); - if (!Target) - return Target.takeError(); - Config.OutputFormat = Target->Format; - Config.OutputArch = Target->Machine; + if (Config.OutputFormat == FileFormat::Unspecified) { + if (OutputFormat.empty()) { + Config.OutputFormat = Config.InputFormat; + } else { + Expected Target = + getOutputTargetInfoByTargetName(OutputFormat); + if (!Target) + return Target.takeError(); + Config.OutputFormat = Target->Format; + Config.OutputArch = Target->Machine; + } } if (auto Arg = InputArgs.getLastArg(OBJCOPY_compress_debug_sections,