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 17/11/16 18:20, H.J. Lu wrote:
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

Yep, I was wondering why the if CONFIG_RELOCATABLE was there..
And yes it is working fine for x86_64 and 4.9-rc5

Do you want to take care of the patch or do you want me to do it ?
Btw, I guess the patch will qualify for stable.

Br and thanks,
Carlos

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



--
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