• H.J. Lu's avatar
    x86/build: Build compressed x86 kernels as PIE · 6d92bc9d
    H.J. Lu authored
    The 32-bit x86 assembler in binutils 2.26 will generate R_386_GOT32X
    relocation to get the symbol address in PIC.  When the compressed x86
    kernel isn't built as PIC, the linker optimizes R_386_GOT32X relocations
    to their fixed symbol addresses.  However, when the compressed x86
    kernel is loaded at a different address, it leads to the following
    load failure:
    
      Failed to allocate space for phdrs
    
    during the decompression stage.
    
    If the compressed x86 kernel is relocatable at run-time, it should be
    compiled with -fPIE, instead of -fPIC, if possible and should be built as
    Position Independent Executable (PIE) so that linker won't optimize
    R_386_GOT32X relocation to its fixed symbol address.
    
    Older linkers generate R_386_32 relocations against locally defined
    symbols, _bss, _ebss, _got and _egot, in PIE.  It isn't wrong, just less
    optimal than R_386_RELATIVE.  But the x86 kernel fails to properly handle
    R_386_32 relocations when relocating the kernel.  To generate
    R_386_RELATIVE relocations, we mark _bss, _ebss, _got and _egot as
    hidden in both 32-bit and 64-bit x86 kernels.
    
    To build a 64-bit compressed x86 kernel as PIE, we need to disable the
    relocation overflow check to avoid relocation overflow errors. We do
    this with a new linker command-line option, -z noreloc-overflow, which
    got added recently:
    
     commit 4c10bbaa0912742322f10d9d5bb630ba4e15dfa7
     Author: H.J. Lu <hjl.tools@gmail.com>
     Date:   Tue Mar 15 11:07:06 2016 -0700
    
        Add -z noreloc-overflow option to x86-64 ld
    
        Add -z noreloc-overflow command-line option to the x86-64 ELF linker to
        disable relocation overflow check.  This can be used to avoid relocation
        overflow check if there will be no dynamic relocation overflow at
        run-time.
    
    The 64-bit compressed x86 kernel is built as PIE only if the linker supports
    -z noreloc-overflow.  So far 64-bit relocatable compressed x86 kernel
    boots fine even when it is built as a normal executable.
    Signed-off-by: default avatarH.J. Lu <hjl.tools@gmail.com>
    Cc: Andy Lutomirski <luto@amacapital.net>
    Cc: Borislav Petkov <bp@alien8.de>
    Cc: Brian Gerst <brgerst@gmail.com>
    Cc: Denys Vlasenko <dvlasenk@redhat.com>
    Cc: H. Peter Anvin <hpa@zytor.com>
    Cc: Linus Torvalds <torvalds@linux-foundation.org>
    Cc: Peter Zijlstra <peterz@infradead.org>
    Cc: Thomas Gleixner <tglx@linutronix.de>
    Cc: linux-kernel@vger.kernel.org
    [ Edited the changelog and comments. ]
    Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
    6d92bc9d
head_64.S 10.2 KB