<html>
<head>
<base href="https://llvm.org/bugs/" />
</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 --- - naked functions with parameters are impossible to use correctly"
href="https://llvm.org/bugs/show_bug.cgi?id=24556">24556</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>naked functions with parameters are impossible to use correctly
</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>-New Bugs
</td>
</tr>
<tr>
<th>Assignee</th>
<td>unassignedclangbugs@nondot.org
</td>
</tr>
<tr>
<th>Reporter</th>
<td>froydnj@gmail.com
</td>
</tr>
<tr>
<th>CC</th>
<td>llvm-bugs@lists.llvm.org
</td>
</tr>
<tr>
<th>Classification</th>
<td>Unclassified
</td>
</tr></table>
<p>
<div>
<pre>The following testcase is a cut-down version of real code from Firefox:
struct siginfo_t;
// Shortened to act as an example.
struct sigaction {
void (*sa_sigaction)(int, siginfo_t*, void*);
};
extern void SetSignalHandler(int sig, struct sigaction*);
// Some (old) Linux kernels on ARM have a bug where a signal handler
// can be called without clearing the IT bits in CPSR first. The result
// is that the first few instructions of the handler could be skipped,
// ultimately resulting in crashes. To workaround this bug, the handler
// on ARM is a trampoline that starts with enough NOP instructions, so
// that even if the IT bits are not cleared, only the NOP instructions
// will be skipped over.
template <void (*H)(int, siginfo_t*, void*)>
__attribute__((naked)) void
SignalTrampoline(int aSignal, siginfo_t* aInfo, void* aContext)
{
asm volatile (
"nop; nop; nop; nop"
: : : "memory");
// Because the assembler may generate additional insturctions below, we
// need to ensure NOPs are inserted first by separating them out above.
asm volatile (
"bx %0"
:
: "r"(H)
#ifndef __clang__
, "l"(aSignal), "l"(aInfo), "l"(aContext)
#endif
: "memory");
}
extern void MySignalHandler(int, siginfo_t*, void*);
void
f()
{
struct sigaction sa;
sa.sa_sigaction = SignalTrampoline<MySignalHandler>;
SetSignalHandler(0, &sa);
}
The #ifndef __clang__ is needed because clang doesn't permit references to
local variables in naked functions. But then there's no way to communicate the
dependence that the asm statement has on the function's parameters. The
generated assembly (-O2 -fno-exceptions -fno-rtti) looks like:
.fnstart
@ BB#0:
ldr r0, .LCPI1_0
ldr r1, .LCPI1_1
@APP
mov r0, r0
mov r0, r0
mov r0, r0
mov r0, r0
@NO_APP
.LPC1_0:
add r0, pc, r0
ldr r0, [r1, r0]
@APP
bx r0
@NO_APP
.align 2
@ BB#1:
.LCPI1_0:
.long _GLOBAL_OFFSET_TABLE_-(.LPC1_0+8)
.LCPI1_1:
.long _Z15MySignalHandleriP9siginfo_tPv(GOT)
.Lfunc_end1:
Both small sequences of code prior to the @APP directives clobber the argument
registers, which is undesirable. (This sample also exhibits undesirable
behavior in that part of the load of the function address to jump to is moved
above the first asm statement. But one thing at a time.)
GCC, AFAICT, gets this correct. (I haven't checked GCC trunk, but the Android
NDK compilers and the arm-none-eabi cross compiler on my Linux distribution
generate code that does the right thing here.)</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>