diff options
Diffstat (limited to 'ld')
-rw-r--r-- | ld/ChangeLog | 11 | ||||
-rw-r--r-- | ld/ldexp.c | 6 | ||||
-rw-r--r-- | ld/ldlang.c | 155 | ||||
-rw-r--r-- | ld/ldlang.h | 3 | ||||
-rw-r--r-- | ld/testsuite/ChangeLog | 8 | ||||
-rw-r--r-- | ld/testsuite/ld-scripts/overlay-size-map.d | 14 |
6 files changed, 115 insertions, 82 deletions
diff --git a/ld/ChangeLog b/ld/ChangeLog index d74b0a8..206faf0 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,14 @@ +2006-08-16 Alan Modra <amodra@bigpond.net.au> + + 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. + 2006-08-08 Peter S. Mazinger <ps.m@gmx.net> * emulparams/armelf.sh (MAXPAGESIZE): Changed to @@ -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; diff --git a/ld/ldlang.c b/ld/ldlang.c index 0ee1156..e478bd8 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -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; - dot = os->bfd_section->vma; + 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; + + /* 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_union_type *s, 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) { diff --git a/ld/ldlang.h b/ld/ldlang.h index c23c3e5..1c135b6 100644 --- a/ld/ldlang.h +++ b/ld/ldlang.h @@ -150,7 +150,8 @@ typedef struct lang_output_section_statement_struct 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; diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog index 4fc6599..f07e2ca 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2006-08-16 Alan Modra <amodra@bigpond.net.au> + + * ld-scripts/overlay-size-map.d: Update. + 2006-08-11 Thiemo Seufer <ths@mips.com> * ld-elfcomm/elfcomm.exp (dump_common1): Extend regexp to match also @@ -47,10 +51,6 @@ * ld-mips-elf/hash1b.d, ld-mips-elf/hash1c.d: New tests. * ld-mips-elf/mips-elf.exp: Run them. -2006-07-26 Alan Modra <amodra@bigpond.net.au> - - * ld-scripts/overlay-size-map.d: Update. - 2006-07-25 Thiemo Seufer <ths@mips.com> * ld-mips-elf/mips16-call-global-2.s, diff --git a/ld/testsuite/ld-scripts/overlay-size-map.d b/ld/testsuite/ld-scripts/overlay-size-map.d index 852ed81..cd35db0 100644 --- a/ld/testsuite/ld-scripts/overlay-size-map.d +++ b/ld/testsuite/ld-scripts/overlay-size-map.d @@ -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 |