summaryrefslogtreecommitdiffstats
path: root/runtime/loc2c-runtime.h
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/loc2c-runtime.h')
-rw-r--r--runtime/loc2c-runtime.h230
1 files changed, 136 insertions, 94 deletions
diff --git a/runtime/loc2c-runtime.h b/runtime/loc2c-runtime.h
index 1247da51..0af19edc 100644
--- a/runtime/loc2c-runtime.h
+++ b/runtime/loc2c-runtime.h
@@ -201,6 +201,8 @@
#define deref(size, addr) ({ \
intptr_t _i; \
+ if (lookup_bad_addr((unsigned long)addr)) \
+ __deref_bad(); \
switch (size) { \
case 1: _i = kread((u8 *)(addr)); break; \
case 2: _i = kread((u16 *)(addr)); break; \
@@ -213,6 +215,8 @@
})
#define store_deref(size, addr, value) ({ \
+ if (lookup_bad_addr((unsigned long)addr)) \
+ __store_deref_bad(); \
switch (size) { \
case 1: kwrite((u8 *)(addr), (value)); break; \
case 2: kwrite((u16 *)(addr), (value)); break; \
@@ -234,30 +238,36 @@ extern void __store_deref_bad(void);
int _bad = 0; \
u8 _b; u16 _w; u32 _l; \
intptr_t _v; \
- switch (size) \
- { \
- case 1: __get_user_asm(_b,addr,_bad,"b","b","=q",1); _v = _b; break; \
- case 2: __get_user_asm(_w,addr,_bad,"w","w","=r",1); _v = _w; break; \
- case 4: __get_user_asm(_l,addr,_bad,"l","","=r",1); _v = _l; break; \
- default: _v = __get_user_bad(); \
- } \
- if (_bad) \
- DEREF_FAULT(addr); \
+ if (lookup_bad_addr((unsigned long)addr)) \
+ _bad = 1; \
+ else \
+ switch (size) \
+ { \
+ case 1: __get_user_asm(_b,addr,_bad,"b","b","=q",1); _v = _b; break; \
+ case 2: __get_user_asm(_w,addr,_bad,"w","w","=r",1); _v = _w; break; \
+ case 4: __get_user_asm(_l,addr,_bad,"l","","=r",1); _v = _l; break; \
+ default: _v = __get_user_bad(); \
+ } \
+ if (_bad) \
+ DEREF_FAULT(addr); \
_v; \
})
#define store_deref(size, addr, value) \
({ \
int _bad = 0; \
- switch (size) \
- { \
- case 1: __put_user_asm(((u8)(value)),addr,_bad,"b","b","iq",1); break; \
- case 2: __put_user_asm(((u16)(value)),addr,_bad,"w","w","ir",1); break; \
- case 4: __put_user_asm(((u32)(value)),addr,_bad,"l","k","ir",1); break; \
- default: __put_user_bad(); \
- } \
- if (_bad) \
- STORE_DEREF_FAULT(addr); \
+ if (lookup_bad_addr((unsigned long)addr)) \
+ _bad = 1; \
+ else \
+ switch (size) \
+ { \
+ case 1: __put_user_asm(((u8)(value)),addr,_bad,"b","b","iq",1); break;\
+ case 2: __put_user_asm(((u16)(value)),addr,_bad,"w","w","ir",1); break;\
+ case 4: __put_user_asm(((u32)(value)),addr,_bad,"l","k","ir",1); break;\
+ default: __put_user_bad(); \
+ } \
+ if (_bad) \
+ STORE_DEREF_FAULT(addr); \
})
@@ -268,14 +278,17 @@ extern void __store_deref_bad(void);
int _bad = 0; \
u8 _b; u16 _w; u32 _l; u64 _q; \
intptr_t _v; \
- switch (size) \
- { \
- case 1: __get_user_asm(_b,addr,_bad,"b","b","=q",1); _v = _b; break; \
- case 2: __get_user_asm(_w,addr,_bad,"w","w","=r",1); _v = _w; break; \
- case 4: __get_user_asm(_l,addr,_bad,"l","","=r",1); _v = _l; break; \
- case 8: __get_user_asm(_q,addr,_bad,"q","","=r",1); _v = _q; break; \
- default: _v = __get_user_bad(); \
- } \
+ if (lookup_bad_addr((unsigned long)addr)) \
+ _bad = 1; \
+ else \
+ switch (size) \
+ { \
+ case 1: __get_user_asm(_b,addr,_bad,"b","b","=q",1); _v = _b; break; \
+ case 2: __get_user_asm(_w,addr,_bad,"w","w","=r",1); _v = _w; break; \
+ case 4: __get_user_asm(_l,addr,_bad,"l","","=r",1); _v = _l; break; \
+ case 8: __get_user_asm(_q,addr,_bad,"q","","=r",1); _v = _q; break; \
+ default: _v = __get_user_bad(); \
+ } \
if (_bad) \
DEREF_FAULT(addr); \
_v; \
@@ -284,14 +297,17 @@ extern void __store_deref_bad(void);
#define store_deref(size, addr, value) \
({ \
int _bad = 0; \
- switch (size) \
- { \
- case 1: __put_user_asm(((u8)(value)),addr,_bad,"b","b","iq",1); break; \
- case 2: __put_user_asm(((u16)(value)),addr,_bad,"w","w","ir",1); break; \
- case 4: __put_user_asm(((u32)(value)),addr,_bad,"l","k","ir",1); break; \
- case 8: __put_user_asm(((u64)(value)),addr,_bad,"q","","Zr",1); break; \
- default: __put_user_bad(); \
- } \
+ if (lookup_bad_addr((unsigned long)addr)) \
+ _bad = 1; \
+ else \
+ switch (size) \
+ { \
+ case 1: __put_user_asm(((u8)(value)),addr,_bad,"b","b","iq",1); break; \
+ case 2: __put_user_asm(((u16)(value)),addr,_bad,"w","w","ir",1); break;\
+ case 4: __put_user_asm(((u32)(value)),addr,_bad,"l","k","ir",1); break;\
+ case 8: __put_user_asm(((u64)(value)),addr,_bad,"q","","Zr",1); break; \
+ default: __put_user_bad(); \
+ } \
if (_bad) \
STORE_DEREF_FAULT(addr); \
})
@@ -301,13 +317,16 @@ extern void __store_deref_bad(void);
({ \
int _bad = 0; \
intptr_t _v=0; \
- switch (size){ \
- case 1: __get_user_size(_v, addr, 1, _bad); break; \
- case 2: __get_user_size(_v, addr, 2, _bad); break; \
- case 4: __get_user_size(_v, addr, 4, _bad); break; \
- case 8: __get_user_size(_v, addr, 8, _bad); break; \
- default: __get_user_unknown(); break; \
- } \
+ if (lookup_bad_addr((unsigned long)addr)) \
+ _bad = 1; \
+ else \
+ switch (size){ \
+ case 1: __get_user_size(_v, addr, 1, _bad); break; \
+ case 2: __get_user_size(_v, addr, 2, _bad); break; \
+ case 4: __get_user_size(_v, addr, 4, _bad); break; \
+ case 8: __get_user_size(_v, addr, 8, _bad); break; \
+ default: __get_user_unknown(); break; \
+ } \
if (_bad) \
DEREF_FAULT(addr); \
_v; \
@@ -316,13 +335,16 @@ extern void __store_deref_bad(void);
#define store_deref(size, addr, value) \
({ \
int _bad=0; \
- switch (size){ \
- case 1: __put_user_size(value, addr, 1, _bad); break; \
- case 2: __put_user_size(value, addr, 2, _bad); break; \
- case 4: __put_user_size(value, addr, 4, _bad); break; \
- case 8: __put_user_size(value, addr, 8, _bad); break; \
- default: __put_user_unknown(); break; \
- } \
+ if (lookup_bad_addr((unsigned long)addr)) \
+ _bad = 1; \
+ else \
+ switch (size){ \
+ case 1: __put_user_size(value, addr, 1, _bad); break; \
+ case 2: __put_user_size(value, addr, 2, _bad); break; \
+ case 4: __put_user_size(value, addr, 4, _bad); break; \
+ case 8: __put_user_size(value, addr, 8, _bad); break; \
+ default: __put_user_unknown(); break; \
+ } \
if (_bad) \
STORE_DEREF_FAULT(addr); \
})
@@ -373,30 +395,36 @@ extern void __store_deref_bad(void);
({ \
int _bad = 0; \
intptr_t _v; \
- switch (size) \
- { \
- case 1: __stp_get_user_asm(_v,addr,_bad,"lbz"); break; \
- case 2: __stp_get_user_asm(_v,addr,_bad,"lhz"); break; \
- case 4: __stp_get_user_asm(_v,addr,_bad,"lwz"); break; \
- case 8: __stp_get_user_asm(_v,addr,_bad,"ld"); break; \
- default: _v = __get_user_bad(); \
- } \
+ if (lookup_bad_addr((unsigned long)addr)) \
+ _bad = 1; \
+ else \
+ switch (size) \
+ { \
+ case 1: __stp_get_user_asm(_v,addr,_bad,"lbz"); break; \
+ case 2: __stp_get_user_asm(_v,addr,_bad,"lhz"); break; \
+ case 4: __stp_get_user_asm(_v,addr,_bad,"lwz"); break; \
+ case 8: __stp_get_user_asm(_v,addr,_bad,"ld"); break; \
+ default: _v = __get_user_bad(); \
+ } \
if (_bad) \
- DEREF_FAULT(addr); \
+ DEREF_FAULT(addr); \
_v; \
})
#define store_deref(size, addr, value) \
({ \
int _bad = 0; \
- switch (size) \
- { \
- case 1: __stp_put_user_asm(((u8)(value)),addr,_bad,"stb"); break; \
- case 2: __stp_put_user_asm(((u16)(value)),addr,_bad,"sth"); break; \
- case 4: __stp_put_user_asm(((u32)(value)),addr,_bad,"stw"); break; \
- case 8: __stp_put_user_asm(((u64)(value)),addr,_bad, "std"); break; \
- default: __put_user_bad(); \
- } \
+ if (lookup_bad_addr((unsigned long)addr)) \
+ _bad = 1; \
+ else \
+ switch (size) \
+ { \
+ case 1: __stp_put_user_asm(((u8)(value)),addr,_bad,"stb"); break; \
+ case 2: __stp_put_user_asm(((u16)(value)),addr,_bad,"sth"); break; \
+ case 4: __stp_put_user_asm(((u32)(value)),addr,_bad,"stw"); break; \
+ case 8: __stp_put_user_asm(((u64)(value)),addr,_bad, "std"); break; \
+ default: __put_user_bad(); \
+ } \
if (_bad) \
STORE_DEREF_FAULT(addr); \
})
@@ -541,12 +569,15 @@ extern void __store_deref_bad(void);
({ \
int _bad = 0; \
intptr_t _v=0; \
- switch (size){ \
- case 1: __stp_get_user_asm_byte(_v, addr, _bad); break; \
- case 2: __stp_get_user_asm_half(_v, addr, _bad); break; \
- case 4: __stp_get_user_asm_word(_v, addr, _bad); break; \
- default: __get_user_bad(); break; \
- } \
+ if (lookup_bad_addr((unsigned long)addr)) \
+ _bad = 1; \
+ else \
+ switch (size){ \
+ case 1: __stp_get_user_asm_byte(_v, addr, _bad); break; \
+ case 2: __stp_get_user_asm_half(_v, addr, _bad); break; \
+ case 4: __stp_get_user_asm_word(_v, addr, _bad); break; \
+ default: __get_user_bad(); break; \
+ } \
if (_bad) \
DEREF_FAULT(addr); \
_v; \
@@ -555,13 +586,16 @@ extern void __store_deref_bad(void);
#define store_deref(size, addr, value) \
({ \
int _bad=0; \
- switch (size){ \
- case 1: __stp_put_user_asm_byte(value, addr, _bad); break; \
- case 2: __stp_put_user_asm_half(value, addr, _bad); break; \
- case 4: __stp_put_user_asm_word(value, addr, _bad); break; \
- case 8: __stp_put_user_asm_dword(value, addr, _bad); break; \
- default: __put_user_bad(); break; \
- } \
+ if (lookup_bad_addr((unsigned long)addr)) \
+ _bad = 1; \
+ else \
+ switch (size){ \
+ case 1: __stp_put_user_asm_byte(value, addr, _bad); break; \
+ case 2: __stp_put_user_asm_half(value, addr, _bad); break; \
+ case 4: __stp_put_user_asm_word(value, addr, _bad); break; \
+ case 8: __stp_put_user_asm_dword(value, addr, _bad); break; \
+ default: __put_user_bad(); break; \
+ } \
if (_bad) \
STORE_DEREF_FAULT(addr); \
})
@@ -624,28 +658,31 @@ extern void __store_deref_bad(void);
u8 _b; u16 _w; u32 _l; u64 _q; \
int _bad = 0; \
intptr_t _v = 0; \
- switch (size) { \
- case 1: { \
+ if (lookup_bad_addr((unsigned long)addr)) \
+ _bad = 1; \
+ else \
+ switch (size) { \
+ case 1: { \
__stp_get_asm(_b, addr, _bad, 1); \
_v = _b; \
break; \
- }; \
- case 2: { \
+ }; \
+ case 2: { \
__stp_get_asm(_w, addr, _bad, 2); \
_v = _w; \
break; \
- }; \
- case 4: { \
+ }; \
+ case 4: { \
__stp_get_asm(_l, addr, _bad, 4); \
_v = _l; \
break; \
- }; \
- case 8: { \
+ }; \
+ case 8: { \
__stp_get_asm(_q, addr, _bad, 8); \
_v = _q; \
break; \
- }; \
- default: \
+ }; \
+ default: \
_bad = -EFAULT; \
} \
if (_bad) \
@@ -657,12 +694,17 @@ extern void __store_deref_bad(void);
({ \
int _bad = 0; \
int i; \
- for(i=0;i<size;i++){ \
- __stp_put_asm((u8)(value>>((size-i-1)*8)&0xff), \
- (u64)addr+i,_bad); \
- if (_bad) \
- STORE_DEREF_FAULT(addr); \
- } \
+ if (lookup_bad_addr((unsigned long)addr)) \
+ _bad = 1; \
+ else \
+ for(i=0;i<size;i++){ \
+ __stp_put_asm((u8)(value>>((size-i-1)*8)&0xff), \
+ (u64)addr+i,_bad); \
+ if (_bad) \
+ break; \
+ } \
+ if (_bad) \
+ STORE_DEREF_FAULT(addr); \
})