bug-binutils
[Top][All Lists]
Advanced

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


reply via email to

[Prev in Thread] Current Thread [Next in Thread]