diff options
-rw-r--r-- | ld/ldexp.c | 12 | ||||
-rw-r--r-- | ld/ldexp.h | 5 | ||||
-rw-r--r-- | ld/ldlang.c | 13 |
3 files changed, 17 insertions, 13 deletions
@@ -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 @@ -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; |