[llvm-objcopy]Add support for *-freebsd output formats
authorJames Henderson <jh7370@my.bristol.ac.uk>
Fri, 22 Mar 2019 10:21:09 +0000 (10:21 +0000)
committerJames Henderson <jh7370@my.bristol.ac.uk>
Fri, 22 Mar 2019 10:21:09 +0000 (10:21 +0000)
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

llvm-svn: 356737

llvm/test/tools/llvm-objcopy/ELF/binary-input-with-arch.test
llvm/test/tools/llvm-objcopy/ELF/cross-arch-headers.test
llvm/tools/llvm-objcopy/CopyConfig.cpp
llvm/tools/llvm-objcopy/CopyConfig.h
llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp

index e8ae841..ff2e82c 100644 (file)
@@ -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 ec76fa6..3e78ee3 100644 (file)
@@ -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 @@ FileHeader:
   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 @@ Symbols:
 # 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 dd3fa3e..bc2b384 100644 (file)
@@ -282,14 +282,14 @@ static Expected<NewSymbolInfo> parseNewSymbolInfo(StringRef FlagValue) {
 }
 
 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 Expected<const MachineInfo &> getMachineInfo(StringRef Arch) {
 }
 
 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 &>
index c9fb4ec..1c1d74f 100644 (file)
@@ -30,6 +30,7 @@ namespace objcopy {
 // ELF file.
 struct MachineInfo {
   uint16_t EMachine;
+  uint8_t OSABI;
   bool Is64Bit;
   bool IsLittleEndian;
 };
index 883ffa0..fc1ac38 100644 (file)
@@ -224,8 +224,10 @@ static Error splitDWOToFile(const CopyConfig &Config, const Reader &Reader,
   };
   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 @@ static Error handleArgs(const CopyConfig &Config, Object &Obj,
             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.