This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[patch] Fix occasional 2MB gap in the linked binary
- From: Jan Kratochvil <jan dot kratochvil at redhat dot com>
- To: binutils at sourceware dot org
- Date: Mon, 11 Aug 2008 15:03:29 +0200
- Subject: [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;