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