1 /* gospec.c -- Specific flags and argument handling of the gcc Go front end.
2    Copyright (C) 2009-2013 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 "gcc.h"
25 #include "opts.h"
26 
27 /* This bit is set if we saw a `-xfoo' language specification.  */
28 #define LANGSPEC	(1<<1)
29 /* This bit is set if they did `-lm' or `-lmath'.  */
30 #define MATHLIB		(1<<2)
31 /* This bit is set if they did `-lpthread'.  */
32 #define THREADLIB	(1<<3)
33 /* This bit is set if they did `-lc'.  */
34 #define WITHLIBC	(1<<4)
35 /* Skip this option.  */
36 #define SKIPOPT		(1<<5)
37 
38 #ifndef MATH_LIBRARY
39 #define MATH_LIBRARY "m"
40 #endif
41 #ifndef MATH_LIBRARY_PROFILE
42 #define MATH_LIBRARY_PROFILE MATH_LIBRARY
43 #endif
44 
45 #define THREAD_LIBRARY "pthread"
46 #define THREAD_LIBRARY_PROFILE THREAD_LIBRARY
47 
48 #define LIBGO "go"
49 #define LIBGO_PROFILE LIBGO
50 #define LIBGOBEGIN "gobegin"
51 
52 void
lang_specific_driver(struct cl_decoded_option ** in_decoded_options,unsigned int * in_decoded_options_count,int * in_added_libraries)53 lang_specific_driver (struct cl_decoded_option **in_decoded_options,
54 		      unsigned int *in_decoded_options_count,
55 		      int *in_added_libraries)
56 {
57   unsigned int i, j;
58 
59   /* If true, the user gave us the `-p' or `-pg' flag.  */
60   bool saw_profile_flag = false;
61 
62   /* This is a tristate:
63      -1 means we should not link in libgo
64      0  means we should link in libgo if it is needed
65      1  means libgo is needed and should be linked in.
66      2  means libgo is needed and should be linked statically.  */
67   int library = 0;
68 
69   /* The new argument list will be contained in this.  */
70   struct cl_decoded_option *new_decoded_options;
71 
72   /* "-lm" or "-lmath" if it appears on the command line.  */
73   const struct cl_decoded_option *saw_math = 0;
74 
75   /* "-lpthread" if it appears on the command line.  */
76   const struct cl_decoded_option *saw_thread = 0;
77 
78   /* "-lc" if it appears on the command line.  */
79   const struct cl_decoded_option *saw_libc = 0;
80 
81   /* An array used to flag each argument that needs a bit set for
82      LANGSPEC, MATHLIB, or WITHLIBC.  */
83   int *args;
84 
85   /* Whether we need the thread library.  */
86   int need_thread = 0;
87 
88   /* By default, we throw on the math library if we have one.  */
89   int need_math = (MATH_LIBRARY[0] != '\0');
90 
91   /* True if we saw -static.  */
92   int static_link = 0;
93 
94   /* True if we should add -shared-libgcc to the command-line.  */
95   int shared_libgcc = 1;
96 
97   /* The total number of arguments with the new stuff.  */
98   unsigned int argc;
99 
100   /* The argument list.  */
101   struct cl_decoded_option *decoded_options;
102 
103   /* The number of libraries added in.  */
104   int added_libraries;
105 
106   /* The total number of arguments with the new stuff.  */
107   int num_args = 1;
108 
109   /* Whether the -o option was used.  */
110   bool saw_opt_o = false;
111 
112   /* Whether the -c option was used.  Also used for -E, -fsyntax-only,
113      in general anything which implies only compilation and not
114      linking.  */
115   bool saw_opt_c = false;
116 
117   /* Whether the -S option was used.  */
118   bool saw_opt_S = false;
119 
120   /* The first input file with an extension of .go.  */
121   const char *first_go_file = NULL;
122 
123   argc = *in_decoded_options_count;
124   decoded_options = *in_decoded_options;
125   added_libraries = *in_added_libraries;
126 
127   args = XCNEWVEC (int, argc);
128 
129   for (i = 1; i < argc; i++)
130     {
131       const char *arg = decoded_options[i].arg;
132 
133       switch (decoded_options[i].opt_index)
134 	{
135 	case OPT_nostdlib:
136 	case OPT_nodefaultlibs:
137 	  library = -1;
138 	  break;
139 
140 	case OPT_l:
141 	  if (strcmp (arg, MATH_LIBRARY) == 0)
142 	    {
143 	      args[i] |= MATHLIB;
144 	      need_math = 0;
145 	    }
146 	  else if (strcmp (arg, THREAD_LIBRARY) == 0)
147 	    args[i] |= THREADLIB;
148 	  else if (strcmp (arg, "c") == 0)
149 	    args[i] |= WITHLIBC;
150 	  else
151 	    /* Unrecognized libraries (e.g. -lfoo) may require libgo.  */
152 	    library = (library == 0) ? 1 : library;
153 	  break;
154 
155 	case OPT_pg:
156 	case OPT_p:
157 	  saw_profile_flag = true;
158 	  break;
159 
160 	case OPT_x:
161 	  if (library == 0 && strcmp (arg, "go") == 0)
162 	    library = 1;
163 	  break;
164 
165 	case OPT_Xlinker:
166 	case OPT_Wl_:
167 	  /* Arguments that go directly to the linker might be .o files,
168 	     or something, and so might cause libgo to be needed.  */
169 	  if (library == 0)
170 	    library = 1;
171 	  break;
172 
173 	case OPT_c:
174 	case OPT_E:
175 	case OPT_M:
176 	case OPT_MM:
177 	case OPT_fsyntax_only:
178 	  /* Don't specify libraries if we won't link, since that would
179 	     cause a warning.  */
180 	  saw_opt_c = true;
181 	  library = -1;
182 	  break;
183 
184 	case OPT_S:
185 	  saw_opt_S = true;
186 	  library = -1;
187 	  break;
188 
189 	case OPT_o:
190 	  saw_opt_o = true;
191 	  break;
192 
193 	case OPT_static:
194 	  static_link = 1;
195 	  break;
196 
197 	case OPT_static_libgcc:
198 	  shared_libgcc = 0;
199 	  break;
200 
201 	case OPT_static_libgo:
202 	  library = library >= 0 ? 2 : library;
203 	  args[i] |= SKIPOPT;
204 	  break;
205 
206 	case OPT_SPECIAL_input_file:
207 	  if (library == 0)
208 	    library = 1;
209 
210 	  if (first_go_file == NULL)
211 	    {
212 	      int len;
213 
214 	      len = strlen (arg);
215 	      if (len > 3 && strcmp (arg + len - 3, ".go") == 0)
216 		first_go_file = arg;
217 	    }
218 
219 	  break;
220 	}
221     }
222 
223   /* There's no point adding -shared-libgcc if we don't have a shared
224      libgcc.  */
225 #ifndef ENABLE_SHARED_LIBGCC
226   shared_libgcc = 0;
227 #endif
228 
229   /* Make sure to have room for the trailing NULL argument.  */
230   num_args = argc + need_math + shared_libgcc + (library > 0) * 5 + 10;
231   new_decoded_options = XNEWVEC (struct cl_decoded_option, num_args);
232 
233   i = 0;
234   j = 0;
235 
236   /* Copy the 0th argument, i.e., the name of the program itself.  */
237   new_decoded_options[j++] = decoded_options[i++];
238 
239   /* If we are linking, pass -fsplit-stack if it is supported.  */
240 #ifdef TARGET_CAN_SPLIT_STACK
241   if (library >= 0)
242     {
243       generate_option (OPT_fsplit_stack, NULL, 1, CL_DRIVER,
244 		       &new_decoded_options[j]);
245       j++;
246     }
247 #endif
248 
249   /* NOTE: We start at 1 now, not 0.  */
250   while (i < argc)
251     {
252       new_decoded_options[j] = decoded_options[i];
253 
254       /* Make sure -lgo is before the math library, since libgo itself
255 	 uses those math routines.  */
256       if (!saw_math && (args[i] & MATHLIB) && library > 0)
257 	{
258 	  --j;
259 	  saw_math = &decoded_options[i];
260 	}
261 
262       if (!saw_thread && (args[i] & THREADLIB) && library > 0)
263 	{
264 	  --j;
265 	  saw_thread = &decoded_options[i];
266 	}
267 
268       if (!saw_libc && (args[i] & WITHLIBC) && library > 0)
269 	{
270 	  --j;
271 	  saw_libc = &decoded_options[i];
272 	}
273 
274       if ((args[i] & SKIPOPT) != 0)
275 	--j;
276 
277       i++;
278       j++;
279     }
280 
281   /* If we didn't see a -o option, add one.  This is because we need
282      the driver to pass all .go files to go1.  Without a -o option the
283      driver will invoke go1 separately for each input file.  FIXME:
284      This should probably use some other interface to force the driver
285      to set combine_inputs.  */
286   if (first_go_file != NULL && !saw_opt_o)
287     {
288       if (saw_opt_c || saw_opt_S)
289 	{
290 	  const char *base;
291 	  int baselen;
292 	  int alen;
293 	  char *out;
294 
295 	  base = lbasename (first_go_file);
296 	  baselen = strlen (base) - 3;
297 	  alen = baselen + 3;
298 	  out = XNEWVEC (char, alen);
299 	  memcpy (out, base, baselen);
300 	  /* The driver will convert .o to some other suffix (e.g.,
301 	     .obj) if appropriate.  */
302 	  out[baselen] = '.';
303 	  if (saw_opt_S)
304 	    out[baselen + 1] = 's';
305 	  else
306 	    out[baselen + 1] = 'o';
307 	  out[baselen + 2] = '\0';
308 	  generate_option (OPT_o, out, 1, CL_DRIVER,
309 			   &new_decoded_options[j]);
310 	}
311       else
312 	generate_option (OPT_o, "a.out", 1, CL_DRIVER,
313 			 &new_decoded_options[j]);
314       j++;
315     }
316 
317   /* Add `-lgo' if we haven't already done so.  */
318   if (library > 0)
319     {
320       generate_option (OPT_l, LIBGOBEGIN, 1, CL_DRIVER,
321 		       &new_decoded_options[j]);
322       added_libraries++;
323       j++;
324 
325 #ifdef HAVE_LD_STATIC_DYNAMIC
326       if (library > 1 && !static_link)
327 	{
328 	  generate_option (OPT_Wl_, LD_STATIC_OPTION, 1, CL_DRIVER,
329 			   &new_decoded_options[j]);
330 	  j++;
331 	}
332 #endif
333 
334       generate_option (OPT_l, saw_profile_flag ? LIBGO_PROFILE : LIBGO, 1,
335 		       CL_DRIVER, &new_decoded_options[j]);
336       added_libraries++;
337       j++;
338 
339 #ifdef HAVE_LD_STATIC_DYNAMIC
340       if (library > 1 && !static_link)
341 	{
342 	  generate_option (OPT_Wl_, LD_DYNAMIC_OPTION, 1, CL_DRIVER,
343 			   &new_decoded_options[j]);
344 	  j++;
345 	}
346 #endif
347 
348       /* When linking libgo statically we also need to link with the
349 	 pthread library.  */
350       if (library > 1 || static_link)
351 	need_thread = 1;
352     }
353 
354   if (saw_thread)
355     new_decoded_options[j++] = *saw_thread;
356   else if (library > 0 && need_thread)
357     {
358       generate_option (OPT_l,
359 		       (saw_profile_flag
360 			? THREAD_LIBRARY_PROFILE
361 			: THREAD_LIBRARY),
362 		       1, CL_DRIVER, &new_decoded_options[j]);
363       added_libraries++;
364       j++;
365     }
366 
367   if (saw_math)
368     new_decoded_options[j++] = *saw_math;
369   else if (library > 0 && need_math)
370     {
371       generate_option (OPT_l,
372 		       saw_profile_flag ? MATH_LIBRARY_PROFILE : MATH_LIBRARY,
373 		       1, CL_DRIVER, &new_decoded_options[j]);
374       added_libraries++;
375       j++;
376     }
377 
378   if (saw_libc)
379     new_decoded_options[j++] = *saw_libc;
380   if (shared_libgcc && !static_link)
381     generate_option (OPT_shared_libgcc, NULL, 1, CL_DRIVER,
382 		     &new_decoded_options[j++]);
383 
384 #ifdef TARGET_CAN_SPLIT_STACK
385   /* libgcc wraps pthread_create to support split stack, however, due to
386      relative ordering of -lpthread and -lgcc, we can't just mark
387      __real_pthread_create in libgcc as non-weak.  But we need to link in
388      pthread_create from pthread if we are statically linking, so we work-
389      around by passing -u pthread_create to to the linker. */
390   if (static_link)
391     {
392       generate_option (OPT_Wl_, "-u,pthread_create", 1, CL_DRIVER,
393 		       &new_decoded_options[j]);
394       j++;
395     }
396 #endif
397 
398   *in_decoded_options_count = j;
399   *in_decoded_options = new_decoded_options;
400   *in_added_libraries = added_libraries;
401 }
402 
403 /* Called before linking.  Returns 0 on success and -1 on failure.  */
lang_specific_pre_link(void)404 int lang_specific_pre_link (void)  /* Not used for Go.  */
405 {
406   return 0;
407 }
408 
409 /* Number of extra output files that lang_specific_pre_link may generate.  */
410 int lang_specific_extra_outfiles = 0;  /* Not used for Go.  */
411