[lld] r248554 - [ELF2] Fix binaries so they actually run on FreeBSD.

Rui Ueyama via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 24 19:29:02 PDT 2015


On Thu, Sep 24, 2015 at 7:25 PM, Sean Silva via llvm-commits <
llvm-commits at lists.llvm.org> wrote:

>
>
> On Thu, Sep 24, 2015 at 6:59 PM, Davide Italiano via llvm-commits <
> llvm-commits at lists.llvm.org> wrote:
>
>> Author: davide
>> Date: Thu Sep 24 20:59:13 2015
>> New Revision: 248554
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=248554&view=rev
>> Log:
>> [ELF2] Fix binaries so they actually run on FreeBSD.
>>
>> Since FreeBSD 4.1, the kernel expects binaries to be marked with
>> ELFOSABI_FREEBSD in the ELF header to exec() them. LLD unconditionally
>> sets OSABI to ELF_OSABINONE, and everything linked with it won't run
>> on FreeBSD (unless explicitly rebranded).
>>
>> Example:
>> % ./aarch64-hello
>> ELF binary type "0" not known.
>> zsh: exec format error: ./aarch64-hello
>>
>> FreeBSD could be modified to accept ELF_OSABINONE, but that would break
>> all
>> existing binaries, so the kernel needs to support both ABINONE and
>> ABIFREEBSD.
>> I plan to push this change in FreeBSD one day, which, unfortunately, is
>> not today. This code patches lld so it sets the header field correctly.
>>
>> For completeness, the rationale of this change is explained in the FreeBSD
>> commit message, and it's apparently to pleasee binutils maintainers at
>> the time.
>> https://svnweb.freebsd.org/base?view=revision&revision=59342
>>
>> Differential Revision:   http://reviews.llvm.org/D13140
>>
>> Added:
>>     lld/trunk/test/elf2/basic-freebsd.s
>> Modified:
>>     lld/trunk/ELF/InputFiles.h
>>     lld/trunk/ELF/Writer.cpp
>>
>> Modified: lld/trunk/ELF/InputFiles.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.h?rev=248554&r1=248553&r2=248554&view=diff
>>
>> ==============================================================================
>> --- lld/trunk/ELF/InputFiles.h (original)
>> +++ lld/trunk/ELF/InputFiles.h Thu Sep 24 20:59:13 2015
>> @@ -105,6 +105,9 @@ public:
>>    llvm::object::ELFFile<ELFT> &getObj() { return ELFObj; }
>>
>>    uint16_t getEMachine() const { return getObj().getHeader()->e_machine;
>> }
>> +  uint8_t getOSABI() const {
>> +    return getObj().getHeader()->e_ident[llvm::ELF::EI_OSABI];
>> +  }
>>
>>    StringRef getStringTable() const { return StringTable; }
>>
>>
>> Modified: lld/trunk/ELF/Writer.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=248554&r1=248553&r2=248554&view=diff
>>
>> ==============================================================================
>> --- lld/trunk/ELF/Writer.cpp (original)
>> +++ lld/trunk/ELF/Writer.cpp Thu Sep 24 20:59:13 2015
>> @@ -500,14 +500,15 @@ template <class ELFT> void Writer<ELFT>:
>>                                 ? ELFDATA2LSB
>>                                 : ELFDATA2MSB;
>>    EHdr->e_ident[EI_VERSION] = EV_CURRENT;
>> -  EHdr->e_ident[EI_OSABI] = ELFOSABI_NONE;
>> +
>> +  const SymbolTable &Symtab = SymTabSec.getSymTable();
>> +  auto &FirstObj = cast<ObjectFile<ELFT>>(*Symtab.getFirstELF());
>> +  EHdr->e_ident[EI_OSABI] = FirstObj.getOSABI();
>>
>>    // FIXME: Generalize the segment construction similar to how we create
>>    // output sections.
>> -  const SymbolTable &Symtab = SymTabSec.getSymTable();
>>
>>    EHdr->e_type = Config->Shared ? ET_DYN : ET_EXEC;
>> -  auto &FirstObj = cast<ObjectFile<ELFT>>(*Symtab.getFirstELF());
>>    EHdr->e_machine = FirstObj.getEMachine();
>>    EHdr->e_version = EV_CURRENT;
>>    SymbolBody *Entry = Symtab.getEntrySym();
>>
>> Added: lld/trunk/test/elf2/basic-freebsd.s
>> URL:
>> http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf2/basic-freebsd.s?rev=248554&view=auto
>>
>> ==============================================================================
>> --- lld/trunk/test/elf2/basic-freebsd.s (added)
>> +++ lld/trunk/test/elf2/basic-freebsd.s Thu Sep 24 20:59:13 2015
>> @@ -0,0 +1,25 @@
>> +# Verify that OSABI is set to the correct value.
>> +
>> +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-freebsd %s -o %t
>> +# RUN: lld -flavor gnu2 %t -o %t2
>> +# RUN: llvm-readobj -file-headers %t2 | FileCheck %s
>> +# REQUIRES: x86
>> +
>> +.globl _start
>> +_start:
>> +  mov $1, %rax
>> +  mov $42, %rdi
>> +  syscall
>> +
>> +# CHECK: ElfHeader {
>> +# CHECK-NEXT:   Ident {
>> +# CHECK-NEXT:     Magic: (7F 45 4C 46)
>> +# CHECK-NEXT:     Class: 64-bit (0x2)
>> +# CHECK-NEXT:     DataEncoding: LittleEndian (0x1)
>> +# CHECK-NEXT:     FileVersion: 1
>> +# CHECK-NEXT:     OS/ABI: FreeBSD (0x9)
>> +# 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)
>>
>
> Presumably the more important thing for this test is that it actually
> loads and runs on amd64 freebsd. Any ideas how we could fit that into our
> testing? (I don't think we have something like `REQUIRES:
> amd64-host,freebsd-host` that we could conditionalize actually running it).
> Hopefully it won't happen, but it's conceivable that some low-level layout
> change or something could cause it to start failing without us noticing
> (e.g. something gets pushed out of the first page).
>

What do we do for clang? Do we have a test which runs clang and then
execute its output?


> -- Sean Silva
>
>
>>
>>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>>
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150924/81bbba0e/attachment.html>


More information about the llvm-commits mailing list