<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] Unaligned stack pointer when calling always_inline function"
   href="https://bugs.llvm.org/show_bug.cgi?id=49828">49828</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>[x86] Unaligned stack pointer when calling always_inline function
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>clang
          </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>C
          </td>
        </tr>

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

        <tr>
          <th>Reporter</th>
          <td>vladislav.valtchev@gmail.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>blitzrakete@gmail.com, dgregor@apple.com, erik.pilkington@gmail.com, llvm-bugs@lists.llvm.org, richard-llvm@metafoo.co.uk
          </td>
        </tr></table>
      <p>
        <div>
        <pre>I noticed that the following code:

#include <inttypes.h>

static __attribute__((always_inline)) inline void
bar(uint8_t a) {
    /* do nothing */
}

void foo(void)
{
   bar(0);
}

Compiled with -m32 -O0 -ffreestanding produces the following instructions, with
any version of clang, from 3.x to 11.x:

foo:                                    
        push    ebp
        mov     ebp, esp
        sub     esp, 1                  # ESP gets unaligned here
        mov     byte ptr [ebp - 1], 0
        add     esp, 1
        pop     ebp
        ret

Notes:
  1. It doesn't happen with any other compiler.
  2. It happens only when __attribute__((always_inline)) is used
  3. It happens only when bar() takes an argument that is < sizeof(void *)
  4. It happens only with -m32
  5. It happens only with -O0

That's, of course, the simplest code making ESP misaligned. I have a real-world
example too, but I believe that such minimal code snippets is what you need
most.


I believe that setting ESP to a misaligned value is pretty dangerous, even if
the function does not perform any function calls, because an interrupt might
occur and it will get the whole stack misaligned. That might lead to UB.
Actually, I discovered this thanks to the UBSAN: the interrupt handler hit the
"unaligned access" UB while reading a value on the stack.

Note: I'm using -ffreestanding just to tell the compiler that interrupts might
occur, but it doesn't make any difference. I suppose, having ESP temporarily
misaligned is a problem in userspace too, because of signals.</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>