* The current linker failed to generate working Linux kernel @ 2006-08-16 13:05 H. J. Lu 2006-08-16 17:16 ` Alan Modra 0 siblings, 1 reply; 12+ messages in thread From: H. J. Lu @ 2006-08-16 13:05 UTC (permalink / raw) To: binutils 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. H.J. ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: The current linker failed to generate working Linux kernel 2006-08-16 13:05 The current linker failed to generate working Linux kernel H. J. Lu @ 2006-08-16 17:16 ` Alan Modra 2006-08-16 18:26 ` H. J. Lu 0 siblings, 1 reply; 12+ messages in thread From: Alan Modra @ 2006-08-16 17:16 UTC (permalink / raw) To: H. J. Lu; +Cc: binutils 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. ld/ PR 3052 * ldlang.h (lang_output_section_statement_type): Replace "processed" field with "processed_vma" and "processed_lma". * ldlang.c (lang_do_assignments_1): Move lma setting code.. (lang_size_sections_1): ..to here. (lang_reset_memory_regions): Adjust for lang_output_section_statement_type change. * ldexp.c (fold_name): Likewise. And this is something I forgot the check in from the previous patch. ld/testsuite/ * ld-scripts/overlay-size-map.d: Adjust. Index: ld/ldlang.h =================================================================== RCS file: /cvs/src/src/ld/ldlang.h,v retrieving revision 1.65 diff -u -p -r1.65 ldlang.h --- ld/ldlang.h 8 Aug 2006 16:08:47 -0000 1.65 +++ ld/ldlang.h 16 Aug 2006 08:03:00 -0000 @@ -150,7 +150,8 @@ typedef struct lang_output_section_state int constraint; flagword flags; enum section_type sectype; - unsigned int processed : 1; + unsigned int processed_vma : 1; + unsigned int processed_lma : 1; unsigned int all_input_readonly : 1; unsigned int ignored : 1; } lang_output_section_statement_type; Index: ld/ldlang.c =================================================================== RCS file: /cvs/src/src/ld/ldlang.c,v retrieving revision 1.233 diff -u -p -r1.233 ldlang.c --- ld/ldlang.c 8 Aug 2006 16:08:47 -0000 1.233 +++ ld/ldlang.c 16 Aug 2006 08:02:59 -0000 @@ -4228,11 +4228,12 @@ lang_size_sections_1 { bfd_vma newdot, after; lang_output_section_statement_type *os; + lang_memory_region_type *r; os = &s->output_section_statement; if (os->addr_tree != NULL) { - os->processed = FALSE; + os->processed_vma = FALSE; exp_fold_tree (os->addr_tree, bfd_abs_section_ptr, &dot); if (!expld.result.valid_p @@ -4361,24 +4362,90 @@ lang_size_sections_1 lang_size_sections_1 (os->children.head, os, &os->children.head, os->fill, newdot, relax, check_regions); - os->processed = TRUE; + os->processed_vma = TRUE; if (bfd_is_abs_section (os->bfd_section) || os->ignored) + ASSERT (os->bfd_section->size == 0); + else { - ASSERT (os->bfd_section->size == 0); - break; + dot = os->bfd_section->vma; + + /* Put the section within the requested block size, or + align at the block boundary. */ + after = ((dot + + TO_ADDR (os->bfd_section->size) + + os->block_value - 1) + & - (bfd_vma) os->block_value); + + os->bfd_section->size = TO_SIZE (after - os->bfd_section->vma); + } + + /* Set section lma. */ + r = os->region; + if (r == NULL) + r = lang_memory_region_lookup (DEFAULT_MEMORY_REGION, FALSE); + + if (os->load_base) + { + bfd_vma lma = exp_get_abs_int (os->load_base, 0, "load base"); + os->bfd_section->lma = lma; + } + else if (os->region != NULL + && os->lma_region != NULL + && os->lma_region != os->region) + { + bfd_vma lma = os->lma_region->current; + + if (os->section_alignment != -1) + lma = align_power (lma, os->section_alignment); + os->bfd_section->lma = lma; } + else if (r->last_os != NULL) + { + bfd_vma lma; + asection *last; + + last = r->last_os->output_section_statement.bfd_section; + /* If dot moved backwards (which is invalid according + to ld docs) then leave lma equal to vma. This + keeps users of buggy ld scripts happy. */ + if (dot >= last->vma) + { + /* If the current vma overlaps the previous section, + then set the current lma to that at the end of + the previous section. The previous section was + probably an overlay. */ + if ((dot >= last->vma + && dot < last->vma + last->size) + || (last->vma >= dot + && last->vma < dot + os->bfd_section->size)) + lma = last->lma + last->size; - dot = os->bfd_section->vma; + /* Otherwise, keep the same lma to vma relationship + as the previous section. */ + else + lma = dot + last->lma - last->vma; + + if (os->section_alignment != -1) + lma = align_power (lma, os->section_alignment); + os->bfd_section->lma = lma; + } + } + os->processed_lma = TRUE; - /* Put the section within the requested block size, or - align at the block boundary. */ - after = ((dot - + TO_ADDR (os->bfd_section->size) - + os->block_value - 1) - & - (bfd_vma) os->block_value); + if (bfd_is_abs_section (os->bfd_section) || os->ignored) + break; - os->bfd_section->size = TO_SIZE (after - os->bfd_section->vma); + /* Keep track of normal sections using the default + lma region. We use this to set the lma for + following sections. Overlays or other linker + script assignment to lma might mean that the + default lma == vma is incorrect. */ + if (((os->bfd_section->flags & SEC_HAS_CONTENTS) != 0 + || (os->bfd_section->flags & SEC_THREAD_LOCAL) == 0) + && os->lma_region == NULL + && !link_info.relocatable) + r->last_os = s; /* .tbss sections effectively have zero size. */ if ((os->bfd_section->flags & SEC_HAS_CONTENTS) != 0 @@ -4410,14 +4477,12 @@ lang_size_sections_1 if (os->lma_region != NULL && os->lma_region != os->region) { - /* Set load_base, which will be handled later. */ - os->load_base = exp_intop (os->lma_region->current); - os->lma_region->current += - TO_ADDR (os->bfd_section->size); + os->lma_region->current + = os->bfd_section->lma + TO_ADDR (os->bfd_section->size); if (check_regions) os_region_check (os, os->lma_region, NULL, - os->lma_region->current); + os->bfd_section->lma); } } } @@ -4717,62 +4782,15 @@ lang_do_assignments_1 (lang_statement_un os = &(s->output_section_statement); if (os->bfd_section != NULL && !os->ignored) { - lang_memory_region_type *r; - dot = os->bfd_section->vma; - r = os->region; - if (r == NULL) - r = lang_memory_region_lookup (DEFAULT_MEMORY_REGION, FALSE); - - if (os->load_base) - os->bfd_section->lma - = exp_get_abs_int (os->load_base, 0, "load base"); - else if (r->last_os != NULL) - { - asection *last; - bfd_vma lma; - - last = r->last_os->output_section_statement.bfd_section; - - /* If the current vma overlaps the previous section, - then set the current lma to that at the end of - the previous section. The previous section was - probably an overlay. */ - if ((dot >= last->vma - && dot < last->vma + last->size) - || (last->vma >= dot - && last->vma < dot + os->bfd_section->size)) - lma = last->lma + last->size; - - /* Otherwise, keep the same lma to vma relationship - as the previous section. */ - else - lma = dot + last->lma - last->vma; - - if (os->section_alignment != -1) - lma = align_power (lma, os->section_alignment); - os->bfd_section->lma = lma; - } - lang_do_assignments_1 (os->children.head, - os, os->fill, dot); + lang_do_assignments_1 (os->children.head, os, os->fill, dot); /* .tbss sections effectively have zero size. */ if ((os->bfd_section->flags & SEC_HAS_CONTENTS) != 0 || (os->bfd_section->flags & SEC_THREAD_LOCAL) == 0 || link_info.relocatable) - { - dot += TO_ADDR (os->bfd_section->size); - - /* Keep track of normal sections using the default - lma region. We use this to set the lma for - following sections. Overlays or other linker - script assignment to lma might mean that the - default lma == vma is incorrect. */ - if (!link_info.relocatable - && os->lma_region == NULL) - r->last_os = s; - } + dot += TO_ADDR (os->bfd_section->size); } } break; @@ -5451,7 +5469,10 @@ lang_reset_memory_regions (void) for (os = &lang_output_section_statement.head->output_section_statement; os != NULL; os = os->next) - os->processed = FALSE; + { + os->processed_vma = FALSE; + os->processed_lma = FALSE; + } for (o = output_bfd->sections; o != NULL; o = o->next) { Index: ld/ldexp.c =================================================================== RCS file: /cvs/src/src/ld/ldexp.c,v retrieving revision 1.61 diff -u -p -r1.61 ldexp.c --- ld/ldexp.c 26 Jul 2006 05:05:52 -0000 1.61 +++ ld/ldexp.c 16 Aug 2006 08:02:56 -0000 @@ -563,7 +563,7 @@ fold_name (etree_type *tree) lang_output_section_statement_type *os; os = lang_output_section_find (tree->name.name); - if (os != NULL && os->processed) + if (os != NULL && os->processed_vma) new_rel (0, NULL, os->bfd_section); } break; @@ -574,7 +574,7 @@ fold_name (etree_type *tree) lang_output_section_statement_type *os; os = lang_output_section_find (tree->name.name); - if (os != NULL && os->processed) + if (os != NULL && os->processed_lma) { if (os->load_base == NULL) new_rel (os->bfd_section->lma - os->bfd_section->vma, @@ -594,7 +594,7 @@ fold_name (etree_type *tree) os = lang_output_section_find (tree->name.name); if (os == NULL) new_abs (0); - else if (os->processed) + else if (os->processed_vma) new_abs (os->bfd_section->size / opb); } break; Index: ld/testsuite/ld-scripts/overlay-size-map.d =================================================================== RCS file: /cvs/src/src/ld/testsuite/ld-scripts/overlay-size-map.d,v retrieving revision 1.2 diff -u -p -r1.2 overlay-size-map.d --- ld/testsuite/ld-scripts/overlay-size-map.d 26 Jul 2006 05:10:05 -0000 1.2 +++ ld/testsuite/ld-scripts/overlay-size-map.d 16 Aug 2006 08:03:02 -0000 @@ -5,19 +5,19 @@ #... \.bss3 *0x0*20000 *0x20 #... -\.mtext *0x0*10000 *0x20 load address 0x0*30000 +\.mtext *0x0*10000 *0x20 #... \.mbss *0x0*20030 *0x230 load address 0x0*20060 #... -\.text1 *0x0*10020 *0x80 load address 0x0*30020 +\.text1 *0x0*10020 *0x80 #... -\.text2 *0x0*10020 *0x40 load address 0x0*300a0 +\.text2 *0x0*10020 *0x40 #... -\.text3 *0x0*10020 *0x20 load address 0x0*300e0 +\.text3 *0x0*10020 *0x20 #... -\.data1 *0x0*20260 *0x30 load address 0x0*30100 +\.data1 *0x0*20260 *0x30 #... -\.data2 *0x0*20260 *0x40 load address 0x0*30130 +\.data2 *0x0*20260 *0x40 #... -\.data3 *0x0*20260 *0x50 load address 0x0*30170 +\.data3 *0x0*20260 *0x50 #pass -- Alan Modra IBM OzLabs - Linux Technology Centre ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: The current linker failed to generate working Linux kernel 2006-08-16 17:16 ` Alan Modra @ 2006-08-16 18:26 ` H. J. Lu 2006-08-17 1:20 ` PATCH: " H. J. Lu 0 siblings, 1 reply; 12+ messages in thread From: H. J. Lu @ 2006-08-16 18:26 UTC (permalink / raw) To: binutils 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/ : { *(.*) } +} ^ permalink raw reply [flat|nested] 12+ messages in thread
* PATCH: The current linker failed to generate working Linux kernel 2006-08-16 18:26 ` H. J. Lu @ 2006-08-17 1:20 ` H. J. Lu 2006-08-17 1:54 ` Alan Modra 0 siblings, 1 reply; 12+ messages in thread From: H. J. Lu @ 2006-08-17 1:20 UTC (permalink / raw) To: binutils On Wed, Aug 16, 2006 at 10:16:12AM -0700, H. J. Lu wrote: > 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. > Here is the updated patch with a fix. H.J. ---- ld/ 2006-08-16 H.J. Lu <hongjiu.lu@intel.com> PR ld/3052 * ldlang.c (lang_size_sections_1): Don't change lma unless the current vma overlaps the previous section. ld/testsuite/ 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/ldlang.c.loadaddr 2006-08-16 10:08:02.000000000 -0700 +++ ld/ldlang.c 2006-08-16 11:20:53.000000000 -0700 @@ -4405,30 +4405,19 @@ lang_size_sections_1 } else if (r->last_os != NULL) { - bfd_vma lma; asection *last; last = r->last_os->output_section_statement.bfd_section; - /* If dot moved backwards (which is invalid according - to ld docs) then leave lma equal to vma. This - keeps users of buggy ld scripts happy. */ - if (dot >= last->vma) + /* lvm should be the same as vma. But if the current vma + overlaps the previous section, then set the current lma + to that at the end of the previous section. The + previous section was probably an overlay. */ + if ((dot >= last->vma + && dot < last->vma + last->size) + || (last->vma >= dot + && last->vma < dot + os->bfd_section->size)) { - /* If the current vma overlaps the previous section, - then set the current lma to that at the end of - the previous section. The previous section was - probably an overlay. */ - if ((dot >= last->vma - && dot < last->vma + last->size) - || (last->vma >= dot - && last->vma < dot + os->bfd_section->size)) - lma = last->lma + last->size; - - /* Otherwise, keep the same lma to vma relationship - as the previous section. */ - else - lma = dot + last->lma - last->vma; - + bfd_vma lma = last->lma + last->size; if (os->section_alignment != -1) lma = align_power (lma, os->section_alignment); os->bfd_section->lma = lma; --- ld/testsuite/ld-elf/loadaddr.s.loadaddr 2006-08-16 10:08:02.000000000 -0700 +++ ld/testsuite/ld-elf/loadaddr.s 2006-08-16 10:08:02.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 10:08:02.000000000 -0700 +++ ld/testsuite/ld-elf/loadaddr1.d 2006-08-16 10:08:02.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 10:08:02.000000000 -0700 +++ ld/testsuite/ld-elf/loadaddr1.t 2006-08-16 10:08:02.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 10:08:02.000000000 -0700 +++ ld/testsuite/ld-elf/loadaddr2.d 2006-08-16 10:08:02.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 10:08:02.000000000 -0700 +++ ld/testsuite/ld-elf/loadaddr2.t 2006-08-16 10:08:02.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/ : { *(.*) } +} ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: PATCH: The current linker failed to generate working Linux kernel 2006-08-17 1:20 ` PATCH: " H. J. Lu @ 2006-08-17 1:54 ` Alan Modra 2006-08-17 5:05 ` H. J. Lu ` (2 more replies) 0 siblings, 3 replies; 12+ messages in thread From: Alan Modra @ 2006-08-17 1:54 UTC (permalink / raw) To: H. J. Lu; +Cc: binutils On Wed, Aug 16, 2006 at 11:26:35AM -0700, H. J. Lu wrote: > PR ld/3052 > * ldlang.c (lang_size_sections_1): Don't change lma unless the > current vma overlaps the previous section. Not OK. The main reason I added this code was to make using overlays simpler. See http://sourceware.org/ml/binutils/2006-07/msg00314.html Your patch means that all loaded sections after an overlay would again need to have their lma specified, which is a pain. I think the new default of keeping the lma to vma relationship the same as previous sections is a much better default than setting lma equal to vma. (Of course, scripts that never specify lma will be unaffected since the "previous section" will have lma equal to vma.) The new default should allow many ld scripts that specify lmas to be simplified. Also, for orphan sections we've kept lma-vma the same as previous sections since 2002-12-05. -- Alan Modra IBM OzLabs - Linux Technology Centre ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: PATCH: The current linker failed to generate working Linux kernel 2006-08-17 1:54 ` Alan Modra @ 2006-08-17 5:05 ` H. J. Lu 2006-08-17 17:04 ` PATCH: 2 ld testcases for lma/vma H. J. Lu 2006-08-17 21:36 ` PATCH: The current linker failed to generate working Linux kernel H. J. Lu 2 siblings, 0 replies; 12+ messages in thread From: H. J. Lu @ 2006-08-17 5:05 UTC (permalink / raw) To: binutils On Thu, Aug 17, 2006 at 10:50:39AM +0930, Alan Modra wrote: > On Wed, Aug 16, 2006 at 11:26:35AM -0700, H. J. Lu wrote: > > PR ld/3052 > > * ldlang.c (lang_size_sections_1): Don't change lma unless the > > current vma overlaps the previous section. > > Not OK. The main reason I added this code was to make using overlays > simpler. See http://sourceware.org/ml/binutils/2006-07/msg00314.html > Your patch means that all loaded sections after an overlay would again > need to have their lma specified, which is a pain. > > I think the new default of keeping the lma to vma relationship the same > as previous sections is a much better default than setting lma equal to > vma. (Of course, scripts that never specify lma will be unaffected > since the "previous section" will have lma equal to vma.) The new > default should allow many ld scripts that specify lmas to be simplified. > Also, for orphan sections we've kept lma-vma the same as previous > sections since 2002-12-05. > One of 2 testcases in my patch fails with the current linker. That is a regression. None of the linker scripts in my testcases use overlay. I think the new havior should be limited to overlay only. Here is a patch with testcases only. 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/ : { *(.*) } +} ^ permalink raw reply [flat|nested] 12+ messages in thread
* PATCH: 2 ld testcases for lma/vma 2006-08-17 1:54 ` Alan Modra 2006-08-17 5:05 ` H. J. Lu @ 2006-08-17 17:04 ` H. J. Lu 2006-08-17 21:36 ` PATCH: The current linker failed to generate working Linux kernel H. J. Lu 2 siblings, 0 replies; 12+ messages in thread From: H. J. Lu @ 2006-08-17 17:04 UTC (permalink / raw) To: binutils On Thu, Aug 17, 2006 at 10:50:39AM +0930, Alan Modra wrote: > On Wed, Aug 16, 2006 at 11:26:35AM -0700, H. J. Lu wrote: > > PR ld/3052 > > * ldlang.c (lang_size_sections_1): Don't change lma unless the > > current vma overlaps the previous section. > > Not OK. The main reason I added this code was to make using overlays > simpler. See http://sourceware.org/ml/binutils/2006-07/msg00314.html > Your patch means that all loaded sections after an overlay would again > need to have their lma specified, which is a pain. I don't see why all loaded sections after an overlay have to have the same lma and vma relationship as the overlay. Do you have an example for this? Some testcases to showe befor and after your change will be nice. > > I think the new default of keeping the lma to vma relationship the same > as previous sections is a much better default than setting lma equal to > vma. (Of course, scripts that never specify lma will be unaffected > since the "previous section" will have lma equal to vma.) The new > default should allow many ld scripts that specify lmas to be simplified. I believe it is wrong, especially when overlay isn't used. According to the linker manual: The linker will normally set the LMA equal to the VMA. You can change that by using the `AT' keyword. The expression LMA that follows the `AT' keyword specifies the load address of the section. The current linker makes the above untrue. I will check in 2 testases enclosed here if there are no objections. BTW, about moving dot backwards, this example from the linker manual .text0 0x1000 : AT (0x4000) { o1/*.o(.text) } __load_start_text0 = LOADADDR (.text0); __load_stop_text0 = LOADADDR (.text0) + SIZEOF (.text0); .text1 0x1000 : AT (0x4000 + SIZEOF (.text0)) { o2/*.o(.text) } __load_start_text1 = LOADADDR (.text1); __load_stop_text1 = LOADADDR (.text1) + SIZEOF (.text1); . = 0x1000 + MAX (SIZEOF (.text0), SIZEOF (.text1)); seems to move dot backwards implicitly when 2 sections are placed at the same address. 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/ : { *(.*) } +} ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: PATCH: The current linker failed to generate working Linux kernel 2006-08-17 1:54 ` Alan Modra 2006-08-17 5:05 ` H. J. Lu 2006-08-17 17:04 ` PATCH: 2 ld testcases for lma/vma H. J. Lu @ 2006-08-17 21:36 ` H. J. Lu 2006-08-18 14:46 ` Alan Modra 2 siblings, 1 reply; 12+ messages in thread From: H. J. Lu @ 2006-08-17 21:36 UTC (permalink / raw) To: binutils On Thu, Aug 17, 2006 at 10:50:39AM +0930, Alan Modra wrote: > On Wed, Aug 16, 2006 at 11:26:35AM -0700, H. J. Lu wrote: > > PR ld/3052 > > * ldlang.c (lang_size_sections_1): Don't change lma unless the > > current vma overlaps the previous section. > > Not OK. The main reason I added this code was to make using overlays > simpler. See http://sourceware.org/ml/binutils/2006-07/msg00314.html > Your patch means that all loaded sections after an overlay would again > need to have their lma specified, which is a pain. > I don't see why I have to specify lma after overlay: [hjl@gnu-13 overlay]$ cat foo.s .section .text1,"ax","progbits" .space 0x10 .section .text2,"ax","progbits" .space 0x20 .section .text .space 0x30 [hjl@gnu-13 overlay]$ cat foo.t SECTIONS { OVERLAY 0x1000 : AT (0x4000) { .text1 {*(.text1)} .text2 {*(.text2)} } . = 0x2000; .text : { *(.text) } /DISCARD/ : { *(.*) } } [hjl@gnu-13 overlay]$ make foo as -o foo.o foo.s ./ld -o foo -T foo.t foo.o [hjl@gnu-13 overlay]$ readelf -l --wide foo Elf file type is EXEC (Executable file) Entry point 0x2000 There are 3 program headers, starting at offset 64 Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align LOAD 0x000000 0x0000000000000000 0x0000000000000000 0x002030 0x002030 R E 0x200000 LOAD 0x201000 0x0000000000001000 0x0000000000004000 0x000010 0x000010 R E 0x200000 LOAD 0x401000 0x0000000000001000 0x0000000000004010 0x000020 0x000020 R E 0x200000 Section to Segment mapping: Segment Sections... 00 .text1 .text2 .text 01 .text1 02 .text1 .text2 [hjl@gnu-13 overlay]$ H.J. ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: PATCH: The current linker failed to generate working Linux kernel 2006-08-17 21:36 ` PATCH: The current linker failed to generate working Linux kernel H. J. Lu @ 2006-08-18 14:46 ` Alan Modra 2006-08-18 19:15 ` H. J. Lu 0 siblings, 1 reply; 12+ messages in thread From: Alan Modra @ 2006-08-18 14:46 UTC (permalink / raw) To: H. J. Lu; +Cc: binutils On Thu, Aug 17, 2006 at 09:44:53AM -0700, H. J. Lu wrote: > On Thu, Aug 17, 2006 at 10:50:39AM +0930, Alan Modra wrote: > > Not OK. The main reason I added this code was to make using overlays > > simpler. See http://sourceware.org/ml/binutils/2006-07/msg00314.html > > Your patch means that all loaded sections after an overlay would again > > need to have their lma specified, which is a pain. > > I don't see why I have to specify lma after overlay: My goal is to be able to insert an OVERLAY stanza into one of the existing linker scripts *without* having to mess around with dot as you are doing in your testcases, and have ld generate a nicely packed object file. I would expect ld -N to not generate any extra segments apart from those for the overlay sections, ie. at most one segment before the overlays, one segment for each overlay section, and at most one after the overlays, and for p_paddr of each segment to follow on from the previous segment's ending p_paddr modulo alignment constraints. This translates to minimum wasted ROM (or whatever the backing store is for the overlays). You'll find that if you try to do this with an old linker, you'll need to specify lma for all sections following the overlay. eg. using your foo.s with this link script SECTIONS { OVERLAY : { .text1 {*(.text1)} .text2 {*(.text2)} } .text : { *(.text) } /DISCARD/ : { *(.*) } } results in ld: section .text [0000000000000020 -> 000000000000004f] overlaps section .text2 [0000000000000010 -> 000000000000002f] -- Alan Modra IBM OzLabs - Linux Technology Centre ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: PATCH: The current linker failed to generate working Linux kernel 2006-08-18 14:46 ` Alan Modra @ 2006-08-18 19:15 ` H. J. Lu 2006-08-20 0:59 ` Alan Modra 0 siblings, 1 reply; 12+ messages in thread From: H. J. Lu @ 2006-08-18 19:15 UTC (permalink / raw) To: binutils On Fri, Aug 18, 2006 at 02:42:35PM +0930, Alan Modra wrote: > On Thu, Aug 17, 2006 at 09:44:53AM -0700, H. J. Lu wrote: > > On Thu, Aug 17, 2006 at 10:50:39AM +0930, Alan Modra wrote: > > > Not OK. The main reason I added this code was to make using overlays > > > simpler. See http://sourceware.org/ml/binutils/2006-07/msg00314.html > > > Your patch means that all loaded sections after an overlay would again > > > need to have their lma specified, which is a pain. > > > > I don't see why I have to specify lma after overlay: > > My goal is to be able to insert an OVERLAY stanza into one of the > existing linker scripts *without* having to mess around with dot as you > are doing in your testcases, and have ld generate a nicely packed > object file. I would expect ld -N to not generate any extra segments > apart from those for the overlay sections, ie. at most one segment > before the overlays, one segment for each overlay section, and at most > one after the overlays, and for p_paddr of each segment to follow on > from the previous segment's ending p_paddr modulo alignment constraints. > This translates to minimum wasted ROM (or whatever the backing store is > for the overlays). You'll find that if you try to do this with an old > linker, you'll need to specify lma for all sections following the > overlay. > It is a nice new feature to have. But it shouldn't break the existing linker scripts. When .data : { *(.data) } is used, I expect its lma == vma unless AT is used, as specified by the linker manual. I will prefer a new linker option or a linker script command to change the behavior. I checked in 2 testcases. One of them fails due to the changed linker behavior. H.J. ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: PATCH: The current linker failed to generate working Linux kernel 2006-08-18 19:15 ` H. J. Lu @ 2006-08-20 0:59 ` Alan Modra 2006-08-20 1:45 ` H. J. Lu 0 siblings, 1 reply; 12+ messages in thread From: Alan Modra @ 2006-08-20 0:59 UTC (permalink / raw) To: H. J. Lu; +Cc: binutils On Fri, Aug 18, 2006 at 07:45:53AM -0700, H. J. Lu wrote: > I checked in 2 testcases. You have no right to commit testcases that currently fail. > One of them fails due to the changed linker behavior. Of course it fails! You've written contrived testcases that depend on the old behaviour. I deliberately changed the default linker behaviour, believing that it was unlikely to affect any real-world scripts. I still believe it is a reasonable change, even though it caused a failure with a linux kernel script of dubious validity that happened to work previously. Any such failure is easily rectified by adding AT(.) to a section that needs lma == vma. -- Alan Modra IBM OzLabs - Linux Technology Centre ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: PATCH: The current linker failed to generate working Linux kernel 2006-08-20 0:59 ` Alan Modra @ 2006-08-20 1:45 ` H. J. Lu 0 siblings, 0 replies; 12+ messages in thread From: H. J. Lu @ 2006-08-20 1:45 UTC (permalink / raw) To: binutils On Sat, Aug 19, 2006 at 09:39:01PM +0930, Alan Modra wrote: > On Fri, Aug 18, 2006 at 07:45:53AM -0700, H. J. Lu wrote: > > I checked in 2 testcases. > > You have no right to commit testcases that currently fail. > > > One of them fails due to the changed linker behavior. > > Of course it fails! You've written contrived testcases that depend on > the old behaviour. I deliberately changed the default linker behaviour, > believing that it was unlikely to affect any real-world scripts. I > still believe it is a reasonable change, even though it caused a failure > with a linux kernel script of dubious validity that happened to work > previously. Any such failure is easily rectified by adding AT(.) to > a section that needs lma == vma. The old behavior is documented in the linker manual and is being used. If we change the linker behavior, the documentation should be updated to reflect it. The failed testcase can be modified for the new behavior. I don't think we should change the linker behavior and keep the linker documentation as is. H.J. ^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2006-08-19 15:10 UTC | newest] Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2006-08-16 13:05 The current linker failed to generate working Linux kernel H. J. Lu 2006-08-16 17:16 ` Alan Modra 2006-08-16 18:26 ` H. J. Lu 2006-08-17 1:20 ` PATCH: " H. J. Lu 2006-08-17 1:54 ` Alan Modra 2006-08-17 5:05 ` H. J. Lu 2006-08-17 17:04 ` PATCH: 2 ld testcases for lma/vma H. J. Lu 2006-08-17 21:36 ` PATCH: The current linker failed to generate working Linux kernel H. J. Lu 2006-08-18 14:46 ` Alan Modra 2006-08-18 19:15 ` H. J. Lu 2006-08-20 0:59 ` Alan Modra 2006-08-20 1:45 ` H. J. Lu
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).