This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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."


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]