Index: test/tools/llvm-objcopy/ELF/binary-input-with-arch.test =================================================================== --- test/tools/llvm-objcopy/ELF/binary-input-with-arch.test +++ test/tools/llvm-objcopy/ELF/binary-input-with-arch.test @@ -2,19 +2,25 @@ # 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: llvm-readobj --file-headers %t.o | FileCheck %s --check-prefixes=CHECK,SYSV # 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 +# elf64-x86-64-freebsd sets the OS/ABI field. +# RUN: llvm-objcopy -I binary -B i386 -O elf64-x86-64-freebsd %t.x-txt %t.freebsd.o +# RUN: llvm-readobj --file-headers %t.freebsd.o | FileCheck %s --check-prefixes=CHECK,FREEBSD + # CHECK: Format: ELF64-x86-64 # CHECK-NEXT: Arch: x86_64 # CHECK-NEXT: AddressSize: 64bit # CHECK: Class: 64-bit # CHECK: DataEncoding: LittleEndian +# SYSV: OS/ABI: SystemV +# FREEBSD: OS/ABI: FreeBSD # CHECK: Machine: EM_X86_64 # CHECK: HeaderSize: 64 # CHECK: SectionHeaderEntrySize: 64 Index: test/tools/llvm-objcopy/ELF/cross-arch-headers.test =================================================================== --- test/tools/llvm-objcopy/ELF/cross-arch-headers.test +++ test/tools/llvm-objcopy/ELF/cross-arch-headers.test @@ -1,19 +1,25 @@ # 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-readobj --file-headers %t.elf32_i386.o | FileCheck %s --check-prefixes=CHECK,I386,32,SYSV # 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-readobj --file-headers %t.elf32_ppcle.o | FileCheck %s --check-prefixes=CHECK,PPC,32,SYSV # 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-readobj --file-headers %t.elf32_x86_64.o | FileCheck %s --check-prefixes=CHECK,X86-64,32,SYSV # 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-readobj --file-headers %t.elf64_ppcle.o | FileCheck %s --check-prefixes=CHECK,PPC64,64,SYSV # 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 +# RUN: llvm-readobj --file-headers %t.elf64_x86_64.o | FileCheck %s --check-prefixes=CHECK,X86-64,64,SYSV + +# RUN: llvm-objcopy %t.o -O elf64-x86-64-freebsd %t.elf64_x86_64_freebsd.o +# RUN: llvm-readobj --file-headers %t.elf64_x86_64_freebsd.o | FileCheck %s --check-prefixes=CHECK,X86-64,64,FREEBSD + +# RUN: llvm-objcopy %t.o -O elf32-i386-freebsd %t.elf32_i386_freebsd.o +# RUN: llvm-readobj --file-headers %t.elf32_i386_freebsd.o | FileCheck %s --check-prefixes=CHECK,I386,32,FREEBSD !ELF FileHeader: @@ -21,6 +27,7 @@ Data: ELFDATA2LSB Type: ET_EXEC Machine: EM_386 + OSABI: ELFOSABI_STANDALONE # Arbitrary non-zero value. Sections: - Name: .text Type: SHT_PROGBITS @@ -59,6 +66,9 @@ # 64: Class: 64-bit # CHECK: DataEncoding: LittleEndian +# SYSV: OS/ABI: SystemV (0x0) +# FREEBSD: OS/ABI: FreeBSD (0x9) + # I386: Machine: EM_386 # PPC: Machine: EM_PPC # PPC64: Machine: EM_PPC64 Index: tools/llvm-objcopy/CopyConfig.h =================================================================== --- tools/llvm-objcopy/CopyConfig.h +++ tools/llvm-objcopy/CopyConfig.h @@ -30,6 +30,7 @@ // ELF file. struct MachineInfo { uint16_t EMachine; + uint8_t OSABI; bool Is64Bit; bool IsLittleEndian; }; Index: tools/llvm-objcopy/CopyConfig.cpp =================================================================== --- tools/llvm-objcopy/CopyConfig.cpp +++ tools/llvm-objcopy/CopyConfig.cpp @@ -282,14 +282,14 @@ } static const StringMap ArchMap{ - // 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}}, + // 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}}, }; static Expected getMachineInfo(StringRef Arch) { @@ -301,12 +301,15 @@ } static const StringMap 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}}, + // 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}}, }; static Expected Index: tools/llvm-objcopy/ELF/ELFObjcopy.cpp =================================================================== --- tools/llvm-objcopy/ELF/ELFObjcopy.cpp +++ tools/llvm-objcopy/ELF/ELFObjcopy.cpp @@ -224,8 +224,10 @@ }; if (Error E = DWOFile->removeSections(OnlyKeepDWOPred)) return E; - if (Config.OutputArch) + if (Config.OutputArch) { DWOFile->Machine = Config.OutputArch.getValue().EMachine; + DWOFile->OSABI = Config.OutputArch.getValue().OSABI; + } FileBuffer FB(File); auto Writer = createWriter(Config, *DWOFile, FB, OutputElfType); if (Error E = Writer->finalize()) @@ -311,8 +313,10 @@ splitDWOToFile(Config, Reader, Config.SplitDWO, OutputElfType)) return E; - if (Config.OutputArch) + if (Config.OutputArch) { Obj.Machine = Config.OutputArch.getValue().EMachine; + Obj.OSABI = Config.OutputArch.getValue().OSABI; + } // TODO: update or remove symbols only if there is an option that affects // them.