History

tccrun: review last changes

- LIBTCCAPI int tcc_set_backtrace_func(void *ud, ...) accept opaque user data pointer, - tcc -vv -run... : show section info - use memalign() to allocate runtime memory - printline_/dwarf : pass output to parent function - tccpe.c : fix -nostdlib -run - --config-backtrace=no : make it work again

grischka committed 2 years ago

Commit d2f8cea1 parent c88b19918 files · +402 −319Browse files

Unified · Split

18 files
  1. Makefile +3 −3
  2. configure +1 −1
  3. lib/Makefile +2 −3
  4. lib/bt-log.c +3 −3
  5. lib/runmain.c +5 −6
  6. libtcc.c +1 −1
  7. libtcc.h +5 −5
  8. tcc.h +5 −2
  9. tccelf.c +4 −4
  10. tccpe.c +3 −1
  11. tccrun.c +325 −270
  12. tests/Makefile +3 −1
  13. tests/libtcc_test_mt.c +36 −12
  14. tests/tcctest.c +1 −1
  15. win32/build-tcc.bat +1 −0
  16. win32/include/malloc.h +2 −2
  17. win32/include/stdlib.h +2 −2
  18. win32/lib/crt1.c +0 −2
Makefile+3−3
@@ -386,13 +386,13 @@ IR = $(IM) mkdir -p $2 && cp -r $1/. $2 · 385 unmodified lines
386386 IM = @echo "-> $2 : $1" ;
387387 BINCHECK = $(if $(wildcard $(PROGS) *-tcc$(EXESUF)),,@echo "Makefile: nothing found to install" && exit 1)
388388
389−B_O = runmain.o bt-exe.o bt-dll.o bcheck.o
389+EXTRA_O = runmain.o bt-exe.o bt-dll.o bt-log.o bcheck.o
390390
391391 # install progs & libs
392392 install-unx:
393393 $(call BINCHECK)
394394 $(call IBw,$(PROGS) *-tcc,"$(bindir)")
395− $(call IFw,$(LIBTCC1) $(B_O) $(LIBTCC1_U),"$(tccdir)")
395+ $(call IFw,$(LIBTCC1) $(EXTRA_O) $(LIBTCC1_U),"$(tccdir)")
396396 $(call IF,$(TOPSRC)/include/*.h $(TOPSRC)/tcclib.h,"$(tccdir)/include")
397397 $(call $(if $(findstring .so,$(LIBTCC)),IBw,IFw),$(LIBTCC),"$(libdir)")
398398 $(call IF,$(TOPSRC)/libtcc.h,"$(includedir)")
@@ -419,7 +419,7 @@ install-win: · 20 unmodified lines
419419 $(call BINCHECK)
420420 $(call IBw,$(PROGS) *-tcc.exe libtcc.dll,"$(bindir)")
421421 $(call IF,$(TOPSRC)/win32/lib/*.def,"$(tccdir)/lib")
422− $(call IFw,libtcc1.a $(B_O) $(LIBTCC1_W),"$(tccdir)/lib")
422+ $(call IFw,libtcc1.a $(EXTRA_O) $(LIBTCC1_W),"$(tccdir)/lib")
423423 $(call IF,$(TOPSRC)/include/*.h $(TOPSRC)/tcclib.h,"$(tccdir)/include")
424424 $(call IR,$(TOPSRC)/win32/include,"$(tccdir)/include")
425425 $(call IR,$(TOPSRC)/win32/examples,"$(tccdir)/examples")
configure+1−1
@@ -365,7 +365,7 @@ case $targetos in · 364 unmodified lines
365365 default tcc_libpaths "{B}:{R}/lib:/system/lib${S}"
366366 default tcc_crtprefix "{R}/lib"
367367 default tcc_elfinterp "/system/bin/linker${S}"
368− default tcc_switches "-Wl,-rpath=$sysroot/lib,-section-alignment=0x1000"
368+ default tcc_switches "-Wl,-rpath=$sysroot/lib"
369369 ;;
370370 WIN32)
371371 mingw32="yes"
lib/Makefile+2−3
@@ -40,7 +40,7 @@ endif · 39 unmodified lines
4040 $(X)BT_O = bt-exe.o bt-log.o
4141 $(X)B_O = $(BCHECK_O) bt-exe.o bt-log.o bt-dll.o
4242 endif
43−$(X)BT_O += tcov.o
43+$(X)BT_O += runmain.o tcov.o
4444
4545 DSO_O = dsohandle.o
4646
@@ -67,8 +67,7 @@ OBJ-arm-eabihf = $(ARM_O) $(DSO_O) · 20 unmodified lines
6767 OBJ-arm-wince = $(ARM_O) $(WIN_O)
6868 OBJ-riscv64 = $(RISCV64_O) $(BCHECK_O) $(DSO_O)
6969
70−OBJ-extra = $(filter-out bt-log.o,$(filter $(B_O),$(OBJ-$T)))
71−OBJ-extra += runmain.o
70+OBJ-extra = $(filter $(B_O) runmain.o,$(OBJ-$T))
7271 OBJ-libtcc1 = $(addprefix $(X),$(filter-out $(OBJ-extra),$(OBJ-$T)))
7372
7473 ALL = $(addprefix $(TOP)/,$(X)libtcc1.a $(OBJ-extra))
lib/bt-log.c+3−3
@@ -23,19 +23,19 @@ typedef struct rt_frame { · 22 unmodified lines
2323 } rt_frame;
2424
2525 __attribute__((weak))
26−int __rt_dump(rt_frame *f, const char *msg, const char *fmt, va_list ap);
26+int _tcc_backtrace(rt_frame *f, const char *fmt, va_list ap);
2727
2828 DLL_EXPORT int tcc_backtrace(const char *fmt, ...)
2929 {
3030 va_list ap;
3131 int ret;
3232
33− if (__rt_dump) {
33+ if (_tcc_backtrace) {
3434 rt_frame f;
3535 f.fp = __builtin_frame_address(1);
3636 f.ip = __builtin_return_address(0);
3737 va_start(ap, fmt);
38− ret = __rt_dump(&f, NULL, fmt, ap);
38+ ret = _tcc_backtrace(&f, fmt, ap);
3939 va_end(ap);
4040 } else {
4141 const char *p, *nl = "\n";
lib/runmain.c+5−6
@@ -29,7 +29,7 @@ static void run_dtors(void) · 28 unmodified lines
2929
3030 static void *rt_exitfunc[32];
3131 static void *rt_exitarg[32];
32−int __rt_nr_exit;
32+static int __rt_nr_exit;
3333
3434 void __run_on_exit(int ret)
3535 {
@@ -59,16 +59,16 @@ typedef struct rt_frame { · 23 unmodified lines
5959 void *ip, *fp, *sp;
6060 } rt_frame;
6161
62−void __rt_longjmp(rt_frame *, int);
62+void __rt_exit(rt_frame *, int);
6363
6464 void exit(int code)
6565 {
6666 rt_frame f;
6767 run_dtors();
6868 __run_on_exit(code);
69− f.fp = __builtin_frame_address(1);
70− f.ip = __builtin_return_address(0);
71− __rt_longjmp(&f, code);
69+ f.fp = 0;
70+ f.ip = exit;
71+ __rt_exit(&f, code);
7272 }
7373
7474 #ifndef _WIN32
@@ -77,7 +77,6 @@ int main(int, char**, char**); · 2 unmodified lines
7777 int _runmain(int argc, char **argv, char **envp)
7878 {
7979 int ret;
80− __rt_nr_exit = 0;
8180 run_ctors(argc, argv, envp);
8281 ret = main(argc, argv, envp);
8382 run_dtors();
libtcc.c+1−1
@@ -229,7 +229,7 @@ static void *default_reallocator(void *ptr, unsigned long size) · 228 unmodified lines
229229 return ptr1;
230230 }
231231
232−static void libc_free(void *ptr)
232+ST_FUNC void libc_free(void *ptr)
233233 {
234234 free(ptr);
235235 }
libtcc.h+5−5
@@ -104,12 +104,12 @@ LIBTCCAPI void tcc_list_symbols(TCCState *s, void *ctx, · 103 unmodified lines
104104
105105 /* catch runtime exceptions (optionally limit backtraces at top_func),
106106 when using tcc_set_options("-bt") and when not using tcc_run() */
107−LIBTCCAPI void *_tcc_setjmp(TCCState *s1, void *longjmp, void *jmp_buf, void *top_func);
108−#define tcc_setjmp(s1,jb,f) setjmp(_tcc_setjmp(s1, longjmp, jb, f))
107+LIBTCCAPI void *_tcc_setjmp(TCCState *s1, void *jmp_buf, void *top_func, void *longjmp);
108+#define tcc_setjmp(s1,jb,f) setjmp(_tcc_setjmp(s1, jb, f, longjmp))
109109
110−/* set custom error printer for runtime exceptions */
111−typedef void TCCBtFunc(void *pc, const char *file, int line, const char* func);
112−LIBTCCAPI void tcc_set_backtrace_func(TCCState *s1, TCCBtFunc*);
110+/* custom error printer for runtime exceptions. Returning 0 stops backtrace */
111+typedef int TCCBtFunc(void *udata, void *pc, const char *file, int line, const char* func, const char *msg);
112+LIBTCCAPI void tcc_set_backtrace_func(TCCState *s1, void* userdata, TCCBtFunc*);
113113
114114 #ifdef __cplusplus
115115 }
tcc.h+5−2
@@ -1003,7 +1003,9 @@ struct TCCState { · 1002 unmodified lines
10031003 struct TCCState *next;
10041004 struct rt_context *rc; /* pointer to backtrace info block */
10051005 void *run_lj, *run_jb; /* sj/lj for tcc_setjmp()/tcc_run() */
1006− void (*bt_func)(void *, const char*, int, const char*);
1006+ TCCBtFunc *bt_func;
1007+ void *bt_data;
1008+ int run_tid;
10071009 #endif
10081010
10091011 #ifdef CONFIG_TCC_BACKTRACE
@@ -1250,6 +1252,7 @@ PUB_FUNC void *tcc_realloc_debug(void *ptr, unsigned long size, const char *file · 240 unmodified lines
12501252 PUB_FUNC char *tcc_strdup_debug(const char *str, const char *file, int line);
12511253 #endif
12521254
1255+ST_FUNC void libc_free(void *ptr);
12531256 #define free(p) use_tcc_free(p)
12541257 #define malloc(s) use_tcc_malloc(s)
12551258 #define realloc(p, s) use_tcc_realloc(p, s)
@@ -1982,7 +1985,7 @@ ST_FUNC void wait_sem(TCCSem *p) · 726 unmodified lines
19821985 sem_init(&p->sem, 0, 1), p->init = 1;
19831986 while (sem_wait(&p->sem) < 0 && errno == EINTR);
19841987 }
1985−ST_INLN void post_sem(TCCSem *p)
1988+ST_FUNC void post_sem(TCCSem *p)
19861989 {
19871990 sem_post(&p->sem);
19881991 }
tccelf.c+4−4
@@ -1606,7 +1606,7 @@ ST_FUNC void tcc_add_btstub(TCCState *s1) · 1605 unmodified lines
16061606 (uint64_t)1 << 32);
16071607 #endif
16081608 }
1609− n = 4 * PTR_SIZE;
1609+ n = 3 * PTR_SIZE;
16101610 #ifdef CONFIG_TCC_BCHECK
16111611 if (s1->do_bounds_check) {
16121612 put_ptr(s1, bounds_section, 0);
@@ -1617,9 +1617,7 @@ ST_FUNC void tcc_add_btstub(TCCState *s1) · 4 unmodified lines
16171617 p = section_ptr_add(s, 2 * sizeof (int));
16181618 p[0] = s1->rt_num_callers;
16191619 p[1] = s1->dwarf;
1620−
1621− if (s->data_offset - o != 11 * PTR_SIZE + 2 * sizeof (int))
1622− exit(99);
1620+ // if (s->data_offset - o != 10*PTR_SIZE + 2*sizeof (int)) exit(99);
16231621
16241622 if (s1->output_type == TCC_OUTPUT_MEMORY) {
16251623 set_global_sym(s1, __rt_info, s, o);
@@ -1778,6 +1776,8 @@ ST_FUNC void tcc_add_runtime(TCCState *s1) · 152 unmodified lines
17781776 if (s1->do_backtrace) {
17791777 if (s1->output_type & TCC_OUTPUT_EXE)
17801778 tcc_add_support(s1, "bt-exe.o");
1779+ if (s1->output_type != TCC_OUTPUT_DLL)
1780+ tcc_add_support(s1, "bt-log.o");
17811781 tcc_add_btstub(s1);
17821782 lpthread = 1;
17831783 }
tccpe.c+3−1
@@ -1943,7 +1943,7 @@ static void pe_add_runtime(TCCState *s1, struct pe_info *pe) · 1942 unmodified lines
19431943 pe_type = PE_EXE;
19441944
19451945 }
1946− if (TCC_OUTPUT_MEMORY == s1->output_type)
1946+ if (TCC_OUTPUT_MEMORY == s1->output_type && !s1->nostdlib)
19471947 start_symbol = run_symbol;
19481948 }
19491949
@@ -1961,6 +1961,8 @@ static void pe_add_runtime(TCCState *s1, struct pe_info *pe) · 11 unmodified lines
19611961 tcc_add_support(s1, "bt-exe.o");
19621962 if (s1->output_type == TCC_OUTPUT_DLL)
19631963 tcc_add_support(s1, "bt-dll.o");
1964+ if (s1->output_type != TCC_OUTPUT_DLL)
1965+ tcc_add_support(s1, "bt-log.o");
19641966 tcc_add_btstub(s1);
19651967 }
19661968 #endif
tccrun.c+325−270
@@ -24,6 +24,7 @@ · 23 unmodified lines
2424 #ifdef TCC_IS_NATIVE
2525
2626 #ifdef CONFIG_TCC_BACKTRACE
27+/* runtime debug info block */
2728 typedef struct rt_context
2829 {
2930 /* tccelf.c:tcc_add_btstub() wants these in that order: */
@@ -42,32 +43,33 @@ typedef struct rt_context · 12 unmodified lines
4243 ElfW(Sym) *esym_start;
4344 ElfW(Sym) *esym_end;
4445 char *elf_str;
45− // 6
46+ // 6 * PTR_SIZE
4647 addr_t prog_base;
4748 void *bounds_start;
4849 void *top_func;
49− TCCState *s1;
5050 struct rt_context *next;
51− // 11
51+ // 10 * PTR_SIZE
5252 int num_callers;
5353 int dwarf;
54−} rt_context; /* size = 11 * PTR_SIZE + 2 * sizeof (int) */
54+} rt_context;
55+
56+/* linked list of rt_contexts */
57+static rt_context *g_rc;
58+static int signal_set;
59+static void set_exception_handler(void);
60+#endif /* def CONFIG_TCC_BACKTRACE */
5561
5662 typedef struct rt_frame {
5763 addr_t ip, fp, sp;
5864 } rt_frame;
5965
60−/* linked list of rt_contexts */
61−static rt_context *g_rc;
6266 static TCCState *g_s1;
6367 /* semaphore to protect it */
6468 TCC_SEM(static rt_sem);
65−static int signal_set;
66−static void set_exception_handler(void);
6769 static void rt_wait_sem(void) { WAIT_SEM(&rt_sem); }
6870 static void rt_post_sem(void) { POST_SEM(&rt_sem); }
6971 static int rt_get_caller_pc(addr_t *paddr, rt_frame *f, int level);
70−#endif /* def CONFIG_TCC_BACKTRACE */
72+static void rt_exit(rt_frame *f, int code);
7173
7274 /* ------------------------------------------------------------- */
7375 /* defined when included from lib/bt-exe.c */
@@ -79,73 +81,26 @@ static int rt_get_caller_pc(addr_t *paddr, rt_frame *f, int level); · 5 unmodified lines
7981
8082 static int protect_pages(void *ptr, unsigned long length, int mode);
8183 static int tcc_relocate_ex(TCCState *s1, void *ptr, unsigned ptr_diff);
82−static int __rt_dump(rt_frame *f, const char *msg, const char *fmt, va_list ap);
83−static void rt_longjmp(rt_frame *f, int code);
84+static void st_link(TCCState *s1);
85+static void st_unlink(TCCState *s1);
86+#ifdef CONFIG_TCC_BACKTRACE
87+static int _tcc_backtrace(rt_frame *f, const char *fmt, va_list ap);
88+#endif
8489 #ifdef _WIN64
8590 static void *win64_add_function_table(TCCState *s1);
8691 static void win64_del_function_table(void *);
8792 #endif
8893
89−static void bt_link(TCCState *s1)
90−{
91−#ifdef CONFIG_TCC_BACKTRACE
92− rt_context *rc;
93− void *p;
94−
95− if (!s1->do_backtrace)
96− return;
97− rc = tcc_get_symbol(s1, "__rt_info");
98− if (!rc)
99− return;
100− rc->esym_start = (ElfW(Sym) *)(symtab_section->data);
101− rc->esym_end = (ElfW(Sym) *)(symtab_section->data + symtab_section->data_offset);
102− rc->elf_str = (char *)symtab_section->link->data;
103− if (PTR_SIZE == 8 && !s1->dwarf)
104− rc->prog_base &= 0xffffffff00000000ULL;
105−#ifdef CONFIG_TCC_BCHECK
106− if (s1->do_bounds_check) {
107− if ((p = tcc_get_symbol(s1, "__bound_init")))
108− ((void(*)(void*,int))p)(rc->bounds_start, 1);
109− }
110−#endif
111− rc->next = g_rc, g_rc = rc, rc->s1 = s1, s1->rc = rc;
112− if (0 == signal_set)
113− set_exception_handler(), signal_set = 1;
114−#endif
115−}
116−
117−static void bt_unlink(TCCState *s1)
118−{
119−#ifdef CONFIG_TCC_BACKTRACE
120− rt_context *rc, **pp;
121− for (pp = &g_rc; rc = *pp, rc; pp = &rc->next)
122− if (rc->s1 == s1) {
123− *pp = rc->next;
124− break;
125− }
94+#ifdef __APPLE__
95+# define CONFIG_RUNMEM_ALIGNED 0
96+#else
97+# ifndef CONFIG_RUNMEM_ALIGNED
98+# define CONFIG_RUNMEM_ALIGNED 1
99+# endif
100+# if CONFIG_RUNMEM_ALIGNED
101+# include <malloc.h> /* memalign() */
102+# endif
126103 #endif
127−}
128−
129−static void st_link(TCCState *s1)
130−{
131− rt_wait_sem();
132− s1->next = g_s1, g_s1 = s1;
133− bt_link(s1);
134− rt_post_sem();
135−}
136−
137−static void st_unlink(TCCState *s1)
138−{
139− TCCState *s2, **pp;
140− rt_wait_sem();
141− bt_unlink(s1);
142− for (pp = &g_s1; s2 = *pp, s2; pp = &s2->next)
143− if (s2 == s1) {
144− *pp = s2->next;
145− break;
146− }
147− rt_post_sem();
148−}
149104
150105 #if !_WIN32 && !__APPLE__
151106 //#define HAVE_SELINUX 1
@@ -172,7 +127,15 @@ static int rt_mem(TCCState *s1, int size) · 20 unmodified lines
172127 ptr_diff = (char*)prw - (char*)ptr; /* = size; */
173128 //printf("map %p %p %p\n", ptr, prw, (void*)ptr_diff);
174129 #else
175− ptr = tcc_malloc(size);
130+# if !CONFIG_RUNMEM_ALIGNED
131+ ptr = tcc_malloc(size += PAGESIZE);
132+# elif _WIN32
133+ ptr = _aligned_malloc(size, PAGESIZE);
134+# else
135+ ptr = memalign(PAGESIZE, size);
136+# endif
137+ if (NULL == ptr)
138+ return tcc_error_noabort("tccrun: could not allocate memory");
176139 #endif
177140 s1->run_ptr = ptr;
178141 s1->run_size = size;
@@ -189,12 +152,10 @@ LIBTCCAPI int tcc_relocate(TCCState *s1) · 10 unmodified lines
189152
190153 if (s1->run_ptr)
191154 exit(tcc_error_noabort("'tcc_relocate()' twice is no longer supported"));
192−
193155 #ifdef CONFIG_TCC_BACKTRACE
194156 if (s1->do_backtrace)
195− tcc_add_symbol(s1, "__rt_dump", __rt_dump); /* for bt-log.c */
157+ tcc_add_symbol(s1, "_tcc_backtrace", _tcc_backtrace); /* for bt-log.c */
196158 #endif
197−
198159 size = tcc_relocate_ex(s1, NULL, 0);
199160 if (size < 0)
200161 return -1;
@@ -236,31 +197,24 @@ ST_FUNC void tcc_run_free(TCCState *s1) · 35 unmodified lines
236197 #else
237198 /* unprotect memory to make it usable for malloc again */
238199 protect_pages(ptr, size, 2 /*rw*/);
239−#ifdef _WIN64
200+# ifdef _WIN64
240201 win64_del_function_table(s1->run_function_table);
241−#endif
202+# endif
203+# if !CONFIG_RUNMEM_ALIGNED
242204 tcc_free(ptr);
205+# elif _WIN32
206+ _aligned_free(ptr);
207+# else
208+ libc_free(ptr);
209+# endif
243210 #endif
244211 }
245212
246−LIBTCCAPI void *_tcc_setjmp(TCCState *s1, void *p_longjmp, void *p_jmp_buf, void *func)
247−{
248− s1->run_lj = p_longjmp;
249− s1->run_jb = p_jmp_buf;
250− if (func && s1->rc)
251− s1->rc->top_func = func;
252− return p_jmp_buf;
253−}
254−
255−LIBTCCAPI void tcc_set_backtrace_func(TCCState *s1, TCCBtFunc *func)
256−{
257− s1->bt_func = func;
258−}
259−
260213 /* launch the compiled program with the given arguments */
261214 LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv)
262215 {
263216 int (*prog_main)(int, char **, char **), ret;
217+ const char *top_sym;
264218 jmp_buf main_jb;
265219
266220 #if defined(__APPLE__) || defined(__FreeBSD__)
@@ -276,20 +230,25 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv) · 9 unmodified lines
276230 if ((s1->dflag & 16) && (addr_t)-1 == get_sym_addr(s1, "main", 0, 1))
277231 return 0;
278232
279− tcc_add_support(s1, "runmain.o");
280− tcc_add_symbol(s1, "__rt_longjmp", rt_longjmp);
281− s1->run_main = (s1->nostdlib ? "_start" : "_runmain");
233+ tcc_add_symbol(s1, "__rt_exit", rt_exit);
234+ if (s1->nostdlib) {
235+ s1->run_main = top_sym = "_start";
236+ } else {
237+ tcc_add_support(s1, "runmain.o");
238+ s1->run_main = "_runmain";
239+ top_sym = "main";
240+ }
282241 if (tcc_relocate(s1) < 0)
283− return -1;
242+ return 1;
284243
285244 prog_main = (void*)get_sym_addr(s1, s1->run_main, 1, 1);
286245 if ((addr_t)-1 == (addr_t)prog_main)
287− return -1;
246+ return 1;
288247 errno = 0; /* clean errno value */
289248 fflush(stdout);
290249 fflush(stderr);
291250
292− ret = tcc_setjmp(s1, main_jb, tcc_get_symbol(s1, "main"));
251+ ret = tcc_setjmp(s1, main_jb, tcc_get_symbol(s1, top_sym));
293252 if (0 == ret)
294253 ret = prog_main(argc, argv, envp);
295254 else if (256 == ret)
@@ -344,8 +303,6 @@ static void cleanup_sections(TCCState *s1) · 48 unmodified lines
344303 # define CONFIG_RUNMEM_RO 1
345304 #endif
346305
347−#define DEBUG_RUNMEN 0
348−
349306 /* relocate code. Return -1 on error, required size if ptr is NULL,
350307 otherwise copy code into buffer passed by the caller */
351308 static int tcc_relocate_ex(TCCState *s1, void *ptr, unsigned ptr_diff)
@@ -367,16 +324,17 @@ static int tcc_relocate_ex(TCCState *s1, void *ptr, unsigned ptr_diff) · 15 unmodified lines
367324
368325 offset = copy = 0;
369326 mem = (addr_t)ptr;
370−
371−#if DEBUG_RUNMEN
372− if (mem)
373− fprintf(stderr, "X: <base> %p len %5x\n",
374− ptr, s1->run_size);
375−#endif
376−
377327 redo:
328+ if (s1->verbose == 2 && copy) {
329+ printf(&"-----------------------------------------------------\n"[PTR_SIZE*2 - 8]);
330+ if (1 == copy)
331+ printf("memory %p len %05x\n", ptr, s1->run_size);
332+ }
378333 if (s1->nb_errors)
379334 return -1;
335+ if (copy == 2)
336+ return 0;
337+
380338 for (k = 0; k < 3; ++k) { /* 0:rx, 1:ro, 2:rw sections */
381339 n = 0; addr = 0;
382340 for(i = 1; i < s1->nb_sections; i++) {
@@ -389,7 +347,9 @@ redo: · 6 unmodified lines
389347 length = s->data_offset;
390348
391349 if (copy) { /* final step: copy section data to memory */
392− void *ptr;
350+ if (s1->verbose == 2)
351+ printf("%d: %-16s %p len %05x align %04x\n",
352+ k, s->name, (void*)s->sh_addr, length, s->sh_addralign);
393353 if (addr == 0)
394354 addr = s->sh_addr;
395355 n = (s->sh_addr - addr) + length;
@@ -407,28 +367,25 @@ redo: · 11 unmodified lines
407367 continue;
408368 }
409369
410− align = s->sh_addralign - 1;
370+ align = s->sh_addralign;
411371 if (++n == 1) {
412372 #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
413373 /* To avoid that x86 processors would reload cached instructions
414374 each time when data is written in the near, we need to make
415375 sure that code and data do not share the same 64 byte unit */
416− if (align < 63)
417− align = 63;
376+ if (align < 64)
377+ align = 64;
418378 #endif
419379 /* start new page for different permissions */
420380 if (CONFIG_RUNMEM_RO || k < 2)
421− align = PAGESIZE - 1;
381+ align = PAGESIZE;
422382 }
383+ s->sh_addralign = align;
384+
423385 addr = k ? mem + ptr_diff : mem;
424− offset += -(addr + offset) & align;
386+ offset += -(addr + offset) & (align - 1);
425387 s->sh_addr = mem ? addr + offset : 0;
426388 offset += length;
427−#if DEBUG_RUNMEN
428− if (mem)
429− fprintf(stderr, "%d: %-16s %p len %5x align %04x\n",
430− k, s->name, (void*)s->sh_addr, length, align + 1);
431−#endif
432389 }
433390 if (copy) { /* set permissions */
434391 if (n == 0) /* no data */
@@ -443,30 +400,25 @@ redo: · 8 unmodified lines
443400 continue;
444401 f = 3; /* change only SHF_EXECINSTR to rwx */
445402 }
446−#if DEBUG_RUNMEN
447− fprintf(stderr, "protect %3s %p len %5x\n",
448− &"rx\0r \0rw\0rwx"[f*3],
449− (void*)addr, (unsigned)((n + PAGESIZE-1) & ~(PAGESIZE-1)));
450−#endif
403+ n = (n + PAGESIZE-1) & ~(PAGESIZE-1);
404+ if (s1->verbose == 2) {
405+ printf("protect %3s %p len %05x\n",
406+ &"rx\0r \0rw\0rwx"[f*3], (void*)addr, (unsigned)n);
407+ }
451408 if (protect_pages((void*)addr, n, f) < 0)
452409 return tcc_error_noabort(
453410 "mprotect failed (did you mean to configure --with-selinux?)");
454411 }
455412 }
456413
457− if (0 == mem) {
458− offset = (offset + (PAGESIZE-1)) & ~(PAGESIZE-1);
459−#ifndef HAVE_SELINUX
460− offset += PAGESIZE; /* extra space to align malloc memory start */
461−#endif
462− return offset;
463− }
414+ if (0 == mem)
415+ return (offset + (PAGESIZE-1)) & ~(PAGESIZE-1);
464416
465− if (copy) {
417+ if (++copy == 2) {
466418 /* remove local symbols and free sections except symtab */
467419 cleanup_symbols(s1);
468420 cleanup_sections(s1);
469− return 0;
421+ goto redo;
470422 }
471423
472424 /* relocate symbols */
@@ -478,7 +430,6 @@ redo: · 5 unmodified lines
478430 relocate_plt(s1);
479431 #endif
480432 relocate_sections(s1);
481− copy = 1;
482433 goto redo;
483434 }
484435
@@ -546,6 +497,152 @@ static void win64_del_function_table(void *p) · 61 unmodified lines
546497 }
547498 #endif
548499
500+static void bt_link(TCCState *s1)
501+{
502+#ifdef CONFIG_TCC_BACKTRACE
503+ rt_context *rc;
504+ void *p;
505+
506+ if (!s1->do_backtrace)
507+ return;
508+ rc = tcc_get_symbol(s1, "__rt_info");
509+ if (!rc)
510+ return;
511+ rc->esym_start = (ElfW(Sym) *)(symtab_section->data);
512+ rc->esym_end = (ElfW(Sym) *)(symtab_section->data + symtab_section->data_offset);
513+ rc->elf_str = (char *)symtab_section->link->data;
514+ if (PTR_SIZE == 8 && !s1->dwarf)
515+ rc->prog_base &= 0xffffffff00000000ULL;
516+#ifdef CONFIG_TCC_BCHECK
517+ if (s1->do_bounds_check) {
518+ if ((p = tcc_get_symbol(s1, "__bound_init")))
519+ ((void(*)(void*,int))p)(rc->bounds_start, 1);
520+ }
521+#endif
522+ rc->next = g_rc, g_rc = rc, s1->rc = rc;
523+ if (0 == signal_set)
524+ set_exception_handler(), signal_set = 1;
525+#endif
526+}
527+
528+static void st_link(TCCState *s1)
529+{
530+ rt_wait_sem();
531+ s1->next = g_s1, g_s1 = s1;
532+ bt_link(s1);
533+ rt_post_sem();
534+}
535+
536+/* remove 'el' from 'list' */
537+static void ptr_unlink(void *list, void *e, unsigned next)
538+{
539+ void **pp, **nn, *p;
540+ for (pp = list; !!(p = *pp); pp = nn) {
541+ nn = (void*)((char*)p + next); /* nn = &p->next; */
542+ if (p == e) {
543+ *pp = *nn;
544+ break;
545+ }
546+ }
547+}
548+
549+static void st_unlink(TCCState *s1)
550+{
551+ rt_wait_sem();
552+#ifdef CONFIG_TCC_BACKTRACE
553+ ptr_unlink(&g_rc, s1->rc, offsetof(rt_context, next));
554+#endif
555+ ptr_unlink(&g_s1, s1, offsetof(TCCState, next));
556+ rt_post_sem();
557+}
558+
559+#ifdef _WIN32
560+# define GETTID() GetCurrentThreadId()
561+#elif defined __linux__
562+# define GETTID() gettid()
563+#elif 0
564+# define GETTID() 1234 // threads not supported
565+#endif
566+
567+LIBTCCAPI void *_tcc_setjmp(TCCState *s1, void *p_jmp_buf, void *func, void *p_longjmp)
568+{
569+#ifdef GETTID
570+ int tid = GETTID();
571+ TCCState *s;
572+ rt_wait_sem();
573+ for (s = g_s1; s; s = s->next)
574+ if (s->run_tid == tid)
575+ s->run_tid = -1;
576+ s1->run_tid = (int)tid;
577+ rt_post_sem();
578+#endif
579+ s1->run_lj = p_longjmp;
580+ s1->run_jb = p_jmp_buf;
581+#ifdef CONFIG_TCC_BACKTRACE
582+ if (s1->rc)
583+ s1->rc->top_func = func;
584+#endif
585+ return p_jmp_buf;
586+}
587+
588+LIBTCCAPI void tcc_set_backtrace_func(TCCState *s1, void *data, TCCBtFunc *func)
589+{
590+ s1->bt_func = func;
591+ s1->bt_data = data;
592+}
593+
594+static TCCState *rt_find_state(rt_frame *f)
595+{
596+#ifdef GETTID
597+ int tid = GETTID();
598+ TCCState *s;
599+ for (s = g_s1; s; s = s->next)
600+ if (s->run_tid == tid)
601+ break;
602+ return s;
603+#else
604+ TCCState *s;
605+ int level;
606+ addr_t pc;
607+
608+ s = g_s1;
609+ if (NULL == s || NULL == s->next) {
610+ /* play it safe in the simple case when there is only one state */
611+ return s;
612+ }
613+ for (level = 0; level < 8; ++level) {
614+ if (rt_get_caller_pc(&pc, f, level) < 0)
615+ break;
616+ for (s = g_s1; s; s = s->next) {
617+ if (pc >= (addr_t)s->run_ptr
618+ && pc < (addr_t)s->run_ptr + s->run_size)
619+ return s;
620+ }
621+ }
622+ return NULL;
623+#endif
624+}
625+
626+static void rt_exit(rt_frame *f, int code)
627+{
628+ TCCState *s;
629+ rt_wait_sem();
630+ s = rt_find_state(f);
631+ rt_post_sem();
632+ if (s && s->run_lj) {
633+ if (code == 0)
634+ code = 256;
635+ ((void(*)(void*,int))s->run_lj)(s->run_jb, code);
636+ }
637+ exit(code);
638+}
639+
640+/* ------------------------------------------------------------- */
641+#else // if defined CONFIG_TCC_BACKTRACE_ONLY
642+static void rt_exit(rt_frame *f, int code)
643+{
644+ exit(code);
645+}
549646 #endif //ndef CONFIG_TCC_BACKTRACE_ONLY
550647 /* ------------------------------------------------------------- */
551648 #ifdef CONFIG_TCC_BACKTRACE
@@ -582,11 +679,17 @@ static char *rt_elfsym(rt_context *rc, addr_t wanted_pc, addr_t *func_addr) · 30 unmodified lines
582679 return NULL;
583680 }
584681
682+typedef struct bt_info
683+{
684+ char file[100];
685+ int line;
686+ char func[100];
687+ addr_t func_pc;
688+} bt_info;
585689
586690 /* print the position in the source file of PC value 'pc' by reading
587691 the stabs debug information */
588−static addr_t rt_printline (rt_context *rc, addr_t wanted_pc,
589− rt_context** prc, const char *msg, const char *skip)
692+static addr_t rt_printline (rt_context *rc, addr_t wanted_pc, bt_info *bi)
590693 {
591694 char func_name[128];
592695 addr_t func_addr, last_pc, pc;
@@ -595,15 +698,12 @@ static addr_t rt_printline (rt_context *rc, addr_t wanted_pc, · 2 unmodified lines
595698 const char *str, *p;
596699 Stab_Sym *sym;
597700
598−next:
599701 func_name[0] = '\0';
600702 func_addr = 0;
601703 incl_index = 0;
602704 last_pc = (addr_t)-1;
603705 last_line_num = 1;
604706 last_incl_index = 0;
605− if (NULL == rc)
606− goto found;
607707
608708 for (sym = rc->stab_sym + 1; sym < rc->stab_sym_end; ++sym) {
609709 str = rc->stab_str + sym->n_strx;
@@ -680,50 +780,15 @@ next: · 70 unmodified lines
680780 break;
681781 }
682782 }
683−
684− func_name[0] = '\0';
685− func_addr = 0;
686− last_incl_index = 0;
687−
688− /* we try symtab symbols (no line number info) */
689− p = rt_elfsym(rc, wanted_pc, &func_addr);
690− if (p) {
691− pstrcpy(func_name, sizeof func_name, p);
692− goto found;
693− }
694− rc = rc->next;
695− goto next;
696−
783+ last_incl_index = 0, func_name[0] = 0, func_addr = 0;
697784 found:
698785 i = last_incl_index;
699− str = NULL;
700786 if (i > 0) {
701− str = incl_files[--i];
702− if (skip[0] && strstr(str, skip))
703− return (addr_t)-1;
704− }
705− if (rc && rc->s1 && rc->s1->bt_func) {
706− rc->s1->bt_func((void*)wanted_pc, str, last_line_num, func_name[0] ? func_name : NULL);
707− } else {
708− if (str)
709− rt_printf("%s:%d: ", str, last_line_num);
710− else
711− rt_printf("%08llx : ", (long long)wanted_pc);
712− rt_printf("%s %s", msg, func_name[0] ? func_name : "???");
713− }
714−#if 0
715− if (--i >= 0) {
716− rt_printf(" (included from ");
717− for (;;) {
718− rt_printf("%s", incl_files[i]);
719− if (--i < 0)
720− break;
721− rt_printf(", ");
722− }
723− rt_printf(")");
787+ pstrcpy(bi->file, sizeof bi->file, incl_files[--i]);
788+ bi->line = last_line_num;
724789 }
725−#endif
726− *prc = rc;
790+ pstrcpy(bi->func, sizeof bi->func, func_name);
791+ bi->func_pc = func_addr;
727792 return func_addr;
728793 }
729794
@@ -793,8 +858,7 @@ dwarf_read_sleb128(unsigned char **ln, unsigned char *end) · 63 unmodified lines
793858 return retval;
794859 }
795860
796−static addr_t rt_printline_dwarf (rt_context *rc, addr_t wanted_pc,
797− rt_context** prc, const char *msg, const char *skip)
861+static addr_t rt_printline_dwarf (rt_context *rc, addr_t wanted_pc, bt_info *bi)
798862 {
799863 unsigned char *ln;
800864 unsigned char *cp;
@@ -834,12 +898,10 @@ static addr_t rt_printline_dwarf (rt_context *rc, addr_t wanted_pc, · 33 unmodified lines
834898 char *filename;
835899 char *function;
836900
837−next:
838901 filename = NULL;
902+ function = NULL;
839903 func_addr = 0;
840904 line = 0;
841− if (NULL == rc)
842− goto found;
843905
844906 ln = rc->dwarf_line;
845907 while (ln < rc->dwarf_line_end) {
@@ -1070,44 +1132,28 @@ check_pc: · 224 unmodified lines
10701132 next_line:
10711133 ln = end;
10721134 }
1073−
1074− filename = NULL;
1075− func_addr = 0;
1076− /* we try symtab symbols (no line number info) */
1077− function = rt_elfsym(rc, wanted_pc, &func_addr);
1078− if (function)
1079− goto found;
1080− rc = rc->next;
1081− goto next;
1082−
1135+ filename = function = NULL, func_addr = 0;
10831136 found:
1084− if (rc && rc->s1 && rc->s1->bt_func) {
1085− rc->s1->bt_func((void*)wanted_pc, filename, line, function);
1086− } else {
1087− if (filename) {
1088− if (skip[0] && strstr(filename, skip))
1089− return (addr_t)-1;
1090− rt_printf("%s:%d: ", filename, line);
1091− }
1092− else
1093− rt_printf("0x%08llx : ", (long long)wanted_pc);
1094− rt_printf("%s %s", msg, function ? function : "???");
1095− }
1096− *prc = rc;
1137+ if (filename)
1138+ pstrcpy(bi->file, sizeof bi->file, filename), bi->line = line;
1139+ if (function)
1140+ pstrcpy(bi->func, sizeof bi->func, function);
1141+ bi->func_pc = func_addr;
10971142 return (addr_t)func_addr;
10981143 }
10991144 /* ------------------------------------------------------------- */
11001145 #ifndef CONFIG_TCC_BACKTRACE_ONLY
11011146 static
11021147 #endif
1103−int __rt_dump(rt_frame *f, const char *msg, const char *fmt, va_list ap)
1148+int _tcc_backtrace(rt_frame *f, const char *fmt, va_list ap)
11041149 {
1105− rt_context *rc, *rd;
1106− addr_t pc = 0;
1107− char skip[100];
1150+ rt_context *rc, *rc2;
1151+ addr_t pc;
1152+ char skip[40], msg[200];
11081153 int i, level, ret, n, one;
11091154 const char *a, *b;
1110− addr_t (*printline)(rt_context*, addr_t, rt_context**, const char*, const char*);
1155+ bt_info bi;
1156+ addr_t (*getinfo)(rt_context*, addr_t, bt_info*);
11111157
11121158 skip[0] = 0;
11131159 /* If fmt is like "^file.c^..." then skip calls from 'file.c' */
@@ -1119,41 +1165,73 @@ int __rt_dump(rt_frame *f, const char *msg, const char *fmt, va_list ap) · 5 unmodified lines
11191165 /* hack for bcheck.c:dprintf(): one level, no newline */
11201166 if (fmt[0] == '\001')
11211167 ++fmt, one = 1;
1168+ vsnprintf(msg, sizeof msg, fmt, ap);
11221169
11231170 rt_wait_sem();
11241171 rc = g_rc;
1125− printline = rt_printline, n = 6;
1172+ getinfo = rt_printline, n = 6;
11261173 if (rc) {
11271174 if (rc->dwarf)
1128− printline = rt_printline_dwarf;
1175+ getinfo = rt_printline_dwarf;
11291176 if (rc->num_callers)
11301177 n = rc->num_callers;
11311178 }
1179+
11321180 for (i = level = 0; level < n; i++) {
11331181 ret = rt_get_caller_pc(&pc, f, i);
1134− if (ret != -1) {
1135− pc = printline(rc, pc, &rd, level ? "by" : "at", skip);
1136− if (pc == (addr_t)-1)
1137− continue;
1182+ if (ret == -1)
1183+ break;
1184+ memset(&bi, 0, sizeof bi);
1185+ for (rc2 = rc; rc2; rc2 = rc2->next) {
1186+ if (getinfo(rc2, pc, &bi))
1187+ break;
1188+ /* we try symtab symbols (no line number info) */
1189+ if (!!(a = rt_elfsym(rc2, pc, &bi.func_pc))) {
1190+ pstrcpy(bi.func, sizeof bi.func, a);
1191+ break;
1192+ }
1193+ }
1194+ //fprintf(stderr, "%d rc %p %p\n", i, (void*)pcfunc, (void*)pc);
1195+ if (skip[0] && strstr(bi.file, skip))
1196+ continue;
1197+#ifndef CONFIG_TCC_BACKTRACE_ONLY
1198+ {
1199+ TCCState *s = rt_find_state(f);
1200+ if (s && s->bt_func) {
1201+ ret = s->bt_func(
1202+ s->bt_data,
1203+ (void*)pc,
1204+ bi.file[0] ? bi.file : NULL,
1205+ bi.line,
1206+ bi.func[0] ? bi.func : NULL,
1207+ level == 0 ? msg : NULL
1208+ );
1209+ if (ret == 0)
1210+ break;
1211+ goto check_break;
1212+ }
1213+ }
1214+#endif
1215+ if (bi.file[0]) {
1216+ rt_printf("%s:%d", bi.file, bi.line);
1217+ } else {
1218+ rt_printf("0x%08llx", (long long)pc);
11381219 }
1220+ rt_printf(": %s %s", level ? "by" : "at", bi.func[0] ? bi.func : "???");
11391221 if (level == 0) {
1140− if (rd && rd->s1 && rd->s1->bt_func)
1222+ rt_printf(": %s", msg);
1223+ if (one)
11411224 break;
1142− if (ret != -1)
1143− rt_printf(": ");
1144− if (msg)
1145− rt_printf("%s: ", msg);
1146− rt_vprintf(fmt, ap);
1147− } else if (ret == -1)
1148− break;
1149− if (one)
1150− break;
1225+ }
11511226 rt_printf("\n");
1152− if (ret == -1 || (rd && pc == (addr_t)rd->top_func && pc))
1227+
1228+ check_break:
1229+ if (rc2
1230+ && bi.func_pc
1231+ && bi.func_pc == (addr_t)rc2->top_func)
11531232 break;
11541233 ++level;
11551234 }
1156−
11571235 rt_post_sem();
11581236 return 0;
11591237 }
@@ -1161,49 +1239,14 @@ int __rt_dump(rt_frame *f, const char *msg, const char *fmt, va_list ap) · 1 unmodified line
11611239 /* emit a run time error at position 'pc' */
11621240 static int rt_error(rt_frame *f, const char *fmt, ...)
11631241 {
1164− va_list ap;
1165− int ret;
1242+ va_list ap; char msg[200]; int ret;
11661243 va_start(ap, fmt);
1167− ret = __rt_dump(f, "RUNTIME ERROR", fmt, ap);
1244+ snprintf(msg, sizeof msg, "RUNTIME ERROR: %s", fmt);
1245+ ret = _tcc_backtrace(f, msg, ap);
11681246 va_end(ap);
11691247 return ret;
11701248 }
11711249
1172−static TCCState *rt_find_state(rt_frame *f)
1173−{
1174− TCCState *s;
1175− int level;
1176− addr_t pc;
1177−
1178− rt_wait_sem();
1179− for (s = g_s1; s; s = s->next) {
1180− if (0 == s->run_lj)
1181− continue;
1182− for (level = 0; level < 8; ++level) {
1183− if (rt_get_caller_pc(&pc, f, level) < 0)
1184− break;
1185− if (pc >= (addr_t)s->run_ptr
1186− && pc < (addr_t)s->run_ptr + s->run_size)
1187− goto found;
1188− }
1189− }
1190−found:
1191− rt_post_sem();
1192− //fprintf(stderr, "\nrt_state found %s %p %p\n", s ? "YES" : "NO", s, s->rc->top_func), fflush(stderr);
1193− return s;
1194−}
1195−
1196−static void rt_longjmp(rt_frame *f, int code)
1197−{
1198− TCCState *s = rt_find_state(f);
1199− if (s && s->run_lj) {
1200− if (code == 0)
1201− code = 256;
1202− ((void(*)(void*,int))s->run_lj)(s->run_jb, code);
1203− }
1204− exit(code);
1205−}
1206−
12071250 /* ------------------------------------------------------------- */
12081251
12091252 #ifndef _WIN32
@@ -1338,8 +1381,13 @@ static void sig_error(int signum, siginfo_t *siginf, void *puc) · 128 unmodified lines
13381381 rt_error(&f, "caught signal %d", signum);
13391382 break;
13401383 }
1341− set_exception_handler();
1342− rt_longjmp(&f, 255);
1384+ {
1385+ sigset_t s;
1386+ sigemptyset(&s);
1387+ sigaddset(&s, signum);
1388+ sigprocmask(SIG_UNBLOCK, &s, NULL);
1389+ }
1390+ rt_exit(&f, 255);
13431391 }
13441392
13451393 #ifndef SA_SIGINFO
@@ -1353,12 +1401,11 @@ static void set_exception_handler(void) · 7 unmodified lines
13531401 /* install TCC signal handlers to print debug info on fatal
13541402 runtime errors */
13551403 sigemptyset (&sigact.sa_mask);
1356− sigact.sa_flags = SA_SIGINFO | SA_RESETHAND | SA_NODEFER;
1404+ sigact.sa_flags = SA_SIGINFO; //| SA_RESETHAND;
13571405 #if 0//def SIGSTKSZ // this causes signals not to work at all on some (older) linuxes
13581406 sigact.sa_flags |= SA_ONSTACK;
13591407 #endif
13601408 sigact.sa_sigaction = sig_error;
1361− sigemptyset(&sigact.sa_mask);
13621409 sigaction(SIGFPE, &sigact, NULL);
13631410 sigaction(SIGILL, &sigact, NULL);
13641411 sigaction(SIGSEGV, &sigact, NULL);
@@ -1406,7 +1453,7 @@ static long __stdcall cpu_exception_handler(EXCEPTION_POINTERS *ex_info) · 41 unmodified lines
14061453 rt_error(&f, "caught exception %08x", code);
14071454 break;
14081455 }
1409− rt_longjmp(&f, 255);
1456+ rt_exit(&f, 255);
14101457 return EXCEPTION_EXECUTE_HANDLER;
14111458 }
14121459
@@ -1506,6 +1553,14 @@ static int rt_get_caller_pc(addr_t *paddr, rt_frame *rc, int level) · 93 unmodified lines
15061553 }
15071554
15081555 #endif
1556+#else // for runmain.c:exit(); when CONFIG_TCC_BACKTRACE == 0 */
1557+static int rt_get_caller_pc(addr_t *paddr, rt_frame *f, int level)
1558+{
1559+ if (level)
1560+ return -1;
1561+ *paddr = f->ip;
1562+ return 0;
1563+}
15091564 #endif /* CONFIG_TCC_BACKTRACE */
15101565 /* ------------------------------------------------------------- */
15111566 #ifdef CONFIG_TCC_STATIC
tests/Makefile+3−1
@@ -26,7 +26,9 @@ TESTS = \ · 25 unmodified lines
2626 # test4_static -- Not all relocation types are implemented yet.
2727 # asmtest / asmtest2 -- minor differences with gcc
2828
29−ifneq ($(CONFIG_bcheck),no)
29+ifeq ($(CONFIG_backtrace),no)
30+ TESTS := $(filter-out libtest_mt, $(TESTS))
31+else ifneq ($(CONFIG_bcheck),no)
3032 TESTS += btest test1b tccb
3133 endif
3234 ifeq ($(CONFIG_dll),no)
tests/libtcc_test_mt.c+36−12
@@ -83,11 +83,13 @@ PROG(my_program) · 82 unmodified lines
8383 " return add(fib(n-1),fib(n-2));\n"
8484 "}\n"
8585 "\n"
86+"void bar(void) { *(void**)0 = 0; }\n"
87+"\n"
8688 "int foo(int n)\n"
8789 "{\n"
88−" if (n >= N_CRASH && n < N_CRASH + 3)\n"
89−" *(void**)0 = 0;\n"
9090 " printf(\" %d\", fib(n));\n"
91+" if (n >= N_CRASH && n < N_CRASH + 8)\n"
92+" bar();\n"
9193 " return 0;\n"
9294 "# warning is this the correct file:line...\n"
9395 "}\n";
@@ -113,9 +115,27 @@ void parse_args(TCCState *s) · 19 unmodified lines
113115 }
114116 }
115117
116−void bt_func(void *pc, const char *file, int line, const char *func)
118+int backtrace_func(
119+ void *ud,
120+ void *pc,
121+ const char *file,
122+ int line,
123+ const char *func,
124+ const char *msg)
117125 {
118− printf(" *** at %s:%d in '%s'\n", file, line, func);
126+#if 0
127+ printf("\n *** %p %s %s:%d in '%s'",
128+ pc,
129+ msg ? "at" : "by",
130+ file ? file : "?",
131+ line,
132+ func ? func : "?");
133+ return 1; // want more backtrace levels
134+#else
135+ //printf(" [%d]", *(int*)ud);
136+ printf("!");
137+ return 0; // cancel backtrace
138+#endif
119139 }
120140
121141 TCCState *new_state(int w)
@@ -132,9 +152,8 @@ TCCState *new_state(int w) · 10 unmodified lines
132152 if (w & 2) {
133153 tcc_set_options(s, "-bt");
134154 tcc_define_symbol(s, "N_CRASH", str(M/2));
135− tcc_set_backtrace_func(s, bt_func);
136155 } else
137− tcc_define_symbol(s, "N_CRASH", "99");
156+ tcc_define_symbol(s, "N_CRASH", "-1000");
138157 tcc_set_output_type(s, TCC_OUTPUT_MEMORY);
139158 return s;
140159 }
@@ -171,8 +190,7 @@ int state_test(int w) · 30 unmodified lines
171190 if (c < M)
172191 funcs[c] = reloc_state(s[c], "foo");
173192 if (d < M && funcs[d]) {
174− if ((w & 2) && d == 8)
175− printf("\n");
193+ tcc_set_backtrace_func(s[d], &d, backtrace_func);
176194 if (0 == tcc_setjmp(s[d], jb, funcs[d]))
177195 funcs[d](F(d));
178196 }
@@ -189,15 +207,19 @@ TF_TYPE(thread_test_simple, vn) · 10 unmodified lines
189207 int (*func)(int);
190208 int ret;
191209 int n = (size_t)vn;
210+ jmp_buf jb;
192211
193− s = new_state(0);
212+ s = new_state(0); /* '2' for exceptions */
194213 sleep_ms(1);
195214 ret = tcc_compile_string(s, my_program);
196215 sleep_ms(1);
197216 if (ret >= 0) {
198217 func = reloc_state(s, "foo");
199− if (func)
200− func(F(n));
218+ tcc_set_backtrace_func(s, &n, backtrace_func);
219+ if (func) {
220+ if (0 == tcc_setjmp(s, jb, func))
221+ func(F(n));
222+ }
201223 }
202224 tcc_delete(s);
203225 return 0;
@@ -281,18 +303,20 @@ int main(int argc, char **argv) · 77 unmodified lines
281303 printf("\n (%u ms)\n", getclock_ms() - t);
282304 #endif
283305 #if 1
284− printf("producing some exceptions\n "), fflush(stdout);
306+ printf("producing some exceptions (!)\n "), fflush(stdout);
285307 t = getclock_ms();
286308 state_test(2);
287309 printf("\n (%u ms)\n", getclock_ms() - t);
288310 #endif
289311 #if 1
312+ //{ int i; for (i = 0; i < 100; ++i) { printf("(%d) ", i);
290313 printf("running fib in threads\n "), fflush(stdout);
291314 t = getclock_ms();
292315 for (n = 0; n < M; ++n)
293316 create_thread(thread_test_simple, n);
294317 wait_threads(n);
295318 printf("\n (%u ms)\n", getclock_ms() - t);
319+ //}}
296320 #endif
297321 #if 1
298322 printf("running tcc.c in threads to run fib\n "), fflush(stdout);
tests/tcctest.c+1−1
@@ -3889,7 +3889,7 @@ static void builtin_test_bits(unsigned long long x, int cnt[]) · 3888 unmodified lines
38893889 if ((unsigned long) x) cnt[7] += __builtin_ctzl(x);
38903890 if ((unsigned long long) x) cnt[8] += __builtin_ctzll(x);
38913891
3892−#if CC_NAME != CC_clang || GCC_MAJOR >= 11
3892+#if GCC_MAJOR >= 6 && (CC_NAME != CC_clang || GCC_MAJOR >= 11)
38933893 /* Apple clang 10 does not have __builtin_clrsb[l[l]] */
38943894 cnt[9] += __builtin_clrsb(x);
38953895 cnt[10] += __builtin_clrsbl(x);
win32/build-tcc.bat+1−0
@@ -202,4 +202,5 @@ exit /B %ERRORLEVEL% · 201 unmodified lines
202202 .\tcc -B. -m%1 -c ../lib/bt-exe.c -o lib/%2bt-exe.o
203203 .\tcc -B. -m%1 -c ../lib/bt-log.c -o lib/%2bt-log.o
204204 .\tcc -B. -m%1 -c ../lib/bt-dll.c -o lib/%2bt-dll.o
205+.\tcc -B. -m%1 -c ../lib/runmain.c -o lib/%2runmain.o
205206 exit /B %ERRORLEVEL%
win32/include/malloc.h+2−2
@@ -62,8 +62,8 @@ extern "C" { · 61 unmodified lines
6262 void *__cdecl malloc(size_t _Size);
6363 void *__cdecl realloc(void *_Memory,size_t _NewSize);
6464 _CRTIMP void *__cdecl _recalloc(void *_Memory,size_t _Count,size_t _Size);
65− /* _CRTIMP void __cdecl _aligned_free(void *_Memory);
66− _CRTIMP void *__cdecl _aligned_malloc(size_t _Size,size_t _Alignment); */
65+ _CRTIMP void __cdecl _aligned_free(void *_Memory);
66+ _CRTIMP void *__cdecl _aligned_malloc(size_t _Size,size_t _Alignment);
6767 _CRTIMP void *__cdecl _aligned_offset_malloc(size_t _Size,size_t _Alignment,size_t _Offset);
6868 _CRTIMP void *__cdecl _aligned_realloc(void *_Memory,size_t _Size,size_t _Alignment);
6969 _CRTIMP void *__cdecl _aligned_recalloc(void *_Memory,size_t _Count,size_t _Size,size_t _Alignment);
win32/include/stdlib.h+2−2
@@ -403,8 +403,8 @@ extern "C" { · 402 unmodified lines
403403 void *__cdecl malloc(size_t _Size);
404404 void *__cdecl realloc(void *_Memory,size_t _NewSize);
405405 _CRTIMP void *__cdecl _recalloc(void *_Memory,size_t _Count,size_t _Size);
406− //_CRTIMP void __cdecl _aligned_free(void *_Memory);
407− //_CRTIMP void *__cdecl _aligned_malloc(size_t _Size,size_t _Alignment);
406+ _CRTIMP void __cdecl _aligned_free(void *_Memory);
407+ _CRTIMP void *__cdecl _aligned_malloc(size_t _Size,size_t _Alignment);
408408 _CRTIMP void *__cdecl _aligned_offset_malloc(size_t _Size,size_t _Alignment,size_t _Offset);
409409 _CRTIMP void *__cdecl _aligned_realloc(void *_Memory,size_t _Size,size_t _Alignment);
410410 _CRTIMP void *__cdecl _aligned_recalloc(void *_Memory,size_t _Count,size_t _Size,size_t _Alignment);
win32/lib/crt1.c+0−2
@@ -70,7 +70,6 @@ void _tstart(void) · 69 unmodified lines
7070 // =============================================
7171 // for 'tcc -run ,,,'
7272
73−__attribute__((weak)) extern int __rt_nr_exit;
7473 __attribute__((weak)) extern int __run_on_exit();
7574
7675 int _runtmain(int argc, /* as tcc passed in */ char **argv)
@@ -92,7 +91,6 @@ int _runtmain(int argc, /* as tcc passed in */ char **argv) · 15 unmodified lines
9291 #if defined __i386__ || defined __x86_64__
9392 _controlfp(_PC_53, _MCW_PC);
9493 #endif
95− __rt_nr_exit = 0;
9694 run_ctors(__argc, __targv, _tenviron);
9795 ret = _tmain(__argc, __targv, _tenviron);
9896 run_dtors();

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t