forked from M-Labs/artiq
1
0
Fork 0

runtime: do not use buggy llvm.eh.sjlj.* intrinsics

This commit is contained in:
Sebastien Bourdeauducq 2014-09-23 22:09:08 +08:00
parent 8b769a0417
commit af15f45bb9
7 changed files with 56 additions and 7 deletions

View File

@ -62,6 +62,10 @@ class LinkInterface:
self.llvm_module.add_function(func_type, "__syscall_"+func_name) self.llvm_module.add_function(func_type, "__syscall_"+func_name)
# exception handling # exception handling
func_type = lc.Type.function(lc.Type.int(), [lc.Type.pointer(lc.Type.int(8))])
function = self.llvm_module.add_function(func_type, "__eh_setjmp")
function.add_attribute(lc.ATTR_NO_UNWIND)
func_type = lc.Type.function(lc.Type.pointer(lc.Type.int(8)), []) func_type = lc.Type.function(lc.Type.pointer(lc.Type.int(8)), [])
self.llvm_module.add_function(func_type, "__eh_push") self.llvm_module.add_function(func_type, "__eh_push")
@ -90,11 +94,10 @@ class LinkInterface:
return r return r
def build_catch(self, builder): def build_catch(self, builder):
eh_setjmp = self.llvm_module.get_function_named("__eh_setjmp")
eh_push = self.llvm_module.get_function_named("__eh_push") eh_push = self.llvm_module.get_function_named("__eh_push")
setjmp = lc.Function.intrinsic(self.llvm_module,
lc.INTR_EH_SJLJ_SETJMP, [])
jmpbuf = builder.call(eh_push, []) jmpbuf = builder.call(eh_push, [])
exception_occured = builder.call(setjmp, [jmpbuf]) exception_occured = builder.call(eh_setjmp, [jmpbuf])
return builder.icmp(lc.ICMP_NE, return builder.icmp(lc.ICMP_NE,
exception_occured, exception_occured,
lc.Constant.int(lc.Type.int(), 0)) lc.Constant.int(lc.Type.int(), 0))

View File

@ -3,7 +3,7 @@ include $(MSCDIR)/software/common.mak
BOARD=papilio_pro BOARD=papilio_pro
SERIAL=/dev/ttyUSB1 SERIAL=/dev/ttyUSB1
OBJECTS=isr.o elf_loader.o exceptions.o services.o corecom_serial.o gpio.o rtio.o dds.o main.o OBJECTS=isr.o elf_loader.o exception_jmp.o exceptions.o services.o corecom_serial.o gpio.o rtio.o dds.o main.o
all: runtime.bin all: runtime.bin

View File

@ -0,0 +1,41 @@
.global exception_setjmp
.type exception_setjmp,@function
exception_setjmp:
l.sw 0(r3), r1
l.sw 4(r3), r2
l.sw 8(r3), r9
l.sw 12(r3), r10
l.sw 16(r3), r14
l.sw 20(r3), r16
l.sw 24(r3), r18
l.sw 28(r3), r20
l.sw 32(r3), r22
l.sw 36(r3), r24
l.sw 40(r3), r26
l.sw 44(r3), r28
l.sw 48(r3), r30
l.jr r9
l.ori r11,r0,0
.global exception_longjmp
.type exception_longjmp,@function
exception_longjmp:
l.sfeqi r4, 0
l.bnf 1f
l.addi r11, r4, 0
l.ori r11, r0, 1
1: l.lwz r1, 0(r3)
l.lwz r2, 4(r3)
l.lwz r9, 8(r3)
l.lwz r10, 12(r3)
l.lwz r14, 16(r3)
l.lwz r16, 20(r3)
l.lwz r18, 24(r3)
l.lwz r20, 28(r3)
l.lwz r22, 32(r3)
l.lwz r24, 36(r3)
l.lwz r26, 40(r3)
l.lwz r28, 44(r3)
l.lwz r30, 48(r3)
l.jr r9
l.nop

View File

@ -1,9 +1,10 @@
#include "exceptions.h" #include "exceptions.h"
#include "corecom.h"
#define MAX_EXCEPTION_CONTEXTS 64 #define MAX_EXCEPTION_CONTEXTS 64
struct exception_context { struct exception_context {
void *jb[5]; void *jb[13];
}; };
static struct exception_context exception_contexts[MAX_EXCEPTION_CONTEXTS]; static struct exception_context exception_contexts[MAX_EXCEPTION_CONTEXTS];
@ -29,5 +30,5 @@ int exception_getid(void)
void exception_raise(int id) void exception_raise(int id)
{ {
__builtin_longjmp(exception_contexts[--ec_top].jb, 1); exception_longjmp(exception_contexts[--ec_top].jb, 1);
} }

View File

@ -5,6 +5,9 @@ enum {
EID_NOMEM = 0 EID_NOMEM = 0
}; };
int exception_setjmp(void *jb) __attribute__((returns_twice));
void exception_longjmp(void *jb, int val) __attribute__((noreturn));
void *exception_push(void); void *exception_push(void);
void exception_pop(int levels); void exception_pop(int levels);
int exception_getid(void); int exception_getid(void);

View File

@ -77,7 +77,7 @@ static int run_kernel(const char *kernel_name, int *eid)
} }
jb = exception_push(); jb = exception_push();
if(__builtin_setjmp(jb)) { if(exception_setjmp(jb)) {
*eid = exception_getid(); *eid = exception_getid();
return KERNEL_RUN_EXCEPTION; return KERNEL_RUN_EXCEPTION;
} else { } else {

View File

@ -21,6 +21,7 @@ static const struct symbol syscalls[] = {
}; };
static const struct symbol eh[] = { static const struct symbol eh[] = {
{"setjmp", exception_setjmp},
{"push", exception_push}, {"push", exception_push},
{"pop", exception_pop}, {"pop", exception_pop},
{"getid", exception_getid}, {"getid", exception_getid},