<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 - Add support for range extension thunks with addends."
   href="https://bugs.llvm.org/show_bug.cgi?id=40438">40438</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Add support for range extension thunks with addends.
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>lld
          </td>
        </tr>

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

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

        <tr>
          <th>OS</th>
          <td>Linux
          </td>
        </tr>

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

        <tr>
          <th>Severity</th>
          <td>enhancement
          </td>
        </tr>

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

        <tr>
          <th>Component</th>
          <td>ELF
          </td>
        </tr>

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

        <tr>
          <th>Reporter</th>
          <td>peter.smith@linaro.org
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org, peter.smith@linaro.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Range extension thunks are added in between the source and destination of a
relocated branch when the disance between source and destination exceeds the
branch range.

In the vast majority of cases the relocation will represent a function call and
will be directly to the symbol and not symbol + offset. There is however a case
used in the linux kernel (when assembled by GNU as) that can result to a branch
relocation to symbol + offset.

In arch/arm/include/asm/futex.h there is a fragment of inline assembler
#define __futex_atomic_ex_table(err_reg)                        \
        "3:\n"                                                  \
        "       .pushsection __ex_table,\"a\"\n"                \
        "       .align  3\n"                                    \
        "       .long   1b, 4f, 2b, 4f\n"                       \
        "       .popsection\n"                                  \
        "       .pushsection .text.fixup,\"ax\"\n"              \
        "       .align  2\n"                                    \
        "4:     mov     %0, " err_reg "\n"                      \
        "       b       3b\n"                                   \
        "       .popsection"

the branch b 3b at the end is to the local label 3: . Clang's integrated
assembler will create a temporary label to branch to and all is fine. When
-fno-integrated-as is used GNU as will use a branch relocation to the section
symbol + offset to 3, with the offset encoded in the relocation addend
(instruction on Arm).

The current thunk implementation assumes that there is no relocation addend
when calculating the range, so if the b 3b happens to be before 3: in the
address space it could underestimate the range and we'll end up with an out of
range relocation. I think that such cases will be rare as it will require the
distance between the b 3b instruction and 3: to be range - (offset to 3b from
section defining it's base).

In theory this shouldn't be difficult to fix, but it will require passing
enough information to needsThunk to permit the relocation addend to be
calculated.

Not planning to work on this immediately but raising as PR to go back to later.</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>