[llvm-bugs] [Bug 24556] New: naked functions with parameters are impossible to use correctly
via llvm-bugs
llvm-bugs at lists.llvm.org
Mon Aug 24 10:26:13 PDT 2015
https://llvm.org/bugs/show_bug.cgi?id=24556
Bug ID: 24556
Summary: naked functions with parameters are impossible to use
correctly
Product: clang
Version: unspecified
Hardware: PC
OS: Linux
Status: NEW
Severity: normal
Priority: P
Component: -New Bugs
Assignee: unassignedclangbugs at nondot.org
Reporter: froydnj at gmail.com
CC: llvm-bugs at lists.llvm.org
Classification: Unclassified
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.)
--
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20150824/2cbdb107/attachment.html>
More information about the llvm-bugs
mailing list