Bug 492183

Summary: ld linker script behavior regresses between binutils-2.18.50.0.9-8.fc10.i386 and binutils-2.19.51.0.2-16.fc11.i586
Product: [Fedora] Fedora Reporter: Peter Jones <pjones>
Component: binutilsAssignee: Nick Clifton <nickc>
Status: CLOSED NEXTRELEASE QA Contact: Fedora Extras Quality Assurance <extras-qa>
Severity: urgent Docs Contact:
Priority: low    
Version: rawhideCC: jakub, jan.kratochvil, katzj, nickc, roland
Target Milestone: ---   
Target Release: ---   
Hardware: i386   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2009-04-01 13:49:08 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On:    
Bug Blocks: 446452    
Attachments:
Description Flags
linker script in use.
none
Extended linker script none

Description Peter Jones 2009-03-25 19:15:35 UTC
Created attachment 336693 [details]
linker script in use.

Description of problem: in gnu-efi, we're using a a custom linker script.  In f10 it works fine, but in rawhide, linking produces errors:

/usr/bin/gcc -I./../apps -I./../apps/../inc -I./../apps/../inc/ia32 -I./../apps/../inc/protocol   -O2 -fpic -Wall -fshort-wchar -fno-strict-aliasing -fno-merge-constants -DCONFIG_ia32 -D__KERNEL__ -I/usr/src/sys/build/include -c t.c -o t.o
/usr/bin/ld -nostdlib -T ./../apps/../gnuefi/elf_ia32_efi.lds -shared -Bsymbolic -L../lib -L../gnuefi ../gnuefi/crt0-efi-ia32.o t.o -o t.so -lefi -lgnuefi /usr/lib/gcc/i586-redhat-linux/4.4.0/libgcc.a
/usr/bin/ld: section .data [0000000000000000 -> 0000000000002317] overlaps section .hash [0000000000000000 -> 0000000000000653]
/usr/bin/ld: section .text [0000000000001000 -> 0000000000005ee1] overlaps section .data [0000000000000000 -> 0000000000002317]
/usr/bin/ld: section .dynamic [0000000000003000 -> 0000000000003077] overlaps section .text [0000000000001000 -> 0000000000005ee1]
/usr/bin/ld: t.so: section .data vma 0x0 overlaps previous sections
/usr/bin/ld: t.so: section .text vma 0x1000 overlaps previous sections
/usr/bin/ld: t.so: section .dynamic vma 0x3000 overlaps previous sections
/usr/bin/ld: t.so: section .rel vma 0x4000 overlaps previous sections
/usr/bin/ld: t.so: section .dynsym vma 0x5000 overlaps previous sections
/usr/bin/ld: t.so: section .dynstr vma 0x6000 overlaps previous sections
make[1]: *** [t.so] Error 1

This doesn't really make sense, as the linker script (attached) doesn't allow .data to be at 0.

(This is keeping us from booting 1st-gen apple EFI machines, which we have supported in the past.)

Comment 1 Roland McGrath 2009-03-25 19:23:24 UTC
I don't see anything wrong in the linker script.  Moreover, I don't know any reason why ld's behavior on this should have changed from f10 to f11.

Comment 2 Nick Clifton 2009-03-27 10:28:37 UTC
Hi Peter,

  Can you provide a way to reproduce this problem in full ?  I tried using a normal i686-pc-linux-gnu toolchain but could not make it happen.

  It seems to me however that maybe the problem is that your linker script is not being used, despite it being provided on the gcc command line.  Could you try adding "-v" and "-Wl,--verbose" to the command line to check that the correct script is being used ?

Cheers
  Nick

Comment 3 Peter Jones 2009-03-27 14:53:38 UTC
vroomfondel:~/build/BUILD/gnu-efi-3.0e/apps$ /usr/bin/ld --verbose -nostdlib -T ./../gnuefi/elf_ia32_efi.lds -shared -Bsymbolic -L../lib -L../gnuefi ../gnuefi/crt0-efi-ia32.o t.o -o t.so -lefi -lgnuefi /usr/lib/gcc/i586-redhat-linux/4.4.0/libgcc.a
vroomfondel:~/build/BUILD/gnu-efi-3.0e/apps$ /usr/bin/ld --verbose -nostdlib -T ./../gnuefi/elf_ia32_efi.lds -shared -Bsymbolic -L../lib -L../gnuefi ../gnuefi/crt0-efi-ia32.o t.o -o t.so -lefi -lgnuefi /usr/lib/gcc/i586-redhat-linux/4.4.0/libgcc.a
GNU ld version 2.19.51.0.2-16.fc11 20090204
  Supported emulations:
   elf_i386
   i386linux
   elf_x86_64
