1 /* gospec.c -- Specific flags and argument handling of the gcc Go front end.
2    Copyright (C) 2009-2020 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   argc = *in_decoded_options_count;
131   decoded_options = *in_decoded_options;
132   added_libraries = *in_added_libraries;
133 
134   args = XCNEWVEC (int, argc);
135 
136   for (i = 1; i < argc; i++)
137     {
138       const char *arg = decoded_options[i].arg;
139 
140       switch (decoded_options[i].opt_index)
141 	{
142 	case OPT_r:
143 	case OPT_nostdlib:
144 	case OPT_nodefaultlibs:
145 	  library = -1;
146 	  break;
147 
148 	case OPT_l:
149 	  if (strcmp (arg, MATH_LIBRARY) == 0)
150 	    {
151 	      args[i] |= MATHLIB;
152 	      need_math = 0;
153 	    }
154 	  else if (strcmp (arg, THREAD_LIBRARY) == 0)
155 	    args[i] |= THREADLIB;
156 	  else if (strcmp (arg, "c") == 0)
157 	    args[i] |= WITHLIBC;
158 	  else
159 	    /* Unrecognized libraries (e.g. -lfoo) may require libgo.  */
160 	    library = (library == 0) ? 1 : library;
161 	  break;
162 
163 #ifdef TARGET_CAN_SPLIT_STACK_64BIT
164 	case OPT_m32:
165 	  is_m64 = false;
166 	  break;
167 
168 	case OPT_m64:
169 	  is_m64 = true;
170 	  break;
171 #endif
172 
173 	case OPT_pg:
174 	case OPT_p:
175 	  saw_profile_flag = true;
176 	  break;
177 
178 	case OPT_x:
179 	  if (library == 0 && strcmp (arg, "go") == 0)
180 	    library = 1;
181 	  break;
182 
183 	case OPT_Xlinker:
184 	case OPT_Wl_:
185 	  /* Arguments that go directly to the linker might be .o files,
186 	     or something, and so might cause libgo to be needed.  */
187 	  if (library == 0)
188 	    library = 1;
189 	  break;
190 
191 	case OPT_c:
192 	case OPT_E:
193 	case OPT_M:
194 	case OPT_MM:
195 	case OPT_fsyntax_only:
196 	  /* Don't specify libraries if we won't link, since that would
197 	     cause a warning.  */
198 	  saw_opt_c = true;
199 	  library = -1;
200 	  break;
201 
202 	case OPT_S:
203 	  saw_opt_S = true;
204 	  library = -1;
205 	  break;
206 
207 	case OPT_o:
208 	  saw_opt_o = true;
209 	  break;
210 
211 	case OPT_static:
212 	  static_link = 1;
213 	  break;
214 
215 	case OPT_static_libgcc:
216 	  shared_libgcc = 0;
217 	  break;
218 
219 	case OPT_static_libgo:
220 	  library = library >= 0 ? 2 : library;
221 	  args[i] |= SKIPOPT;
222 	  break;
223 
224 	case OPT_SPECIAL_input_file:
225 	  if (library == 0)
226 	    library = 1;
227 
228 	  if (first_go_file == NULL)
229 	    {
230 	      int len;
231 
232 	      len = strlen (arg);
233 	      if (len > 3 && strcmp (arg + len - 3, ".go") == 0)
234 		first_go_file = arg;
235 	    }
236 
237 	  break;
238 	}
239     }
240 
241   /* There's no point adding -shared-libgcc if we don't have a shared
242      libgcc.  */
243 #ifndef ENABLE_SHARED_LIBGCC
244   shared_libgcc = 0;
245 #endif
246 
247   /* Make sure to have room for the trailing NULL argument.  */
248   num_args = argc + need_math + shared_libgcc + (library > 0) * 5 + 10;
249   new_decoded_options = XNEWVEC (struct cl_decoded_option, num_args);
250 
251   i = 0;
252   j = 0;
253 
254   /* Copy the 0th argument, i.e., the name of the program itself.  */
255   new_decoded_options[j++] = decoded_options[i++];
256 
257 #ifdef TARGET_CAN_SPLIT_STACK
258   supports_split_stack = 1;
259 #endif
260 
261 #ifdef TARGET_CAN_SPLIT_STACK_64BIT
262   if (is_m64)
263     supports_split_stack = 1;
264 #endif
265 
266   /* If we are linking, pass -fsplit-stack if it is supported.  */
267   if ((library >= 0) && supports_split_stack)
268     {
269       generate_option (OPT_fsplit_stack, NULL, 1, CL_DRIVER,
270 		       &new_decoded_options[j]);
271       j++;
272     }
273 
274   /* NOTE: We start at 1 now, not 0.  */
275   while (i < argc)
276     {
277       new_decoded_options[j] = decoded_options[i];
278 
279       /* Make sure -lgo is before the math library, since libgo itself
280 	 uses those math routines.  */
281       if (!saw_math && (args[i] & MATHLIB) && library > 0)
282 	{
283 	  --j;
284 	  saw_math = &decoded_options[i];
285 	}
286 
287       if (!saw_thread && (args[i] & THREADLIB) && library > 0)
288 	{
289 	  --j;
290 	  saw_thread = &decoded_options[i];
291 	}
292 
293       if (!saw_libc && (args[i] & WITHLIBC) && library > 0)
294 	{
295 	  --j;
296 	  saw_libc = &decoded_options[i];
297 	}
298 
299       if ((args[i] & SKIPOPT) != 0)
300 	--j;
301 
302       i++;
303       j++;
304     }
305 
306   /* If we didn't see a -o option, add one.  This is because we need
307      the driver to pass all .go files to go1.  Without a -o option the
308      driver will invoke go1 separately for each input file.  FIXME:
309      This should probably use some other interface to force the driver
310      to set combine_inputs.  */
311   if (first_go_file != NULL && !saw_opt_o)
312     {
313       if (saw_opt_c || saw_opt_S)
314 	{
315 	  const char *base;
316 	  int baselen;
317 	  int alen;
318 	  char *out;
319 
320 	  base = lbasename (first_go_file);
321 	  baselen = strlen (base) - 3;
322 	  alen = baselen + 3;
323 	  out = XNEWVEC (char, alen);
324 	  memcpy (out, base, baselen);
325 	  /* The driver will convert .o to some other suffix (e.g.,
326 	     .obj) if appropriate.  */
327 	  out[baselen] = '.';
328 	  if (saw_opt_S)
329 	    out[baselen + 1] = 's';
330 	  else
331 	    out[baselen + 1] = 'o';
332 	  out[baselen + 2] = '\0';
333 	  generate_option (OPT_o, out, 1, CL_DRIVER,
334 			   &new_decoded_options[j]);
335 	}
336       else
337 	generate_option (OPT_o, "a.out", 1, CL_DRIVER,
338 			 &new_decoded_options[j]);
339       j++;
340     }
341 
342   /* Add `-lgo' if we haven't already done so.  */
343   if (library > 0)
344     {
345       generate_option (OPT_l, LIBGOBEGIN, 1, CL_DRIVER,
346 		       &new_decoded_options[j]);
347       added_libraries++;
348       j++;
349 
350 #ifdef HAVE_LD_STATIC_DYNAMIC
351       if (library > 1 && !static_link)
352 	{
353 	  generate_option (OPT_Wl_, LD_STATIC_OPTION, 1, CL_DRIVER,
354 			   &new_decoded_options[j]);
355 	  j++;
356 	}
357 #endif
358 
359       generate_option (OPT_l, saw_profile_flag ? LIBGO_PROFILE : LIBGO, 1,
360 		       CL_DRIVER, &new_decoded_options[j]);
361       added_libraries++;
362       j++;
363 
364 #ifdef HAVE_LD_STATIC_DYNAMIC
365       if (library > 1 && !static_link)
366 	{
367 	  generate_option (OPT_Wl_, LD_DYNAMIC_OPTION, 1, CL_DRIVER,
368 			   &new_decoded_options[j]);
369 	  j++;
370 	}
371 #endif
372 
373       /* When linking libgo statically we also need to link with the
374 	 pthread library.  */
375       if (library > 1 || static_link)
376 	need_thread = 1;
377     }
378 
379   if (saw_thread)
380     new_decoded_options[j++] = *saw_thread;
381   else if (library > 0 && need_thread)
382     {
383       generate_option (OPT_l,
384 		       (saw_profile_flag
385 			? THREAD_LIBRARY_PROFILE
386 			: THREAD_LIBRARY),
387 		       1, CL_DRIVER, &new_decoded_options[j]);
388       added_libraries++;
389       j++;
390     }
391 
392   if (saw_math)
393     new_decoded_options[j++] = *saw_math;
394   else if (library > 0 && need_math)
395     {
396       generate_option (OPT_l,
397 		       saw_profile_flag ? MATH_LIBRARY_PROFILE : MATH_LIBRARY,
398 		       1, CL_DRIVER, &new_decoded_options[j]);
399       added_libraries++;
400       j++;
401     }
402 
403   if (saw_libc)
404     new_decoded_options[j++] = *saw_libc;
405   if (shared_libgcc && !static_link)
406     generate_option (OPT_shared_libgcc, NULL, 1, CL_DRIVER,
407 		     &new_decoded_options[j++]);
408 
409   /* libgcc wraps pthread_create to support split stack, however, due to
410      relative ordering of -lpthread and -lgcc, we can't just mark
411      __real_pthread_create in libgcc as non-weak.  But we need to link in
412      pthread_create from pthread if we are statically linking, so we work-
413      around by passing -u pthread_create to the linker. */
414   if (static_link && supports_split_stack)
415     {
416       generate_option (OPT_Wl_, "-u,pthread_create", 1, CL_DRIVER,
417 		       &new_decoded_options[j]);
418       j++;
419     }
420 
421 #if defined(TARGET_SOLARIS) && !defined(USE_GLD)
422   /* We use a common symbol for go$zerovalue.  On Solaris, when not
423      using the GNU linker, the Solaris linker needs an option to not
424      warn about this.  Everything works without this option, but you
425      get unsightly warnings at link time.  */
426   generate_option (OPT_Wl_, "-t", 1, CL_DRIVER, &new_decoded_options[j]);
427   j++;
428 #endif
429 
430   *in_decoded_options_count = j;
431   *in_decoded_options = new_decoded_options;
432   *in_added_libraries = added_libraries;
433 }
434 
435 /* Called before linking.  Returns 0 on success and -1 on failure.  */
lang_specific_pre_link(void)436 int lang_specific_pre_link (void)  /* Not used for Go.  */
437 {
438   return 0;
439 }
440 
441 /* Number of extra output files that lang_specific_pre_link may generate.  */
442 int lang_specific_extra_outfiles = 0;  /* Not used for Go.  */
443