From ea7c2e6c9b3798ae7d73c370857761f130e95e00 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Wed, 12 Jan 2011 12:07:19 +0000 Subject: [PATCH] PR ld/12380 * ldexp.h (enum phase_enum): Comment. Add exp_dataseg_done. * ldexp.c (fold_unary ): Rearrange code. Test for exp_dataseg_done rather than expld.phase == lang_final_phase_enum to detect when we've finished sizing sections. (fold_binary ): Likewise. (fold_binary ): Likewise. Also test that we are not inside an output section statement. * ldlang.c (lang_size_sections): Set exp_dataseg_done on exit if not exp_dataseg_relro_adjust or exp_dataseg_adjust. Don't set lang_final_phase_enum here. (lang_process): Set lang_final_phase_enum here. --- ld/ChangeLog | 15 +++++++++++ ld/ldexp.c | 73 +++++++++++++++++++++++++++++----------------------- ld/ldexp.h | 9 +++++-- ld/ldlang.c | 10 ++++--- 4 files changed, 69 insertions(+), 38 deletions(-) diff --git a/ld/ChangeLog b/ld/ChangeLog index 6f835c918fe..457e380c6ea 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,18 @@ +2011-01-12 Alan Modra + + PR ld/12380 + * ldexp.h (enum phase_enum): Comment. Add exp_dataseg_done. + * ldexp.c (fold_unary ): Rearrange code. Test + for exp_dataseg_done rather than expld.phase == lang_final_phase_enum + to detect when we've finished sizing sections. + (fold_binary ): Likewise. + (fold_binary ): Likewise. Also test + that we are not inside an output section statement. + * ldlang.c (lang_size_sections): Set exp_dataseg_done on exit if + not exp_dataseg_relro_adjust or exp_dataseg_adjust. Don't set + lang_final_phase_enum here. + (lang_process): Set lang_final_phase_enum here. + 2011-01-10 Nick Clifton * po/da.po: Updated Danish translation. diff --git a/ld/ldexp.c b/ld/ldexp.c index 326188424ef..9aad09214f2 100644 --- a/ld/ldexp.c +++ b/ld/ldexp.c @@ -1,6 +1,6 @@ /* This module handles expression trees. Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, - 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 + 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. Written by Steve Chamberlain of Cygnus Support . @@ -259,20 +259,22 @@ fold_unary (etree_type *tree) break; case DATA_SEGMENT_END: - if (expld.phase != lang_first_phase_enum - && expld.section == bfd_abs_section_ptr - && (expld.dataseg.phase == exp_dataseg_align_seen - || expld.dataseg.phase == exp_dataseg_relro_seen - || expld.dataseg.phase == exp_dataseg_adjust - || expld.dataseg.phase == exp_dataseg_relro_adjust - || expld.phase == lang_final_phase_enum)) + if (expld.phase == lang_first_phase_enum + || expld.section != bfd_abs_section_ptr) { - if (expld.dataseg.phase == exp_dataseg_align_seen - || expld.dataseg.phase == exp_dataseg_relro_seen) - { - expld.dataseg.phase = exp_dataseg_end_seen; - expld.dataseg.end = expld.result.value; - } + expld.result.valid_p = FALSE; + } + else if (expld.dataseg.phase == exp_dataseg_align_seen + || expld.dataseg.phase == exp_dataseg_relro_seen) + { + expld.dataseg.phase = exp_dataseg_end_seen; + expld.dataseg.end = expld.result.value; + } + else if (expld.dataseg.phase == exp_dataseg_done + || expld.dataseg.phase == exp_dataseg_adjust + || expld.dataseg.phase == exp_dataseg_relro_adjust) + { + /* OK. */ } else expld.result.valid_p = FALSE; @@ -402,12 +404,10 @@ fold_binary (etree_type *tree) case DATA_SEGMENT_ALIGN: expld.dataseg.relro = exp_dataseg_relro_start; - if (expld.phase != lang_first_phase_enum - && expld.section == bfd_abs_section_ptr - && (expld.dataseg.phase == exp_dataseg_none - || expld.dataseg.phase == exp_dataseg_adjust - || expld.dataseg.phase == exp_dataseg_relro_adjust - || expld.phase == lang_final_phase_enum)) + if (expld.phase == lang_first_phase_enum + || expld.section != bfd_abs_section_ptr) + expld.result.valid_p = FALSE; + else { bfd_vma maxpage = lhs.value; bfd_vma commonpage = expld.result.value; @@ -415,10 +415,20 @@ fold_binary (etree_type *tree) expld.result.value = align_n (expld.dot, maxpage); if (expld.dataseg.phase == exp_dataseg_relro_adjust) expld.result.value = expld.dataseg.base; - else if (expld.dataseg.phase != exp_dataseg_adjust) + else if (expld.dataseg.phase == exp_dataseg_adjust) + { + if (commonpage < maxpage) + expld.result.value += ((expld.dot + commonpage - 1) + & (maxpage - commonpage)); + } + else { expld.result.value += expld.dot & (maxpage - 1); - if (expld.phase == lang_allocating_phase_enum) + if (expld.dataseg.phase == exp_dataseg_done) + { + /* OK. */ + } + else if (expld.dataseg.phase == exp_dataseg_none) { expld.dataseg.phase = exp_dataseg_align_seen; expld.dataseg.min_base = expld.dot; @@ -427,22 +437,21 @@ fold_binary (etree_type *tree) expld.dataseg.maxpagesize = maxpage; expld.dataseg.relro_end = 0; } + else + expld.result.valid_p = FALSE; } - else if (commonpage < maxpage) - expld.result.value += ((expld.dot + commonpage - 1) - & (maxpage - commonpage)); } - else - expld.result.valid_p = FALSE; break; case DATA_SEGMENT_RELRO_END: expld.dataseg.relro = exp_dataseg_relro_end; - if (expld.phase != lang_first_phase_enum - && (expld.dataseg.phase == exp_dataseg_align_seen - || expld.dataseg.phase == exp_dataseg_adjust - || expld.dataseg.phase == exp_dataseg_relro_adjust - || expld.phase == lang_final_phase_enum)) + if (expld.phase == lang_first_phase_enum + || expld.section != bfd_abs_section_ptr) + expld.result.valid_p = FALSE; + else if (expld.dataseg.phase == exp_dataseg_align_seen + || expld.dataseg.phase == exp_dataseg_adjust + || expld.dataseg.phase == exp_dataseg_relro_adjust + || expld.dataseg.phase == exp_dataseg_done) { if (expld.dataseg.phase == exp_dataseg_align_seen || expld.dataseg.phase == exp_dataseg_relro_adjust) diff --git a/ld/ldexp.h b/ld/ldexp.h index 31a06ac86b7..6c94be2eaba 100644 --- a/ld/ldexp.h +++ b/ld/ldexp.h @@ -1,6 +1,6 @@ /* ldexp.h - Copyright 1991, 1992, 1993, 1994, 1995, 1998, 1999, 2000, 2001, 2002, - 2003, 2004, 2005, 2007 Free Software Foundation, Inc. + 2003, 2004, 2005, 2007, 2011 Free Software Foundation, Inc. This file is part of the GNU Binutils. @@ -103,12 +103,17 @@ typedef enum { union lang_statement_union; enum phase_enum { + /* We step through the first four states here as we see the + associated linker script tokens. */ exp_dataseg_none, exp_dataseg_align_seen, exp_dataseg_relro_seen, exp_dataseg_end_seen, + /* The last three states are final, and affect the value returned + by DATA_SEGMENT_ALIGN. */ exp_dataseg_relro_adjust, - exp_dataseg_adjust + exp_dataseg_adjust, + exp_dataseg_done }; enum relro_enum { diff --git a/ld/ldlang.c b/ld/ldlang.c index 52518049c76..4fe80a8f6ca 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -1,6 +1,6 @@ /* Linker command language support. Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, - 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 + 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. This file is part of the GNU Binutils. @@ -5425,9 +5425,11 @@ lang_size_sections (bfd_boolean *relax, bfd_boolean check_regions) lang_reset_memory_regions (); one_lang_size_sections_pass (relax, check_regions); } + else + expld.dataseg.phase = exp_dataseg_done; } - - expld.phase = lang_final_phase_enum; + else + expld.dataseg.phase = exp_dataseg_done; } /* Worker function for lang_do_assignments. Recursiveness goes here. */ @@ -6520,7 +6522,7 @@ lang_process (void) /* Do all the assignments, now that we know the final resting places of all the symbols. */ - + expld.phase = lang_final_phase_enum; lang_do_assignments (); ldemul_finish (); -- 2.30.2