PR ld/12380

* ldexp.h (enum phase_enum): Comment.  Add exp_dataseg_done.
	* ldexp.c (fold_unary <DATA_SEGMENT_END>): 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 <DATA_SEGMENT_ALIGN>): Likewise.
	(fold_binary <DATA_SEGMENT_RELRO_END>): 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.
This commit is contained in:
Alan Modra 2011-01-12 12:07:19 +00:00
parent d5ae309f06
commit ea7c2e6c9b
4 changed files with 69 additions and 38 deletions

View File

@ -1,3 +1,18 @@
2011-01-12 Alan Modra <amodra@gmail.com>
PR ld/12380
* ldexp.h (enum phase_enum): Comment. Add exp_dataseg_done.
* ldexp.c (fold_unary <DATA_SEGMENT_END>): 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 <DATA_SEGMENT_ALIGN>): Likewise.
(fold_binary <DATA_SEGMENT_RELRO_END>): 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 <nickc@redhat.com>
* po/da.po: Updated Danish translation.

View File

@ -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 <sac@cygnus.com>.
@ -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)

View File

@ -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 {

View File

@ -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 ();