[llvm-objcopy]Add support for *-freebsd output formats
GNU objcopy can support output formats like elf32-i386-freebsd and
elf64-x86-64-freebsd. The only difference from their regular non-freebsd
counterparts that I have observed is that the freebsd versions set the
OS/ABI field to ELFOSABI_FREEBSD. This patch sets the OS/ABI field
according based on the format whenever --output-format is specified.
Reviewed by: rupprecht, grimar
Differential Revision: https://reviews.llvm.org/D59645
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@356737 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/tools/llvm-objcopy/ELF/binary-input-with-arch.test b/test/tools/llvm-objcopy/ELF/binary-input-with-arch.test
index e8ae841..ff2e82c 100644
--- a/test/tools/llvm-objcopy/ELF/binary-input-with-arch.test
+++ b/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
diff --git a/test/tools/llvm-objcopy/ELF/cross-arch-headers.test b/test/tools/llvm-objcopy/ELF/cross-arch-headers.test
index ec76fa6..3e78ee3 100644
--- a/test/tools/llvm-objcopy/ELF/cross-arch-headers.test
+++ b/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
diff --git a/tools/llvm-objcopy/CopyConfig.cpp b/tools/llvm-objcopy/CopyConfig.cpp
index dd3fa3e..bc2b384 100644
--- a/tools/llvm-objcopy/CopyConfig.cpp
+++ b/tools/llvm-objcopy/CopyConfig.cpp
@@ -282,14 +282,14 @@
}
static const StringMap<MachineInfo> 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<const MachineInfo &> getMachineInfo(StringRef Arch) {
@@ -301,12 +301,15 @@
}
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}},
+ // 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<const MachineInfo &>
diff --git a/tools/llvm-objcopy/CopyConfig.h b/tools/llvm-objcopy/CopyConfig.h
index c9fb4ec..1c1d74f 100644
--- a/tools/llvm-objcopy/CopyConfig.h
+++ b/tools/llvm-objcopy/CopyConfig.h
@@ -30,6 +30,7 @@
// ELF file.
struct MachineInfo {
uint16_t EMachine;
+ uint8_t OSABI;
bool Is64Bit;
bool IsLittleEndian;
};
diff --git a/tools/llvm-objcopy/ELF/ELFObjcopy.cpp b/tools/llvm-objcopy/ELF/ELFObjcopy.cpp
index 883ffa0..fc1ac38 100644
--- a/tools/llvm-objcopy/ELF/ELFObjcopy.cpp
+++ b/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.