opened script file ./../gnuefi/elf_ia32_efi.lds
using external linker script:
==================================================
OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
OUTPUT_ARCH(i386)
ENTRY(_start)
SECTIONS
{
  . = 0;
  ImageBase = .;
  .hash : { *(.hash) }	/* this MUST come first! */
  . = ALIGN(4096);
  .text :
  {
   *(.text)
   *(.text.*)
   *(.gnu.linkonce.t.*)
  }
  .reloc :
  {
   *(.reloc)
  }
  . = ALIGN(4096);
  .data :
  {
   *(.rodata*)
   *(.data)
   *(.data1)
   *(.data.*)
   *(.sdata)
   *(.got.plt)
   *(.got)
   /* the EFI loader doesn't seem to like a .bss section, so we stick
      it all into .data: */
   *(.sbss)
   *(.scommon)
   *(.dynbss)
   *(.bss)
   *(COMMON)
  }
  . = ALIGN(4096);
  .dynamic  : { *(.dynamic) }
  . = ALIGN(4096);
  .rel :
  {
    *(.rel.data)
    *(.rel.data.*)
    *(.rel.got)
    *(.rel.stab)
    *(.data.rel.ro.local)
    *(.data.rel.local)
    *(.data.rel.ro)
    *(.data.rel*)
  }
  . = ALIGN(4096);
  .dynsym   : { *(.dynsym) }
  . = ALIGN(4096);
  .dynstr   : { *(.dynstr) }
  . = ALIGN(4096);
  /DISCARD/ :
  {
    *(.rel.reloc)
    *(.eh_frame)
  }
}

==================================================
attempt to open ../gnuefi/crt0-efi-ia32.o succeeded
../gnuefi/crt0-efi-ia32.o
attempt to open t.o succeeded
t.o
attempt to open ../lib/libefi.so failed
attempt to open ../lib/libefi.a succeeded
(../lib/libefi.a)init.o
(../lib/libefi.a)misc.o
(../lib/libefi.a)str.o
(../lib/libefi.a)efirtlib.o
(../lib/libefi.a)rtstr.o
(../lib/libefi.a)rtdata.o
(../lib/libefi.a)initplat.o
(../lib/libefi.a)data.o
(../lib/libefi.a)dpath.o
(../lib/libefi.a)guid.o
(../lib/libefi.a)hand.o
(../lib/libefi.a)print.o
(../lib/libefi.a)math.o
(../lib/libefi.a)console.o
(../lib/libefi.a)error.o
(../lib/libefi.a)event.o
attempt to open ../lib/libgnuefi.so failed
attempt to open ../lib/libgnuefi.a failed
attempt to open ../gnuefi/libgnuefi.so failed
attempt to open ../gnuefi/libgnuefi.a succeeded
(../gnuefi/libgnuefi.a)reloc_ia32.o
attempt to open /usr/lib/gcc/i586-redhat-linux/4.4.0/libgcc.a succeeded
(/usr/lib/gcc/i586-redhat-linux/4.4.0/libgcc.a)_udivdi3.o
(/usr/lib/gcc/i586-redhat-linux/4.4.0/libgcc.a)_umoddi3.o
/usr/bin/ld: section .data [0000000000000000 -> 0000000000002317] overlaps section .hash [0000000000000000 -> 0000000000000653]
/usr/bin/ld: section .text [0000000000001000 -> 0000000000005ee1] overlaps section .data [0000000000000000 -> 0000000000002317]
/usr/bin/ld: section .dynamic [0000000000003000 -> 0000000000003077] overlaps section .text [0000000000001000 -> 0000000000005ee1]
/usr/bin/ld: t.so: section .data vma 0x0 overlaps previous sections
/usr/bin/ld: t.so: section .text vma 0x1000 overlaps previous sections
/usr/bin/ld: t.so: section .dynamic vma 0x3000 overlaps previous sections
/usr/bin/ld: t.so: section .rel vma 0x4000 overlaps previous sections
/usr/bin/ld: t.so: section .dynsym vma 0x5000 overlaps previous sections
/usr/bin/ld: t.so: section .dynstr vma 0x6000 overlaps previous sections
vroomfondel:~/build/BUILD/gnu-efi-3.0e/apps$

Comment 4 Peter Jones 2009-03-31 16:42:29 UTC
We see this building gnu-efi in rawhide, minus gnu-efi-3.0e-pad-all-sections.patch (which makes it build again, but doesn't actually result in a working result.)

Comment 5 Peter Jones 2009-03-31 16:48:05 UTC
"rpmbuild --rebuild gnu-efi-3.0e-6.1.fc11.src.rpm" of the rpm at http://pjones.fedorapeople.org/gnu-efi-3.0e-6.1.fc11.src.rpm should reproduce the problem.

Comment 6 Nick Clifton 2009-04-01 13:39:45 UTC
Created attachment 337523 [details]
Extended linker script

Comment 7 Nick Clifton 2009-04-01 13:49:08 UTC
Hi Peter,

  The problem is caused by the fact that the toolchain is generating some sections which are not mentioned in your linker script.  (Notably the .comment and .note.GNU-stack sections).  The linker was changed a while ago to improve its placement of these so-called orphan sections so that, for example, read-only orphan sections are placed after the end of the text sections whereas read-write orphan sections are placed after the end of the data sections.  

In your particular case appending the .comment and .note.GNU-stack sections to the end of the text sections also has the side effect of resetting the location counter to zero (since they do not contain loadable code) which then resulted in the strange overlap warnings that you were seeing.

Obviously the linker's behaviour in this area needs improvement, but in the meantime there is a simple workaround - add explicit placement of these orphan sections to your linker script.  I have uploaded an enhanced elf_ia32_efi.lds script that does just this for the 32-bit case.  You will need to make a similar change to the 64-bit script as well.

Cheers
  Nick

PS.  By the way if you add "-Map efi.map" to your linker command line the linker will generate a file called efi.map describing exactly where it is placing all of the input sections.  This is how I tracked down the names of the orphan sections.

Comment 8 Peter Jones 2009-04-03 14:45:14 UTC
Thanks!