[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 20:52:38 PDT 2015
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.
-- 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/00abe669/attachment.html>
More information about the llvm-commits
mailing list