2003-05-14 H.J. Lu * ldlang.c (lang_size_sections_1): Take one more argument to indicate if the relax finalize pass is needed. (lang_size_sections): Updated. (lang_process): Likewise. * ldlang.h (lang_size_sections_1): Likewise. * pe-dll.c (pe_dll_fill_sections): Likewise. (pe_exe_fill_sections): Likewise. * emultempl/elf32.em (gld${EMULATION_NAME}_finish): Likewise. * emultempl/hppaelf.em (hppaelf_layout_sections_again): Likewise. * emultempl/ppc64elf.em (ppc_before_allocation): Likewise. (ppc_layout_sections_again): Likewise. * ldlang.c (lang_size_sections): Don't adjust data segment address after the relax finalize pass starts. (lang_process): Perform the relax finalize pass only when needed. Finalize addresses before the relax finalize pass. --- ld/emultempl/elf32.em.final 2003-05-09 08:13:31.000000000 -0700 +++ ld/emultempl/elf32.em 2003-05-14 15:21:48.000000000 -0700 @@ -1430,7 +1430,8 @@ gld${EMULATION_NAME}_finish () /* Resize the sections. */ lang_size_sections (stat_ptr->head, abs_output_section, - &stat_ptr->head, 0, (bfd_vma) 0, NULL, TRUE); + &stat_ptr->head, 0, (bfd_vma) 0, NULL, + NULL, TRUE); /* Redo special stuff. */ ldemul_after_allocation (); --- ld/emultempl/hppaelf.em.final 2003-02-28 12:53:34.000000000 -0800 +++ ld/emultempl/hppaelf.em 2003-05-14 15:21:57.000000000 -0700 @@ -231,7 +231,8 @@ hppaelf_layout_sections_again () /* Resize the sections. */ lang_size_sections (stat_ptr->head, abs_output_section, - &stat_ptr->head, 0, (bfd_vma) 0, NULL, TRUE); + &stat_ptr->head, 0, (bfd_vma) 0, NULL, NULL, + TRUE); /* Redo special stuff. */ ldemul_after_allocation (); --- ld/emultempl/ppc64elf.em.final 2003-02-28 12:53:38.000000000 -0800 +++ ld/emultempl/ppc64elf.em 2003-05-14 15:22:16.000000000 -0700 @@ -118,7 +118,8 @@ ppc_before_allocation () /* Size the sections. This is premature, but we want to know the TLS segment layout so that certain optimizations can be done. */ lang_size_sections (stat_ptr->head, abs_output_section, - &stat_ptr->head, 0, (bfd_vma) 0, NULL, TRUE); + &stat_ptr->head, 0, (bfd_vma) 0, + NULL, NULL, TRUE); if (!ppc64_elf_tls_optimize (output_bfd, &link_info)) { @@ -273,7 +274,8 @@ ppc_layout_sections_again () /* Resize the sections. */ lang_size_sections (stat_ptr->head, abs_output_section, - &stat_ptr->head, 0, (bfd_vma) 0, NULL, TRUE); + &stat_ptr->head, 0, (bfd_vma) 0, + NULL, NULL, TRUE); /* Recalculate TOC base. */ ldemul_after_allocation (); --- ld/ldlang.c.final 2003-05-13 08:45:34.000000000 -0700 +++ ld/ldlang.c 2003-05-14 15:36:47.000000000 -0700 @@ -199,9 +199,10 @@ static void os_region_check PARAMS ((lang_output_section_statement_type *, struct memory_region_struct *, etree_type *, bfd_vma)); static bfd_vma lang_size_sections_1 - PARAMS ((lang_statement_union_type *, lang_output_section_statement_type *, - lang_statement_union_type **, fill_type *, bfd_vma, bfd_boolean *, - bfd_boolean)); + PARAMS ((lang_statement_union_type *, + lang_output_section_statement_type *, + lang_statement_union_type **, fill_type *, bfd_vma, + bfd_boolean *, bfd_boolean *, bfd_boolean)); typedef void (*callback_t) PARAMS ((lang_wild_statement_type *, struct wildcard_list *, asection *, lang_input_statement_type *, PTR)); @@ -2978,14 +2979,15 @@ os_region_check (os, region, tree, base) /* Set the sizes for all the output sections. */ static bfd_vma -lang_size_sections_1 (s, output_section_statement, prev, fill, dot, relax, - check_regions) +lang_size_sections_1 (s, output_section_statement, prev, fill, dot, + relax, need_finalize_relax, check_regions) lang_statement_union_type *s; lang_output_section_statement_type *output_section_statement; lang_statement_union_type **prev; fill_type *fill; bfd_vma dot; bfd_boolean *relax; + bfd_boolean *need_finalize_relax; bfd_boolean check_regions; { unsigned opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture, @@ -3123,8 +3125,10 @@ lang_size_sections_1 (s, output_section_ os->bfd_section->output_offset = 0; } - lang_size_sections_1 (os->children.head, os, &os->children.head, - os->fill, dot, relax, check_regions); + lang_size_sections_1 (os->children.head, os, + &os->children.head, os->fill, dot, + relax, need_finalize_relax, + check_regions); /* Put the section within the requested block size, or align at the block boundary. */ @@ -3193,7 +3197,9 @@ lang_size_sections_1 (s, output_section_ dot = lang_size_sections_1 (constructor_list.head, output_section_statement, &s->wild_statement.children.head, - fill, dot, relax, check_regions); + fill, dot, relax, + need_finalize_relax, + check_regions); break; case lang_data_statement_enum: @@ -3257,7 +3263,9 @@ lang_size_sections_1 (s, output_section_ dot = lang_size_sections_1 (s->wild_statement.children.head, output_section_statement, &s->wild_statement.children.head, - fill, dot, relax, check_regions); + fill, dot, relax, + need_finalize_relax, + check_regions); break; @@ -3286,6 +3294,7 @@ lang_size_sections_1 (s, output_section_ einfo (_("%P%F: can't relax section: %E\n")); if (again) *relax = TRUE; + *need_finalize_relax |= i->need_finalize_relax; } dot = size_input_section (prev, output_section_statement, output_section_statement->fill, dot); @@ -3355,7 +3364,9 @@ lang_size_sections_1 (s, output_section_ dot = lang_size_sections_1 (s->group_statement.children.head, output_section_statement, &s->group_statement.children.head, - fill, dot, relax, check_regions); + fill, dot, relax, + need_finalize_relax, + check_regions); break; default: @@ -3372,22 +3383,28 @@ lang_size_sections_1 (s, output_section_ } bfd_vma -lang_size_sections (s, output_section_statement, prev, fill, dot, relax, - check_regions) +lang_size_sections (s, output_section_statement, prev, fill, dot, + relax, need_finalize_relax, check_regions) lang_statement_union_type *s; lang_output_section_statement_type *output_section_statement; lang_statement_union_type **prev; fill_type *fill; bfd_vma dot; bfd_boolean *relax; + bfd_boolean *need_finalize_relax; bfd_boolean check_regions; { bfd_vma result; exp_data_seg.phase = exp_dataseg_none; - result = lang_size_sections_1 (s, output_section_statement, prev, fill, - dot, relax, check_regions); - if (exp_data_seg.phase == exp_dataseg_end_seen) + result = lang_size_sections_1 (s, output_section_statement, prev, + fill, dot, relax, need_finalize_relax, + check_regions); + + /* We can't change addresses after the relax finalize pass starts + since the relaxation may assume addresses won't be changes. */ + if (!link_info.relax_finalizing + && exp_data_seg.phase == exp_dataseg_end_seen) { /* If DATA_SEGMENT_ALIGN DATA_SEGMENT_END pair was seen, check whether a page could be saved in the data segment. */ @@ -3401,8 +3418,10 @@ lang_size_sections (s, output_section_st && first + last <= exp_data_seg.pagesize) { exp_data_seg.phase = exp_dataseg_adjust; - result = lang_size_sections_1 (s, output_section_statement, prev, - fill, dot, relax, check_regions); + result = lang_size_sections_1 (s, output_section_statement, + prev, fill, dot, relax, + need_finalize_relax, + check_regions); } } @@ -4378,7 +4397,7 @@ lang_process () /* Size up the sections. */ lang_size_sections (statement_list.head, abs_output_section, - &statement_list.head, 0, (bfd_vma) 0, NULL, + &statement_list.head, 0, (bfd_vma) 0, NULL, NULL, command_line.relax ? FALSE : TRUE); /* Now run around and relax if we can. */ @@ -4386,6 +4405,7 @@ lang_process () { /* Keep relaxing until bfd_relax_section gives up. */ bfd_boolean relax_again; + bfd_boolean need_finalize_relax; do { @@ -4408,14 +4428,29 @@ lang_process () lang_size_sections (statement_list.head, abs_output_section, &statement_list.head, 0, (bfd_vma) 0, - &relax_again, FALSE); + &relax_again, &need_finalize_relax, + FALSE); /* If the normal relax is done and the relax finalize pass is not performed yet, we perform another relax pass. */ - if (!relax_again && !link_info.relax_finalizing) + if (!relax_again + && need_finalize_relax + && !link_info.relax_finalizing) { link_info.relax_finalizing = TRUE; relax_again = TRUE; + if (exp_data_seg.phase == exp_dataseg_adjust) + { + /* Make sure addresses are finalized. */ + lang_reset_memory_regions (); + lang_do_assignments (statement_list.head, + abs_output_section, + (fill_type *) 0, (bfd_vma) 0); + lang_size_sections (statement_list.head, + abs_output_section, + &statement_list.head, 0, + (bfd_vma) 0, NULL, NULL, TRUE); + } } } while (relax_again); @@ -4428,7 +4463,7 @@ lang_process () lang_size_sections (statement_list.head, abs_output_section, & statement_list.head, 0, (bfd_vma) 0, - NULL, TRUE); + NULL, NULL, TRUE); } /* See if anything special should be done now we know how big --- ld/ldlang.h.final 2003-03-04 11:11:00.000000000 -0800 +++ ld/ldlang.h 2003-05-14 15:09:58.000000000 -0700 @@ -482,7 +482,9 @@ extern bfd_vma lang_size_sections PARAMS ((lang_statement_union_type *s, lang_output_section_statement_type *output_section_statement, lang_statement_union_type **prev, fill_type *fill, - bfd_vma dot, bfd_boolean *relax, bfd_boolean check_regions)); + bfd_vma dot, bfd_boolean *relax, + bfd_boolean *need_finalize_relax, + bfd_boolean check_regions)); extern void lang_enter_group PARAMS ((void)); extern void lang_leave_group --- ld/pe-dll.c.final 2003-04-02 13:42:02.000000000 -0800 +++ ld/pe-dll.c 2003-05-14 15:10:50.000000000 -0700 @@ -2703,7 +2703,8 @@ pe_dll_fill_sections (abfd, info) /* Resize the sections. */ lang_size_sections (stat_ptr->head, abs_output_section, - &stat_ptr->head, 0, (bfd_vma) 0, NULL, TRUE); + &stat_ptr->head, 0, (bfd_vma) 0, + NULL, NULL, TRUE); /* Redo special stuff. */ ldemul_after_allocation (); @@ -2738,7 +2739,8 @@ pe_exe_fill_sections (abfd, info) /* Resize the sections. */ lang_size_sections (stat_ptr->head, abs_output_section, - &stat_ptr->head, 0, (bfd_vma) 0, NULL, TRUE); + &stat_ptr->head, 0, (bfd_vma) 0, + NULL, NULL, TRUE); /* Redo special stuff. */ ldemul_after_allocation ();