Rev 6074 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 6074 | Rev 6536 | ||
---|---|---|---|
1 | /* |
1 | /* |
2 | * crt1.c |
2 | * crt1.c |
3 | * This file has no copyright assigned and is placed in the Public Domain. |
3 | * This file has no copyright assigned and is placed in the Public Domain. |
4 | * This file is a part of the mingw-runtime package. |
4 | * This file is a part of the mingw-runtime package. |
5 | * No warranty is given; refer to the file DISCLAIMER within the package. |
5 | * No warranty is given; refer to the file DISCLAIMER within the package. |
6 | * |
6 | * |
7 | * Source code for the startup proceedures used by all programs. This code |
7 | * Source code for the startup proceedures used by all programs. This code |
8 | * is compiled to make crt1.o, which should be located in the library path. |
8 | * is compiled to make crt1.o, which should be located in the library path. |
9 | * |
9 | * |
10 | */ |
10 | */ |
11 | 11 | ||
12 | /* Hide the declaration of _fmode with dllimport attribute in stdlib.h to |
12 | /* Hide the declaration of _fmode with dllimport attribute in stdlib.h to |
13 | avoid problems with older GCC. */ |
13 | avoid problems with older GCC. */ |
14 | - | ||
15 | #include |
- | |
16 | #include |
14 | |
17 | #include |
- | |
18 | #include |
- | |
19 | #include |
- | |
20 | #include |
15 | #include |
21 | 16 | ||
22 | struct app_hdr |
17 | struct app_hdr |
23 | { |
18 | { |
24 | char banner[8]; |
19 | char banner[8]; |
25 | int version; |
20 | int version; |
26 | int start; |
21 | int start; |
27 | int iend; |
22 | int iend; |
28 | int memsize; |
23 | int memsize; |
29 | int stacktop; |
24 | int stacktop; |
30 | char *cmdline; |
25 | char *cmdline; |
31 | char *path; |
26 | char *path; |
32 | int __subsystem__; |
27 | int __subsystem__; |
33 | }; |
28 | }; |
- | 29 | ||
- | 30 | extern void init_reent(); |
|
34 | 31 | extern void init_stdio(); |
|
35 | void __init_conio(); |
32 | extern void __init_conio(); |
- | 33 | extern void __fini_conio(); |
|
36 | void __fini_conio(); |
34 | |
37 | 35 | extern void tls_init(void); |
|
38 | extern int main (int, char **, char **); |
36 | extern int main (int, char **, char **); |
39 | 37 | ||
40 | /* NOTE: The code for initializing the _argv, _argc, and environ variables |
38 | /* NOTE: The code for initializing the _argv, _argc, and environ variables |
41 | * has been moved to a separate .c file which is included in both |
39 | * has been moved to a separate .c file which is included in both |
42 | * crt1.c and dllcrt1.c. This means changes in the code don't have to |
40 | * crt1.c and dllcrt1.c. This means changes in the code don't have to |
43 | * be manually synchronized, but it does lead to this not-generally- |
41 | * be manually synchronized, but it does lead to this not-generally- |
44 | * a-good-idea use of include. */ |
42 | * a-good-idea use of include. */ |
45 | 43 | ||
46 | char* __appenv; |
44 | char* __appenv; |
47 | int __appenv_size; |
45 | int __appenv_size; |
48 | - | ||
49 | extern char _tls_map[128]; |
- | |
50 | 46 | ||
51 | char * __libc_getenv(const char *name) |
47 | char * __libc_getenv(const char *name) |
52 | { |
48 | { |
53 | return NULL; |
49 | return NULL; |
54 | } |
50 | } |
55 | 51 | ||
56 | static int split_cmdline(char *cmdline, char **argv) |
52 | static int split_cmdline(char *cmdline, char **argv) |
57 | { |
53 | { |
58 | enum quote_state |
54 | enum quote_state |
59 | { |
55 | { |
60 | QUOTE_NONE, /* no " active in current parm */ |
56 | QUOTE_NONE, /* no " active in current parm */ |
61 | QUOTE_DELIMITER, /* " was first char and must be last */ |
57 | QUOTE_DELIMITER, /* " was first char and must be last */ |
62 | QUOTE_STARTED /* " was seen, look for a match */ |
58 | QUOTE_STARTED /* " was seen, look for a match */ |
63 | }; |
59 | }; |
64 | 60 | ||
65 | enum quote_state state; |
61 | enum quote_state state; |
66 | unsigned int argc; |
62 | unsigned int argc; |
67 | char *p = cmdline; |
63 | char *p = cmdline; |
68 | char *new_arg, *start; |
64 | char *new_arg, *start; |
69 | 65 | ||
70 | argc = 0; |
66 | argc = 0; |
71 | 67 | ||
72 | for(;;) |
68 | for(;;) |
73 | { |
69 | { |
74 | /* skip over spaces and tabs */ |
70 | /* skip over spaces and tabs */ |
75 | if ( *p ) |
71 | if ( *p ) |
76 | { |
72 | { |
77 | while (*p == ' ' || *p == '\t') |
73 | while (*p == ' ' || *p == '\t') |
78 | ++p; |
74 | ++p; |
79 | } |
75 | } |
80 | 76 | ||
81 | if (*p == '\0') |
77 | if (*p == '\0') |
82 | break; |
78 | break; |
83 | 79 | ||
84 | state = QUOTE_NONE; |
80 | state = QUOTE_NONE; |
85 | if( *p == '\"' ) |
81 | if( *p == '\"' ) |
86 | { |
82 | { |
87 | p++; |
83 | p++; |
88 | state = QUOTE_DELIMITER; |
84 | state = QUOTE_DELIMITER; |
89 | } |
85 | } |
90 | new_arg = start = p; |
86 | new_arg = start = p; |
91 | for (;;) |
87 | for (;;) |
92 | { |
88 | { |
93 | if( *p == '\"' ) |
89 | if( *p == '\"' ) |
94 | { |
90 | { |
95 | p++; |
91 | p++; |
96 | if( state == QUOTE_NONE ) |
92 | if( state == QUOTE_NONE ) |
97 | { |
93 | { |
98 | state = QUOTE_STARTED; |
94 | state = QUOTE_STARTED; |
99 | } |
95 | } |
100 | else |
96 | else |
101 | { |
97 | { |
102 | state = QUOTE_NONE; |
98 | state = QUOTE_NONE; |
103 | } |
99 | } |
104 | continue; |
100 | continue; |
105 | } |
101 | } |
106 | 102 | ||
107 | if( *p == ' ' || *p == '\t' ) |
103 | if( *p == ' ' || *p == '\t' ) |
108 | { |
104 | { |
109 | if( state == QUOTE_NONE ) |
105 | if( state == QUOTE_NONE ) |
110 | { |
106 | { |
111 | break; |
107 | break; |
112 | } |
108 | } |
113 | } |
109 | } |
114 | 110 | ||
115 | if( *p == '\0' ) |
111 | if( *p == '\0' ) |
116 | break; |
112 | break; |
117 | 113 | ||
118 | if( *p == '\\' ) |
114 | if( *p == '\\' ) |
119 | { |
115 | { |
120 | if( p[1] == '\"' ) |
116 | if( p[1] == '\"' ) |
121 | { |
117 | { |
122 | ++p; |
118 | ++p; |
123 | if( p[-2] == '\\' ) |
119 | if( p[-2] == '\\' ) |
124 | { |
120 | { |
125 | continue; |
121 | continue; |
126 | } |
122 | } |
127 | } |
123 | } |
128 | } |
124 | } |
129 | if( argv ) |
125 | if( argv ) |
130 | { |
126 | { |
131 | *(new_arg++) = *p; |
127 | *(new_arg++) = *p; |
132 | } |
128 | } |
133 | ++p; |
129 | ++p; |
134 | }; |
130 | }; |
135 | 131 | ||
136 | if( argv ) |
132 | if( argv ) |
137 | { |
133 | { |
138 | argv[ argc ] = start; |
134 | argv[ argc ] = start; |
139 | ++argc; |
135 | ++argc; |
140 | 136 | ||
141 | /* |
137 | /* |
142 | The *new = '\0' is req'd in case there was a \" to " |
138 | The *new = '\0' is req'd in case there was a \" to " |
143 | translation. It must be after the *p check against |
139 | translation. It must be after the *p check against |
144 | '\0' because new and p could point to the same char |
140 | '\0' because new and p could point to the same char |
145 | in which case the scan would be terminated too soon. |
141 | in which case the scan would be terminated too soon. |
146 | */ |
142 | */ |
147 | 143 | ||
148 | if( *p == '\0' ) |
144 | if( *p == '\0' ) |
149 | { |
145 | { |
150 | *new_arg = '\0'; |
146 | *new_arg = '\0'; |
151 | break; |
147 | break; |
152 | } |
148 | } |
153 | *new_arg = '\0'; |
149 | *new_arg = '\0'; |
154 | ++p; |
150 | ++p; |
155 | } |
151 | } |
156 | else |
152 | else |
157 | { |
153 | { |
158 | ++argc; |
154 | ++argc; |
159 | if( *p == '\0' ) |
155 | if( *p == '\0' ) |
160 | { |
156 | { |
161 | break; |
157 | break; |
162 | } |
158 | } |
163 | ++p; |
159 | ++p; |
164 | } |
160 | } |
165 | } |
161 | } |
166 | 162 | ||
167 | return argc; |
163 | return argc; |
168 | }; |
164 | }; |
169 | 165 | ||
170 | void __attribute__((noreturn)) |
166 | void __attribute__((noreturn)) |
171 | __crt_startup (void) |
167 | __libc_init (void) |
172 | { |
168 | { |
173 | struct app_hdr *header = NULL; |
169 | struct app_hdr *header = NULL; |
174 | int retval = 0; |
170 | int retval = 0; |
175 | 171 | ||
176 | char **argv; |
172 | char **argv; |
177 | int argc; |
173 | int argc; |
178 | - | ||
179 | memset(_tls_map, 0xFF, 32*4); |
174 | |
180 | _tls_map[0] = 0xE0; |
175 | tls_init(); |
181 | init_reent(); |
176 | init_reent(); |
182 | init_stdio(); |
177 | init_stdio(); |
183 | 178 | ||
184 | if(header->__subsystem__ == 3) |
179 | if(header->__subsystem__ == 3) |
185 | __init_conio(); |
180 | __init_conio(); |
186 | 181 | ||
187 | if( header->cmdline[0] != 0) |
182 | if( header->cmdline[0] != 0) |
188 | { |
183 | { |
189 | argc = split_cmdline(header->cmdline, NULL) + 1; |
184 | argc = split_cmdline(header->cmdline, NULL) + 1; |
190 | argv = alloca((argc+1)*sizeof(char*)); |
185 | argv = alloca((argc+1)*sizeof(char*)); |
191 | argv[0] = header->path; |
186 | argv[0] = header->path; |
192 | 187 | ||
193 | split_cmdline(header->cmdline, argv + 1); |
188 | split_cmdline(header->cmdline, argv + 1); |
194 | } |
189 | } |
195 | else |
190 | else |
196 | { |
191 | { |
197 | argc = 1; |
192 | argc = 1; |
198 | argv = alloca((argc+1)*sizeof(char*)); |
193 | argv = alloca((argc+1)*sizeof(char*)); |
199 | argv[0] = header->path; |
194 | argv[0] = header->path; |
200 | } |
195 | } |
201 | argv[argc] = NULL; |
196 | argv[argc] = NULL; |
202 | 197 | ||
203 | retval = main(argc, argv, NULL); |
198 | retval = main(argc, argv, NULL); |
204 | done: |
199 | done: |
205 | if(header->__subsystem__ == 3) |
200 | if(header->__subsystem__ == 3) |
206 | __fini_conio(); |
201 | __fini_conio(); |
207 | 202 | ||
208 | exit (retval); |
203 | exit (retval); |
209 | } |
204 | } |