summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2004-12-17 15:50:02 +0000
committerJakub Jelinek <jakub@redhat.com>2004-12-17 15:50:02 +0000
commit58843219cea7c1e1d8ad5d0c7673e87776b1b612 (patch)
tree56089b25f647faab4ea125d5aee03f5e2cf46d87
parentd6d4f7e26582832951d157195853b15eaa9f9629 (diff)
downloadbinutils-redhat-58843219cea7c1e1d8ad5d0c7673e87776b1b612.tar.gz
* ldexp.h (exp_data_seg): Add min_base and maxpagesize fields.
* ldexp.c (fold_binary) <case DATA_SEGMENT_ALIGN>: Initialize them. * ldlang.c (lang_size_sections): Use them to avoid wasting virtual address space at DATA_SEGMENT_ALIGN. Fix computation of expected PT_GNU_RELRO segment end.
-rw-r--r--ld/ChangeLog8
-rw-r--r--ld/ldexp.c2
-rw-r--r--ld/ldexp.h2
-rw-r--r--ld/ldlang.c14
4 files changed, 21 insertions, 5 deletions
diff --git a/ld/ChangeLog b/ld/ChangeLog
index 0844e9a69c..f5ef3a7a02 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,3 +1,11 @@
+2004-12-17 Jakub Jelinek <jakub@redhat.com>
+
+ * ldexp.h (exp_data_seg): Add min_base and maxpagesize fields.
+ * ldexp.c (fold_binary) <case DATA_SEGMENT_ALIGN>: Initialize them.
+ * ldlang.c (lang_size_sections): Use them to avoid wasting virtual
+ address space at DATA_SEGMENT_ALIGN. Fix computation of expected
+ PT_GNU_RELRO segment end.
+
2004-12-14 P.J. Darcy <darcypj@us.ibm.com>
* configure.tgt: Add s390x-ibm-tpf support.
diff --git a/ld/ldexp.c b/ld/ldexp.c
index cd6068cc47..f971ecfaeb 100644
--- a/ld/ldexp.c
+++ b/ld/ldexp.c
@@ -435,8 +435,10 @@ fold_binary (etree_type *tree,
if (allocation_done == lang_allocating_phase_enum)
{
exp_data_seg.phase = exp_dataseg_align_seen;
+ exp_data_seg.min_base = align_n (dot, maxpage);
exp_data_seg.base = result.value;
exp_data_seg.pagesize = other.value;
+ exp_data_seg.maxpagesize = maxpage;
exp_data_seg.relro_end = 0;
}
}
diff --git a/ld/ldexp.h b/ld/ldexp.h
index addf83424a..59a5627508 100644
--- a/ld/ldexp.h
+++ b/ld/ldexp.h
@@ -100,7 +100,7 @@ extern struct exp_data_seg {
exp_dataseg_relro_adjust,
exp_dataseg_adjust
} phase;
- bfd_vma base, relro_end, end, pagesize;
+ bfd_vma base, min_base, relro_end, end, pagesize, maxpagesize;
} exp_data_seg;
/* A maps from a segment name to a base address. */
diff --git a/ld/ldlang.c b/ld/ldlang.c
index c3a49344af..ab34090e41 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -3858,15 +3858,21 @@ lang_size_sections
{
/* If DATA_SEGMENT_ALIGN DATA_SEGMENT_RELRO_END pair was seen, try
to put exp_data_seg.relro on a (common) page boundary. */
- bfd_vma old_base, relro_end;
+ bfd_vma old_min_base, relro_end, maxpage;
exp_data_seg.phase = exp_dataseg_relro_adjust;
- old_base = exp_data_seg.base;
+ old_min_base = exp_data_seg.min_base;
+ maxpage = exp_data_seg.maxpagesize;
exp_data_seg.base += (-exp_data_seg.relro_end
& (exp_data_seg.pagesize - 1));
/* Compute the expected PT_GNU_RELRO segment end. */
relro_end = (exp_data_seg.relro_end + exp_data_seg.pagesize - 1)
- & (exp_data_seg.pagesize - 1);
+ & ~(exp_data_seg.pagesize - 1);
+ if (old_min_base + maxpage < exp_data_seg.base)
+ {
+ exp_data_seg.base -= maxpage;
+ relro_end -= maxpage;
+ }
result = lang_size_sections_1 (s, output_section_statement, prev, fill,
dot, relax, check_regions);
if (exp_data_seg.relro_end > relro_end)
@@ -3888,7 +3894,7 @@ lang_size_sections
if (((bfd_vma) 1 << max_alignment_power) < exp_data_seg.pagesize)
{
if (exp_data_seg.base - (1 << max_alignment_power)
- < old_base)
+ < old_min_base)
exp_data_seg.base += exp_data_seg.pagesize;
exp_data_seg.base -= (1 << max_alignment_power);
result = lang_size_sections_1 (s, output_section_statement,