<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 - x86 regression: incorrect ELF relocation for llvm.memset and some other builtins"
   href="https://bugs.llvm.org/show_bug.cgi?id=51736">51736</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>x86 regression: incorrect ELF relocation for llvm.memset and some other builtins
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>new-bugs
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>12.0
          </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>new bugs
          </td>
        </tr>

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

        <tr>
          <th>Reporter</th>
          <td>tijl@coosemans.org
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>htmldeveloper@gmail.com, llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Consider the following C code:
--------
#include <string.h>

void *
test_memset(void *p, int c, size_t len) {
        return (memset(p, c, len));
}

void *
test_memcpy(void *dst, const void *src, size_t len) {
        return (memcpy(dst, src, len));
}

void *
test_memmove(void *dst, const void *src, size_t len) {
        return (memmove(dst, src, len));
}
--------
When compiled with "clang12 -c test.c -m32" (so targeting x86) the resulting
ELF object file has the following relocations (readelf -r test.o):

r_offset r_info   r_type              st_value st_name
0000002c 00000504 R_386_PLT32         00000000 memset
00000067 00000304 R_386_PLT32         00000000 memcpy
000000a7 00000402 R_386_PC32          00000000 memmove

With clang11:

00000036 00000502 R_386_PC32          00000000 memset
00000083 00000302 R_386_PC32          00000000 memcpy
000000d2 00000402 R_386_PC32          00000000 memmove

Note how memset and memcpy (also __stack_chk_fail) are R_386_PLT32 with
clang12.  When the object file is linked into a shared object (clang -shared -o
libtest.so test.o -z notext) these relocations are converted to PLT entries
that depend on a PIC register (%ebx) which isn't valid because the code hasn't
been compiled with -fPIC so test_memset and test_memcpy tend to crash.  They
work fine when compiled with clang11.

The .ll code generated by both clang11 and clang12 is the same so the problem
must be in LLVM somewhere.</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>