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-binutils mailing list bug-binutils@gnu.org https://lists.gnu.org/mailman/listinfo/bug-binutils