<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/54873>54873</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            -fsanitize-coverage produces incorrect debug info at function entry points
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          khuey
      </td>
    </tr>
</table>

<pre>
    Consider the following function:

```c
int square(int i) {
    return i * i;
}
```

Compiling with

```
Debian clang version 15.0.0-++20220411071831+e995526e661f-1~exp1~20220411071915.217
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/local/bin
```

The assembly looks like:

```asm
0000000000001130 <square>:
    1130:       55                      push   %rbp
    1131:       48 89 e5                mov    %rsp,%rbp
    1134:       89 7d fc                mov    %edi,-0x4(%rbp)
    1137:       8b 45 fc                mov    -0x4(%rbp),%eax
    113a:       0f af 45 fc             imul   -0x4(%rbp),%eax
    113e:       5d                      pop    %rbp
    113f:       c3                      retq   
```

The DWARF output from `dwarfdump -i` is:
```
<snip>
< 1><0x00000023>    DW_TAG_subprogram
                      DW_AT_low_pc                (indirect address, index 0x0): 0x00001130
                      DW_AT_high_pc               <offset-from-lowpc>16
                      DW_AT_frame_base            len 0x0001: 56: DW_OP_reg6
                      DW_AT_name                  (indirect string, index 0x3): square
                      DW_AT_decl_file             0x00000000
                      DW_AT_decl_line             0x00000001
                      DW_AT_prototyped            yes
                      DW_AT_type                  0x00000064<.debug_info+0x00000064>
                      DW_AT_external              yes
< 2><0x00000032>      DW_TAG_formal_parameter
                        DW_AT_location              len 0x0002: 917c: DW_OP_fbreg -4
                        DW_AT_name                  (indirect string, index 0x6): i
                        DW_AT_decl_file             0x00000000
                        DW_AT_decl_line             0x00000001
                        DW_AT_type                  0x00000064<.debug_info+0x00000064>

<snip>
```

And from `dwarfdump -l`
```
.debug_line: line number info for a single cu
Source lines (from CU-DIE at .debug_info offset 0x0000000c):

            NS new statement, BB new basic block, ET end of text sequence
            PE prologue end, EB epilogue begin
            IS=val ISA number, DI=val discriminator value
<pc>        [lno,col] NS BB ET PE EB IS= DI= uri: "filepath"
0x00001130  [   1, 0] NS uri: "/build/coverage-test.c"
0x00001137  [   2,10] NS PE
<snip>
```

Note that the debug_info declares the parameter is on the stack at -0x4(%rbp), not in the register specified in the ABI (this is normal for debug builds). The debug_line section specifies the prologue end is at 0x1137 (the PE marker) so that's where a debugger will place a breakpoint at function entry. Because that's after the value of %edi at function entry has been moved into the stack slot, everything will work as expected.

Now add `-fsanitize-coverage=trace-pc-guard` to the compiler arguments:

The assembly looks like:

```asm
000000000002d8c0 <square>:
   2d8c0:       55                      push   %rbp
   2d8c1:       48 89 e5                mov    %rsp,%rbp
   2d8c4:       48 83 ec 10             sub    $0x10,%rsp
   2d8c8:       89 7d f8                mov    %edi,-0x8(%rbp)
   2d8cb:       48 8d 3d be 72 01 00    lea    0x172be(%rip),%rdi        # 44b90 <__TMC_END__>
   2d8d2:       e8 19 02 ff ff          callq  1daf0 <__sanitizer_cov_trace_pc_guard>
   2d8d7:       8b 7d f8                mov    -0x8(%rbp),%edi
   2d8da:       89 7d fc                mov    %edi,-0x4(%rbp)
   2d8dd:       8b 45 fc                mov    -0x4(%rbp),%eax
   2d8e0:       0f af 45 fc             imul   -0x4(%rbp),%eax
   2d8e4:       48 83 c4 10             add    $0x10,%rsp
   2d8e8:       5d                      pop    %rbp
   2d8e9:       c3                      retq   
   2d8ea:       66 0f 1f 44 00 00       nopw   0x0(%rax,%rax,1)

```

Note that the compiler has inserted a call to __sanitizer_cov_trace_pc_guard, and a second stack slot for the original value of %edi at -0x8(%rbp).

