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 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)

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -2,8 +2,8 @@
#include <windows.h>
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 */

View File

@ -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;