From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 6507 invoked by alias); 14 May 2003 22:53:49 -0000 Mailing-List: contact gcc-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Archive: List-Post: List-Help: Sender: gcc-owner@gcc.gnu.org Received: (qmail 6483 invoked from network); 14 May 2003 22:53:49 -0000 Received: from unknown (HELO sccrmhc02.attbi.com) (204.127.202.62) by sources.redhat.com with SMTP; 14 May 2003 22:53:49 -0000 Received: from lucon.org (12-234-88-5.client.attbi.com[12.234.88.5]) by attbi.com (sccrmhc02) with ESMTP id <200305142253480020046bo3e>; Wed, 14 May 2003 22:53:48 +0000 Received: by lucon.org (Postfix, from userid 1000) id 5F7842C681; Wed, 14 May 2003 15:53:46 -0700 (PDT) Date: Wed, 14 May 2003 22:53:00 -0000 From: "H. J. Lu" To: Richard Henderson , gcc@gcc.gnu.org Cc: binutils@sources.redhat.com, amodra@bigpond.net.au, jakub@redhat.com Subject: PATCH: Fix the relax finalize pass Message-ID: <20030514155346.A9453@lucon.org> References: <20030513163647.B21871@lucon.org> <20030514075330.GC16863@redhat.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="pf9I7BMVVzbSWLtt" Content-Disposition: inline User-Agent: Mutt/1.2.5.1i In-Reply-To: <20030514075330.GC16863@redhat.com>; from rth@redhat.com on Wed, May 14, 2003 at 12:53:30AM -0700 X-SW-Source: 2003-05/txt/msg01472.txt.bz2 --pf9I7BMVVzbSWLtt Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-length: 453 On Wed, May 14, 2003 at 12:53:30AM -0700, Richard Henderson wrote: > On Tue, May 13, 2003 at 04:36:47PM -0700, H. J. Lu wrote: > > I am not sure if it is the right usage of LTOFF22X > > It is. You're allowed to use it with any operand whatsoever. > > The problem is linker keeps changing data segment address after the relax finalize pass starts. It makes the GP calculation in the relax finalize pass invalid. This patch tries to avoid it. H.J. --pf9I7BMVVzbSWLtt Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="ld-final.patch" Content-length: 11106 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 (); --pf9I7BMVVzbSWLtt--