[PATCH] D95370: [ELF] Infer OSABI from input files for -m options without explicit OSABI

Alexander Richardson via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Jan 25 08:42:17 PST 2021


arichardson created this revision.
arichardson added reviewers: MaskRay, jrtc27, kevans, dim, emaste, bsdjhb.
Herald added subscribers: luismarques, s.egerton, PkmX, simoncook, krytarowski.
arichardson requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

Currently only -m *_fbsd and -m msp430elf explicitly specifiy the OSABI
field, all others set the value to zero.
FreeBSD expects the OSABI field to be set for all executables, but both
GCC and Clang pass `-melf64lriscv` to the linker. This causes all RISC-V
executables to have a SysV OSABI which confuses tools such as ldd.

This patch changes the behaviour to infer the OSABI from the first input
.o file for -m options that don't encode a specific OSABI.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D95370

Files:
  lld/ELF/Config.h
  lld/ELF/Driver.cpp
  lld/ELF/SyntheticSections.cpp
  lld/test/ELF/basic-freebsd.s


Index: lld/test/ELF/basic-freebsd.s
===================================================================
--- lld/test/ELF/basic-freebsd.s
+++ lld/test/ELF/basic-freebsd.s
@@ -2,8 +2,16 @@
 # Verify that OSABI is set to the correct value.
 
 # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-freebsd %s -o %t
+# RUN: llvm-readobj --file-headers %t | FileCheck %s --check-prefixes CHECK,CHECK-OBJ
 # RUN: ld.lld %t -o %t2
-# RUN: llvm-readobj --file-headers %t2 | FileCheck %s
+# RUN: llvm-readobj --file-headers %t2 | FileCheck %s --check-prefixes CHECK,CHECK-EXE
+# An explicit _fbsd emulation should set the FreeBSD OSABI
+# RUN: ld.lld -m elf_x86_64_fbsd %t -o %t2
+# RUN: llvm-readobj --file-headers %t2 | FileCheck %s --check-prefixes CHECK,CHECK-EXE
+# If the emulation does not encode a specific OSABI, we should infer
+# it from the first input .o file rather than using SysV.
+# RUN: ld.lld -m elf_x86_64 %t -o %t2
+# RUN: llvm-readobj --file-headers %t2 | FileCheck %s --check-prefixes CHECK,CHECK-EXE
 
 .globl _start
 _start:
@@ -21,5 +29,6 @@
 # CHECK-NEXT:     ABIVersion: 0
 # CHECK-NEXT:     Unused: (00 00 00 00 00 00 00)
 # CHECK-NEXT:   }
-# CHECK-NEXT:   Type: Executable (0x2)
-# CHECK-NEXT:   Machine: EM_X86_64 (0x3E)
+# CHECK-OBJ-NEXT: Type: Relocatable (0x1)
+# CHECK-EXE-NEXT: Type: Executable (0x2)
+# CHECK-NEXT:     Machine: EM_X86_64 (0x3E)
Index: lld/ELF/SyntheticSections.cpp
===================================================================
--- lld/ELF/SyntheticSections.cpp
+++ lld/ELF/SyntheticSections.cpp
@@ -3709,7 +3709,7 @@
   eHdr->e_ident[EI_CLASS] = config->is64 ? ELFCLASS64 : ELFCLASS32;
   eHdr->e_ident[EI_DATA] = config->isLE ? ELFDATA2LSB : ELFDATA2MSB;
   eHdr->e_ident[EI_VERSION] = EV_CURRENT;
-  eHdr->e_ident[EI_OSABI] = config->osabi;
+  eHdr->e_ident[EI_OSABI] = *config->osabi;
   eHdr->e_ident[EI_ABIVERSION] = getAbiVersion();
   eHdr->e_machine = config->emachine;
   eHdr->e_version = EV_CURRENT;
Index: lld/ELF/Driver.cpp
===================================================================
--- lld/ELF/Driver.cpp
+++ lld/ELF/Driver.cpp
@@ -134,8 +134,9 @@
 }
 
 // Parses a linker -m option.
-static std::tuple<ELFKind, uint16_t, uint8_t> parseEmulation(StringRef emul) {
-  uint8_t osabi = 0;
+static std::tuple<ELFKind, uint16_t, Optional<uint8_t>>
+parseEmulation(StringRef emul) {
+  Optional<uint8_t> osabi;
   StringRef s = emul;
   if (s.endswith("_fbsd")) {
     s = s.drop_back(5);
@@ -1465,16 +1466,19 @@
 
 // If -m <machine_type> was not given, infer it from object files.
 void LinkerDriver::inferMachineType() {
-  if (config->ekind != ELFNoneKind)
+  if (config->ekind != ELFNoneKind && config->osabi)
     return;
 
   for (InputFile *f : files) {
     if (f->ekind == ELFNoneKind)
       continue;
-    config->ekind = f->ekind;
-    config->emachine = f->emachine;
-    config->osabi = f->osabi;
-    config->mipsN32Abi = config->emachine == EM_MIPS && isMipsN32Abi(f);
+    if (config->ekind == ELFNoneKind) {
+      config->ekind = f->ekind;
+      config->emachine = f->emachine;
+      config->mipsN32Abi = config->emachine == EM_MIPS && isMipsN32Abi(f);
+    }
+    if (!config->osabi)
+      config->osabi = f->osabi;
     return;
   }
   error("target emulation unknown: -m or at least one .o file required");
Index: lld/ELF/Config.h
===================================================================
--- lld/ELF/Config.h
+++ lld/ELF/Config.h
@@ -89,7 +89,7 @@
 // and such fields have the same name as the corresponding options.
 // Most fields are initialized by the driver.
 struct Configuration {
-  uint8_t osabi = 0;
+  llvm::Optional<uint8_t> osabi;
   uint32_t andFeatures = 0;
   llvm::CachePruningPolicy thinLTOCachePolicy;
   llvm::SetVector<llvm::CachedHashString> dependencyFiles; // for --dependency-file


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D95370.319028.patch
Type: text/x-patch
Size: 3809 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210125/31cc2f74/attachment.bin>


More information about the llvm-commits mailing list