aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ld/ldexp.c12
-rw-r--r--ld/ldexp.h5
-rw-r--r--ld/ldlang.c13
3 files changed, 17 insertions, 13 deletions
diff --git a/ld/ldexp.c b/ld/ldexp.c
index 5f904aa..a38cec7 100644
--- a/ld/ldexp.c
+++ b/ld/ldexp.c
@@ -469,7 +469,8 @@ fold_segment_align (seg_align_type *seg, etree_value_type *lhs)
}
else
{
- expld.result.value += expld.dot & (maxpage - 1);
+ if (!link_info.relro)
+ expld.result.value += expld.dot & (maxpage - 1);
if (seg->phase == exp_seg_done)
{
/* OK. */
@@ -478,8 +479,9 @@ fold_segment_align (seg_align_type *seg, etree_value_type *lhs)
{
seg->phase = exp_seg_align_seen;
seg->base = expld.result.value;
- seg->pagesize = commonpage;
+ seg->commonpagesize = commonpage;
seg->maxpagesize = maxpage;
+ seg->relropagesize = maxpage;
seg->relro_end = 0;
}
else
@@ -508,10 +510,10 @@ fold_segment_relro_end (seg_align_type *seg, etree_value_type *lhs)
seg->relro_end = lhs->value + expld.result.value;
if (seg->phase == exp_seg_relro_adjust
- && (seg->relro_end & (seg->pagesize - 1)))
+ && (seg->relro_end & (seg->relropagesize - 1)))
{
- seg->relro_end += seg->pagesize - 1;
- seg->relro_end &= ~(seg->pagesize - 1);
+ seg->relro_end += seg->relropagesize - 1;
+ seg->relro_end &= ~(seg->relropagesize - 1);
expld.result.value = seg->relro_end - expld.result.value;
}
else
diff --git a/ld/ldexp.h b/ld/ldexp.h
index ac4fa7e..ed6fb8b 100644
--- a/ld/ldexp.h
+++ b/ld/ldexp.h
@@ -136,7 +136,10 @@ enum relro_enum {
typedef struct {
enum phase_enum phase;
- bfd_vma base, relro_offset, relro_end, end, pagesize, maxpagesize;
+ bfd_vma base, relro_offset, relro_end, end;
+ /* MAXPAGESIZE and COMMMONPAGESIZE as passed to DATA_SEGMENT_ALIGN.
+ relropagesize sets the alignment of the end of the relro segment. */
+ bfd_vma maxpagesize, commonpagesize, relropagesize;
enum relro_enum relro;
diff --git a/ld/ldlang.c b/ld/ldlang.c
index 84511c4..f481586 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -6352,12 +6352,12 @@ lang_size_segment (seg_align_type *seg)
a page could be saved in the data segment. */
bfd_vma first, last;
- first = -seg->base & (seg->pagesize - 1);
- last = seg->end & (seg->pagesize - 1);
+ first = -seg->base & (seg->commonpagesize - 1);
+ last = seg->end & (seg->commonpagesize - 1);
if (first && last
- && ((seg->base & ~(seg->pagesize - 1))
- != (seg->end & ~(seg->pagesize - 1)))
- && first + last <= seg->pagesize)
+ && ((seg->base & ~(seg->commonpagesize - 1))
+ != (seg->end & ~(seg->commonpagesize - 1)))
+ && first + last <= seg->commonpagesize)
{
seg->phase = exp_seg_adjust;
return true;
@@ -6374,8 +6374,7 @@ lang_size_relro_segment_1 (seg_align_type *seg)
asection *sec;
/* Compute the expected PT_GNU_RELRO/PT_LOAD segment end. */
- relro_end = ((seg->relro_end + seg->pagesize - 1)
- & ~(seg->pagesize - 1));
+ relro_end = (seg->relro_end + seg->relropagesize - 1) & -seg->relropagesize;
/* Adjust by the offset arg of XXX_SEGMENT_RELRO_END. */
desired_end = relro_end - seg->relro_offset;