From 5f1743cd074cc7d45744d1acc8db379513b4501c Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Tue, 2 Jul 2024 11:00:42 -0700 Subject: [PATCH] [ELF] Infer EI_OSABI from object files The first object file whose EI_OSABI is not ELFOSABI_NONE is selected. This is useful for some OSes to identify themselves. This achieves similar effects to BFD emulations `ld.lld -m *_fbsd` but is more lightweight. Pull Request: https://github.com/llvm/llvm-project/pull/97144 --- lld/ELF/Driver.cpp | 16 +++++++++++----- lld/test/ELF/basic-freebsd.s | 15 ++++++++++++--- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp index ed773f5e69f773..73e260073da0c2 100644 --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -2021,16 +2021,22 @@ void LinkerDriver::inferMachineType() { if (config->ekind != ELFNoneKind) return; + bool inferred = false; for (InputFile *f : files) { if (f->ekind == ELFNoneKind) continue; - config->ekind = f->ekind; - config->emachine = f->emachine; + if (!inferred) { + inferred = true; + config->ekind = f->ekind; + config->emachine = f->emachine; + config->mipsN32Abi = config->emachine == EM_MIPS && isMipsN32Abi(f); + } config->osabi = f->osabi; - config->mipsN32Abi = config->emachine == EM_MIPS && isMipsN32Abi(f); - return; + if (f->osabi != ELFOSABI_NONE) + return; } - error("target emulation unknown: -m or at least one .o file required"); + if (!inferred) + error("target emulation unknown: -m or at least one .o file required"); } // Parse -z max-page-size=. The default value is defined by diff --git a/lld/test/ELF/basic-freebsd.s b/lld/test/ELF/basic-freebsd.s index 078f9744244633..a34f568bbcf81a 100644 --- a/lld/test/ELF/basic-freebsd.s +++ b/lld/test/ELF/basic-freebsd.s @@ -1,15 +1,24 @@ # REQUIRES: x86 # Verify that OSABI is set to the correct value. -# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-freebsd %s -o %t -# RUN: ld.lld %t -o %t2 -# RUN: llvm-readobj --file-headers %t2 | FileCheck %s +# RUN: rm -rf %t && split-file %s %t && cd %t +# RUN: llvm-mc -filetype=obj -triple=x86_64 empty.s -o empty.o +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-freebsd a.s -o a.o +# RUN: llvm-mc -filetype=obj -triple=x86_64-linux gnu.s -o gnu.o +# RUN: ld.lld a.o -o out +# RUN: llvm-readobj --file-headers out | FileCheck %s +# RUN: ld.lld empty.o a.o gnu.o empty.o -o out2 +# RUN: llvm-readobj --file-headers out2 | FileCheck %s +#--- empty.s +#--- a.s .globl _start _start: mov $1, %rax mov $42, %rdi syscall +#--- gnu.s +.section retain,"aR" # CHECK: ElfHeader { # CHECK-NEXT: Ident {