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

Sean Silva via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 24 21:01:16 PDT 2015


On Thu, Sep 24, 2015 at 8:56 PM, Rui Ueyama <ruiu at google.com> wrote:

> On Thu, Sep 24, 2015 at 8:52 PM, Sean Silva <chisophugis at gmail.com> wrote:
>
>>
>>
>> On Thu, Sep 24, 2015 at 7:29 PM, Rui Ueyama <ruiu at google.com> wrote:
>>
>>> 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?
>>>
>>
>> Clang does not produce executables.
>>
>
> My point is that we check for compiler outputs but do not have tests that
> covers end-to-end user's real use case.
>

We do. Things like test-suite etc. My question here is if we could perhaps
get a simpler/more targeted sanity check as part of the regular lit tests.
I guess it got lost, but what I originally replying about is providing a
comment explaining what the test file is expected to do and how to test it
manually. Otherwise, what is the point of actually having code in _start?

-- Sean Silva


>
>
>> -- Sean Silva
>>
>>
>>>
>>>
>>>> -- 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/80e473e5/attachment-0001.html>


More information about the llvm-commits mailing list