aboutsummaryrefslogtreecommitdiff
path: root/ld/ldexp.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2004-10-04 13:41:15 +0000
committerJakub Jelinek <jakub@redhat.com>2004-10-04 13:41:15 +0000
commita4f5ad884ecd1b56c973e0d562d97720140d1ec8 (patch)
tree53f1cb3832ca29707b8bacd44f9ff14538fbbbce /ld/ldexp.c
parentdaab19f765f12cce4c9f73efaff8b8ba75a139b5 (diff)
downloadfsf-binutils-gdb-a4f5ad884ecd1b56c973e0d562d97720140d1ec8.zip
fsf-binutils-gdb-a4f5ad884ecd1b56c973e0d562d97720140d1ec8.tar.gz
fsf-binutils-gdb-a4f5ad884ecd1b56c973e0d562d97720140d1ec8.tar.bz2
* ldgram.y (DATA_SEGMENT_RELRO_END): Add one argument.
* scripttempl/elf.sc (DATA_SEGMENT_RELRO_END): Add 0 as first argument. (DATA_SEGMENT_RELRO_GOTPLT_END): Pass $SEPARATE_GOTPLT as first and . as second argument. (GOTPLT): Move $DATA_SEGMENT_RELRO_GOTPLT_END before the section. * ldexp.c (fold_unary): Remove DATA_SEGMENT_RELRO_END handling here. (fold_binary): Add it here. Insert padding to make relro_end COMMONPAGESIZE bytes aligned. For DATA_SEGMENT_ALIGN in exp_dataseg_relro_adjust phase just use previously computed exp_data_seg.base. * ldlang.c (lang_size_sections): Set exp_data_seg.base for relro_adjust here. Call lang_size_sections_1 once more if there was too big padding at DATA_SEGMENT_RELRO_END. * ld.texinfo (DATA_SEGMENT_RELRO_END): Add documentation.
Diffstat (limited to 'ld/ldexp.c')
-rw-r--r--ld/ldexp.c53
1 files changed, 27 insertions, 26 deletions
diff --git a/ld/ldexp.c b/ld/ldexp.c
index de239b2..4110f57 100644
--- a/ld/ldexp.c
+++ b/ld/ldexp.c
@@ -265,25 +265,6 @@ fold_unary (etree_type *tree,
result.valid_p = FALSE;
break;
- case DATA_SEGMENT_RELRO_END:
- if (allocation_done != lang_first_phase_enum
- && (exp_data_seg.phase == exp_dataseg_align_seen
- || exp_data_seg.phase == exp_dataseg_adjust
- || exp_data_seg.phase == exp_dataseg_relro_adjust
- || allocation_done != lang_allocating_phase_enum))
- {
- if (exp_data_seg.phase == exp_dataseg_align_seen
- || exp_data_seg.phase == exp_dataseg_relro_adjust)
- exp_data_seg.relro_end
- = result.value + current_section->bfd_section->vma;
- if (exp_data_seg.phase == exp_dataseg_align_seen)
- exp_data_seg.phase = exp_dataseg_relro_seen;
- result.value = dot - current_section->bfd_section->vma;
- }
- else
- result.valid_p = FALSE;
- break;
-
case DATA_SEGMENT_END:
if (allocation_done != lang_first_phase_enum
&& current_section == abs_output_section
@@ -422,13 +403,7 @@ fold_binary (etree_type *tree,
result.value = align_n (dot, maxpage);
if (exp_data_seg.phase == exp_dataseg_relro_adjust)
- {
- /* Attempt to align DATA_SEGMENT_RELRO_END at
- a common page boundary. */
- exp_data_seg.base += (-exp_data_seg.relro_end
- & (other.value - 1));
- result.value = exp_data_seg.base;
- }
+ result.value = exp_data_seg.base;
else if (exp_data_seg.phase != exp_dataseg_adjust)
{
result.value += dot & (maxpage - 1);
@@ -448,6 +423,32 @@ fold_binary (etree_type *tree,
result.valid_p = FALSE;
break;
+ case DATA_SEGMENT_RELRO_END:
+ if (allocation_done != lang_first_phase_enum
+ && (exp_data_seg.phase == exp_dataseg_align_seen
+ || exp_data_seg.phase == exp_dataseg_adjust
+ || exp_data_seg.phase == exp_dataseg_relro_adjust
+ || allocation_done != lang_allocating_phase_enum))
+ {
+ if (exp_data_seg.phase == exp_dataseg_align_seen
+ || exp_data_seg.phase == exp_dataseg_relro_adjust)
+ exp_data_seg.relro_end
+ = result.value + other.value;
+ if (exp_data_seg.phase == exp_dataseg_relro_adjust
+ && (exp_data_seg.relro_end
+ & (exp_data_seg.pagesize - 1)))
+ {
+ exp_data_seg.relro_end += exp_data_seg.pagesize - 1;
+ exp_data_seg.relro_end &= ~(exp_data_seg.pagesize - 1);
+ result.value = exp_data_seg.relro_end - other.value;
+ }
+ if (exp_data_seg.phase == exp_dataseg_align_seen)
+ exp_data_seg.phase = exp_dataseg_relro_seen;
+ }
+ else
+ result.valid_p = FALSE;
+ break;
+
default:
FAIL ();
}