The DWARF output from `dwarfdump -i` is:
```
<snip>
< 1><0x0000002b>    DW_TAG_subprogram
                      DW_AT_low_pc                (indirect address, index 0x0): 0x0002d8c0
                      DW_AT_high_pc               <offset-from-lowpc>42
                      DW_AT_frame_base            len 0x0001: 56: DW_OP_reg6
                      DW_AT_name                  (indirect string, index 0x3): square
                      DW_AT_decl_file             0x00000000
                      DW_AT_decl_line             0x00000001
                      DW_AT_prototyped            yes
                      DW_AT_type                  0x0000006c<.debug_info+0x0000006c>
                      DW_AT_external              yes
< 2><0x0000003a>      DW_TAG_formal_parameter
                        DW_AT_location              len 0x0002: 917c: DW_OP_fbreg -4
                        DW_AT_name                  (indirect string, index 0x6): i
                        DW_AT_decl_file             0x00000000
                        DW_AT_decl_line             0x00000001
                        DW_AT_type                  0x0000006c<.debug_info+0x0000006c>
<snip>
```
i.e. essentially unchanged, note that the DWARF still claims the variable lives at -0x4(%rbp).

The output from `dwarfdump -l`, however, is:
```
.debug_line: line number info for a single cu
Source lines (from CU-DIE at .debug_info offset 0x0000000c):

            NS new statement, BB new basic block, ET end of text sequence
            PE prologue end, EB epilogue begin
            IS=val ISA number, DI=val discriminator value
<pc>        [lno,col] NS BB ET PE EB IS= DI= uri: "filepath"
0x0002d8c0  [   1, 0] NS uri: "/build/coverage-test.c"
0x0002d8cb  [   1, 0] NS PE
0x0002d8dd  [   2,10] NS
<snip>
```

The prologue end marker is now placed at 0x2d8cb, which is after the value of %rdi has been moved to the newly added stack slot -0x8(%rbp). But the DWARF still claims that value of `i` is in -0x4(%rbp), which is not initialized until 0x2d8dd. So a debugger will break at 0x2d8cb, read the value of `i` from -0x4(%rbp), and get a garbage value because that slot is not yet initialized.

This affects displaying the values of variables on function entry, including setting conditional breakpoints on them

