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