<html>
<head>
<base href="https://bugs.freedesktop.org/">
</head>
<body>
<p>
<div>
<b><a class="bz_bug_link
bz_status_NEW "
title="NEW - Pulseaudio segfaults when ORC is used on x32"
href="https://bugs.freedesktop.org/show_bug.cgi?id=99066#c12">Comment # 12</a>
on <a class="bz_bug_link
bz_status_NEW "
title="NEW - Pulseaudio segfaults when ORC is used on x32"
href="https://bugs.freedesktop.org/show_bug.cgi?id=99066">bug 99066</a>
from <span class="vcard"><a class="email" href="mailto:tanuk@iki.fi" title="Tanu Kaskinen <tanuk@iki.fi>"> <span class="fn">Tanu Kaskinen</span></a>
</span></b>
<pre>I found out the reason for the get_cpuid() crash. The function looks like this
(slightly edited for readability):
static void get_cpuid(uint32_t op,
uint32_t *a, uint32_t *b, uint32_t *c, uint32_t *d) {
__asm__ __volatile__ (
" push %%rbx \n\t"
" cpuid \n\t"
" mov %%ebx, %%esi \n\t"
" pop %%rbx \n\t"
: "=a" (*a), "=S" (*b), "=c" (*c), "=d" (*d)
: "0" (op)
);
}
When building without optimizations, the function parameters are saved in the
stack. The stack pointer register isn't updated, however, so our push
instruction ends up overwriting the op and a parameters! Before that happens,
the op parameter is saved in the eax register, and the stack memory for op
won't be needed after that, so that's fine, but the a parameter is replaced
with whatever happened to be in the rbx register. When trying to save the cpuid
result in the memory pointed to by a, a segfault happens, because a is an
invalid pointer at that point.
If the stack pointer was updated when the compiler wrote the parameters in the
stack, this would have been avoided. So is this a compiler bug? I'm not sure. I
found out that the AMD64 ABI allows the compiler to not update the stack
pointer in functions that don't call other functions. However, if the stack
pointer is not updated, inline assembly that relies on the stack pointer will
not work as intended (as seen here), so maybe the compiler should always update
the stack pointer if it sees that the function contains inline assembly code
that has push/pop instructions?
This code happens to work on a "normal" 64-bit system by chance, because the
memory layout for the pointers is a bit different, and the push operation will
only overwrite the op parameter, which does no harm. When building with
optimizations, I guess the function parameters aren't saved in the stack, so
that will also avoid the crash.
I guess I'll have to prepare a bug report for GCC next (I'm not sure if it's a
compiler bug, but hopefully they'll tell me).</pre>
</div>
</p>
<hr>
<span>You are receiving this mail because:</span>
<ul>
<li>You are the QA Contact for the bug.</li>
<li>You are the assignee for the bug.</li>
</ul>
</body>
</html>