This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: Fix relro when COMMONPAGESIZE < MAXPAGESIZE
Jakub Jelinek <jakub@redhat.com> writes:
> The constraints are:
> 1) for all segments, (p_vaddr % MAXPAGESIZE) == (p_offset % MAXPAGESIZE)
> This is because the ELF object ought to be usable on systems with
> MAXPAGESIZE page size.
This is what DATA_SEGMENT_ALIGN ensures.
> 2) so that the PT_GNU_RELRO region can be successfully protected
> when system page size <= COMMONPAGESIZE, PT_GNU_RELRO's end must be
> COMMONPAGESIZE aligned. For system page size > COMMONPAGESIZE the
> library/binary shall be usable, but no protection will work.
This is what DATA_SEGMENT_RELRO_GOTPLT_END ensures. So the task is to
insert padding at the start of data until both constraints are met. This
patch implements that.
2004-09-09 Andreas Schwab <schwab@suse.de>
* ldexp.c (fold_binary) [DATA_SEGMENT_ALIGN]: Adjust data segment
base so that relro end is suitably aligned.
--- ld/ldexp.c 02 Sep 2004 15:29:34 +0200 1.33
+++ ld/ldexp.c 09 Sep 2004 14:00:15 +0200
@@ -425,12 +425,9 @@ fold_binary (etree_type *tree,
{
/* Attempt to align DATA_SEGMENT_RELRO_END at
a common page boundary. */
- bfd_vma relro;
-
- result.value += dot & (maxpage - 1);
- relro = exp_data_seg.relro_end - exp_data_seg.base;
- result.value += -relro & (other.value - 1);
- exp_data_seg.base = result.value;
+ exp_data_seg.base += (-exp_data_seg.relro_end
+ & (other.value - 1));
+ result.value = exp_data_seg.base;
}
else if (exp_data_seg.phase != exp_dataseg_adjust)
{
>> Also, looking at the linker script template elf.sc, I'm wondering why
>> DATA_SEGMENT_RELRO_GOTPLT_END isn't defined as this:
>>
>> DATA_SEGMENT_RELRO_GOTPLT_END=". = DATA_SEGMENT_RELRO_END (. + ${SEPARATE_GOTPLT}) - ${SEPARATE_GOTPLT};"
>
> DATA_SEGMENT_RELRO_END as currently implemented returns dot, not its
> argument.
Ok, it didn't know that. In that case the current definition is correct.
>> and why this definition is only active when COMMONPAGESIZE is defined. In
>> other places SEPARATE_GOTPLT is used even when COMMONPAGESIZE is not
>> defined.
>
> Because DATA_SEGMENT_RELRO_END relies on DATA_SEGMENT_ALIGN/DATA_SEGMENT_END
> directives to be also present in the linker script, and they are only
> present if COMMONPAGESIZE is defined.
Thanks for your explanation. The logic in elf.sc is a bit convoluted and
underdocumented.
> If you want them appear, but the commonly used page size is equal to
> MAXPAGESIZE, just define COMMONPAGESIZE to MAXPAGESIZE as already
> e.g. i386 is doing.
How about making that the default?
> When there is no COMMONPAGESIZE definition, that tells the linker
> to not do any DATA_SEGMENT_* adjustements (as even without -z relro
> they are disk space unfriendly; though without -z relro they may
> waste just up to COMMONPAGESIZE bytes on the disk).
If COMMONPAGESIZE is equal to MAXPAGESIZE then DATA_SEGMENT_ALIGN is a
no-op anyway.
Andreas.
--
Andreas Schwab, SuSE Labs, schwab@suse.de
SuSE Linux AG, Maxfeldstraße 5, 90409 Nürnberg, Germany
Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5
"And now for something completely different."