mirror of
https://github.com/corda/corda.git
synced 2025-01-23 04:48:09 +00:00
fix ARM stack unwinding
This commit is contained in:
parent
17449eaf1b
commit
fb5c0bfebd
40
src/arm.cpp
40
src/arm.cpp
@ -872,19 +872,13 @@ addC(Context* c, unsigned size, Assembler::Constant* a,
|
|||||||
|
|
||||||
int32_t v = a->value->value();
|
int32_t v = a->value->value();
|
||||||
if (v) {
|
if (v) {
|
||||||
if (v > 0 and v < 1024 and v % 4 == 0) {
|
if (v > 0 and v < 256) {
|
||||||
|
emit(c, addi(dst->low, b->low, v));
|
||||||
|
} else if (v > 0 and v < 1024 and v % 4 == 0) {
|
||||||
emit(c, addi(dst->low, b->low, v >> 2, 15));
|
emit(c, addi(dst->low, b->low, v >> 2, 15));
|
||||||
} else {
|
} else {
|
||||||
emit(c, addi(dst->low, b->low, lo8(v)));
|
// todo
|
||||||
if (not isOfWidth(v, 8)) {
|
abort(c);
|
||||||
emit(c, addi(dst->low, b->low, hi8(v), 12));
|
|
||||||
if (not isOfWidth(v, 16)) {
|
|
||||||
emit(c, addi(dst->low, b->low, lo8(hi16(v)), 8));
|
|
||||||
if (not isOfWidth(v, 24)) {
|
|
||||||
emit(c, addi(dst->low, b->low, hi8(hi16(v)), 4));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
moveRR(c, size, b, size, dst);
|
moveRR(c, size, b, size, dst);
|
||||||
@ -898,14 +892,17 @@ subC(Context* c, unsigned size, Assembler::Constant* a,
|
|||||||
assert(c, size == BytesPerWord);
|
assert(c, size == BytesPerWord);
|
||||||
|
|
||||||
int32_t v = a->value->value();
|
int32_t v = a->value->value();
|
||||||
|
if (v) {
|
||||||
if (v > 0 and v < 256) {
|
if (v > 0 and v < 256) {
|
||||||
emit(c, subi(dst->low, b->low, v));
|
emit(c, subi(dst->low, b->low, v));
|
||||||
} else if (v > 0 and v < 1024 and v % 4 == 0) {
|
} else if (v > 0 and v < 1024 and v % 4 == 0) {
|
||||||
emit(c, subi(dst->low, b->low, v >> 2, 15));
|
emit(c, subi(dst->low, b->low, v >> 2, 15));
|
||||||
} else {
|
} else {
|
||||||
ResolvedPromise promise(- v);
|
// todo
|
||||||
Assembler::Constant constant(&promise);
|
abort(c);
|
||||||
addC(c, size, &constant, b, dst);
|
}
|
||||||
|
} else {
|
||||||
|
moveRR(c, size, b, size, dst);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1613,9 +1610,15 @@ memoryBarrier(Context*) {}
|
|||||||
|
|
||||||
// END OPERATION COMPILERS
|
// END OPERATION COMPILERS
|
||||||
|
|
||||||
|
unsigned
|
||||||
|
argumentFootprint(unsigned footprint)
|
||||||
|
{
|
||||||
|
return max(pad(footprint, StackAlignmentInWords), StackAlignmentInWords);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nextFrame(ArchitectureContext* c UNUSED, uint32_t* start, unsigned size UNUSED,
|
nextFrame(ArchitectureContext* c UNUSED, uint32_t* start, unsigned size UNUSED,
|
||||||
unsigned footprint, int32_t*, void* link, void* stackLimit,
|
unsigned footprint, int32_t*, void* link, void*,
|
||||||
unsigned targetParameterFootprint UNUSED, void** ip, void** stack)
|
unsigned targetParameterFootprint UNUSED, void** ip, void** stack)
|
||||||
{
|
{
|
||||||
assert(c, *ip >= start);
|
assert(c, *ip >= start);
|
||||||
@ -1633,8 +1636,7 @@ nextFrame(ArchitectureContext* c UNUSED, uint32_t* start, unsigned size UNUSED,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned offset = footprint + FrameHeaderSize
|
unsigned offset = footprint + FrameHeaderSize;
|
||||||
- (stackLimit == *stack ? 1 : 0);
|
|
||||||
|
|
||||||
if (instruction <= start + 2) {
|
if (instruction <= start + 2) {
|
||||||
*ip = link;
|
*ip = link;
|
||||||
@ -1658,7 +1660,7 @@ nextFrame(ArchitectureContext* c UNUSED, uint32_t* start, unsigned size UNUSED,
|
|||||||
// todo: use frameTable to check for and handle tail calls
|
// todo: use frameTable to check for and handle tail calls
|
||||||
}
|
}
|
||||||
|
|
||||||
*ip = reinterpret_cast<void**>(*stack)[offset];
|
*ip = reinterpret_cast<void**>(*stack)[offset - 1];
|
||||||
*stack = reinterpret_cast<void**>(*stack) + offset;
|
*stack = reinterpret_cast<void**>(*stack) + offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1810,7 +1812,7 @@ class MyArchitecture: public Assembler::Architecture {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual unsigned argumentFootprint(unsigned footprint) {
|
virtual unsigned argumentFootprint(unsigned footprint) {
|
||||||
return max(pad(footprint, StackAlignmentInWords), StackAlignmentInWords);
|
return ::argumentFootprint(footprint);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool argumentAlignment() {
|
virtual bool argumentAlignment() {
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define THREAD_STACK 2148
|
#define THREAD_STACK 2148
|
||||||
|
#define THREAD_SCRATCH 2152
|
||||||
#define THREAD_CONTINUATION 2156
|
#define THREAD_CONTINUATION 2156
|
||||||
#define THREAD_EXCEPTION 44
|
#define THREAD_EXCEPTION 44
|
||||||
#define THREAD_EXCEPTION_STACK_ADJUSTMENT 2160
|
#define THREAD_EXCEPTION_STACK_ADJUSTMENT 2160
|
||||||
@ -50,18 +51,14 @@ GLOBAL(vmInvoke):
|
|||||||
[sp, #4] : returnType
|
[sp, #4] : returnType
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// save stack frame
|
|
||||||
mov ip, sp
|
|
||||||
|
|
||||||
// save all non-volatile registers
|
// save all non-volatile registers
|
||||||
stmfd sp!, {r4-r11, lr}
|
stmfd sp!, {r4-r11, lr}
|
||||||
|
|
||||||
// save return type
|
// save return type
|
||||||
ldr r4, [ip, #4]
|
ldr r4, [sp, #4]
|
||||||
str r4, [sp, #-4]!
|
str r4, [sp, #-4]!
|
||||||
|
|
||||||
// we're at the bottom of our local stack frame; save it
|
str sp, [r0, #THREAD_SCRATCH]
|
||||||
mov ip, sp
|
|
||||||
|
|
||||||
// align stack, if necessary
|
// align stack, if necessary
|
||||||
eor r4, sp, r3
|
eor r4, sp, r3
|
||||||
@ -82,9 +79,6 @@ LOCAL(vmInvoke_argumentTest):
|
|||||||
cmp r4, r3
|
cmp r4, r3
|
||||||
blt LOCAL(vmInvoke_argumentLoop)
|
blt LOCAL(vmInvoke_argumentLoop)
|
||||||
|
|
||||||
// save frame
|
|
||||||
str ip, [sp, #-8]!
|
|
||||||
|
|
||||||
// we use r8 to hold the thread pointer, by convention
|
// we use r8 to hold the thread pointer, by convention
|
||||||
mov r8, r0
|
mov r8, r0
|
||||||
|
|
||||||
@ -93,17 +87,16 @@ LOCAL(vmInvoke_argumentTest):
|
|||||||
|
|
||||||
.globl GLOBAL(vmInvoke_returnAddress)
|
.globl GLOBAL(vmInvoke_returnAddress)
|
||||||
GLOBAL(vmInvoke_returnAddress):
|
GLOBAL(vmInvoke_returnAddress):
|
||||||
|
// restore stack pointer
|
||||||
// restore frame
|
ldr sp, [r8, #THREAD_SCRATCH]
|
||||||
ldr sp, [sp]
|
|
||||||
|
|
||||||
// clear MyThread::stack to avoid confusing another thread calling
|
// clear MyThread::stack to avoid confusing another thread calling
|
||||||
// java.lang.Thread.getStackTrace on this one. See
|
// java.lang.Thread.getStackTrace on this one. See
|
||||||
// MyProcess::getStackTrace in compile.cpp for details on how we get
|
// MyProcess::getStackTrace in compile.cpp for details on how we get
|
||||||
// a reliable stack trace from a thread that might be interrupted at
|
// a reliable stack trace from a thread that might be interrupted at
|
||||||
// any point in its execution.
|
// any point in its execution.
|
||||||
mov r5,#0
|
mov r5, #0
|
||||||
str r5,[r8,#THREAD_STACK]
|
str r5, [r8, #THREAD_STACK]
|
||||||
|
|
||||||
.globl GLOBAL(vmInvoke_safeStack)
|
.globl GLOBAL(vmInvoke_safeStack)
|
||||||
GLOBAL(vmInvoke_safeStack):
|
GLOBAL(vmInvoke_safeStack):
|
||||||
|
Loading…
Reference in New Issue
Block a user