<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 - Unable to read return value of arm64 functions returning large objects"
   href="https://bugs.llvm.org/show_bug.cgi?id=33042">33042</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Unable to read return value of arm64 functions returning large objects
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>lldb
          </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>normal
          </td>
        </tr>

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

        <tr>
          <th>Component</th>
          <td>All Bugs
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>lldb-dev@lists.llvm.org
          </td>
        </tr>

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

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Aarch64 Procedure Call Standard specifies that for returning large objects, the
caller passes in a pointer in the x8 register, which points to the memory which
will be populated by the result. However, it does not state that the function
needs to preserve this register -- it remains a volatile reg, like the
registers used to pass other arguments.

Now, ABISysV_arm64 plugin implements "get the return value of a function call"
functionality by reading the x8 register *after* the function returns, and
decoding the memory it points to. This is wrong, as the register could be
clobbered by that point. It happens to work for simple functions that don't do
much, in most cases, but for example it fails if the compiler decides to copy
the object into the destination via memcpy, and memcpy clobbers r8 (this
happens with clang and some versions of android libc, at least).

It's not really clear to me how this can be improved, but I'm filing this bug
for posterity, and in case anyone has an idea. I guess it could be done if the
caller specifies (via dwarf?) the memory it expects the result to be put in,
but as far as I can tell, there is no such dwarf facility at the moment. In the
mean time, I am going to disable the relevant checks in TestReturnValue for
targets I know to be affected.</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>