<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 - -fsanitize-coverage=trace-cmp passes parameters incorrectly"
   href="https://bugs.llvm.org/show_bug.cgi?id=33732">33732</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>-fsanitize-coverage=trace-cmp passes parameters incorrectly
          </td>
        </tr>

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

        <tr>
          <th>Version</th>
          <td>trunk
          </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>-New Bugs
          </td>
        </tr>

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

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

        <tr>
          <th>CC</th>
          <td>dvyukov@google.com, kcc@google.com, llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Consider the following program:

==========dummy.ii================
char *_copy_from_user(void *to, const void *from, unsigned n);
long dev_write(struct file *filep, const char *buffer) {
  char s[16];
  _copy_from_user(s, buffer, 1);
  if (s[0] == 's')
    return 1;
  return 0;
}
==================================

When compiled as follows:

$ clang -O2 -fsanitize-coverage=trace-pc -fsanitize-coverage=trace-cmp  -x c
dummy.ii -c -o dummy.o -w

it produces the following assembly:

$ objdump -dr dummy.o

dummy.o:     file format elf64-x86-64


Disassembly of section .text:

0000000000000000 <dev_write>:
   0:   53                      push   %rbx
   1:   48 83 ec 10             sub    $0x10,%rsp
   5:   48 89 f3                mov    %rsi,%rbx
   8:   e8 00 00 00 00          callq  d <dev_write+0xd>
                        9: R_X86_64_PC32        __sanitizer_cov_trace_pc-0x4
   d:   48 89 e7                mov    %rsp,%rdi
  10:   ba 01 00 00 00          mov    $0x1,%edx
  15:   48 89 de                mov    %rbx,%rsi
  18:   e8 00 00 00 00          callq  1d <dev_write+0x1d>
                        19: R_X86_64_PC32       _copy_from_user-0x4
  1d:   8b 1c 24                mov    (%rsp),%ebx
  20:   be 73 00 00 00          mov    $0x73,%esi
  25:   89 df                   mov    %ebx,%edi
  27:   e8 00 00 00 00          callq  2c <dev_write+0x2c>
                        28: R_X86_64_PC32       __sanitizer_cov_trace_cmp1-0x4
  2c:   31 c0                   xor    %eax,%eax
  2e:   80 fb 73                cmp    $0x73,%bl
  31:   0f 94 c0                sete   %al
  34:   48 83 c4 10             add    $0x10,%rsp
  38:   5b                      pop    %rbx
  39:   c3                      retq   


Note that the first parameter to __sanitizer_cov_trace_cmp1() is a 4-byte value
taken directly from the stack, despite __sanitizer_cov_trace_cmp1() expects a
1-byte value.

This looks like a violation of the x86_64 ABI, which mandates that byte-sized
arguments are extended (in this case zero-extended) to the full register.

If I change the s[] size to, say, 1, Clang generates correct code:


   d:   48 8d 7c 24 0f          lea    0xf(%rsp),%rdi
  12:   ba 01 00 00 00          mov    $0x1,%edx
  17:   48 89 de                mov    %rbx,%rsi
  1a:   e8 00 00 00 00          callq  1f <dev_write+0x1f>
                        1b: R_X86_64_PC32       _copy_from_user-0x4
  1f:   0f b6 5c 24 0f          movzbl 0xf(%rsp),%ebx
  24:   be 73 00 00 00          mov    $0x73,%esi
  29:   89 df                   mov    %ebx,%edi
  2b:   e8 00 00 00 00          callq  30 <dev_write+0x30>
                        2c: R_X86_64_PC32       __sanitizer_cov_trace_cmp1-0x4</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>