(This issue was originally reported to me by @hsivonen in a Rust binary produced by cargo-fuzz.)
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJztWV1z4jgW_TXkRQXlL74eeAiQbOVhe7sm2ZpHSrZl0MZYbskOoX_9nivbYPORpHuyMztVTVEhWNLR1b1HV_eIUMX72UJlRsZCs2IjWKLSVO1ktmZJmUWFVFnPv-05y57T_B051TuqvsusYOZbybXoeRP6InvelPXG86qZ4aVFUeqMSdbzbtHs10298fIEsj3PQm1zmZIhO1lsLlpQfV2KUPKMRSlH3xehDWxm7nDgDJx-z5vj7Tme5wSu64zdie_igZhOh0NvJEYjN-m7vfGdeM3po9VxCgTPHVdTPHG9FgUcwV4no9Uo6OdRH6aVr_11VtZdNlrwmG1VLFLqmCsjX6umh8wUPE1FvJSamnrefWk0_qYq4ik-Q5m94YgnRIUbI7ZhumepUs-GpfJZXAsLN9vqidN6ua7vsJ6_qAPl3x1GU3yolQyrXsMhu_jKS7PBR88b6jDvDHaPg4MJm0yZOIPYqhdWDzZ5z1tcQAmOKIAYxyyJrqOIGDRb9J3XAKyrwbxpB2_cwgtZMLyOdwZj7RP8tYPHj3hOwnhyAVJuy_TDeKLl8viKy1XeeO3EWclxcORfHoxd940Gv82s5e-3v90zVRZ5WbBEqy1Dp3jHdRKX25z1Jb4yaY5sOwECpzKZE6Oa78y1_Fo4rxX3PB_fyaDl76un23-sTBnmWq013x5XdP5C59unFVLRKj8Lm000sdQiKhiPYy2MgYsZnolXhmnJ5XBPZYAl97sTbeR6cz4TVqGSxIiiT57pw5o8wmLc0fuACdYnViE3ot2Wiqwyy26Z4Yj-ov-_vq60WH8ANQPoeVvbH6bQyJltd_i1O-q9_-4csYjSVSLT7kRNNJ0PONMiID9eQXDfRwBBClXsc9HZGHth3h9Ko87bmslHyDKLQSzCcr2SWaJwGLSb7t7HF6-F0BlPu20H02gDeN0N4Hv1BjhsgUTpLU9XOSeSAO6tWY9bIeJ0HHfbDoTyKMRTdxwdKZWEIBXrBx9B_xlijWpiyY9M8EdY9Rm8-kx6XEl9l1LsbRZfyqrpsVt3VD03LZJcaxebldsQ1RnZg_JMM84MIgFPRnXt8ahKHQnb2VDM7ISLf_eXD3eMF6y1Hlals6PPoiqGbZPbfvnyyDKxQ-x5IbYiKyj887l9htQmIxaCls_09O6JCaxVJazADmFGfCtFFl1IN1_vGHZ3qtaloBF27JwJ1Hr2USjWTTXUHvXw2POXL9h1D4-3tUNo5PKhfhxLE2m5lRkv4CE8KcUhSjZnN0C94TzNENdFpNLecEkrxIJgPeyCHXaeCpaVWlblmke8zTmqUM-ra6vD0WIRgeuSOU6NeBxJ1V0pUyzzPlIoTvla9AthikF0jjVusDBq4TZYX-9-gG5fVCFQxiPoVMu34k5bB9nf2OeHvIODnSGj0DOEOHomtlwoXlimUNZX_ZBSpKGhJheRTCQydN1yO38g8hUbgOKd2RxnCWvtYNYPOKinA_Z0MM4S3AgrNA6QtZUtlhAgJ9paN9lZBEVsy_UzMWHKjLLr7nljw3YboVEzV1OsYetOpinLUx7RU2RF_pwrkiqAbFQOZin0fsDmIuKlEUcwnhS1NLKsIoZX9ef5aLbhBgRGSkZhaR1TqJZzTarsBhLgwR5ustIGhu2UhucNgwiBI0Q86EZ0RzUO5Y9-YngmC_ld9BsugaaFxrJIkKxxvMdUrdWTRlZAwXaIl5I2rznZ6J8gLLx4El0XFrb1Z4UFDf7jwoJQgi6Kz0TEXKeDgpq0QglAMaeGMV2YyZk-mVw35qBPJhf1CeGFXbNi5scgDxt7zHGZY-1LBacP2DT2QlEjyaOk0GBhk9c8nwVBOLXRWK2e_rlY3X1Zrlbtmgazxt5xVjFh7pQ5HksSeh9eEKUplIMb86RGa3inVyDeyjIOxfKqYtzJBF3Z9ZabzrxTyaRYdvD4J8pCwos_URYCTzifKAsJ74ytUXDKVsoH7G22isnPqksaPP1BdVkPa4VqNCJvuPBGQFx2mgVkKt8xVok06wmsvrLf_uMeovXhQ-6Q5ij5yswIjRSKNE8splT4DnuRj3lG_XEIKfxzTNX26KIZlJaoSXCWXTgATjk8OE2wf4K-Dv9KfV3l-M_V14H3S1-_i_B_qq-j6wIq-l_pa_5LX_9d9PWH6PGO1JEDMWDISShpJZL8nqEI3_BsLeJaq7ROhyr9moLqbCgguTV1Ka8lD1PSzC_CXJI9Z4n8egq3Yh4zb9SOSnsbwqsJ_ZfA__sI_ErdfI7AtxX_RaxG4DfdqLg7vwf4gUuAp1PxXKnkSpTvKh0cV3K60iEwZreR0caq7Ityl4TGibitVSaYgh2IKkF0aqezuojNyzd2JIw5Tjdy6qKIbhYuXUccjK3uJSSlAdR3MRIBYKtlxfGAPaqzSwAr_k_Wbn-46664NsHus0sWUMm4xjbjbM11iJjXY8PW7UHliNrKvehYepJdrN8TnAKGeI4A7ely4GCSIZualGVvbLr3DtWhEaVlTMOw_Qv6pHJWUieetu48mgufbafM9iZP1bWNwSJ2CHRT8yK2WuTK1tSIOA6xcM96gbMx8kVlIANCxNlvpSlYiP56T8yLSyIYOkZcr1U_Kb9_H8BxN_HMj6f-lN8UskjF7MJ9RjOaQh8pbQ_G6vbIJrfzG5dqTTelTmebosht2vXu8V7LYlOGA6gD-qE1fWk--pjhP4DFV7taVLb3w2Ay9m82Mz7FAT8c8cQLEt-NIiF8340hvf0g5kMe3KQ8FKmZYXdic1OOtBC00YfLGzmrfz723Ik7dIaDyWg4DJwJ504SxqFw4Tax5TIdkB0Dpdc3emZNwvoMGlNpCnNs5MbIdSaEnQ74vCw2Ss-eN6XY39iJZ9bw_wJK1o0i">