From 039e4ec2a4fd22cd5e94d5ccc33dc00c1a8c143e Mon Sep 17 00:00:00 2001 From: herman ten brugge Date: Mon, 22 Jun 2020 14:55:27 +0200 Subject: [PATCH] Call __bound_main_arg at startup This uses a glibc feature present since constructor/destructor support was added. Modify tccrun.c to call constructor with argc, argcv, envp. In lib/bcheck.c use these values to register them in the splay tree. Remove HAS_ENVIRON is lib/bcheck.c as it is not needed any more. Modify win32/lib/crt1.c/win32/lib/dllcrt1.c/win32/lib/wincrt1.c to also call constructor with argc, argcv, envp. While implementing I saw that tccrun did nog call main with envp. Fixed it. Also fix fetch_and_add_arm.S to make it work on armv6 (raspberry pi default). --- lib/bcheck.c | 73 +++++++++++++++++++---------------------- lib/fetch_and_add_arm.S | 10 +++--- tccrun.c | 13 ++++---- win32/lib/crt1.c | 10 ++++-- win32/lib/dllcrt1.c | 6 ++-- win32/lib/wincrt1.c | 10 ++++-- 6 files changed, 62 insertions(+), 60 deletions(-) diff --git a/lib/bcheck.c b/lib/bcheck.c index ec861df9..8d2614f4 100644 --- a/lib/bcheck.c +++ b/lib/bcheck.c @@ -70,7 +70,6 @@ #define WAIT_SEM() #define POST_SEM() #define HAVE_MEMALIGN (0) -#define HAS_ENVIRON (0) #define MALLOC_REDIR (0) #define HAVE_PTHREAD_CREATE (0) #define HAVE_CTYPE (0) @@ -85,7 +84,6 @@ static CRITICAL_SECTION bounds_sem; #define WAIT_SEM() EnterCriticalSection(&bounds_sem) #define POST_SEM() LeaveCriticalSection(&bounds_sem) #define HAVE_MEMALIGN (0) -#define HAS_ENVIRON (0) #define MALLOC_REDIR (0) #define HAVE_PTHREAD_CREATE (0) #define HAVE_CTYPE (0) @@ -123,7 +121,6 @@ static pthread_spinlock_t bounds_spin; #define POST_SEM() if (use_sem) pthread_spin_unlock (&bounds_spin) #endif #define HAVE_MEMALIGN (1) -#define HAS_ENVIRON (1) #define MALLOC_REDIR (1) #define HAVE_PTHREAD_CREATE (1) #define HAVE_CTYPE (1) @@ -207,7 +204,7 @@ DLL_EXPORT void * __bound_ptr_indir16(void *p, size_t offset); DLL_EXPORT void FASTCALL __bound_local_new(void *p1); DLL_EXPORT void FASTCALL __bound_local_delete(void *p1); void __bound_init(size_t *, int); -void __bound_main_arg(char **p); +void __bound_main_arg(int argc, char **argv, char **envp); void __bound_exit(void); #if !defined(_WIN32) void *__bound_mmap (void *start, size_t size, int prot, int flags, int fd, @@ -934,61 +931,57 @@ no_bounds: dprintf(stderr, "%s, %s(): end\n\n", __FILE__, __FUNCTION__); } -void __bound_main_arg(char **p) -{ - char *start = (char *) p; - - WAIT_SEM (); - while (*p) { - tree = splay_insert((size_t) *p, strlen (*p) + 1, tree); - ++p; - } - tree = splay_insert((size_t) start, (char *) p - start, tree); - POST_SEM (); -#if BOUND_DEBUG - if (print_calls) { - p = (char **) start; - while (*p) { - dprintf(stderr, "%s, %s(): %p 0x%lx\n", - __FILE__, __FUNCTION__, - *p, (unsigned long)(strlen (*p) + 1)); - ++p; - } - dprintf(stderr, "%s, %s(): argv %p 0x%lx\n", - __FILE__, __FUNCTION__, - start, (unsigned long)((char *) p - start)); - } +void +#if (defined(__GLIBC__) && (__GLIBC_MINOR__ >= 4)) || defined(_WIN32) +__attribute__((constructor)) #endif - -#if HAS_ENVIRON - { - extern char **environ; +__bound_main_arg(int argc, char **argv, char **envp) +{ + __bound_init (0, -1); + if (argc && argv) { + int i; + + WAIT_SEM (); + for (i = 0; i < argc; i++) + tree = splay_insert((size_t) argv[i], strlen (argv[i]) + 1, tree); + tree = splay_insert((size_t) argv, argc * sizeof(char *), tree); + POST_SEM (); +#if BOUND_DEBUG + if (print_calls) { + for (i = 0; i < argc; i++) + dprintf(stderr, "%s, %s(): arg %p 0x%lx\n", + __FILE__, __FUNCTION__, + argv[i], (unsigned long)(strlen (argv[i]) + 1)); + dprintf(stderr, "%s, %s(): argv %p 0x%lx\n", + __FILE__, __FUNCTION__, argv, argc * sizeof(char *)); + } +#endif + } + + if (envp && *envp) { + char **p = envp; WAIT_SEM (); - p = environ; - start = (char *) p; while (*p) { tree = splay_insert((size_t) *p, strlen (*p) + 1, tree); ++p; } - tree = splay_insert((size_t) start, (char *) p - start, tree); + tree = splay_insert((size_t) envp, p - envp, tree); POST_SEM (); #if BOUND_DEBUG if (print_calls) { - p = environ; + p = envp; while (*p) { - dprintf(stderr, "%s, %s(): %p 0x%lx\n", + dprintf(stderr, "%s, %s(): env %p 0x%lx\n", __FILE__, __FUNCTION__, *p, (unsigned long)(strlen (*p) + 1)); ++p; } dprintf(stderr, "%s, %s(): environ %p 0x%lx\n", - __FILE__, __FUNCTION__, - start, (unsigned long)((char *) p - start)); + __FILE__, __FUNCTION__, envp, p - envp); } #endif } -#endif } void __attribute__((destructor)) __bound_exit(void) diff --git a/lib/fetch_and_add_arm.S b/lib/fetch_and_add_arm.S index 2fec2c54..773128b1 100644 --- a/lib/fetch_and_add_arm.S +++ b/lib/fetch_and_add_arm.S @@ -4,25 +4,25 @@ .type fetch_and_add_arm, %function fetch_and_add_arm: #ifdef __TINYC__ - .int 0xf57ff05b + .int 0xee070fba .int 0xe1903f9f .int 0xe0833001 .int 0xe1802f93 .int 0xe3520000 .int 0x1afffffa - .int 0xf57ff05b + .int 0xee070fba .int 0xe12fff1e #else - .arch armv7-a + .arch armv6 - dmb ish + mcr p15, 0, r0, c7, c10, 5 .L0: ldrex r3, [r0] add r3, r3, r1 strex r2, r3, [r0] cmp r2, #0 bne .L0 - dmb ish + mcr p15, 0, r0, c7, c10, 5 bx lr #endif .size fetch_and_add_arm, .-fetch_and_add_arm diff --git a/tccrun.c b/tccrun.c index d0379c9b..dd6e37ff 100644 --- a/tccrun.c +++ b/tccrun.c @@ -124,18 +124,19 @@ ST_FUNC void tcc_run_free(TCCState *s1) tcc_free(s1->runtime_mem); } -static void run_cdtors(TCCState *s1, const char *start, const char *end) +static void run_cdtors(TCCState *s1, const char *start, const char *end, + int argc, char **argv, char **envp) { void **a = (void **)get_sym_addr(s1, start, 0, 0); void **b = (void **)get_sym_addr(s1, end, 0, 0); while (a != b) - ((void(*)(void))*a++)(); + ((void(*)(int, char **, char **))*a++)(argc, argv, envp); } /* launch the compiled program with the given arguments */ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv) { - int (*prog_main)(int, char **), ret; + int (*prog_main)(int, char **, char **), ret; #ifdef CONFIG_TCC_BACKTRACE rt_context *rc = &g_rtctxt; #endif @@ -183,14 +184,14 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv) fflush(stdout); fflush(stderr); /* These aren't C symbols, so don't need leading underscore handling. */ - run_cdtors(s1, "__init_array_start", "__init_array_end"); + run_cdtors(s1, "__init_array_start", "__init_array_end", argc, argv, environ); #ifdef CONFIG_TCC_BACKTRACE if (!rc->do_jmp || !(ret = setjmp(rc->jmp_buf))) #endif { - ret = prog_main(argc, argv); + ret = prog_main(argc, argv, environ); } - run_cdtors(s1, "__fini_array_start", "__fini_array_end"); + run_cdtors(s1, "__fini_array_start", "__fini_array_end", 0, NULL, NULL); if ((s1->dflag & 16) && ret) fprintf(s1->ppfp, "[returns %d]\n", ret), fflush(s1->ppfp); return ret; diff --git a/win32/lib/crt1.c b/win32/lib/crt1.c index abe31b9b..96dcb0ec 100644 --- a/win32/lib/crt1.c +++ b/win32/lib/crt1.c @@ -34,8 +34,8 @@ int __cdecl __tgetmainargs(int *pargc, _TCHAR ***pargv, _TCHAR ***penv, int glob void __cdecl __set_app_type(int apptype); unsigned int __cdecl _controlfp(unsigned int new_value, unsigned int mask); extern int _tmain(int argc, _TCHAR * argv[], _TCHAR * env[]); -extern void (*__init_array_start[]) (void); -extern void (*__init_array_end[]) (void); +extern void (*__init_array_start[]) (int argc, char **argv, char **envp); +extern void (*__init_array_end[]) (int argc, char **argv, char **envp); extern void (*__fini_array_start[]) (void); extern void (*__fini_array_end[]) (void); @@ -46,7 +46,11 @@ static int do_main (int argc, _TCHAR * argv[], _TCHAR * env[]) i = 0; while (&__init_array_start[i] != __init_array_end) { - (*__init_array_start[i++])(); +#ifdef UNICODE + (*__init_array_start[i++])(0, NULL, NULL); +#else + (*__init_array_start[i++])(argc, argv, env); +#endif } retval = _tmain(__argc, __targv, _tenviron); i = 0; diff --git a/win32/lib/dllcrt1.c b/win32/lib/dllcrt1.c index 7c9be14a..c92cf0fd 100644 --- a/win32/lib/dllcrt1.c +++ b/win32/lib/dllcrt1.c @@ -2,8 +2,8 @@ #include -extern void (*__init_array_start[]) (void); -extern void (*__init_array_end[]) (void); +extern void (*__init_array_start[]) (int argc, char **argv, char **envp); +extern void (*__init_array_end[]) (int argc, char **argv, char **envp); extern void (*__fini_array_start[]) (void); extern void (*__fini_array_end[]) (void); @@ -17,7 +17,7 @@ BOOL WINAPI _dllstart(HINSTANCE hDll, DWORD dwReason, LPVOID lpReserved) if (dwReason == DLL_PROCESS_ATTACH) { /* ignore DLL_THREAD_ATTACH */ i = 0; while (&__init_array_start[i] != __init_array_end) { - (*__init_array_start[i++])(); + (*__init_array_start[i++])(0, NULL, NULL); } } if (dwReason == DLL_PROCESS_DETACH) { /* ignore DLL_THREAD_DETACH */ diff --git a/win32/lib/wincrt1.c b/win32/lib/wincrt1.c index 95ed3df6..b294d9b0 100644 --- a/win32/lib/wincrt1.c +++ b/win32/lib/wincrt1.c @@ -23,8 +23,8 @@ int APIENTRY wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int); #define _runtwinmain _runwinmain #endif -extern void (*__init_array_start[]) (void); -extern void (*__init_array_end[]) (void); +extern void (*__init_array_start[]) (int argc, char **argv, char **envp); +extern void (*__init_array_end[]) (int argc, char **argv, char **envp); extern void (*__fini_array_start[]) (void); extern void (*__fini_array_end[]) (void); @@ -57,7 +57,11 @@ static int go_winmain(TCHAR *arg1) #endif i = 0; while (&__init_array_start[i] != __init_array_end) { - (*__init_array_start[i++])(); +#ifdef UNICODE + (*__init_array_start[i++])(0, NULL, NULL); +#else + (*__init_array_start[i++])(__argc, __targv, _tenviron); +#endif } retval = _tWinMain(GetModuleHandle(NULL), NULL, szCmd, fShow); i = 0;