This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: The current linker failed to generate working Linux kernel
On Wed, Aug 16, 2006 at 06:00:17PM +0930, Alan Modra wrote:
> On Tue, Aug 15, 2006 at 06:10:42PM -0700, H. J. Lu wrote:
> > FYI, I opened a linker bug
> >
> > http://sources.redhat.com/bugzilla/show_bug.cgi?id=3052
> >
> > The current linker failed to generate working Linux 2.6 x86-64 kernel.
> > There is a small testcase in the bug report.
>
> The kernel script is invalid because it moves dot backwards. Sigh.
>
> This patch moves the code the sets section lmas from lang_do_assignments
> to lang_size_sections, which I think is a more natural place to do
> this. I've also tweaked the lma code to fall back to lma == vma if dot
> moves backwards, for compatibility with buggy ld scripts.
>
I don't think this fix is complete. Here is a patch with 2 testcases.
The first one moves dot backwards similar to Linux kernel and the
second doesn't. The issue here is
.bar XXX : AT (YYY)
. = LOADADDR(.bar) + ZZZ;
.data : { *(.data) }
For .bar, lma != vma. But we can't assume it is also true for .data.
H.J.
---
2006-08-16 H.J. Lu <hongjiu.lu@intel.com>
PR ld/3052
* ld-elf/loadaddr.s: New file.
* ld-elf/loadaddr1.d: Likewise.
* ld-elf/loadaddr1.t: Likewise.
* ld-elf/loadaddr2.d: Likewise.
* ld-elf/loadaddr2.t: Likewise.
--- ld/testsuite/ld-elf/loadaddr.s.loadaddr 2006-08-16 09:52:59.000000000 -0700
+++ ld/testsuite/ld-elf/loadaddr.s 2006-08-16 09:18:31.000000000 -0700
@@ -0,0 +1,16 @@
+ .text
+ .globl main
+ .globl start
+ .globl _start
+ .globl __start
+main:
+start:
+_start:
+__start:
+ .byte 0
+ .section .bar,"ax","progbits"
+ .byte 0
+ .section .foo,"aw","progbits"
+ .byte 0
+ .data
+ .byte 0
--- ld/testsuite/ld-elf/loadaddr1.d.loadaddr 2006-08-16 09:52:59.000000000 -0700
+++ ld/testsuite/ld-elf/loadaddr1.d 2006-08-16 09:42:20.000000000 -0700
@@ -0,0 +1,10 @@
+#source: loadaddr.s
+#ld: -T loadaddr1.t -z max-page-size=0x200000
+#readelf: -l --wide
+#target: *-*-linux*
+
+#...
+ LOAD +0x000000 0xf*80000000 0xf*80000000 0x100041 0x100041 RWE 0x200000
+ LOAD +0x200000 0xf*ff600000 0xf*80101000 0x0*1 0x0*1 R E 0x200000
+ LOAD +0x302000 0xf*80102000 0xf*80102000 0x0*1 0x0*1 RW 0x200000
+#pass
--- ld/testsuite/ld-elf/loadaddr1.t.loadaddr 2006-08-16 09:52:59.000000000 -0700
+++ ld/testsuite/ld-elf/loadaddr1.t 2006-08-16 09:12:08.000000000 -0700
@@ -0,0 +1,13 @@
+SECTIONS
+{
+ . = -0x7ff00000;
+ .text : {*(.text .text.*)}
+ . = ALIGN(64);
+ .foo : { *(.foo) }
+ .bar -0xa00000 : AT ((LOADADDR(.foo) + SIZEOF(.foo) + 4095) & ~(4095))
+ { *(.bar) }
+ . = LOADADDR(.bar) + 4096;
+ . = ALIGN(8192);
+ .data : { *(.data) }
+ /DISCARD/ : { *(.*) }
+}
--- ld/testsuite/ld-elf/loadaddr2.d.loadaddr 2006-08-16 09:52:59.000000000 -0700
+++ ld/testsuite/ld-elf/loadaddr2.d 2006-08-16 09:51:43.000000000 -0700
@@ -0,0 +1,10 @@
+#source: loadaddr.s
+#ld: -T loadaddr2.t -z max-page-size=0x200000
+#readelf: -l --wide
+#target: *-*-linux*
+
+#...
+ LOAD +0x000000 0xf*80000000 0xf*80000000 0x100041 0x100041 RWE 0x200000
+ LOAD +0x110000 0xf*80110000 0xf*80101000 0x0*1 0x0*1 R E 0x200000
+ LOAD +0x302000 0xf*80302000 0xf*80302000 0x0*1 0x0*1 RW 0x200000
+#pass
--- ld/testsuite/ld-elf/loadaddr2.t.loadaddr 2006-08-16 09:52:59.000000000 -0700
+++ ld/testsuite/ld-elf/loadaddr2.t 2006-08-16 09:50:05.000000000 -0700
@@ -0,0 +1,13 @@
+SECTIONS
+{
+ . = -0x7ff00000;
+ .text : {*(.text .text.*)}
+ . = ALIGN(64);
+ .foo : { *(.foo) }
+ .bar -0x7fef0000 : AT ((LOADADDR(.foo) + SIZEOF(.foo) + 4095) & ~(4095))
+ { *(.bar) }
+ . = LOADADDR(.bar) + 0x200000;
+ . = ALIGN(8192);
+ .data : { *(.data) }
+ /DISCARD/ : { *(.*) }
+}