mirror of
https://github.com/mirror/tinycc.git
synced 2024-12-28 04:00:06 +08:00
ef42295fe8
This makes it possible to get backtraces with executables (including DLLs/SOs) like we had it already with -g -run. Option -b includes -bt, and -bt includes -g. - new file lib/bt-exe.c: used to link rt_printline and the exception handler from tccrun.c into executables/DLLs. - new file lib/bt-log.c: provides a function that may be called from user code to print out a backtrace with a message (currently for i386/x86_64 only): int (*tcc_backtrace)(const char *fmt, ...); As an extra hack, if 'fmt' is prefixed like "^file.c^..." then the backtrace will skip calls from within 'file.c'. - new file lib/bt-dll.c: used on win32 to link the backtrace and bcheck functions with the main module at runtime - bcheck.c: now uses the tcc_backtrace function from above - tccgen.c: minor cleanups - tccelf.c: stab sections get SHF_ALLOC for easy access. Also in relocate_section(): 64bit relocations for stabs in DLLs cannot work. To find DLL addresses, the DLL base is added manually in tccrun.c via rc.prog_base instead. - tccpe.c: there are some changes to allow merging sections, used to merge .finit_array into .data in the first place. - tccpp.c: tcc -run now #defines __TCC_RUN__ also: refactor a line in tal_realloc that was incompatible with bcheck - tcctest.c: fixed a problem with r12 which tcc cannot preserve as well as gcc does. - tests2/112_backtrace.c: test the feature and the bcheck test18 that previously was in boundtest.c
44 lines
1.2 KiB
C
44 lines
1.2 KiB
C
/* ------------------------------------------------------------- */
|
|
/* for linking rt_printline and the signal/exception handler
|
|
from tccrun.c into executables. */
|
|
|
|
#define CONFIG_TCC_BACKTRACE_ONLY
|
|
#include "../tccrun.c"
|
|
|
|
int (*__rt_error)(void*, void*, const char *, va_list);
|
|
|
|
#ifndef _WIN32
|
|
# define __declspec(n)
|
|
#endif
|
|
|
|
__declspec(dllexport)
|
|
void __bt_init(rt_context *p, int num_callers)
|
|
{
|
|
__attribute__((weak)) int main();
|
|
__attribute__((weak)) void __bound_init(void*);
|
|
struct rt_context *rc = &g_rtctxt;
|
|
//fprintf(stderr, "__bt_init %d %p %p\n", num_callers, p->stab_sym, p->bounds_start), fflush(stderr);
|
|
if (num_callers) {
|
|
memcpy(rc, p, offsetof(rt_context, next));
|
|
rc->num_callers = num_callers - 1;
|
|
rc->top_func = main;
|
|
__rt_error = _rt_error;
|
|
set_exception_handler();
|
|
} else {
|
|
p->next = rc->next, rc->next = p;
|
|
}
|
|
if (__bound_init && p->bounds_start)
|
|
__bound_init(p->bounds_start);
|
|
}
|
|
|
|
/* copy a string and truncate it. */
|
|
static char *pstrcpy(char *buf, size_t buf_size, const char *s)
|
|
{
|
|
int l = strlen(s);
|
|
if (l >= buf_size)
|
|
l = buf_size - 1;
|
|
memcpy(buf, s, l);
|
|
buf[l] = 0;
|
|
return buf;
|
|
}
|