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).
This commit is contained in:
herman ten brugge 2020-06-22 14:55:27 +02:00
parent 0262f0eb1e
commit 039e4ec2a4
6 changed files with 62 additions and 60 deletions

View file

@ -70,7 +70,6 @@
#define WAIT_SEM() #define WAIT_SEM()
#define POST_SEM() #define POST_SEM()
#define HAVE_MEMALIGN (0) #define HAVE_MEMALIGN (0)
#define HAS_ENVIRON (0)
#define MALLOC_REDIR (0) #define MALLOC_REDIR (0)
#define HAVE_PTHREAD_CREATE (0) #define HAVE_PTHREAD_CREATE (0)
#define HAVE_CTYPE (0) #define HAVE_CTYPE (0)
@ -85,7 +84,6 @@ static CRITICAL_SECTION bounds_sem;
#define WAIT_SEM() EnterCriticalSection(&bounds_sem) #define WAIT_SEM() EnterCriticalSection(&bounds_sem)
#define POST_SEM() LeaveCriticalSection(&bounds_sem) #define POST_SEM() LeaveCriticalSection(&bounds_sem)
#define HAVE_MEMALIGN (0) #define HAVE_MEMALIGN (0)
#define HAS_ENVIRON (0)
#define MALLOC_REDIR (0) #define MALLOC_REDIR (0)
#define HAVE_PTHREAD_CREATE (0) #define HAVE_PTHREAD_CREATE (0)
#define HAVE_CTYPE (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) #define POST_SEM() if (use_sem) pthread_spin_unlock (&bounds_spin)
#endif #endif
#define HAVE_MEMALIGN (1) #define HAVE_MEMALIGN (1)
#define HAS_ENVIRON (1)
#define MALLOC_REDIR (1) #define MALLOC_REDIR (1)
#define HAVE_PTHREAD_CREATE (1) #define HAVE_PTHREAD_CREATE (1)
#define HAVE_CTYPE (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_new(void *p1);
DLL_EXPORT void FASTCALL __bound_local_delete(void *p1); DLL_EXPORT void FASTCALL __bound_local_delete(void *p1);
void __bound_init(size_t *, int); 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); void __bound_exit(void);
#if !defined(_WIN32) #if !defined(_WIN32)
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,
@ -934,61 +931,57 @@ no_bounds:
dprintf(stderr, "%s, %s(): end\n\n", __FILE__, __FUNCTION__); dprintf(stderr, "%s, %s(): end\n\n", __FILE__, __FUNCTION__);
} }
void __bound_main_arg(char **p) void
#if (defined(__GLIBC__) && (__GLIBC_MINOR__ >= 4)) || defined(_WIN32)
__attribute__((constructor))
#endif
__bound_main_arg(int argc, char **argv, char **envp)
{ {
char *start = (char *) p; __bound_init (0, -1);
if (argc && argv) {
int i;
WAIT_SEM (); WAIT_SEM ();
while (*p) { for (i = 0; i < argc; i++)
tree = splay_insert((size_t) *p, strlen (*p) + 1, tree); tree = splay_insert((size_t) argv[i], strlen (argv[i]) + 1, tree);
++p; tree = splay_insert((size_t) argv, argc * sizeof(char *), tree);
}
tree = splay_insert((size_t) start, (char *) p - start, tree);
POST_SEM (); POST_SEM ();
#if BOUND_DEBUG #if BOUND_DEBUG
if (print_calls) { if (print_calls) {
p = (char **) start; for (i = 0; i < argc; i++)
while (*p) { dprintf(stderr, "%s, %s(): arg %p 0x%lx\n",
dprintf(stderr, "%s, %s(): %p 0x%lx\n",
__FILE__, __FUNCTION__, __FILE__, __FUNCTION__,
*p, (unsigned long)(strlen (*p) + 1)); argv[i], (unsigned long)(strlen (argv[i]) + 1));
++p;
}
dprintf(stderr, "%s, %s(): argv %p 0x%lx\n", dprintf(stderr, "%s, %s(): argv %p 0x%lx\n",
__FILE__, __FUNCTION__, __FILE__, __FUNCTION__, argv, argc * sizeof(char *));
start, (unsigned long)((char *) p - start));
} }
#endif #endif
}
#if HAS_ENVIRON if (envp && *envp) {
{ char **p = envp;
extern char **environ;
WAIT_SEM (); WAIT_SEM ();
p = environ;
start = (char *) p;
while (*p) { while (*p) {
tree = splay_insert((size_t) *p, strlen (*p) + 1, tree); tree = splay_insert((size_t) *p, strlen (*p) + 1, tree);
++p; ++p;
} }
tree = splay_insert((size_t) start, (char *) p - start, tree); tree = splay_insert((size_t) envp, p - envp, tree);
POST_SEM (); POST_SEM ();
#if BOUND_DEBUG #if BOUND_DEBUG
if (print_calls) { if (print_calls) {
p = environ; p = envp;
while (*p) { while (*p) {
dprintf(stderr, "%s, %s(): %p 0x%lx\n", dprintf(stderr, "%s, %s(): env %p 0x%lx\n",
__FILE__, __FUNCTION__, __FILE__, __FUNCTION__,
*p, (unsigned long)(strlen (*p) + 1)); *p, (unsigned long)(strlen (*p) + 1));
++p; ++p;
} }
dprintf(stderr, "%s, %s(): environ %p 0x%lx\n", dprintf(stderr, "%s, %s(): environ %p 0x%lx\n",
__FILE__, __FUNCTION__, __FILE__, __FUNCTION__, envp, p - envp);
start, (unsigned long)((char *) p - start));
} }
#endif #endif
} }
#endif
} }
void __attribute__((destructor)) __bound_exit(void) void __attribute__((destructor)) __bound_exit(void)

