[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Bug ld/19203] New: DATA_SEGMENT_ALIGN documentation is not consistent w
From: |
srk31 at srcf dot ucam.org |
Subject: |
[Bug ld/19203] New: DATA_SEGMENT_ALIGN documentation is not consistent with behaviour |
Date: |
Wed, 04 Nov 2015 12:01:25 +0000 |
https://sourceware.org/bugzilla/show_bug.cgi?id=19203
Bug ID: 19203
Summary: DATA_SEGMENT_ALIGN documentation is not consistent
with behaviour
Product: binutils
Version: 2.25
Status: NEW
Severity: normal
Priority: P2
Component: ld
Assignee: unassigned at sourceware dot org
Reporter: srk31 at srcf dot ucam.org
Target Milestone: ---
Created attachment 8765
--> https://sourceware.org/bugzilla/attachment.cgi?id=8765&action=edit
Test case showing the actual behaviour
The texinfo manual for GNU ld documents DATA_SEGMENT_ALIGN as follows.
"DATA_SEGMENT_ALIGN(MAXPAGESIZE, COMMONPAGESIZE)
is equivalent to either
(ALIGN(MAXPAGESIZE) + (. & (MAXPAGESIZE - 1)))
or
(ALIGN(MAXPAGESIZE) + (. & (MAXPAGESIZE - COMMONPAGESIZE)))
depending on whether the latter uses fewer COMMONPAGESIZE sized
pages for the data segment (area between the result of this
expression and `DATA_SEGMENT_END') than the former or not. If the
latter form is used, it means COMMONPAGESIZE bytes of runtime
memory will be saved at the expense of up to COMMONPAGESIZE wasted
bytes in the on-disk file."
As an example, if `.' has the value 0x4017dc, and we then do
DATA_SEGMENT_ALIGN(0x200000, 0x1000)
we'd expect the two alternatives to be (respectively)
(ALIGN(0x200000) + (0x4017dc & 0xffff)) == 0x6017dc
and
(ALIGN(0x200000) + (0x4017dc & (0x200000 - 0x1000)))
== 0x600000 + (0x4017dc & (0x1ff000))
== 0x601000
but actually, when we run the linker, it chooses 0x602000, i.e. neither of the
above.
It turns out that the code for option 2 is actually computing:
(. + COMMONPAGESIZE - 1) & (MAXPAGESIZE - COMMONPAGESIZE)
... at least from my reading of ldexp.c around line 478.
468 case DATA_SEGMENT_ALIGN:
469 expld.dataseg.relro = exp_dataseg_relro_start;
470 if (expld.phase == lang_first_phase_enum
471 || expld.section != bfd_abs_section_ptr)
472 expld.result.valid_p = FALSE;
473 else
474 {
475 bfd_vma maxpage = lhs.value;
476 bfd_vma commonpage = expld.result.value;
477
478 expld.result.value = align_n (expld.dot, maxpage);
479 if (expld.dataseg.phase == exp_dataseg_relro_adjust)
480 expld.result.value = expld.dataseg.base;
481 else if (expld.dataseg.phase == exp_dataseg_adjust)
482 {
483 if (commonpage < maxpage)
484 expld.result.value += ((expld.dot + commonpage - 1)
485 & (maxpage - commonpage));
486 }
487 else
488 {
489 expld.result.value += expld.dot & (maxpage - 1);
The attached tarball illustrates the problem. Run `make', and true.map should
contain the following.
.exception_ranges
*(.exception_ranges .exception_ranges*)
0x00000000004017dc . = (ALIGN (0x200000) -
((0x200000 - .) & 0x1fffff))
0x0000000000602000 . = DATA_SEGMENT_ALIGN
(0x200000, 0x1000)
--
You are receiving this mail because:
You are on the CC list for the bug.
- [Bug ld/19203] New: DATA_SEGMENT_ALIGN documentation is not consistent with behaviour,
srk31 at srcf dot ucam.org <=