This is the mail archive of the binutils@sourceware.org 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]

[patch] Fix occasional 2MB gap in the linked binary


Hi,

Regular
-rwxr-xr-x 1 root root 355264 May 13 13:14 /usr/sbin/cupsd
got sometimes linked as:
-rwxr-xr-x 1 root root 2475480 Aug  7 17:12 cups-1.3.7-2.x86_64/usr/sbin/cupsd

because:
Additional info:
Section Headers:
[Nr] Name                 Type         Addr             Off      Size     ES
Flags Lk Inf Al
...
[16] .eh_frame            PROGBITS     0000000000057178 00057178 00002a5c  0 A 
    0   0  8
[17] .ctors               PROGBITS     0000000000259bd0 00259bd0 00000010  0 WA
    0   0  8

.eh_frame ends at 0x59bd4 but .ctors starts at 0x259bd0.  This makes the runtime
mapping overlap and a whole MAXPAGE (2MB) range gets inserted into the file.

It is because lang_size_sections() condition
              if (expld.dataseg.base - (1 << max_alignment_power)
                  < old_min_base)
                expld.dataseg.base += expld.dataseg.pagesize;
does not work as OLD_MIN_BASE is there 0x200000 and for example (0x259bec - 32)
can never get under it.  Fixed OLD_MIN_BASE in the attached patch to ensure a
positive gap size for the runtime.  This lang_size_sections() condition is
trying to push the sections even more down if at the first try the GNU_RELRO
segment exceeds the page boundary due to alignments.  The condition to insert
the the additional COMMONPAGESIZE could never be satisfied due to the
OLD_MIN_BASE value which is now fixed.


Regards,
Jan
2008-08-11  Jan Kratochvil  <jan.kratochvil@redhat.com>

	PR ld/6833
	* ldexp.c (fold_binary <DATA_SEGMENT_ALIGN>): Keep
	EXPLD.DATASEG.MIN_BASE congruent with EXPLD.DOT modulo MAXPAGE.

--- ld/ldexp.c	7 May 2008 14:30:41 -0000	1.74
+++ ld/ldexp.c	11 Aug 2008 12:10:58 -0000
@@ -415,7 +415,20 @@ fold_binary (etree_type *tree)
 		      if (expld.phase == lang_allocating_phase_enum)
 			{
 			  expld.dataseg.phase = exp_dataseg_align_seen;
-			  expld.dataseg.min_base = align_n (expld.dot, maxpage);
+
+			  /* Required is only `align_n (expld.dot, maxpage)' to
+			     separate the runtime MAXPAGE mapping of the
+			     writable data segment from the previous readonly
+			     segment.  We still force even at least the same
+			     offset inside MAXPAGE as if we would assign VMA
+			     between MAXPAGE..MAXPAGE+DOT the file-offset for
+			     the data segment start would have to be another
+			     almost MAXPAGE higher to get it congruent modulo
+			     MAXPAGE for the runtime mapping.  */
+			  expld.dataseg.min_base = expld.dot;
+			  if (expld.dataseg.min_base & (maxpage - 1))
+			    expld.dataseg.min_base += maxpage;
+
 			  expld.dataseg.base = expld.result.value;
 			  expld.dataseg.pagesize = commonpage;
 			  expld.dataseg.maxpagesize = maxpage;

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