Re: [x86-64] Compressed kernel does not boot when built with binutils 2.27 and CONFIG_RELOCATABLE is not set

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, Nov 17, 2016 at 2:47 AM, Carlos Chinea <carlos.chinea@xxxxxxxxx> wrote:
> Hi,
>
> We have been trying to boot up a kernel (4.9-rc5, also tested with 4.4.31
> and 4.1.35) build with the latest binutils 2.27.
> However, all those kernels fail to boot on qemu and no console logs can be
> seen.
> The same kernels build with binutils 2.26.1 boot without problems.
>
> Here some extra info:
>
> We have used qemu 1.6.2 to test this, with the following command:
>
> qemu-system-x86_64 -nographic  -nodefaults  -serial stdio  -append
> "console=ttyS0,38400" -kernel bzImage
>
> and we have used gcc 4.9.4 and binutils 2.27 to build the kernel.
> The kernel is configure with:
>
> # CONFIG_RELOCATABLE is not set
>
> you can see the full defconfig at the end of the email.
>
> After bisecting binutils, we narrowed the issue to the following commit:
>
> commit bae420ef26f4331415b0503141c5931318025906
> Author: H.J. Lu <hjl.tools@xxxxxxxxx>
> Date:   Fri Feb 26 09:38:08 2016 -0800
>
>     Optimize x86 GOT32X/GOTPCRELX relocations
>
>     R_386_GOT32X, R_X86_64_GOTPCRELX and R_X86_64_REX_GOTPCRELX relocations
>     retrieve the symbol address via its GOT slot.  If the symbol address is
>     known at the link-time, we can use it directly by changing instruction
>     encoding.  Indirect branch can only be converted to PC relative direct
>     branch.  MOV can be changed to LEA or encoded differently with signed
>     address.  The subset of binary operations can be encoded only with
>     signed address.
>
>     If undefined weak symbol is resolved to zero link-time, we can use it
>     as address.  Zero addresss can't used with PC relative direct branch
>     when PIC is true since the current PC is unknown.  In 64-bit, 32-bit
>     relocation for PC relatiave direct branch to zero may also overflow.
>
>     If this optimization causes relocation overflow, --no-relax can be used
>     to work around it.
>
>     bfd/
>
>             PR ld/19609
>             * elf32-i386.c (elf_i386_convert_load): Convert to R_386_32 for
>             load with locally bound symbols if PIC is false or there is no
>             base register.  Optimize branch to 0 if PIC is false.
>             (elf_i386_relocate_section): Don't generate dynamic relocations
>             against undefined weak symbols if PIC is false.
>             * elf64-x86-64.c (elf_x86_64_convert_load): Disable optimization
>             if we can't estimate relocation overflow with --no-relax.
>             Convert to R_X86_64_32S/R_X86_64_32 for load with locally bound
>             symbols if PIC is false.  Optimize branch to 0 if PIC is false.
>             (elf_x86_64_relocate_section): Don't generate dynamic
> relocations
>             against undefined weak symbols if PIC is false.
>
> So it seems that with the latest binutils the linker does some optimization
> that breaks
> the booting.
> Disabling the linker relaxation with (--no-relax) fixes the issue.
> The same happens whew linking with (-pie -z noreloc-overflow) options.
>

The compressed kernel is built with PIE/PIC and may be loaded at any
address by bootloader, regardless if CONFIG_RELOCATABLE is set or
not.  Please try

diff --git a/arch/x86/boot/compressed/Makefile
b/arch/x86/boot/compressed/Makefile
index 536ccfc..e598a81 100644
--- a/arch/x86/boot/compressed/Makefile
+++ b/arch/x86/boot/compressed/Makefile
@@ -40,7 +40,6 @@ GCOV_PROFILE := n
 UBSAN_SANITIZE :=n

 LDFLAGS := -m elf_$(UTS_MACHINE)
-ifeq ($(CONFIG_RELOCATABLE),y)
 # If kernel is relocatable, build compressed kernel as PIE.
 ifeq ($(CONFIG_X86_32),y)
 LDFLAGS += $(call ld-option, -pie) $(call ld-option, --no-dynamic-linker)
@@ -51,7 +50,6 @@ else
 LDFLAGS += $(shell $(LD) --help 2>&1 | grep -q "\-z noreloc-overflow" \
   && echo "-z noreloc-overflow -pie --no-dynamic-linker")
 endif
-endif
 LDFLAGS_vmlinux := -T

 hostprogs-y   := mkpiggy


-- 
H.J.
--
To unsubscribe from this list: send the line "unsubscribe linux-x86_64" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux ia64]     [Linux Kernel]     [DCCP]     [Linux ARM]     [Yosemite News]     [Linux SCSI]     [Linux Hams]
  Powered by Linux