Branch data Line data Source code
1 : : /* gospec.cc -- Specific flags and argument handling of the gcc Go front end.
2 : : Copyright (C) 2009-2024 Free Software Foundation, Inc.
3 : :
4 : : This file is part of GCC.
5 : :
6 : : GCC is free software; you can redistribute it and/or modify it under
7 : : the terms of the GNU General Public License as published by the Free
8 : : Software Foundation; either version 3, or (at your option) any later
9 : : version.
10 : :
11 : : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 : : WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 : : FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 : : for more details.
15 : :
16 : : You should have received a copy of the GNU General Public License
17 : : along with GCC; see the file COPYING3. If not see
18 : : <http://www.gnu.org/licenses/>. */
19 : :
20 : : #include "config.h"
21 : : #include "system.h"
22 : : #include "coretypes.h"
23 : : #include "tm.h"
24 : : #include "opts.h"
25 : :
26 : : /* This bit is set if we saw a `-xfoo' language specification. */
27 : : #define LANGSPEC (1<<1)
28 : : /* This bit is set if they did `-lm' or `-lmath'. */
29 : : #define MATHLIB (1<<2)
30 : : /* This bit is set if they did `-lpthread'. */
31 : : #define THREADLIB (1<<3)
32 : : /* This bit is set if they did `-lc'. */
33 : : #define WITHLIBC (1<<4)
34 : : /* Skip this option. */
35 : : #define SKIPOPT (1<<5)
36 : :
37 : : #ifndef MATH_LIBRARY
38 : : #define MATH_LIBRARY "m"
39 : : #endif
40 : : #ifndef MATH_LIBRARY_PROFILE
41 : : #define MATH_LIBRARY_PROFILE MATH_LIBRARY
42 : : #endif
43 : :
44 : : #define THREAD_LIBRARY "pthread"
45 : : #define THREAD_LIBRARY_PROFILE THREAD_LIBRARY
46 : :
47 : : #define LIBGO "go"
48 : : #define LIBGO_PROFILE LIBGO
49 : : #define LIBGOBEGIN "gobegin"
50 : :
51 : : void
52 : 7340 : lang_specific_driver (struct cl_decoded_option **in_decoded_options,
53 : : unsigned int *in_decoded_options_count,
54 : : int *in_added_libraries)
55 : : {
56 : 7340 : unsigned int i, j;
57 : :
58 : : /* If true, the user gave us the `-p' or `-pg' flag. */
59 : 7340 : bool saw_profile_flag = false;
60 : :
61 : : /* This is a tristate:
62 : : -1 means we should not link in libgo
63 : : 0 means we should link in libgo if it is needed
64 : : 1 means libgo is needed and should be linked in.
65 : : 2 means libgo is needed and should be linked statically. */
66 : 7340 : int library = 0;
67 : :
68 : : /* The new argument list will be contained in this. */
69 : 7340 : struct cl_decoded_option *new_decoded_options;
70 : :
71 : : /* "-lm" or "-lmath" if it appears on the command line. */
72 : 7340 : const struct cl_decoded_option *saw_math = 0;
73 : :
74 : : /* "-lpthread" if it appears on the command line. */
75 : 7340 : const struct cl_decoded_option *saw_thread = 0;
76 : :
77 : : /* "-lc" if it appears on the command line. */
78 : 7340 : const struct cl_decoded_option *saw_libc = 0;
79 : :
80 : : /* An array used to flag each argument that needs a bit set for
81 : : LANGSPEC, MATHLIB, or WITHLIBC. */
82 : 7340 : int *args;
83 : :
84 : : /* Whether we need the thread library. */
85 : 7340 : int need_thread = 0;
86 : :
87 : : /* By default, we throw on the math library if we have one. */
88 : 7340 : int need_math = (MATH_LIBRARY[0] != '\0');
89 : :
90 : : /* True if we saw -static. */
91 : 7340 : int static_link = 0;
92 : :
93 : : /* True if we should add -shared-libgcc to the command-line. */
94 : 7340 : int shared_libgcc = 1;
95 : :
96 : : /* The total number of arguments with the new stuff. */
97 : 7340 : unsigned int argc;
98 : :
99 : : /* The argument list. */
100 : 7340 : struct cl_decoded_option *decoded_options;
101 : :
102 : : /* The number of libraries added in. */
103 : 7340 : int added_libraries;
104 : :
105 : : /* The total number of arguments with the new stuff. */
106 : 7340 : int num_args = 1;
107 : :
108 : : /* Supports split stack */
109 : 7340 : int supports_split_stack = 0;
110 : :
111 : : /* Whether the -o option was used. */
112 : 7340 : bool saw_opt_o = false;
113 : :
114 : : /* Whether the -c option was used. Also used for -E, -fsyntax-only,
115 : : in general anything which implies only compilation and not
116 : : linking. */
117 : 7340 : bool saw_opt_c = false;
118 : :
119 : : /* Whether the -S option was used. */
120 : 7340 : bool saw_opt_S = false;
121 : :
122 : : #ifdef TARGET_CAN_SPLIT_STACK_64BIT
123 : : /* Whether the -m64 option is in force. */
124 : : bool is_m64 = TARGET_CAN_SPLIT_STACK_64BIT;
125 : : #endif
126 : :
127 : : /* The first input file with an extension of .go. */
128 : 7340 : const char *first_go_file = NULL;
129 : :
130 : : /* Whether we saw any -g option. */
131 : 7340 : bool saw_opt_g = false;
132 : :
133 : 7340 : argc = *in_decoded_options_count;
134 : 7340 : decoded_options = *in_decoded_options;
135 : 7340 : added_libraries = *in_added_libraries;
136 : :
137 : 7340 : args = XCNEWVEC (int, argc);
138 : :
139 : 130924 : for (i = 1; i < argc; i++)
140 : : {
141 : 123584 : const char *arg = decoded_options[i].arg;
142 : :
143 : 123584 : switch (decoded_options[i].opt_index)
144 : : {
145 : : case OPT_r:
146 : : case OPT_nostdlib:
147 : : case OPT_nodefaultlibs:
148 : 123584 : library = -1;
149 : : break;
150 : :
151 : 1775 : case OPT_l:
152 : 1775 : if (strcmp (arg, MATH_LIBRARY) == 0)
153 : : {
154 : 1367 : args[i] |= MATHLIB;
155 : 1367 : need_math = 0;
156 : : }
157 : 408 : else if (strcmp (arg, THREAD_LIBRARY) == 0)
158 : 392 : args[i] |= THREADLIB;
159 : 16 : else if (strcmp (arg, "c") == 0)
160 : 0 : args[i] |= WITHLIBC;
161 : : else
162 : : /* Unrecognized libraries (e.g. -lfoo) may require libgo. */
163 : 16 : library = (library == 0) ? 1 : library;
164 : : break;
165 : :
166 : : #ifdef TARGET_CAN_SPLIT_STACK_64BIT
167 : : case OPT_m32:
168 : : is_m64 = false;
169 : : break;
170 : :
171 : : case OPT_m64:
172 : : is_m64 = true;
173 : : break;
174 : : #endif
175 : :
176 : : case OPT_pg:
177 : : case OPT_p:
178 : 123584 : saw_profile_flag = true;
179 : : break;
180 : :
181 : 1354 : case OPT_x:
182 : 1354 : if (library == 0 && strcmp (arg, "go") == 0)
183 : 478 : library = 1;
184 : : break;
185 : :
186 : 713 : case OPT_Xlinker:
187 : 713 : case OPT_Wl_:
188 : : /* Arguments that go directly to the linker might be .o files,
189 : : or something, and so might cause libgo to be needed. */
190 : 713 : if (library == 0)
191 : 478 : library = 1;
192 : : break;
193 : :
194 : 4182 : case OPT_c:
195 : 4182 : case OPT_E:
196 : 4182 : case OPT_M:
197 : 4182 : case OPT_MM:
198 : 4182 : case OPT_fsyntax_only:
199 : : /* Don't specify libraries if we won't link, since that would
200 : : cause a warning. */
201 : 4182 : saw_opt_c = true;
202 : 4182 : library = -1;
203 : 4182 : break;
204 : :
205 : 877 : case OPT_S:
206 : 877 : saw_opt_S = true;
207 : 877 : library = -1;
208 : 877 : break;
209 : :
210 : 5139 : case OPT_o:
211 : 5139 : saw_opt_o = true;
212 : 5139 : break;
213 : :
214 : 7324 : case OPT_g:
215 : 7324 : case OPT_gdwarf:
216 : 7324 : case OPT_gdwarf_:
217 : 7324 : case OPT_ggdb:
218 : 7324 : case OPT_gvms:
219 : 7324 : saw_opt_g = true;
220 : 7324 : break;
221 : :
222 : 6 : case OPT_static:
223 : 6 : static_link = 1;
224 : 6 : break;
225 : :
226 : 6 : case OPT_static_libgcc:
227 : 6 : shared_libgcc = 0;
228 : 6 : break;
229 : :
230 : 6 : case OPT_static_libgo:
231 : 6 : library = library >= 0 ? 2 : library;
232 : 6 : args[i] |= SKIPOPT;
233 : 6 : break;
234 : :
235 : 15679 : case OPT_SPECIAL_input_file:
236 : 15679 : if (library == 0)
237 : 1829 : library = 1;
238 : :
239 : 15679 : if (first_go_file == NULL)
240 : : {
241 : 7556 : int len;
242 : :
243 : 7556 : len = strlen (arg);
244 : 7556 : if (len > 3 && strcmp (arg + len - 3, ".go") == 0)
245 : 123584 : first_go_file = arg;
246 : : }
247 : :
248 : : break;
249 : : }
250 : : }
251 : :
252 : : /* There's no point adding -shared-libgcc if we don't have a shared
253 : : libgcc. */
254 : : #ifndef ENABLE_SHARED_LIBGCC
255 : : shared_libgcc = 0;
256 : : #endif
257 : :
258 : : /* Make sure to have room for the trailing NULL argument. */
259 : 7340 : num_args = argc + need_math + shared_libgcc + (library > 0) * 5 + 10;
260 : 7340 : new_decoded_options = XNEWVEC (struct cl_decoded_option, num_args);
261 : :
262 : 7340 : i = 0;
263 : 7340 : j = 0;
264 : :
265 : : /* Copy the 0th argument, i.e., the name of the program itself. */
266 : 7340 : new_decoded_options[j++] = decoded_options[i++];
267 : :
268 : : #ifdef TARGET_CAN_SPLIT_STACK
269 : 7340 : supports_split_stack = 1;
270 : : #endif
271 : :
272 : : #ifdef TARGET_CAN_SPLIT_STACK_64BIT
273 : : if (is_m64)
274 : : supports_split_stack = 1;
275 : : #endif
276 : :
277 : : /* If we are linking, pass -fsplit-stack if it is supported. */
278 : 7340 : if ((library >= 0) && supports_split_stack)
279 : : {
280 : 2267 : generate_option (OPT_fsplit_stack, NULL, 1, CL_DRIVER,
281 : : &new_decoded_options[j]);
282 : 2267 : j++;
283 : : }
284 : :
285 : : /* The go1 compiler is going to enable debug info by default. If we
286 : : don't see any -g options, force -g, so that we invoke the
287 : : assembler with the right debug option. */
288 : 7340 : if (!saw_opt_g)
289 : : {
290 : 1444 : generate_option (OPT_g, "1", 0, CL_DRIVER, &new_decoded_options[j]);
291 : 1444 : j++;
292 : : }
293 : :
294 : : /* NOTE: We start at 1 now, not 0. */
295 : 130924 : while (i < argc)
296 : : {
297 : 123584 : new_decoded_options[j] = decoded_options[i];
298 : :
299 : : /* Make sure -lgo is before the math library, since libgo itself
300 : : uses those math routines. */
301 : 123584 : if (!saw_math && (args[i] & MATHLIB) && library > 0)
302 : : {
303 : 1366 : --j;
304 : 1366 : saw_math = &decoded_options[i];
305 : : }
306 : :
307 : 123584 : if (!saw_thread && (args[i] & THREADLIB) && library > 0)
308 : : {
309 : 392 : --j;
310 : 392 : saw_thread = &decoded_options[i];
311 : : }
312 : :
313 : 123584 : if (!saw_libc && (args[i] & WITHLIBC) && library > 0)
314 : : {
315 : 0 : --j;
316 : 0 : saw_libc = &decoded_options[i];
317 : : }
318 : :
319 : 123584 : if ((args[i] & SKIPOPT) != 0)
320 : 6 : --j;
321 : :
322 : 123584 : i++;
323 : 123584 : j++;
324 : : }
325 : :
326 : : /* If we didn't see a -o option, add one. This is because we need
327 : : the driver to pass all .go files to go1. Without a -o option the
328 : : driver will invoke go1 separately for each input file. FIXME:
329 : : This should probably use some other interface to force the driver
330 : : to set combine_inputs. */
331 : 7340 : if (first_go_file != NULL && !saw_opt_o)
332 : : {
333 : 395 : if (saw_opt_c || saw_opt_S)
334 : : {
335 : 395 : const char *base;
336 : 395 : int baselen;
337 : 395 : int alen;
338 : 395 : char *out;
339 : :
340 : 395 : base = lbasename (first_go_file);
341 : 395 : baselen = strlen (base) - 3;
342 : 395 : alen = baselen + 3;
343 : 395 : out = XNEWVEC (char, alen);
344 : 395 : memcpy (out, base, baselen);
345 : : /* The driver will convert .o to some other suffix (e.g.,
346 : : .obj) if appropriate. */
347 : 395 : out[baselen] = '.';
348 : 395 : if (saw_opt_S)
349 : 0 : out[baselen + 1] = 's';
350 : : else
351 : 395 : out[baselen + 1] = 'o';
352 : 395 : out[baselen + 2] = '\0';
353 : 395 : generate_option (OPT_o, out, 1, CL_DRIVER,
354 : 395 : &new_decoded_options[j]);
355 : : }
356 : : else
357 : 0 : generate_option (OPT_o, "a.out", 1, CL_DRIVER,
358 : 0 : &new_decoded_options[j]);
359 : 395 : j++;
360 : : }
361 : :
362 : : /* Add `-lgo' if we haven't already done so. */
363 : 7340 : if (library > 0)
364 : : {
365 : 1494 : generate_option (OPT_l, LIBGOBEGIN, 1, CL_DRIVER,
366 : 1494 : &new_decoded_options[j]);
367 : 1494 : added_libraries++;
368 : 1494 : j++;
369 : :
370 : : #ifdef HAVE_LD_STATIC_DYNAMIC
371 : 1494 : if (library > 1 && !static_link)
372 : : {
373 : 2 : generate_option (OPT_Wl_, LD_STATIC_OPTION, 1, CL_DRIVER,
374 : 2 : &new_decoded_options[j]);
375 : 2 : j++;
376 : : }
377 : : #endif
378 : :
379 : 1494 : generate_option (OPT_l, saw_profile_flag ? LIBGO_PROFILE : LIBGO, 1,
380 : 1494 : CL_DRIVER, &new_decoded_options[j]);
381 : 1494 : added_libraries++;
382 : 1494 : j++;
383 : :
384 : : #ifdef HAVE_LD_STATIC_DYNAMIC
385 : 1494 : if (library > 1 && !static_link)
386 : : {
387 : 2 : generate_option (OPT_Wl_, LD_DYNAMIC_OPTION, 1, CL_DRIVER,
388 : 2 : &new_decoded_options[j]);
389 : 2 : j++;
390 : : }
391 : : #endif
392 : :
393 : : /* When linking libgo statically we also need to link with the
394 : : pthread library. */
395 : 1494 : if (library > 1 || static_link)
396 : 5 : need_thread = 1;
397 : : }
398 : :
399 : 7340 : if (saw_thread)
400 : 392 : new_decoded_options[j++] = *saw_thread;
401 : 6948 : else if (library > 0 && need_thread)
402 : : {
403 : 2 : generate_option (OPT_l,
404 : : (saw_profile_flag
405 : : ? THREAD_LIBRARY_PROFILE
406 : : : THREAD_LIBRARY),
407 : 2 : 1, CL_DRIVER, &new_decoded_options[j]);
408 : 2 : added_libraries++;
409 : 2 : j++;
410 : : }
411 : :
412 : 7340 : if (saw_math)
413 : 1366 : new_decoded_options[j++] = *saw_math;
414 : 5974 : else if (library > 0 && need_math)
415 : : {
416 : 128 : generate_option (OPT_l,
417 : : saw_profile_flag ? MATH_LIBRARY_PROFILE : MATH_LIBRARY,
418 : 128 : 1, CL_DRIVER, &new_decoded_options[j]);
419 : 128 : added_libraries++;
420 : 128 : j++;
421 : : }
422 : :
423 : 7340 : if (saw_libc)
424 : 0 : new_decoded_options[j++] = *saw_libc;
425 : 7340 : if (shared_libgcc && !static_link)
426 : 7328 : generate_option (OPT_shared_libgcc, NULL, 1, CL_DRIVER,
427 : 7328 : &new_decoded_options[j++]);
428 : :
429 : : /* libgcc wraps pthread_create to support split stack, however, due to
430 : : relative ordering of -lpthread and -lgcc, we can't just mark
431 : : __real_pthread_create in libgcc as non-weak. But we need to link in
432 : : pthread_create from pthread if we are statically linking, so we work-
433 : : around by passing -u pthread_create to the linker. */
434 : 7340 : if (static_link && supports_split_stack)
435 : : {
436 : 6 : generate_option (OPT_Wl_, "-u,pthread_create", 1, CL_DRIVER,
437 : 6 : &new_decoded_options[j]);
438 : 6 : j++;
439 : : }
440 : :
441 : : #if defined(TARGET_SOLARIS) && !defined(USE_GLD)
442 : : /* We use a common symbol for go$zerovalue. On Solaris, when not
443 : : using the GNU linker, the Solaris linker needs an option to not
444 : : warn about this. Everything works without this option, but you
445 : : get unsightly warnings at link time. */
446 : : if (library > 0)
447 : : {
448 : : generate_option (OPT_Wl_, "-t", 1, CL_DRIVER, &new_decoded_options[j]);
449 : : j++;
450 : : }
451 : : #endif
452 : :
453 : 7340 : *in_decoded_options_count = j;
454 : 7340 : *in_decoded_options = new_decoded_options;
455 : 7340 : *in_added_libraries = added_libraries;
456 : 7340 : }
457 : :
458 : : /* Called before linking. Returns 0 on success and -1 on failure. */
459 : 6111 : int lang_specific_pre_link (void) /* Not used for Go. */
460 : : {
461 : 6111 : return 0;
462 : : }
463 : :
464 : : /* Number of extra output files that lang_specific_pre_link may generate. */
465 : : int lang_specific_extra_outfiles = 0; /* Not used for Go. */
|