aboutsummaryrefslogtreecommitdiff
path: root/ld/ldexp.c
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2011-01-12 12:07:19 +0000
committerAlan Modra <amodra@gmail.com>2011-01-12 12:07:19 +0000
commitea7c2e6c9b3798ae7d73c370857761f130e95e00 (patch)
treea258cb40d9bd565acdc8376ef33bcfa0a2039c24 /ld/ldexp.c
parentd5ae309f069331dbec7bfd3e5d8c597aa0619ba2 (diff)
downloadgdb-ea7c2e6c9b3798ae7d73c370857761f130e95e00.zip
gdb-ea7c2e6c9b3798ae7d73c370857761f130e95e00.tar.gz
gdb-ea7c2e6c9b3798ae7d73c370857761f130e95e00.tar.bz2
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.
Diffstat (limited to 'ld/ldexp.c')
-rw-r--r--ld/ldexp.c73
1 files changed, 41 insertions, 32 deletions
diff --git a/ld/ldexp.c b/ld/ldexp.c
index 3261884..9aad092 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 <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)