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).
Unified · Split
| @@ -70,7 +70,6 @@ · 69 unmodified lines | ||
| 70 | 70 | #define WAIT_SEM() |
| 71 | 71 | #define POST_SEM() |
| 72 | 72 | #define HAVE_MEMALIGN (0) |
| 73 | −#define HAS_ENVIRON (0) | |
| 74 | 73 | #define MALLOC_REDIR (0) |
| 75 | 74 | #define HAVE_PTHREAD_CREATE (0) |
| 76 | 75 | #define HAVE_CTYPE (0) |
| @@ -85,7 +84,6 @@ static CRITICAL_SECTION bounds_sem; · 8 unmodified lines | ||
| 85 | 84 | #define WAIT_SEM() EnterCriticalSection(&bounds_sem) |
| 86 | 85 | #define POST_SEM() LeaveCriticalSection(&bounds_sem) |
| 87 | 86 | #define HAVE_MEMALIGN (0) |
| 88 | −#define HAS_ENVIRON (0) | |
| 89 | 87 | #define MALLOC_REDIR (0) |
| 90 | 88 | #define HAVE_PTHREAD_CREATE (0) |
| 91 | 89 | #define HAVE_CTYPE (0) |
| @@ -123,7 +121,6 @@ static pthread_spinlock_t bounds_spin; · 31 unmodified lines | ||
| 123 | 121 | #define POST_SEM() if (use_sem) pthread_spin_unlock (&bounds_spin) |
| 124 | 122 | #endif |
| 125 | 123 | #define HAVE_MEMALIGN (1) |
| 126 | −#define HAS_ENVIRON (1) | |
| 127 | 124 | #define MALLOC_REDIR (1) |
| 128 | 125 | #define HAVE_PTHREAD_CREATE (1) |
| 129 | 126 | #define HAVE_CTYPE (1) |
| @@ -207,7 +204,7 @@ DLL_EXPORT void * __bound_ptr_indir16(void *p, size_t offset); · 77 unmodified lines | ||
| 207 | 204 | DLL_EXPORT void FASTCALL __bound_local_new(void *p1); |
| 208 | 205 | DLL_EXPORT void FASTCALL __bound_local_delete(void *p1); |
| 209 | 206 | void __bound_init(size_t *, int); |
| 210 | −void __bound_main_arg(char **p); | |
| 207 | +void __bound_main_arg(int argc, char **argv, char **envp); | |
| 211 | 208 | void __bound_exit(void); |
| 212 | 209 | #if !defined(_WIN32) |
| 213 | 210 | void *__bound_mmap (void *start, size_t size, int prot, int flags, int fd, |
| @@ -934,61 +931,57 @@ no_bounds: · 720 unmodified lines | ||
| 934 | 931 | dprintf(stderr, "%s, %s(): end\n\n", __FILE__, __FUNCTION__); |
| 935 | 932 | } |
| 936 | 933 | |
| 937 | −void __bound_main_arg(char **p) | |
| 934 | +void | |
| 935 | +#if (defined(__GLIBC__) && (__GLIBC_MINOR__ >= 4)) || defined(_WIN32) | |
| 936 | +__attribute__((constructor)) | |
| 937 | +#endif | |
| 938 | +__bound_main_arg(int argc, char **argv, char **envp) | |
| 938 | 939 | { |
| 939 | − char *start = (char *) p; | |
| 940 | + __bound_init (0, -1); | |
| 941 | + if (argc && argv) { | |
| 942 | + int i; | |
| 940 | 943 | |
| 941 | − WAIT_SEM (); | |
| 942 | − while (*p) { | |
| 943 | − tree = splay_insert((size_t) *p, strlen (*p) + 1, tree); | |
| 944 | − ++p; | |
| 945 | − } | |
| 946 | − tree = splay_insert((size_t) start, (char *) p - start, tree); | |
| 947 | − POST_SEM (); | |
| 944 | + WAIT_SEM (); | |
| 945 | + for (i = 0; i < argc; i++) | |
| 946 | + tree = splay_insert((size_t) argv[i], strlen (argv[i]) + 1, tree); | |
| 947 | + tree = splay_insert((size_t) argv, argc * sizeof(char *), tree); | |
| 948 | + POST_SEM (); | |
| 948 | 949 | #if BOUND_DEBUG |
| 949 | − if (print_calls) { | |
| 950 | − p = (char **) start; | |
| 951 | − while (*p) { | |
| 952 | − dprintf(stderr, "%s, %s(): %p 0x%lx\n", | |
| 953 | − __FILE__, __FUNCTION__, | |
| 954 | − *p, (unsigned long)(strlen (*p) + 1)); | |
| 955 | − ++p; | |
| 950 | + if (print_calls) { | |
| 951 | + for (i = 0; i < argc; i++) | |
| 952 | + dprintf(stderr, "%s, %s(): arg %p 0x%lx\n", | |
| 953 | + __FILE__, __FUNCTION__, | |
| 954 | + argv[i], (unsigned long)(strlen (argv[i]) + 1)); | |
| 955 | + dprintf(stderr, "%s, %s(): argv %p 0x%lx\n", | |
| 956 | + __FILE__, __FUNCTION__, argv, argc * sizeof(char *)); | |
| 956 | 957 | } |
| 957 | − dprintf(stderr, "%s, %s(): argv %p 0x%lx\n", | |
| 958 | − __FILE__, __FUNCTION__, | |
| 959 | − start, (unsigned long)((char *) p - start)); | |
| 960 | − } | |
| 961 | 958 | #endif |
| 959 | + } | |
| 962 | 960 | |
| 963 | −#if HAS_ENVIRON | |
| 964 | − { | |
| 965 | − extern char **environ; | |
| 961 | + if (envp && *envp) { | |
| 962 | + char **p = envp; | |
| 966 | 963 | |
| 967 | 964 | WAIT_SEM (); |
| 968 | − p = environ; | |
| 969 | − start = (char *) p; | |
| 970 | 965 | while (*p) { |
| 971 | 966 | tree = splay_insert((size_t) *p, strlen (*p) + 1, tree); |
| 972 | 967 | ++p; |
| 973 | 968 | } |
| 974 | − tree = splay_insert((size_t) start, (char *) p - start, tree); | |
| 969 | + tree = splay_insert((size_t) envp, p - envp, tree); | |
| 975 | 970 | POST_SEM (); |
| 976 | 971 | #if BOUND_DEBUG |
| 977 | 972 | if (print_calls) { |
| 978 | − p = environ; | |
| 973 | + p = envp; | |
| 979 | 974 | while (*p) { |
| 980 | − dprintf(stderr, "%s, %s(): %p 0x%lx\n", | |
| 975 | + dprintf(stderr, "%s, %s(): env %p 0x%lx\n", | |
| 981 | 976 | __FILE__, __FUNCTION__, |
| 982 | 977 | *p, (unsigned long)(strlen (*p) + 1)); |
| 983 | 978 | ++p; |
| 984 | 979 | } |
| 985 | 980 | dprintf(stderr, "%s, %s(): environ %p 0x%lx\n", |
| 986 | − __FILE__, __FUNCTION__, | |
| 987 | − start, (unsigned long)((char *) p - start)); | |
| 981 | + __FILE__, __FUNCTION__, envp, p - envp); | |
| 988 | 982 | } |
| 989 | 983 | #endif |
| 990 | 984 | } |
| 991 | −#endif | |
| 992 | 985 | } |
| 993 | 986 | |
| 994 | 987 | void __attribute__((destructor)) __bound_exit(void) |
| @@ -4,25 +4,25 @@ · 3 unmodified lines | ||
| 4 | 4 | .type fetch_and_add_arm, %function |
| 5 | 5 | fetch_and_add_arm: |
| 6 | 6 | #ifdef __TINYC__ |
| 7 | − .int 0xf57ff05b | |
| 7 | + .int 0xee070fba | |
| 8 | 8 | .int 0xe1903f9f |
| 9 | 9 | .int 0xe0833001 |
| 10 | 10 | .int 0xe1802f93 |
| 11 | 11 | .int 0xe3520000 |
| 12 | 12 | .int 0x1afffffa |
| 13 | − .int 0xf57ff05b | |
| 13 | + .int 0xee070fba | |
| 14 | 14 | .int 0xe12fff1e |
| 15 | 15 | #else |
| 16 | − .arch armv7-a | |
| 16 | + .arch armv6 | |
| 17 | 17 | |
| 18 | − dmb ish | |
| 18 | + mcr p15, 0, r0, c7, c10, 5 | |
| 19 | 19 | .L0: |
| 20 | 20 | ldrex r3, [r0] |
| 21 | 21 | add r3, r3, r1 |
| 22 | 22 | strex r2, r3, [r0] |
| 23 | 23 | cmp r2, #0 |
| 24 | 24 | bne .L0 |
| 25 | − dmb ish | |
| 25 | + mcr p15, 0, r0, c7, c10, 5 | |
| 26 | 26 | bx lr |
| 27 | 27 | #endif |
| 28 | 28 | .size fetch_and_add_arm, .-fetch_and_add_arm |
| @@ -124,18 +124,19 @@ ST_FUNC void tcc_run_free(TCCState *s1) · 123 unmodified lines | ||
| 124 | 124 | tcc_free(s1->runtime_mem); |
| 125 | 125 | } |
| 126 | 126 | |
| 127 | −static void run_cdtors(TCCState *s1, const char *start, const char *end) | |
| 127 | +static void run_cdtors(TCCState *s1, const char *start, const char *end, | |
| 128 | + int argc, char **argv, char **envp) | |
| 128 | 129 | { |
| 129 | 130 | void **a = (void **)get_sym_addr(s1, start, 0, 0); |
| 130 | 131 | void **b = (void **)get_sym_addr(s1, end, 0, 0); |
| 131 | 132 | while (a != b) |
| 132 | − ((void(*)(void))*a++)(); | |
| 133 | + ((void(*)(int, char **, char **))*a++)(argc, argv, envp); | |
| 133 | 134 | } |
| 134 | 135 | |
| 135 | 136 | /* launch the compiled program with the given arguments */ |
| 136 | 137 | LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv) |
| 137 | 138 | { |
| 138 | − int (*prog_main)(int, char **), ret; | |
| 139 | + int (*prog_main)(int, char **, char **), ret; | |
| 139 | 140 | #ifdef CONFIG_TCC_BACKTRACE |
| 140 | 141 | rt_context *rc = &g_rtctxt; |
| 141 | 142 | #endif |
| @@ -183,14 +184,14 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv) · 41 unmodified lines | ||
| 183 | 184 | fflush(stdout); |
| 184 | 185 | fflush(stderr); |
| 185 | 186 | /* These aren't C symbols, so don't need leading underscore handling. */ |
| 186 | − run_cdtors(s1, "__init_array_start", "__init_array_end"); | |
| 187 | + run_cdtors(s1, "__init_array_start", "__init_array_end", argc, argv, environ); | |
| 187 | 188 | #ifdef CONFIG_TCC_BACKTRACE |
| 188 | 189 | if (!rc->do_jmp || !(ret = setjmp(rc->jmp_buf))) |
| 189 | 190 | #endif |
| 190 | 191 | { |
| 191 | − ret = prog_main(argc, argv); | |
| 192 | + ret = prog_main(argc, argv, environ); | |
| 192 | 193 | } |
| 193 | − run_cdtors(s1, "__fini_array_start", "__fini_array_end"); | |
| 194 | + run_cdtors(s1, "__fini_array_start", "__fini_array_end", 0, NULL, NULL); | |
| 194 | 195 | if ((s1->dflag & 16) && ret) |
| 195 | 196 | fprintf(s1->ppfp, "[returns %d]\n", ret), fflush(s1->ppfp); |
| 196 | 197 | return ret; |
| @@ -34,8 +34,8 @@ int __cdecl __tgetmainargs(int *pargc, _TCHAR ***pargv, _TCHAR ***penv, int glob · 33 unmodified lines | ||
| 34 | 34 | void __cdecl __set_app_type(int apptype); |
| 35 | 35 | unsigned int __cdecl _controlfp(unsigned int new_value, unsigned int mask); |
| 36 | 36 | extern int _tmain(int argc, _TCHAR * argv[], _TCHAR * env[]); |
| 37 | −extern void (*__init_array_start[]) (void); | |
| 38 | −extern void (*__init_array_end[]) (void); | |
| 37 | +extern void (*__init_array_start[]) (int argc, char **argv, char **envp); | |
| 38 | +extern void (*__init_array_end[]) (int argc, char **argv, char **envp); | |
| 39 | 39 | extern void (*__fini_array_start[]) (void); |
| 40 | 40 | extern void (*__fini_array_end[]) (void); |
| 41 | 41 | |
| @@ -46,7 +46,11 @@ static int do_main (int argc, _TCHAR * argv[], _TCHAR * env[]) · 4 unmodified lines | ||
| 46 | 46 | |
| 47 | 47 | i = 0; |
| 48 | 48 | while (&__init_array_start[i] != __init_array_end) { |
| 49 | − (*__init_array_start[i++])(); | |
| 49 | +#ifdef UNICODE | |
| 50 | + (*__init_array_start[i++])(0, NULL, NULL); | |
| 51 | +#else | |
| 52 | + (*__init_array_start[i++])(argc, argv, env); | |
| 53 | +#endif | |
| 50 | 54 | } |
| 51 | 55 | retval = _tmain(__argc, __targv, _tenviron); |
| 52 | 56 | i = 0; |
| @@ -2,8 +2,8 @@ · 1 unmodified line | ||
| 2 | 2 | |
| 3 | 3 | #include <windows.h> |
| 4 | 4 | |
| 5 | −extern void (*__init_array_start[]) (void); | |
| 6 | −extern void (*__init_array_end[]) (void); | |
| 5 | +extern void (*__init_array_start[]) (int argc, char **argv, char **envp); | |
| 6 | +extern void (*__init_array_end[]) (int argc, char **argv, char **envp); | |
| 7 | 7 | extern void (*__fini_array_start[]) (void); |
| 8 | 8 | extern void (*__fini_array_end[]) (void); |
| 9 | 9 | |
| @@ -17,7 +17,7 @@ BOOL WINAPI _dllstart(HINSTANCE hDll, DWORD dwReason, LPVOID lpReserved) · 7 unmodified lines | ||
| 17 | 17 | if (dwReason == DLL_PROCESS_ATTACH) { /* ignore DLL_THREAD_ATTACH */ |
| 18 | 18 | i = 0; |
| 19 | 19 | while (&__init_array_start[i] != __init_array_end) { |
| 20 | − (*__init_array_start[i++])(); | |
| 20 | + (*__init_array_start[i++])(0, NULL, NULL); | |
| 21 | 21 | } |
| 22 | 22 | } |
| 23 | 23 | if (dwReason == DLL_PROCESS_DETACH) { /* ignore DLL_THREAD_DETACH */ |
| @@ -23,8 +23,8 @@ int APIENTRY wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int); · 22 unmodified lines | ||
| 23 | 23 | #define _runtwinmain _runwinmain |
| 24 | 24 | #endif |
| 25 | 25 | |
| 26 | −extern void (*__init_array_start[]) (void); | |
| 27 | −extern void (*__init_array_end[]) (void); | |
| 26 | +extern void (*__init_array_start[]) (int argc, char **argv, char **envp); | |
| 27 | +extern void (*__init_array_end[]) (int argc, char **argv, char **envp); | |
| 28 | 28 | extern void (*__fini_array_start[]) (void); |
| 29 | 29 | extern void (*__fini_array_end[]) (void); |
| 30 | 30 | |
| @@ -57,7 +57,11 @@ static int go_winmain(TCHAR *arg1) · 26 unmodified lines | ||
| 57 | 57 | #endif |
| 58 | 58 | i = 0; |
| 59 | 59 | while (&__init_array_start[i] != __init_array_end) { |
| 60 | − (*__init_array_start[i++])(); | |
| 60 | +#ifdef UNICODE | |
| 61 | + (*__init_array_start[i++])(0, NULL, NULL); | |
| 62 | +#else | |
| 63 | + (*__init_array_start[i++])(__argc, __targv, _tenviron); | |
| 64 | +#endif | |
| 61 | 65 | } |
| 62 | 66 | retval = _tWinMain(GetModuleHandle(NULL), NULL, szCmd, fShow); |
| 63 | 67 | i = 0; |