<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - Clang handles .ctors and .init_array priority differently from GCC"
   href="https://bugs.llvm.org/show_bug.cgi?id=48106">48106</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Clang handles .ctors and .init_array priority differently from GCC
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>clang
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>unspecified
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>All
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>normal
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>-New Bugs
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedclangbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>dlj@google.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>htmldeveloper@gmail.com, llvm-bugs@lists.llvm.org, neeilans@live.com, richard-llvm@metafoo.co.uk
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Under GCC and BFD ld, .ctors and .init_array with priorities are sorted to run
in a specific order.

Example 1: <a href="https://compiler-explorer.com/z/9xTh1e">https://compiler-explorer.com/z/9xTh1e</a>
Example 2: <a href="https://compiler-explorer.com/z/chTc5n">https://compiler-explorer.com/z/chTc5n</a>
(nearly identical examples as <a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - Clang does not reject .ctor and .init_array in the same TU"
   href="show_bug.cgi?id=48105">bug 48105</a>, except that Example 2 does compile
with GCC)

Per <a href="https://gcc.gnu.org/bugzilla/show_bug.cgi?id=46770">https://gcc.gnu.org/bugzilla/show_bug.cgi?id=46770</a>, I believe that order is
intended to be:

.ctors.* (class-type variables with 'init_priority(<value in [101, 65535]>)',
sorted lexicographically with suffix of (65535-init_priority))
.ctors
.init_array.* (the suffix is a number, and these are sorted numerically)
.init_array

(You can also check with your friendly local
/usr/lib/x86_64-linux-gnu/ldscripts/elf32_x86_64.x or similar.)

However, based on Example 1, when both .init_array and .ctors sections are
present, the actual behavior from GCC appears to be:

.ctors.*
.init_array.*
.init_array
.ctors

Notably, .ctors.00000 (the section name which would correspond to
init_priority(65535)) runs before .init_array.0.


Also in Example 1, Gold merges priority sections, so, for example, this
ordering:

'.init_array.101' and '.ctors.65434' (in some order)
'.init_array.65535' and '.ctors.00000' and '.ctors' (in some order)
'.init_array'
'.ctors'

seems valid. (Merging corresponding priorities of .ctors.* and .init_array.*
seems to satisfy much of the discussion on
<a href="https://gcc.gnu.org/bugzilla/show_bug.cgi?id=46770">https://gcc.gnu.org/bugzilla/show_bug.cgi?id=46770</a>.)



Based on Example 2, GCC's order with _only_ .ctors.* and .ctors is:

.ctors.{65535..65435} (which would correspond to init_priority(0..100), but
those are only allowed for use by the implementation)
.ctors.{65434..00001} (which correspond to init_priority(101..65534))
{.ctors.00000 .ctors} (which correspond to init_priority(65535) and no
init_priority, respectively)

In particular, I believe .ctors.00000 and .ctors are being treated as the same
equivalence class, because of this sequence:

.ctors.00000  (the section name corresponding to init_priority(65535))
X::X          (corresponds to .ctors)
X::X init_priority(65535)  (corresponds to .ctors.00000)
.ctors        (corresponds to no init_priority)



However, Clang produces results I can't quite explain. Again, using Example 2
above, Clang with BFD ld produce this output (slightly edited for clarity):

.ctors.65535
.init_array.0
.init_array.2
.ctors.65434
.init_array.101
X::X init_priority(101)
.ctors.00000
.init_array.65535
.ctors
.init_array
X::X init_priority(65535)
X::X


This seems odd, for two reasons:

1. Clang seems to be either merging or mis-attributing these sections, because
I would expect BFD ld to retain the same overall sequence as from GCC (i.e.,
all .ctors.* before .init_array.*, etc.).

2. Based on GCC in Example 1, I would expect this sequence (from BFD ld):
    .ctors.00000
    .init_array.65535
    .ctors
    .init_array
    X::X init_priority(65535)
    X::X
to be more like:
    <other .ctors.*>       <- added for completeness
    .ctors.00000
    X::X init_priority(65535)  <- moved
    <other .init_array.*>  <- added for completeness
    .init_array.65535
    .init_array
    .ctors                 <- moved
    X::X

and this sequence (from Gold):
    .ctors.00000
    .init_array.65535
    .init_array
    X::X init_priority(65535)
    X::X
    .ctors
to be more like:
    .ctors.00000
    X::X init_priority(65535)  <- moved
    .init_array.65535
    .init_array
    .ctors
    X::X</pre>
        </div>
      </p>


      <hr>
      <span>You are receiving this mail because:</span>

      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>