View file

@ -4,25 +4,25 @@
.type fetch_and_add_arm, %function .type fetch_and_add_arm, %function
fetch_and_add_arm: fetch_and_add_arm:
#ifdef __TINYC__ #ifdef __TINYC__
.int 0xf57ff05b .int 0xee070fba
.int 0xe1903f9f .int 0xe1903f9f
.int 0xe0833001 .int 0xe0833001
.int 0xe1802f93 .int 0xe1802f93
.int 0xe3520000 .int 0xe3520000
.int 0x1afffffa .int 0x1afffffa
.int 0xf57ff05b .int 0xee070fba
.int 0xe12fff1e .int 0xe12fff1e
#else #else
.arch armv7-a .arch armv6
dmb ish mcr p15, 0, r0, c7, c10, 5
.L0: .L0:
ldrex r3, [r0] ldrex r3, [r0]
add r3, r3, r1 add r3, r3, r1
strex r2, r3, [r0] strex r2, r3, [r0]
cmp r2, #0 cmp r2, #0
bne .L0 bne .L0
dmb ish mcr p15, 0, r0, c7, c10, 5
bx lr bx lr
#endif #endif
.size fetch_and_add_arm, .-fetch_and_add_arm .size fetch_and_add_arm, .-fetch_and_add_arm

View file

@ -124,18 +124,19 @@ ST_FUNC void tcc_run_free(TCCState *s1)
tcc_free(s1->runtime_mem); 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 **a = (void **)get_sym_addr(s1, start, 0, 0);
void **b = (void **)get_sym_addr(s1, end, 0, 0); void **b = (void **)get_sym_addr(s1, end, 0, 0);
while (a != b) while (a != b)
((void(*)(void))*a++)(); ((void(*)(int, char **, char **))*a++)(argc, argv, envp);
} }
/* launch the compiled program with the given arguments */ /* launch the compiled program with the given arguments */
LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv) 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 #ifdef CONFIG_TCC_BACKTRACE
rt_context *rc = &g_rtctxt; rt_context *rc = &g_rtctxt;
#endif #endif
@ -183,14 +184,14 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv)
fflush(stdout); fflush(stdout);
fflush(stderr); fflush(stderr);
/* These aren't C symbols, so don't need leading underscore handling. */ /* 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 #ifdef CONFIG_TCC_BACKTRACE
if (!rc->do_jmp || !(ret = setjmp(rc->jmp_buf))) if (!rc->do_jmp || !(ret = setjmp(rc->jmp_buf)))
#endif #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) if ((s1->dflag & 16) && ret)
fprintf(s1->ppfp, "[returns %d]\n", ret), fflush(s1->ppfp); fprintf(s1->ppfp, "[returns %d]\n", ret), fflush(s1->ppfp);
return ret; return ret;

View file

@ -34,8 +34,8 @@ int __cdecl __tgetmainargs(int *pargc, _TCHAR ***pargv, _TCHAR ***penv, int glob
void __cdecl __set_app_type(int apptype); void __cdecl __set_app_type(int apptype);
unsigned int __cdecl _controlfp(unsigned int new_value, unsigned int mask); unsigned int __cdecl _controlfp(unsigned int new_value, unsigned int mask);
extern int _tmain(int argc, _TCHAR * argv[], _TCHAR * env[]); extern int _tmain(int argc, _TCHAR * argv[], _TCHAR * env[]);
extern void (*__init_array_start[]) (void); extern void (*__init_array_start[]) (int argc, char **argv, char **envp);
extern void (*__init_array_end[]) (void); extern void (*__init_array_end[]) (int argc, char **argv, char **envp);
extern void (*__fini_array_start[]) (void); extern void (*__fini_array_start[]) (void);
extern void (*__fini_array_end[]) (void); extern void (*__fini_array_end[]) (void);
@ -46,7 +46,11 @@ static int do_main (int argc, _TCHAR * argv[], _TCHAR * env[])
i = 0; i = 0;
while (&__init_array_start[i] != __init_array_end) { 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); retval = _tmain(__argc, __targv, _tenviron);
i = 0; i = 0;

View file

@ -2,8 +2,8 @@
#include <windows.h> #include <windows.h>
extern void (*__init_array_start[]) (void); extern void (*__init_array_start[]) (int argc, char **argv, char **envp);
extern void (*__init_array_end[]) (void); extern void (*__init_array_end[]) (int argc, char **argv, char **envp);
extern void (*__fini_array_start[]) (void); extern void (*__fini_array_start[]) (void);
extern void (*__fini_array_end[]) (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 */ if (dwReason == DLL_PROCESS_ATTACH) { /* ignore DLL_THREAD_ATTACH */
i = 0; i = 0;
while (&__init_array_start[i] != __init_array_end) { 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 */ if (dwReason == DLL_PROCESS_DETACH) { /* ignore DLL_THREAD_DETACH */

View file

@ -23,8 +23,8 @@ int APIENTRY wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int);
#define _runtwinmain _runwinmain #define _runtwinmain _runwinmain
#endif #endif
extern void (*__init_array_start[]) (void); extern void (*__init_array_start[]) (int argc, char **argv, char **envp);
extern void (*__init_array_end[]) (void); extern void (*__init_array_end[]) (int argc, char **argv, char **envp);
extern void (*__fini_array_start[]) (void); extern void (*__fini_array_start[]) (void);
extern void (*__fini_array_end[]) (void); extern void (*__fini_array_end[]) (void);
@ -57,7 +57,11 @@ static int go_winmain(TCHAR *arg1)
#endif #endif
i = 0; i = 0;
while (&__init_array_start[i] != __init_array_end) { 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); retval = _tWinMain(GetModuleHandle(NULL), NULL, szCmd, fShow);
i = 0; i = 0;