mirror of
https://github.com/mirror/tinycc.git
synced 2025-01-13 05:10:07 +08:00
bcheck: remove "tcc_location()" & x86_64 double fix
using (modified) tcc_backtrace() instead. Also Also fix the original bug with doubles on x86_64. (which was not caused by incr_offset() actually). See598134fff6
Also cleanup on_exit() stuff Fromfef701b57f
This commit is contained in:
parent
ff2a372a9a
commit
3f3cbb51ed
@ -41,7 +41,7 @@
|
||||
#define BOUND_STATISTIC (1)
|
||||
|
||||
#if BOUND_DEBUG
|
||||
#define dprintf(a...) if (print_calls) { bounds_loc; fprintf(a); }
|
||||
#define dprintf(a...) if (print_calls) { bounds_loc(a); }
|
||||
#else
|
||||
#define dprintf(a...)
|
||||
#endif
|
||||
@ -446,7 +446,6 @@ static unsigned long long bound_splay_delete;
|
||||
#endif
|
||||
|
||||
int tcc_backtrace(const char *fmt, ...);
|
||||
void tcc_location(const char *fmt);
|
||||
|
||||
/* print a bound error message */
|
||||
#define bound_warning(...) \
|
||||
@ -463,10 +462,10 @@ void tcc_location(const char *fmt);
|
||||
exit(255); \
|
||||
} while (0)
|
||||
|
||||
#define bounds_loc \
|
||||
#define bounds_loc(fp, ...) \
|
||||
do { \
|
||||
WAIT_SEM (); \
|
||||
tcc_location("^bcheck.c^"); \
|
||||
tcc_backtrace("^bcheck.c^\001" __VA_ARGS__); \
|
||||
POST_SEM (); \
|
||||
} while (0)
|
||||
|
||||
|
@ -8,7 +8,6 @@
|
||||
REDIR(__bt_init) \
|
||||
REDIR(__bt_exit) \
|
||||
REDIR(tcc_backtrace) \
|
||||
REDIR(tcc_location) \
|
||||
\
|
||||
REDIR(__bound_ptr_add) \
|
||||
REDIR(__bound_ptr_indir1) \
|
||||
|
@ -8,7 +8,6 @@
|
||||
#include "../tccrun.c"
|
||||
|
||||
int (*__rt_error)(void*, void*, const char *, va_list);
|
||||
void (*__rt_location)(void*, void*, const char *);
|
||||
__attribute__((weak)) void __bound_checking_lock(void);
|
||||
__attribute__((weak)) void __bound_checking_unlock(void);
|
||||
|
||||
@ -34,7 +33,6 @@ void __bt_init(rt_context *p, int num_callers)
|
||||
rc->num_callers = num_callers - 1;
|
||||
rc->top_func = main;
|
||||
__rt_error = _rt_error;
|
||||
__rt_location = _rt_location;
|
||||
set_exception_handler();
|
||||
} else {
|
||||
p->next = rc->next, rc->next = p;
|
||||
|
16
lib/bt-log.c
16
lib/bt-log.c
@ -6,7 +6,6 @@
|
||||
#include <string.h>
|
||||
|
||||
int (*__rt_error)(void*, void*, const char *, va_list);
|
||||
void (*__rt_location)(void*, void*, const char *);
|
||||
|
||||
#ifdef _WIN32
|
||||
# define DLL_EXPORT __declspec(dllexport)
|
||||
@ -32,26 +31,19 @@ DLL_EXPORT int tcc_backtrace(const char *fmt, ...)
|
||||
ret = __rt_error(fp, ip, fmt, ap);
|
||||
va_end(ap);
|
||||
} else {
|
||||
const char *p;
|
||||
const char *p, *nl = "\n";
|
||||
if (fmt[0] == '^' && (p = strchr(fmt + 1, fmt[0])))
|
||||
fmt = p + 1;
|
||||
if (fmt[0] == '\001')
|
||||
++fmt, nl = "";
|
||||
va_start(ap, fmt);
|
||||
ret = vfprintf(stderr, fmt, ap);
|
||||
va_end(ap);
|
||||
fprintf(stderr, "\n"), fflush(stderr);
|
||||
fprintf(stderr, nl), fflush(stderr);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
DLL_EXPORT void tcc_location(const char *fmt)
|
||||
{
|
||||
if (__rt_location) {
|
||||
void *fp = __builtin_frame_address(1);
|
||||
void *ip = __builtin_return_address(0);
|
||||
__rt_location(fp, ip, fmt);
|
||||
}
|
||||
}
|
||||
|
||||
#if (defined(__GNUC__) && (__GNUC__ >= 6)) || defined(__clang__)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
2
tccgen.c
2
tccgen.c
@ -6010,7 +6010,6 @@ special_math_val:
|
||||
indir();
|
||||
qualifiers = vtop->type.t & (VT_CONSTANT | VT_VOLATILE);
|
||||
test_lvalue();
|
||||
gaddrof();
|
||||
/* expect pointer on structure */
|
||||
if ((vtop->type.t & VT_BTYPE) != VT_STRUCT)
|
||||
expect("struct or union");
|
||||
@ -6021,6 +6020,7 @@ special_math_val:
|
||||
expect("field name");
|
||||
s = find_field(&vtop->type, tok, &cumofs);
|
||||
/* add field offset to pointer */
|
||||
gaddrof();
|
||||
vtop->type = char_pointer_type; /* change type to 'char *' */
|
||||
vpushi(cumofs);
|
||||
gen_op('+');
|
||||
|
168
tccrun.c
168
tccrun.c
@ -23,9 +23,9 @@
|
||||
/* only native compiler supports -run */
|
||||
#ifdef TCC_IS_NATIVE
|
||||
|
||||
#ifdef CONFIG_TCC_BACKTRACE
|
||||
typedef struct rt_context
|
||||
{
|
||||
#ifdef CONFIG_TCC_BACKTRACE
|
||||
/* --> tccelf.c:tcc_add_btstub wants those below in that order: */
|
||||
union {
|
||||
struct {
|
||||
@ -46,15 +46,27 @@ typedef struct rt_context
|
||||
int num_callers;
|
||||
addr_t ip, fp, sp;
|
||||
void *top_func;
|
||||
jmp_buf jmp_buf;
|
||||
char do_jmp;
|
||||
#endif
|
||||
jmp_buf jb;
|
||||
int do_jmp;
|
||||
# define NR_AT_EXIT 32
|
||||
int nr_exit;
|
||||
void *exitfunc[NR_AT_EXIT];
|
||||
void *exitarg[NR_AT_EXIT];
|
||||
} rt_context;
|
||||
|
||||
static rt_context g_rtctxt;
|
||||
static void rt_exit(int code)
|
||||
{
|
||||
rt_context *rc = &g_rtctxt;
|
||||
if (rc->do_jmp)
|
||||
longjmp(rc->jb, code ? code : 256);
|
||||
exit(code);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_TCC_BACKTRACE
|
||||
static void set_exception_handler(void);
|
||||
static int _rt_error(void *fp, void *ip, const char *fmt, va_list ap);
|
||||
static void _rt_location(void *fp, void *ip, const char *fmt);
|
||||
static void rt_exit(int code);
|
||||
#endif /* CONFIG_TCC_BACKTRACE */
|
||||
|
||||
/* defined when included from lib/bt-exe.c */
|
||||
@ -147,79 +159,35 @@ static void run_cdtors(TCCState *s1, const char *start, const char *end,
|
||||
((void(*)(int, char **, char **))*a++)(argc, argv, envp);
|
||||
}
|
||||
|
||||
#define NR_AT_EXIT 32
|
||||
|
||||
static struct exit_context {
|
||||
int exit_called;
|
||||
int nr_exit;
|
||||
void (*exitfunc[NR_AT_EXIT])(int, void *);
|
||||
void *exitarg[NR_AT_EXIT];
|
||||
#ifndef CONFIG_TCC_BACKTRACE
|
||||
jmp_buf run_jmp_buf;
|
||||
#endif
|
||||
} g_exit_context;
|
||||
|
||||
static void init_exit(void)
|
||||
static void run_on_exit(int ret)
|
||||
{
|
||||
struct exit_context *e = &g_exit_context;
|
||||
|
||||
e->exit_called = 0;
|
||||
e->nr_exit = 0;
|
||||
rt_context *rc = &g_rtctxt;
|
||||
int n = rc->nr_exit;
|
||||
while (n)
|
||||
--n, ((void(*)(int,void*))rc->exitfunc[n])(ret, rc->exitarg[n]);
|
||||
}
|
||||
|
||||
static void call_exit(int ret)
|
||||
static int rt_on_exit(void *function, void *arg)
|
||||
{
|
||||
struct exit_context *e = &g_exit_context;
|
||||
|
||||
while (e->nr_exit) {
|
||||
e->nr_exit--;
|
||||
e->exitfunc[e->nr_exit](ret, e->exitarg[e->nr_exit]);
|
||||
}
|
||||
}
|
||||
|
||||
static int rt_atexit(void (*function)(void))
|
||||
{
|
||||
struct exit_context *e = &g_exit_context;
|
||||
|
||||
if (e->nr_exit < NR_AT_EXIT) {
|
||||
e->exitfunc[e->nr_exit] = (void (*)(int, void *))function;
|
||||
e->exitarg[e->nr_exit++] = NULL;
|
||||
rt_context *rc = &g_rtctxt;
|
||||
if (rc->nr_exit < NR_AT_EXIT) {
|
||||
rc->exitfunc[rc->nr_exit] = function;
|
||||
rc->exitarg[rc->nr_exit++] = arg;
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int rt_on_exit(void (*function)(int, void *), void *arg)
|
||||
static int rt_atexit(void *function)
|
||||
{
|
||||
struct exit_context *e = &g_exit_context;
|
||||
|
||||
if (e->nr_exit < NR_AT_EXIT) {
|
||||
e->exitfunc[e->nr_exit] = function;
|
||||
e->exitarg[e->nr_exit++] = arg;
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void run_exit(int code)
|
||||
{
|
||||
struct exit_context *e = &g_exit_context;
|
||||
|
||||
e->exit_called = 1;
|
||||
#ifdef CONFIG_TCC_BACKTRACE
|
||||
longjmp((&g_rtctxt)->jmp_buf, code ? code : 256);
|
||||
#else
|
||||
longjmp(e->run_jmp_buf, code ? code : 256);
|
||||
#endif
|
||||
return rt_on_exit(function, NULL);
|
||||
}
|
||||
|
||||
/* launch the compiled program with the given arguments */
|
||||
LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv)
|
||||
{
|
||||
int (*prog_main)(int, char **, char **), ret;
|
||||
#ifdef CONFIG_TCC_BACKTRACE
|
||||
rt_context *rc = &g_rtctxt;
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__) || defined(__FreeBSD__)
|
||||
char **envp = NULL;
|
||||
@ -233,17 +201,21 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv)
|
||||
s1->runtime_main = s1->nostdlib ? "_start" : "main";
|
||||
if ((s1->dflag & 16) && (addr_t)-1 == get_sym_addr(s1, s1->runtime_main, 0, 1))
|
||||
return 0;
|
||||
tcc_add_symbol(s1, "exit", run_exit);
|
||||
|
||||
tcc_add_symbol(s1, "exit", rt_exit);
|
||||
tcc_add_symbol(s1, "atexit", rt_atexit);
|
||||
tcc_add_symbol(s1, "on_exit", rt_on_exit);
|
||||
if (tcc_relocate(s1, TCC_RELOCATE_AUTO) < 0)
|
||||
return -1;
|
||||
|
||||
prog_main = (void*)get_sym_addr(s1, s1->runtime_main, 1, 1);
|
||||
if ((addr_t)-1 == (addr_t)prog_main)
|
||||
return -1;
|
||||
|
||||
#ifdef CONFIG_TCC_BACKTRACE
|
||||
memset(rc, 0, sizeof *rc);
|
||||
rc->do_jmp = 1;
|
||||
|
||||
#ifdef CONFIG_TCC_BACKTRACE
|
||||
if (s1->do_debug) {
|
||||
void *p;
|
||||
if (s1->dwarf) {
|
||||
@ -272,11 +244,8 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv)
|
||||
#endif
|
||||
rc->top_func = tcc_get_symbol(s1, "main");
|
||||
rc->num_callers = s1->rt_num_callers;
|
||||
rc->do_jmp = 1;
|
||||
if ((p = tcc_get_symbol(s1, "__rt_error")))
|
||||
*(void**)p = _rt_error;
|
||||
if ((p = tcc_get_symbol(s1, "__rt_location")))
|
||||
*(void**)p = _rt_location;
|
||||
#ifdef CONFIG_TCC_BCHECK
|
||||
if (s1->do_bounds_check) {
|
||||
rc->bounds_start = (void*)bounds_section->sh_addr;
|
||||
@ -291,23 +260,15 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv)
|
||||
errno = 0; /* clean errno value */
|
||||
fflush(stdout);
|
||||
fflush(stderr);
|
||||
init_exit();
|
||||
|
||||
/* These aren't C symbols, so don't need leading underscore handling. */
|
||||
run_cdtors(s1, "__init_array_start", "__init_array_end", argc, argv, envp);
|
||||
#ifdef CONFIG_TCC_BACKTRACE
|
||||
if (!(ret = setjmp(rc->jmp_buf)))
|
||||
#else
|
||||
if (!(ret = setjmp((&g_exit_context)->run_jmp_buf)))
|
||||
#endif
|
||||
{
|
||||
if (!(ret = setjmp(rc->jb)))
|
||||
ret = prog_main(argc, argv, envp);
|
||||
}
|
||||
run_cdtors(s1, "__fini_array_start", "__fini_array_end", 0, NULL, NULL);
|
||||
call_exit(ret);
|
||||
if ((s1->dflag & 16) && ret)
|
||||
run_on_exit(ret);
|
||||
if (s1->dflag & 16 && ret) /* tcc -dt -run ... */
|
||||
fprintf(s1->ppfp, "[returns %d]\n", ret), fflush(s1->ppfp);
|
||||
if ((s1->dflag & 16) == 0 && (&g_exit_context)->exit_called)
|
||||
exit(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1044,7 +1005,7 @@ static int _rt_error(void *fp, void *ip, const char *fmt, va_list ap)
|
||||
rt_context *rc = &g_rtctxt;
|
||||
addr_t pc = 0;
|
||||
char skip[100];
|
||||
int i, level, ret, n;
|
||||
int i, level, ret, n, one;
|
||||
const char *a, *b, *msg;
|
||||
|
||||
if (fp) {
|
||||
@ -1063,6 +1024,10 @@ static int _rt_error(void *fp, void *ip, const char *fmt, va_list ap)
|
||||
memcpy(skip, a, b - a), skip[b - a] = 0;
|
||||
fmt = b + 1;
|
||||
}
|
||||
one = 0;
|
||||
/* hack for bcheck.c:dprintf(): one level, no newline */
|
||||
if (fmt[0] == '\001')
|
||||
++fmt, one = 1;
|
||||
|
||||
n = rc->num_callers ? rc->num_callers : 6;
|
||||
for (i = level = 0; level < n; i++) {
|
||||
@ -1082,6 +1047,8 @@ static int _rt_error(void *fp, void *ip, const char *fmt, va_list ap)
|
||||
rt_vprintf(fmt, ap);
|
||||
} else if (ret == -1)
|
||||
break;
|
||||
if (one)
|
||||
break;
|
||||
rt_printf("\n");
|
||||
if (ret == -1 || (pc == (addr_t)rc->top_func && pc))
|
||||
break;
|
||||
@ -1092,41 +1059,6 @@ static int _rt_error(void *fp, void *ip, const char *fmt, va_list ap)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void _rt_location(void *fp, void *ip, const char *fmt)
|
||||
{
|
||||
rt_context *rc = &g_rtctxt;
|
||||
addr_t pc = 0;
|
||||
char skip[100];
|
||||
int i, ret;
|
||||
const char *a, *b;
|
||||
|
||||
rc->fp = (addr_t)fp;
|
||||
rc->ip = (addr_t)ip;
|
||||
|
||||
skip[0] = 0;
|
||||
/* If fmt is like "^file.c^..." then skip calls from 'file.c' */
|
||||
if (fmt[0] == '^' && (b = strchr(a = fmt + 1, fmt[0])))
|
||||
memcpy(skip, a, b - a), skip[b - a] = 0;
|
||||
|
||||
for (i = 0; ; i++) {
|
||||
ret = rt_get_caller_pc(&pc, rc, i);
|
||||
a = "";
|
||||
if (ret != -1) {
|
||||
if (rc->dwarf)
|
||||
pc = rt_printline_dwarf(rc, pc, "at", skip);
|
||||
else
|
||||
pc = rt_printline(rc, pc, "at", skip);
|
||||
if (pc == (addr_t)-1)
|
||||
continue;
|
||||
a = ": ";
|
||||
}
|
||||
rt_printf(a);
|
||||
break;
|
||||
}
|
||||
|
||||
rc->ip = rc->fp = 0;
|
||||
}
|
||||
|
||||
/* emit a run time error at position 'pc' */
|
||||
static int rt_error(const char *fmt, ...)
|
||||
{
|
||||
@ -1138,14 +1070,6 @@ static int rt_error(const char *fmt, ...)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void rt_exit(int code)
|
||||
{
|
||||
rt_context *rc = &g_rtctxt;
|
||||
if (rc->do_jmp)
|
||||
longjmp(rc->jmp_buf, code ? code : 256);
|
||||
exit(code);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------- */
|
||||
|
||||
#ifndef _WIN32
|
||||
|
@ -2047,6 +2047,7 @@ void gen_opf(int op)
|
||||
assert(vtop->r & VT_LVAL);
|
||||
gv(RC_FLOAT);
|
||||
vswap();
|
||||
fc = vtop->c.i; /* bcheck may have saved previous vtop[-1] */
|
||||
}
|
||||
|
||||
if ((ft & VT_BTYPE) == VT_DOUBLE) {
|
||||
|
Loading…
Reference in New Issue
Block a user