1 /* gospec.c -- Specific flags and argument handling of the gcc Go front end.
2    Copyright (C) 2009-2021 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
lang_specific_driver(struct cl_decoded_option ** in_decoded_options,unsigned int * in_decoded_options_count,int * in_added_libraries)52 lang_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 
108   /* Supports split stack */
109   int supports_split_stack = 0;
110 
111   /* Whether the -o option was used.  */
112   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   bool saw_opt_c = false;
118 
119   /* Whether the -S option was used.  */
120   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   const char *first_go_file = NULL;
129 
130   /* Whether we saw any -g option.  */
131   bool saw_opt_g = false;
132 
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 	{
145 	case OPT_r:
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 
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 	  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:
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.  */
201 	  saw_opt_c = true;
202 	  library = -1;
203 	  break;
204 
205 	case OPT_S:
206 	  saw_opt_S = true;
207 	  library = -1;
208 	  break;
209 
210 	case OPT_o:
211 	  saw_opt_o = true;
212 	  break;
213 
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 
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;
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 
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.  */
263   num_args = argc + need_math + shared_libgcc + (library > 0) * 5 + 10;
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 
272 #ifdef TARGET_CAN_SPLIT_STACK
273   supports_split_stack = 1;
274 #endif
275 
276 #ifdef TARGET_CAN_SPLIT_STACK_64BIT
277   if (is_m64)
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)
283     {
284       generate_option (OPT_fsplit_stack, NULL, 1, CL_DRIVER,
285 		       &new_decoded_options[j]);
286       j++;
287     }
288 
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 
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 
330   /* If we didn't see a -o option, add one.  This is because we need
331      the driver to pass all .go files to go1.  Without a -o option the
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)
336     {
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 	}
360       else
361 	generate_option (OPT_o, "a.out", 1, CL_DRIVER,
362 			 &new_decoded_options[j]);
363       j++;
364     }
365 
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 	{
377 	  generate_option (OPT_Wl_, LD_STATIC_OPTION, 1, CL_DRIVER,
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 	{
391 	  generate_option (OPT_Wl_, LD_DYNAMIC_OPTION, 1, CL_DRIVER,
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 
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-
437      around by passing -u pthread_create to the linker. */
438   if (static_link && supports_split_stack)
439     {
440       generate_option (OPT_Wl_, "-u,pthread_create", 1, CL_DRIVER,
441 		       &new_decoded_options[j]);
442       j++;
443     }
444 
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 
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.  */
lang_specific_pre_link(void)460 int 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.  */
466 int lang_specific_extra_outfiles = 0;  /* Not used for Go.  */
467