This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: PATCH: PR ld/12380: Assertion in linker script failed twice
On Tue, Jan 11, 2011 at 11:57:59AM +1030, Alan Modra wrote:
> I believe the real problem is that we set lang_final_phase too soon,
Jakub, would you please cast your eye over this patch that touches
DATA_SEGMENT_ALIGN support? I'm committing it as I'm reasonably
confident the patch is correct, but would appreciate your review.
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.
Index: ld/ldexp.h
===================================================================
RCS file: /cvs/src/src/ld/ldexp.h,v
retrieving revision 1.25
diff -u -p -r1.25 ldexp.h
--- ld/ldexp.h 20 Dec 2010 13:00:13 -0000 1.25
+++ ld/ldexp.h 12 Jan 2011 06:22:23 -0000
@@ -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 {
Index: ld/ldexp.c
===================================================================
RCS file: /cvs/src/src/ld/ldexp.c,v
retrieving revision 1.89
diff -u -p -r1.89 ldexp.c
--- ld/ldexp.c 20 Dec 2010 13:00:13 -0000 1.89
+++ ld/ldexp.c 12 Jan 2011 08:15:23 -0000
@@ -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)
Index: ld/ldlang.c
===================================================================
RCS file: /cvs/src/src/ld/ldlang.c,v
retrieving revision 1.356
diff -u -p -r1.356 ldlang.c
--- ld/ldlang.c 10 Jan 2011 13:13:32 -0000 1.356
+++ ld/ldlang.c 12 Jan 2011 06:22:27 -0000
@@ -5425,9 +5425,11 @@ lang_size_sections (bfd_boolean *relax,
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 ();
--
Alan Modra
Australia Development Lab, IBM