Add sigsetjmp/siglongjmp bound checking support
tcctok.h: - Add sigsetjmp/__sigsetjmp/siglongjmp tccgen.c: - redirect sigsetjmp/siglongjmp to bcheck.c code i386-gen.c/x86_64-gen.c - gcall_or_jmp: Set func_bound_add_epilog also when sigsetjmp is called - gen_bounds_epilog: Only call __bound_local_new when needed (unrelated) bcheck.c: - Add __bound_siglongjmp - __bound_setjmp/__bound_long_jump: Check no_checking - Optimize __bound_local_delete (unrelated) Modify testcase: - 114_bound_signal
This commit is contained in:
parent
045632defb
commit
3b617fdc53
6 changed files with 188 additions and 137 deletions
24
i386-gen.c
24
i386-gen.c
|
@ -363,7 +363,12 @@ static void gcall_or_jmp(int is_jmp)
|
||||||
if (tcc_state->do_bounds_check &&
|
if (tcc_state->do_bounds_check &&
|
||||||
(vtop->sym->v == TOK_alloca ||
|
(vtop->sym->v == TOK_alloca ||
|
||||||
vtop->sym->v == TOK_setjmp ||
|
vtop->sym->v == TOK_setjmp ||
|
||||||
vtop->sym->v == TOK__setjmp))
|
vtop->sym->v == TOK__setjmp
|
||||||
|
#ifndef TCC_TARGET_PE
|
||||||
|
|| vtop->sym->v == TOK_sigsetjmp
|
||||||
|
|| vtop->sym->v == TOK___sigsetjmp
|
||||||
|
#endif
|
||||||
|
))
|
||||||
func_bound_add_epilog = 1;
|
func_bound_add_epilog = 1;
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
|
@ -1092,15 +1097,18 @@ static void gen_bounds_epilog(void)
|
||||||
bounds_ptr = section_ptr_add(lbounds_section, sizeof(addr_t));
|
bounds_ptr = section_ptr_add(lbounds_section, sizeof(addr_t));
|
||||||
*bounds_ptr = 0;
|
*bounds_ptr = 0;
|
||||||
|
|
||||||
/* generate bound local allocation */
|
|
||||||
saved_ind = ind;
|
|
||||||
ind = func_bound_ind;
|
|
||||||
sym_data = get_sym_ref(&char_pointer_type, lbounds_section,
|
sym_data = get_sym_ref(&char_pointer_type, lbounds_section,
|
||||||
func_bound_offset, lbounds_section->data_offset);
|
func_bound_offset, lbounds_section->data_offset);
|
||||||
greloc(cur_text_section, sym_data, ind + 1, R_386_32);
|
|
||||||
ind = ind + 5;
|
/* generate bound local allocation */
|
||||||
gen_static_call(TOK___bound_local_new);
|
if (func_bound_offset != lbounds_section->data_offset) {
|
||||||
ind = saved_ind;
|
saved_ind = ind;
|
||||||
|
ind = func_bound_ind;
|
||||||
|
greloc(cur_text_section, sym_data, ind + 1, R_386_32);
|
||||||
|
ind = ind + 5;
|
||||||
|
gen_static_call(TOK___bound_local_new);
|
||||||
|
ind = saved_ind;
|
||||||
|
}
|
||||||
|
|
||||||
/* generate bound check local freeing */
|
/* generate bound check local freeing */
|
||||||
o(0x5250); /* save returned value, if any */
|
o(0x5250); /* save returned value, if any */
|
||||||
|
|
246
lib/bcheck.c
246
lib/bcheck.c
|
@ -205,6 +205,7 @@ void __bound_exit(void);
|
||||||
void *__bound_mmap (void *start, size_t size, int prot, int flags, int fd,
|
void *__bound_mmap (void *start, size_t size, int prot, int flags, int fd,
|
||||||
off_t offset);
|
off_t offset);
|
||||||
int __bound_munmap (void *start, size_t size);
|
int __bound_munmap (void *start, size_t size);
|
||||||
|
DLL_EXPORT void __bound_siglongjmp(jmp_buf env, int val);
|
||||||
#endif
|
#endif
|
||||||
DLL_EXPORT void __bound_new_region(void *p, size_t size);
|
DLL_EXPORT void __bound_new_region(void *p, size_t size);
|
||||||
DLL_EXPORT void __bound_setjmp(jmp_buf env);
|
DLL_EXPORT void __bound_setjmp(jmp_buf env);
|
||||||
|
@ -510,8 +511,6 @@ void FASTCALL __bound_local_new(void *p1)
|
||||||
void FASTCALL __bound_local_delete(void *p1)
|
void FASTCALL __bound_local_delete(void *p1)
|
||||||
{
|
{
|
||||||
size_t addr, fp, *p = p1;
|
size_t addr, fp, *p = p1;
|
||||||
alloca_list_type *alloca_free_list = NULL;
|
|
||||||
jmp_list_type *jmp_free_list = NULL;
|
|
||||||
|
|
||||||
if (no_checking)
|
if (no_checking)
|
||||||
return;
|
return;
|
||||||
|
@ -524,65 +523,51 @@ void FASTCALL __bound_local_delete(void *p1)
|
||||||
tree = splay_delete(addr + fp, tree);
|
tree = splay_delete(addr + fp, tree);
|
||||||
p += 2;
|
p += 2;
|
||||||
}
|
}
|
||||||
{
|
if (alloca_list) {
|
||||||
alloca_list_type *last = NULL;
|
alloca_list_type *last = NULL;
|
||||||
alloca_list_type *cur = alloca_list;
|
alloca_list_type *cur = alloca_list;
|
||||||
|
|
||||||
while (cur) {
|
do {
|
||||||
if (cur->fp == fp) {
|
if (cur->fp == fp) {
|
||||||
if (last)
|
if (last)
|
||||||
last->next = cur->next;
|
last->next = cur->next;
|
||||||
else
|
else
|
||||||
alloca_list = cur->next;
|
alloca_list = cur->next;
|
||||||
tree = splay_delete ((size_t) cur->p, tree);
|
tree = splay_delete ((size_t) cur->p, tree);
|
||||||
cur->next = alloca_free_list;
|
dprintf(stderr, "%s, %s(): remove alloca/vla %p\n",
|
||||||
alloca_free_list = cur;
|
__FILE__, __FUNCTION__, cur->p);
|
||||||
|
BOUND_FREE (cur);
|
||||||
cur = last ? last->next : alloca_list;
|
cur = last ? last->next : alloca_list;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
last = cur;
|
last = cur;
|
||||||
cur = cur->next;
|
cur = cur->next;
|
||||||
}
|
}
|
||||||
}
|
} while (cur);
|
||||||
}
|
}
|
||||||
{
|
if (jmp_list) {
|
||||||
jmp_list_type *last = NULL;
|
jmp_list_type *last = NULL;
|
||||||
jmp_list_type *cur = jmp_list;
|
jmp_list_type *cur = jmp_list;
|
||||||
|
|
||||||
while (cur) {
|
do {
|
||||||
if (cur->fp == fp) {
|
if (cur->fp == fp) {
|
||||||
if (last)
|
if (last)
|
||||||
last->next = cur->next;
|
last->next = cur->next;
|
||||||
else
|
else
|
||||||
jmp_list = cur->next;
|
jmp_list = cur->next;
|
||||||
cur->next = jmp_free_list;
|
dprintf(stderr, "%s, %s(): remove setjmp %p\n",
|
||||||
jmp_free_list = cur;
|
__FILE__, __FUNCTION__, cur->penv);
|
||||||
|
BOUND_FREE (cur);
|
||||||
cur = last ? last->next : jmp_list;
|
cur = last ? last->next : jmp_list;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
last = cur;
|
last = cur;
|
||||||
cur = cur->next;
|
cur = cur->next;
|
||||||
}
|
}
|
||||||
}
|
} while (cur);
|
||||||
}
|
}
|
||||||
|
|
||||||
POST_SEM ();
|
POST_SEM ();
|
||||||
while (alloca_free_list) {
|
|
||||||
alloca_list_type *next = alloca_free_list->next;
|
|
||||||
|
|
||||||
dprintf(stderr, "%s, %s(): remove alloca/vla %p\n",
|
|
||||||
__FILE__, __FUNCTION__, alloca_free_list->p);
|
|
||||||
BOUND_FREE (alloca_free_list);
|
|
||||||
alloca_free_list = next;
|
|
||||||
}
|
|
||||||
while (jmp_free_list) {
|
|
||||||
jmp_list_type *next = jmp_free_list->next;
|
|
||||||
|
|
||||||
dprintf(stderr, "%s, %s(): remove setjmp %p\n",
|
|
||||||
__FILE__, __FUNCTION__, jmp_free_list->penv);
|
|
||||||
BOUND_FREE (jmp_free_list);
|
|
||||||
jmp_free_list = next;
|
|
||||||
}
|
|
||||||
#if BOUND_DEBUG
|
#if BOUND_DEBUG
|
||||||
if (print_calls) {
|
if (print_calls) {
|
||||||
p = p1;
|
p = p1;
|
||||||
|
@ -647,107 +632,128 @@ void __bound_setjmp(jmp_buf env)
|
||||||
jmp_list_type *jl;
|
jmp_list_type *jl;
|
||||||
void *e = (void *) env;
|
void *e = (void *) env;
|
||||||
|
|
||||||
dprintf(stderr, "%s, %s(): %p\n", __FILE__, __FUNCTION__, e);
|
if (no_checking == 0) {
|
||||||
WAIT_SEM ();
|
dprintf(stderr, "%s, %s(): %p\n", __FILE__, __FUNCTION__, e);
|
||||||
INCR_COUNT(bound_setjmp_count);
|
WAIT_SEM ();
|
||||||
jl = jmp_list;
|
INCR_COUNT(bound_setjmp_count);
|
||||||
while (jl) {
|
jl = jmp_list;
|
||||||
if (jl->penv == e)
|
while (jl) {
|
||||||
break;
|
if (jl->penv == e)
|
||||||
jl = jl->next;
|
break;
|
||||||
}
|
jl = jl->next;
|
||||||
if (jl == NULL) {
|
|
||||||
jl = BOUND_MALLOC (sizeof (jmp_list_type));
|
|
||||||
if (jl) {
|
|
||||||
jl->penv = e;
|
|
||||||
jl->next = jmp_list;
|
|
||||||
jmp_list = jl;
|
|
||||||
}
|
}
|
||||||
}
|
if (jl == NULL) {
|
||||||
if (jl) {
|
jl = BOUND_MALLOC (sizeof (jmp_list_type));
|
||||||
size_t fp;
|
if (jl) {
|
||||||
|
jl->penv = e;
|
||||||
|
jl->next = jmp_list;
|
||||||
|
jmp_list = jl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (jl) {
|
||||||
|
size_t fp;
|
||||||
|
|
||||||
GET_CALLER_FP (fp);
|
GET_CALLER_FP (fp);
|
||||||
jl->fp = fp;
|
jl->fp = fp;
|
||||||
jl->end_fp = (size_t)__builtin_frame_address(0);
|
jl->end_fp = (size_t)__builtin_frame_address(0);
|
||||||
jl->tid = BOUND_GET_TID;
|
jl->tid = BOUND_GET_TID;
|
||||||
|
}
|
||||||
|
POST_SEM ();
|
||||||
}
|
}
|
||||||
POST_SEM ();
|
}
|
||||||
|
|
||||||
|
static void __bound_long_jump(jmp_buf env, int val, int sig, const char *func)
|
||||||
|
{
|
||||||
|
jmp_list_type *jl;
|
||||||
|
void *e;
|
||||||
|
BOUND_TID_TYPE tid;
|
||||||
|
|
||||||
|
if (no_checking == 0) {
|
||||||
|
e = (void *)env;
|
||||||
|
tid = BOUND_GET_TID;
|
||||||
|
dprintf(stderr, "%s, %s(): %p\n", __FILE__, func, e);
|
||||||
|
WAIT_SEM();
|
||||||
|
INCR_COUNT(bound_longjmp_count);
|
||||||
|
jl = jmp_list;
|
||||||
|
while (jl) {
|
||||||
|
if (jl->penv == e && jl->tid == tid) {
|
||||||
|
size_t start_fp = (size_t)__builtin_frame_address(0);
|
||||||
|
size_t end_fp = jl->end_fp;
|
||||||
|
jmp_list_type *cur = jmp_list;
|
||||||
|
jmp_list_type *last = NULL;
|
||||||
|
|
||||||
|
while (cur->penv != e || cur->tid != tid) {
|
||||||
|
if (cur->tid == tid) {
|
||||||
|
dprintf(stderr, "%s, %s(): remove setjmp %p\n",
|
||||||
|
__FILE__, func, cur->penv);
|
||||||
|
if (last)
|
||||||
|
last->next = cur->next;
|
||||||
|
else
|
||||||
|
jmp_list = cur->next;
|
||||||
|
BOUND_FREE (cur);
|
||||||
|
cur = last ? last->next : jmp_list;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
last = cur;
|
||||||
|
cur = cur->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (;;) {
|
||||||
|
Tree *t = tree;
|
||||||
|
alloca_list_type *last;
|
||||||
|
alloca_list_type *cur;
|
||||||
|
|
||||||
|
while (t && (t->start < start_fp || t->start > end_fp))
|
||||||
|
if (t->start < start_fp)
|
||||||
|
t = t->right;
|
||||||
|
else
|
||||||
|
t = t->left;
|
||||||
|
if (t == NULL)
|
||||||
|
break;
|
||||||
|
last = NULL;
|
||||||
|
cur = alloca_list;
|
||||||
|
while (cur) {
|
||||||
|
if ((size_t) cur->p == t->start) {
|
||||||
|
dprintf(stderr, "%s, %s(): remove alloca/vla %p\n",
|
||||||
|
__FILE__, func, cur->p);
|
||||||
|
if (last)
|
||||||
|
last->next = cur->next;
|
||||||
|
else
|
||||||
|
alloca_list = cur->next;
|
||||||
|
BOUND_FREE (cur);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
last = cur;
|
||||||
|
cur = cur->next;
|
||||||
|
}
|
||||||
|
dprintf(stderr, "%s, %s(): delete %p\n",
|
||||||
|
__FILE__, func, (void *) t->start);
|
||||||
|
tree = splay_delete(t->start, tree);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
jl = jl->next;
|
||||||
|
}
|
||||||
|
POST_SEM();
|
||||||
|
}
|
||||||
|
#if !defined(_WIN32)
|
||||||
|
sig ? siglongjmp(env, val) :
|
||||||
|
#endif
|
||||||
|
longjmp (env, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
void __bound_longjmp(jmp_buf env, int val)
|
void __bound_longjmp(jmp_buf env, int val)
|
||||||
{
|
{
|
||||||
jmp_list_type *jl;
|
__bound_long_jump(env,val, 0, __FUNCTION__);
|
||||||
void *e = (void *)env;
|
|
||||||
BOUND_TID_TYPE tid = BOUND_GET_TID;
|
|
||||||
|
|
||||||
dprintf(stderr, "%s, %s(): %p\n", __FILE__, __FUNCTION__, e);
|
|
||||||
WAIT_SEM();
|
|
||||||
INCR_COUNT(bound_longjmp_count);
|
|
||||||
jl = jmp_list;
|
|
||||||
while (jl) {
|
|
||||||
if (jl->penv == e && jl->tid == tid) {
|
|
||||||
size_t start_fp = (size_t)__builtin_frame_address(0);
|
|
||||||
size_t end_fp = jl->end_fp;
|
|
||||||
jmp_list_type *cur = jmp_list;
|
|
||||||
jmp_list_type *last = NULL;
|
|
||||||
|
|
||||||
while (cur->penv != e || cur->tid != tid) {
|
|
||||||
if (cur->tid == tid) {
|
|
||||||
dprintf(stderr, "%s, %s(): remove setjmp %p\n",
|
|
||||||
__FILE__, __FUNCTION__, cur->penv);
|
|
||||||
if (last)
|
|
||||||
last->next = cur->next;
|
|
||||||
else
|
|
||||||
jmp_list = cur->next;
|
|
||||||
BOUND_FREE (cur);
|
|
||||||
cur = last ? last->next : jmp_list;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
last = cur;
|
|
||||||
cur = cur->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (;;) {
|
|
||||||
Tree *t = tree;
|
|
||||||
alloca_list_type *last;
|
|
||||||
alloca_list_type *cur;
|
|
||||||
|
|
||||||
while (t && (t->start < start_fp || t->start > end_fp))
|
|
||||||
if (t->start < start_fp)
|
|
||||||
t = t->right;
|
|
||||||
else
|
|
||||||
t = t->left;
|
|
||||||
if (t == NULL)
|
|
||||||
break;
|
|
||||||
last = NULL;
|
|
||||||
cur = alloca_list;
|
|
||||||
while (cur) {
|
|
||||||
if ((size_t) cur->p == t->start) {
|
|
||||||
dprintf(stderr, "%s, %s(): remove alloca/vla %p\n",
|
|
||||||
__FILE__, __FUNCTION__, cur->p);
|
|
||||||
if (last)
|
|
||||||
last->next = cur->next;
|
|
||||||
else
|
|
||||||
alloca_list = cur->next;
|
|
||||||
BOUND_FREE (cur);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
last = cur;
|
|
||||||
cur = cur->next;
|
|
||||||
}
|
|
||||||
dprintf(stderr, "%s, %s(): delete %p\n",
|
|
||||||
__FILE__, __FUNCTION__, (void *) t->start);
|
|
||||||
tree = splay_delete(t->start, tree);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
jl = jl->next;
|
|
||||||
}
|
|
||||||
POST_SEM();
|
|
||||||
longjmp (env, val);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !defined(_WIN32)
|
||||||
|
void __bound_siglongjmp(jmp_buf env, int val)
|
||||||
|
{
|
||||||
|
__bound_long_jump(env,val, 1, __FUNCTION__);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(__GNUC__) && (__GNUC__ >= 6)
|
#if defined(__GNUC__) && (__GNUC__ >= 6)
|
||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
#endif
|
#endif
|
||||||
|
|
10
tccgen.c
10
tccgen.c
|
@ -911,6 +911,9 @@ ST_FUNC void put_extern_sym2(Sym *sym, int sh_num,
|
||||||
case TOK_mmap:
|
case TOK_mmap:
|
||||||
case TOK_munmap:
|
case TOK_munmap:
|
||||||
case TOK_longjmp:
|
case TOK_longjmp:
|
||||||
|
#ifndef TCC_TARGET_PE
|
||||||
|
case TOK_siglongjmp:
|
||||||
|
#endif
|
||||||
strcpy(buf, "__bound_");
|
strcpy(buf, "__bound_");
|
||||||
strcat(buf, name);
|
strcat(buf, name);
|
||||||
name = buf;
|
name = buf;
|
||||||
|
@ -6018,7 +6021,12 @@ special_math_val:
|
||||||
(nb_args == 1 || nb_args == 2) &&
|
(nb_args == 1 || nb_args == 2) &&
|
||||||
(vtop[-nb_args].r & VT_SYM) &&
|
(vtop[-nb_args].r & VT_SYM) &&
|
||||||
(vtop[-nb_args].sym->v == TOK_setjmp ||
|
(vtop[-nb_args].sym->v == TOK_setjmp ||
|
||||||
vtop[-nb_args].sym->v == TOK__setjmp)) {
|
vtop[-nb_args].sym->v == TOK__setjmp
|
||||||
|
#ifndef TCC_TARGET_PE
|
||||||
|
|| vtop[-nb_args].sym->v == TOK_sigsetjmp
|
||||||
|
|| vtop[-nb_args].sym->v == TOK___sigsetjmp
|
||||||
|
#endif
|
||||||
|
)) {
|
||||||
vpush_global_sym(&func_old_type, TOK___bound_setjmp);
|
vpush_global_sym(&func_old_type, TOK___bound_setjmp);
|
||||||
vpushv(vtop - nb_args);
|
vpushv(vtop - nb_args);
|
||||||
if (nb_args == 2)
|
if (nb_args == 2)
|
||||||
|
|
4
tcctok.h
4
tcctok.h
|
@ -315,6 +315,10 @@
|
||||||
DEF(TOK_realloc, "realloc")
|
DEF(TOK_realloc, "realloc")
|
||||||
DEF(TOK_memalign, "memalign")
|
DEF(TOK_memalign, "memalign")
|
||||||
DEF(TOK_calloc, "calloc")
|
DEF(TOK_calloc, "calloc")
|
||||||
|
# else
|
||||||
|
DEF(TOK_sigsetjmp, "sigsetjmp")
|
||||||
|
DEF(TOK___sigsetjmp, "__sigsetjmp")
|
||||||
|
DEF(TOK_siglongjmp, "siglongjmp")
|
||||||
# endif
|
# endif
|
||||||
DEF(TOK_mmap, "mmap")
|
DEF(TOK_mmap, "mmap")
|
||||||
DEF(TOK_munmap, "munmap")
|
DEF(TOK_munmap, "munmap")
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <setjmp.h>
|
||||||
|
|
||||||
static volatile int run = 1;
|
static volatile int run = 1;
|
||||||
static int dummy[10];
|
static int dummy[10];
|
||||||
|
@ -70,6 +71,8 @@ main (void)
|
||||||
pthread_t id1, id2;
|
pthread_t id1, id2;
|
||||||
struct sigaction act;
|
struct sigaction act;
|
||||||
struct timespec request;
|
struct timespec request;
|
||||||
|
sigjmp_buf sj;
|
||||||
|
sigset_t m;
|
||||||
|
|
||||||
memset (&act, 0, sizeof (act));
|
memset (&act, 0, sizeof (act));
|
||||||
act.sa_handler = signal_handler;
|
act.sa_handler = signal_handler;
|
||||||
|
@ -90,5 +93,19 @@ main (void)
|
||||||
pthread_join(id1, NULL);
|
pthread_join(id1, NULL);
|
||||||
pthread_join(id2, NULL);
|
pthread_join(id2, NULL);
|
||||||
sem_destroy (&sem);
|
sem_destroy (&sem);
|
||||||
|
|
||||||
|
sigemptyset (&m);
|
||||||
|
sigprocmask (SIG_SETMASK, &m, NULL);
|
||||||
|
if (sigsetjmp (sj, 0) == 0)
|
||||||
|
{
|
||||||
|
sigaddset (&m, SIGUSR1);
|
||||||
|
sigprocmask (SIG_SETMASK, &m, NULL);
|
||||||
|
siglongjmp (sj, 1);
|
||||||
|
printf ("failed");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
sigprocmask (SIG_SETMASK, NULL, &m);
|
||||||
|
if (!sigismember (&m, SIGUSR1))
|
||||||
|
printf ("failed");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
24
x86_64-gen.c
24
x86_64-gen.c
|
@ -640,7 +640,12 @@ static void gcall_or_jmp(int is_jmp)
|
||||||
if (tcc_state->do_bounds_check &&
|
if (tcc_state->do_bounds_check &&
|
||||||
(vtop->sym->v == TOK_alloca ||
|
(vtop->sym->v == TOK_alloca ||
|
||||||
vtop->sym->v == TOK_setjmp ||
|
vtop->sym->v == TOK_setjmp ||
|
||||||
vtop->sym->v == TOK__setjmp))
|
vtop->sym->v == TOK__setjmp
|
||||||
|
#ifndef TCC_TARGET_PE
|
||||||
|
|| vtop->sym->v == TOK_sigsetjmp
|
||||||
|
|| vtop->sym->v == TOK___sigsetjmp
|
||||||
|
#endif
|
||||||
|
))
|
||||||
func_bound_add_epilog = 1;
|
func_bound_add_epilog = 1;
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
|
@ -747,15 +752,18 @@ static void gen_bounds_epilog(void)
|
||||||
bounds_ptr = section_ptr_add(lbounds_section, sizeof(addr_t));
|
bounds_ptr = section_ptr_add(lbounds_section, sizeof(addr_t));
|
||||||
*bounds_ptr = 0;
|
*bounds_ptr = 0;
|
||||||
|
|
||||||
/* generate bound local allocation */
|
|
||||||
sym_data = get_sym_ref(&char_pointer_type, lbounds_section,
|
sym_data = get_sym_ref(&char_pointer_type, lbounds_section,
|
||||||
func_bound_offset, lbounds_section->data_offset);
|
func_bound_offset, lbounds_section->data_offset);
|
||||||
saved_ind = ind;
|
|
||||||
ind = func_bound_ind;
|
/* generate bound local allocation */
|
||||||
greloca(cur_text_section, sym_data, ind + 2, R_X86_64_64, 0);
|
if (func_bound_offset != lbounds_section->data_offset) {
|
||||||
ind = ind + 10;
|
saved_ind = ind;
|
||||||
gen_bounds_call(TOK___bound_local_new);
|
ind = func_bound_ind;
|
||||||
ind = saved_ind;
|
greloca(cur_text_section, sym_data, ind + 2, R_X86_64_64, 0);
|
||||||
|
ind = ind + 10;
|
||||||
|
gen_bounds_call(TOK___bound_local_new);
|
||||||
|
ind = saved_ind;
|
||||||
|
}
|
||||||
|
|
||||||
/* generate bound check local freeing */
|
/* generate bound check local freeing */
|
||||||
o(0x5250); /* save returned value, if any */
|
o(0x5250); /* save returned value, if any */
|
||||||
|
|
Loading…
Reference in a new issue