Print this page
9884 cw(1) should use -fpic rather than -Kpic
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/tools/cw/cw.c
+++ new/usr/src/tools/cw/cw.c
1 1
2 2 /*
3 3 * CDDL HEADER START
4 4 *
5 5 * The contents of this file are subject to the terms of the
6 6 * Common Development and Distribution License (the "License").
7 7 * You may not use this file except in compliance with the License.
8 8 *
9 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 10 * or http://www.opensolaris.org/os/licensing.
11 11 * See the License for the specific language governing permissions
12 12 * and limitations under the License.
13 13 *
14 14 * When distributing Covered Code, include this CDDL HEADER in each
15 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 16 * If applicable, add the following below this CDDL HEADER, with the
17 17 * fields enclosed by brackets "[]" replaced with your own identifying
18 18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 19 *
20 20 * CDDL HEADER END
21 21 */
22 22
23 23 /*
24 24 * Copyright 2018, Richard Lowe.
25 25 */
26 26 /*
27 27 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
28 28 * Use is subject to license terms.
29 29 */
30 30
31 31 /*
32 32 * Wrapper for the GNU C compiler to make it accept the Sun C compiler
33 33 * arguments where possible.
34 34 *
35 35 * Since the translation is inexact, this is something of a work-in-progress.
36 36 *
37 37 */
38 38
39 39 /* If you modify this file, you must increment CW_VERSION */
40 40 #define CW_VERSION "3.0"
41 41
42 42 /*
43 43 * -# Verbose mode
44 44 * -### Show compiler commands built by driver, no compilation
45 45 * -A<name[(tokens)]> Preprocessor predicate assertion
46 46 * -B<[static|dynamic]> Specify dynamic or static binding
47 47 * -C Prevent preprocessor from removing comments
48 48 * -c Compile only - produce .o files, suppress linking
49 49 * -cg92 Alias for -xtarget=ss1000
50 50 * -D<name[=token]> Associate name with token as if by #define
51 51 * -d[y|n] dynamic [-dy] or static [-dn] option to linker
52 52 * -E Compile source through preprocessor only, output to stdout
53 53 * -erroff=<t> Suppress warnings specified by tags t(%none, %all, <tag list>)
54 54 * -errtags=<a> Display messages with tags a(no, yes)
55 55 * -errwarn=<t> Treats warnings specified by tags t(%none, %all, <tag list>)
56 56 * as errors
57 57 * -fast Optimize using a selection of options
58 58 * -fd Report old-style function definitions and declarations
59 59 * -fnonstd Initialize floating-point hardware to non-standard preferences
60 60 * -fns[=<yes|no>] Select non-standard floating point mode
61 61 * -fprecision=<p> Set FP rounding precision mode p(single, double, extended)
62 62 * -fround=<r> Select the IEEE rounding mode in effect at startup
63 63 * -fsimple[=<n>] Select floating-point optimization preferences <n>
↓ open down ↓ |
63 lines elided |
↑ open up ↑ |
64 64 * -fsingle Use single-precision arithmetic (-Xt and -Xs modes only)
65 65 * -ftrap=<t> Select floating-point trapping mode in effect at startup
66 66 * -fstore force floating pt. values to target precision on assignment
67 67 * -G Build a dynamic shared library
68 68 * -g Compile for debugging
69 69 * -H Print path name of each file included during compilation
70 70 * -h <name> Assign <name> to generated dynamic shared library
71 71 * -I<dir> Add <dir> to preprocessor #include file search path
72 72 * -i Passed to linker to ignore any LD_LIBRARY_PATH setting
73 73 * -keeptmp Keep temporary files created during compilation
74 - * -KPIC Compile position independent code with 32-bit addresses
75 - * -Kpic Compile position independent code
76 74 * -L<dir> Pass to linker to add <dir> to the library search path
77 75 * -l<name> Link with library lib<name>.a or lib<name>.so
78 76 * -mc Remove duplicate strings from .comment section of output files
79 77 * -mr Remove all strings from .comment section of output files
80 78 * -mr,"string" Remove all strings and append "string" to .comment section
81 79 * -mt Specify options needed when compiling multi-threaded code
82 80 * -native Find available processor, generate code accordingly
83 81 * -nofstore Do not force floating pt. values to target precision
84 82 * on assignment
85 83 * -norunpath Do not build in a runtime path for shared libraries
86 84 * -O Use default optimization level (-xO2 or -xO3. Check man page.)
87 85 * -o <outputfile> Set name of output file to <outputfile>
88 86 * -P Compile source through preprocessor only, output to .i file
89 87 * -p Compile for profiling with prof
90 88 * -Q[y|n] Emit/don't emit identification info to output file
91 89 * -R<dir[:dir]> Build runtime search path list into executable
92 90 * -S Compile and only generate assembly code (.s)
93 91 * -s Strip symbol table from the executable file
94 92 * -t Turn off duplicate symbol warnings when linking
95 93 * -U<name> Delete initial definition of preprocessor symbol <name>
96 94 * -V Report version number of each compilation phase
97 95 * -v Do stricter semantic checking
98 96 * -W<c>,<arg> Pass <arg> to specified component <c> (a,l,m,p,0,2,h,i,u)
99 97 * -w Suppress compiler warning messages
100 98 * -Xa Compile assuming ANSI C conformance, allow K & R extensions
101 99 * (default mode)
102 100 * -Xs Compile assuming (pre-ANSI) K & R C style code
103 101 * -Xt Compile assuming K & R conformance, allow ANSI C
104 102 * -xarch=<a> Specify target architecture instruction set
105 103 * -xbuiltin[=<b>] When profitable inline, or substitute intrinisic functions
106 104 * for system functions, b={%all,%none}
107 105 * -xCC Accept C++ style comments
108 106 * -xchip=<c> Specify the target processor for use by the optimizer
109 107 * -xcode=<c> Generate different code for forming addresses
110 108 * -xcrossfile[=<n>] Enable optimization and inlining across source files,
111 109 * n={0|1}
112 110 * -xe Perform only syntax/semantic checking, no code generation
113 111 * -xF Compile for later mapfile reordering or unused section
114 112 * elimination
115 113 * -xhelp=<f> Display on-line help information f(flags, readme, errors)
116 114 * -xildoff Cancel -xildon
117 115 * -xildon Enable use of the incremental linker, ild
118 116 * -xinline=[<a>,...,<a>] Attempt inlining of specified user routines,
119 117 * <a>={%auto,func,no%func}
120 118 * -xlibmieee Force IEEE 754 return values for math routines in
121 119 * exceptional cases
122 120 * -xlibmil Inline selected libm math routines for optimization
123 121 * -xlic_lib=sunperf Link in the Sun supplied performance libraries
124 122 * -xlicinfo Show license server information
125 123 * -xmaxopt=[off,1,2,3,4,5] maximum optimization level allowed on #pragma opt
126 124 * -xO<n> Generate optimized code (n={1|2|3|4|5})
127 125 * -xP Print prototypes for function definitions
128 126 * -xprofile=<p> Collect data for a profile or use a profile to optimize
129 127 * <p>={{collect,use}[:<path>],tcov}
130 128 * -xregs=<r> Control register allocation
131 129 * -xs Allow debugging without object (.o) files
132 130 * -xsb Compile for use with the WorkShop source browser
133 131 * -xsbfast Generate only WorkShop source browser info, no compilation
134 132 * -xsfpconst Represent unsuffixed floating point constants as single
135 133 * precision
136 134 * -xspace Do not do optimizations that increase code size
137 135 * -xstrconst Place string literals into read-only data segment
138 136 * -xtarget=<t> Specify target system for optimization
139 137 * -xtemp=<dir> Set directory for temporary files to <dir>
140 138 * -xtime Report the execution time for each compilation phase
141 139 * -xunroll=n Enable unrolling loops n times where possible
142 140 * -Y<c>,<dir> Specify <dir> for location of component <c> (a,l,m,p,0,h,i,u)
143 141 * -YA,<dir> Change default directory searched for components
144 142 * -YI,<dir> Change default directory searched for include files
145 143 * -YP,<dir> Change default directory for finding libraries files
146 144 * -YS,<dir> Change default directory for startup object files
147 145 */
148 146
149 147 /*
150 148 * Translation table:
151 149 */
152 150 /*
153 151 * -# -v
154 152 * -### error
155 153 * -A<name[(tokens)]> pass-thru
156 154 * -B<[static|dynamic]> pass-thru (syntax error for anything else)
157 155 * -C pass-thru
158 156 * -c pass-thru
159 157 * -cg92 -m32 -mcpu=v8 -mtune=supersparc (SPARC only)
160 158 * -D<name[=token]> pass-thru
161 159 * -dy or -dn -Wl,-dy or -Wl,-dn
162 160 * -E pass-thru
163 161 * -erroff=E_EMPTY_TRANSLATION_UNIT ignore
164 162 * -errtags=%all -Wall
165 163 * -errwarn=%all -Werror else -Wno-error
166 164 * -fast error
167 165 * -fd error
168 166 * -fnonstd error
169 167 * -fns[=<yes|no>] error
170 168 * -fprecision=<p> error
171 169 * -fround=<r> error
172 170 * -fsimple[=<n>] error
↓ open down ↓ |
87 lines elided |
↑ open up ↑ |
173 171 * -fsingle[=<n>] error
174 172 * -ftrap=<t> error
175 173 * -fstore error
176 174 * -G pass-thru
177 175 * -g pass-thru
178 176 * -H pass-thru
179 177 * -h <name> pass-thru
180 178 * -I<dir> pass-thru
181 179 * -i pass-thru
182 180 * -keeptmp -save-temps
183 - * -KPIC -fPIC
184 - * -Kpic -fpic
185 181 * -L<dir> pass-thru
186 182 * -l<name> pass-thru
187 183 * -mc error
188 184 * -mr error
189 185 * -mr,"string" error
190 186 * -mt -D_REENTRANT
191 187 * -native error
192 188 * -nofstore error
193 189 * -nolib -nodefaultlibs
194 190 * -norunpath ignore
195 191 * -O -O1 (Check the man page to be certain)
196 192 * -o <outputfile> pass-thru
197 193 * -P -E -o filename.i (or error)
198 194 * -p pass-thru
199 195 * -Q[y|n] error
200 196 * -R<dir[:dir]> pass-thru
201 197 * -S pass-thru
202 198 * -s -Wl,-s
203 199 * -t -Wl,-t
204 200 * -U<name> pass-thru
205 201 * -V --version
206 202 * -v -Wall
207 203 * -Wa,<arg> pass-thru
208 204 * -Wp,<arg> pass-thru except -xc99=<a>
209 205 * -Wl,<arg> pass-thru
210 206 * -W{m,0,2,h,i,u> error/ignore
211 207 * -xmodel=kernel -ffreestanding -mcmodel=kernel -mno-red-zone
212 208 * -Wu,-save_args -msave-args
213 209 * -w pass-thru
214 210 * -Xa -std=iso9899:199409 or -ansi
215 211 * -Xt error
216 212 * -Xs -traditional -std=c89
217 213 * -xarch=<a> table
218 214 * -xbuiltin[=<b>] -fbuiltin (-fno-builtin otherwise)
219 215 * -xCC ignore
220 216 * -xchip=<c> table
221 217 * -xcode=<c> table
222 218 * -xdebugformat=<format> ignore (always use dwarf-2 for gcc)
223 219 * -xcrossfile[=<n>] ignore
224 220 * -xe error
225 221 * -xF error
226 222 * -xhelp=<f> error
227 223 * -xildoff ignore
228 224 * -xildon ignore
229 225 * -xinline ignore
230 226 * -xlibmieee error
231 227 * -xlibmil error
232 228 * -xlic_lib=sunperf error
233 229 * -xmaxopt=[...] error
234 230 * -xO<n> -O<n>
235 231 * -xP error
236 232 * -xprofile=<p> error
237 233 * -xregs=<r> table
238 234 * -xs error
239 235 * -xsb error
240 236 * -xsbfast error
241 237 * -xsfpconst error
242 238 * -xspace ignore (-not -Os)
243 239 * -xstrconst ignore
244 240 * -xtarget=<t> table
245 241 * -xtemp=<dir> error
246 242 * -xtime error
247 243 * -xtransition -Wtransition
248 244 * -xunroll=n error
249 245 * -W0,-xdbggen=no%usedonly -fno-eliminate-unused-debug-symbols
250 246 * -fno-eliminate-unused-debug-types
251 247 * -Y<c>,<dir> error
252 248 * -YA,<dir> error
253 249 * -YI,<dir> -nostdinc -I<dir>
254 250 * -YP,<dir> error
255 251 * -YS,<dir> error
256 252 */
257 253
258 254 #include <ctype.h>
259 255 #include <err.h>
260 256 #include <errno.h>
261 257 #include <fcntl.h>
262 258 #include <getopt.h>
263 259 #include <stdio.h>
264 260 #include <stdlib.h>
265 261 #include <string.h>
266 262 #include <unistd.h>
267 263
268 264 #include <sys/param.h>
269 265 #include <sys/stat.h>
270 266 #include <sys/types.h>
271 267 #include <sys/utsname.h>
272 268 #include <sys/wait.h>
273 269
274 270 #define CW_F_CXX 0x01
275 271 #define CW_F_SHADOW 0x02
276 272 #define CW_F_EXEC 0x04
277 273 #define CW_F_ECHO 0x08
278 274 #define CW_F_XLATE 0x10
279 275 #define CW_F_PROG 0x20
280 276
281 277 typedef enum cw_op {
282 278 CW_O_NONE = 0,
283 279 CW_O_PREPROCESS,
284 280 CW_O_COMPILE,
285 281 CW_O_LINK
286 282 } cw_op_t;
287 283
288 284 struct aelist {
289 285 struct ae {
290 286 struct ae *ae_next;
291 287 char *ae_arg;
292 288 } *ael_head, *ael_tail;
293 289 int ael_argc;
294 290 };
295 291
296 292 typedef enum {
297 293 GNU,
298 294 SUN
299 295 } compiler_style_t;
300 296
301 297 typedef struct {
302 298 char *c_name;
303 299 char *c_path;
304 300 compiler_style_t c_style;
305 301 } cw_compiler_t;
306 302
307 303 typedef struct cw_ictx {
308 304 struct cw_ictx *i_next;
309 305 cw_compiler_t *i_compiler;
310 306 struct aelist *i_ae;
311 307 uint32_t i_flags;
312 308 int i_oldargc;
313 309 char **i_oldargv;
314 310 pid_t i_pid;
315 311 char i_discard[MAXPATHLEN];
316 312 char *i_stderr;
317 313 } cw_ictx_t;
318 314
319 315 /*
320 316 * Status values to indicate which Studio compiler and associated
321 317 * flags are being used.
322 318 */
323 319 #define M32 0x01 /* -m32 - only on Studio 12 */
324 320 #define M64 0x02 /* -m64 - only on Studio 12 */
325 321 #define SS11 0x100 /* Studio 11 */
326 322 #define SS12 0x200 /* Studio 12 */
327 323
328 324 #define TRANS_ENTRY 5
329 325 /*
330 326 * Translation table definition for the -xarch= flag. The "x_arg"
331 327 * value is translated into the appropriate gcc flags according
332 328 * to the values in x_trans[n]. The x_flags indicates what compiler
333 329 * is being used and what flags have been set via the use of
334 330 * "x_arg".
335 331 */
336 332 typedef struct xarch_table {
337 333 char *x_arg;
338 334 int x_flags;
339 335 char *x_trans[TRANS_ENTRY];
340 336 } xarch_table_t;
341 337
342 338 /*
343 339 * The translation table for the -xarch= flag used in the Studio compilers.
344 340 */
345 341 static const xarch_table_t xtbl[] = {
346 342 #if defined(__x86)
347 343 { "generic", SS11, {NULL} },
348 344 { "generic64", (SS11|M64), { "-m64", "-mtune=opteron" } },
349 345 { "amd64", (SS11|M64), { "-m64", "-mtune=opteron" } },
350 346 { "386", SS11, { "-march=i386" } },
351 347 { "pentium_pro", SS11, { "-march=pentiumpro" } },
352 348 { "sse", SS11, { "-msse", "-mfpmath=sse" } },
353 349 { "sse2", SS11, { "-msse2", "-mfpmath=sse" } },
354 350 #elif defined(__sparc)
355 351 { "generic", (SS11|M32), { "-m32", "-mcpu=v8" } },
356 352 { "generic64", (SS11|M64), { "-m64", "-mcpu=v9" } },
357 353 { "v8", (SS11|M32), { "-m32", "-mcpu=v8", "-mno-v8plus" } },
358 354 { "v8plus", (SS11|M32), { "-m32", "-mcpu=v9", "-mv8plus" } },
359 355 { "v8plusa", (SS11|M32), { "-m32", "-mcpu=ultrasparc", "-mv8plus",
360 356 "-mvis" } },
361 357 { "v8plusb", (SS11|M32), { "-m32", "-mcpu=ultrasparc3", "-mv8plus",
362 358 "-mvis" } },
363 359 { "v9", (SS11|M64), { "-m64", "-mcpu=v9" } },
364 360 { "v9a", (SS11|M64), { "-m64", "-mcpu=ultrasparc", "-mvis" } },
365 361 { "v9b", (SS11|M64), { "-m64", "-mcpu=ultrasparc3", "-mvis" } },
366 362 { "sparc", SS12, { "-mcpu=v9", "-mv8plus" } },
367 363 { "sparcvis", SS12, { "-mcpu=ultrasparc", "-mvis" } },
368 364 { "sparcvis2", SS12, { "-mcpu=ultrasparc3", "-mvis" } }
369 365 #endif
370 366 };
371 367
372 368 static int xtbl_size = sizeof (xtbl) / sizeof (xarch_table_t);
373 369
374 370 static const char *xchip_tbl[] = {
375 371 #if defined(__x86)
376 372 "386", "-mtune=i386", NULL,
377 373 "486", "-mtune=i486", NULL,
378 374 "pentium", "-mtune=pentium", NULL,
379 375 "pentium_pro", "-mtune=pentiumpro", NULL,
380 376 #elif defined(__sparc)
381 377 "super", "-mtune=supersparc", NULL,
382 378 "ultra", "-mtune=ultrasparc", NULL,
383 379 "ultra3", "-mtune=ultrasparc3", NULL,
384 380 #endif
385 381 NULL, NULL
386 382 };
387 383
388 384 static const char *xcode_tbl[] = {
389 385 #if defined(__sparc)
390 386 "abs32", "-fno-pic", "-mcmodel=medlow", NULL,
391 387 "abs44", "-fno-pic", "-mcmodel=medmid", NULL,
392 388 "abs64", "-fno-pic", "-mcmodel=medany", NULL,
393 389 "pic13", "-fpic", NULL,
394 390 "pic32", "-fPIC", NULL,
395 391 #endif
396 392 NULL, NULL
397 393 };
398 394
399 395 static const char *xtarget_tbl[] = {
400 396 #if defined(__x86)
401 397 "pentium_pro", "-march=pentiumpro", NULL,
402 398 #endif /* __x86 */
403 399 NULL, NULL
404 400 };
405 401
406 402 static const char *xregs_tbl[] = {
407 403 #if defined(__sparc)
408 404 "appl", "-mapp-regs", NULL,
409 405 "no%appl", "-mno-app-regs", NULL,
410 406 "float", "-mfpu", NULL,
411 407 "no%float", "-mno-fpu", NULL,
412 408 #endif /* __sparc */
413 409 NULL, NULL
414 410 };
415 411
416 412 static void
417 413 nomem(void)
418 414 {
419 415 errx(1, "out of memory");
420 416 }
421 417
422 418 static void
423 419 newae(struct aelist *ael, const char *arg)
424 420 {
425 421 struct ae *ae;
426 422
427 423 if ((ae = calloc(sizeof (*ae), 1)) == NULL)
428 424 nomem();
429 425 ae->ae_arg = strdup(arg);
430 426 if (ael->ael_tail == NULL)
431 427 ael->ael_head = ae;
432 428 else
433 429 ael->ael_tail->ae_next = ae;
434 430 ael->ael_tail = ae;
435 431 ael->ael_argc++;
436 432 }
437 433
438 434 static cw_ictx_t *
439 435 newictx(void)
440 436 {
441 437 cw_ictx_t *ctx = calloc(sizeof (cw_ictx_t), 1);
442 438 if (ctx)
443 439 if ((ctx->i_ae = calloc(sizeof (struct aelist), 1)) == NULL) {
444 440 free(ctx);
445 441 return (NULL);
446 442 }
447 443
448 444 return (ctx);
449 445 }
450 446
451 447 static void
452 448 error(const char *arg)
453 449 {
454 450 errx(2, "error: mapping failed at or near arg '%s'", arg);
455 451 }
456 452
457 453 /*
458 454 * Add the current favourite set of warnings to the gcc invocation.
459 455 */
460 456 static void
461 457 warnings(struct aelist *h)
462 458 {
463 459 static int warningsonce;
464 460
465 461 if (warningsonce++)
466 462 return;
467 463
468 464 /*
469 465 * Enable as many warnings as exist, then disable those that we never
470 466 * ever want.
471 467 */
472 468 newae(h, "-Wall");
473 469 newae(h, "-Wextra");
474 470 }
475 471
476 472 static void
477 473 optim_disable(struct aelist *h, int level)
478 474 {
479 475 if (level >= 2) {
480 476 newae(h, "-fno-strict-aliasing");
481 477 newae(h, "-fno-unit-at-a-time");
482 478 newae(h, "-fno-optimize-sibling-calls");
483 479 }
484 480 }
485 481
486 482 /* ARGSUSED */
487 483 static void
488 484 Xamode(struct aelist __unused *h)
489 485 {
490 486 }
491 487
492 488 static void
493 489 Xsmode(struct aelist *h)
494 490 {
495 491 static int xsonce;
496 492
497 493 if (xsonce++)
498 494 return;
499 495
500 496 newae(h, "-traditional");
501 497 newae(h, "-traditional-cpp");
502 498 }
503 499
504 500 static void
505 501 usage()
506 502 {
507 503 extern char *__progname;
508 504 (void) fprintf(stderr,
509 505 "usage: %s [-C] [--versions] --primary <compiler> "
510 506 "[--shadow <compiler>]... -- cflags...\n",
511 507 __progname);
512 508 (void) fprintf(stderr, "compilers take the form: name,path,style\n"
513 509 " - name: a unique name usable in flag specifiers\n"
514 510 " - path: path to the compiler binary\n"
515 511 " - style: the style of flags expected: either sun or gnu\n");
516 512 exit(2);
517 513 }
518 514
519 515 static int
520 516 xlate_xtb(struct aelist *h, const char *xarg)
521 517 {
522 518 int i, j;
523 519
524 520 for (i = 0; i < xtbl_size; i++) {
525 521 if (strcmp(xtbl[i].x_arg, xarg) == 0)
526 522 break;
527 523 }
528 524
529 525 /*
530 526 * At the end of the table and so no matching "arg" entry
531 527 * found and so this must be a bad -xarch= flag.
532 528 */
533 529 if (i == xtbl_size)
534 530 error(xarg);
535 531
536 532 for (j = 0; j < TRANS_ENTRY; j++) {
537 533 if (xtbl[i].x_trans[j] != NULL)
538 534 newae(h, xtbl[i].x_trans[j]);
539 535 else
540 536 break;
541 537 }
542 538 return (xtbl[i].x_flags);
543 539
544 540 }
545 541
546 542 static void
547 543 xlate(struct aelist *h, const char *xarg, const char **table)
548 544 {
549 545 while (*table != NULL && strcmp(xarg, *table) != 0) {
550 546 while (*table != NULL)
551 547 table++;
552 548 table++;
553 549 }
554 550
555 551 if (*table == NULL)
556 552 error(xarg);
557 553
558 554 table++;
559 555
↓ open down ↓ |
365 lines elided |
↑ open up ↑ |
560 556 while (*table != NULL) {
561 557 newae(h, *table);
562 558 table++;
563 559 }
564 560 }
565 561
566 562 static void
567 563 do_gcc(cw_ictx_t *ctx)
568 564 {
569 565 int c;
570 - int pic = 0, nolibc = 0;
566 + int nolibc = 0;
571 567 int in_output = 0, seen_o = 0, c_files = 0;
572 568 cw_op_t op = CW_O_LINK;
573 569 char *model = NULL;
574 570 char *nameflag;
575 571 int mflag = 0;
576 572
577 573 if (ctx->i_flags & CW_F_PROG) {
578 574 newae(ctx->i_ae, "--version");
579 575 return;
580 576 }
581 577
582 578 newae(ctx->i_ae, "-fident");
583 579 newae(ctx->i_ae, "-finline");
584 580 newae(ctx->i_ae, "-fno-inline-functions");
585 581 newae(ctx->i_ae, "-fno-builtin");
586 582 newae(ctx->i_ae, "-fno-asm");
587 583 newae(ctx->i_ae, "-fdiagnostics-show-option");
588 584 newae(ctx->i_ae, "-nodefaultlibs");
589 585
590 586 #if defined(__sparc)
591 587 /*
592 588 * The SPARC ldd and std instructions require 8-byte alignment of
593 589 * their address operand. gcc correctly uses them only when the
594 590 * ABI requires 8-byte alignment; unfortunately we have a number of
595 591 * pieces of buggy code that doesn't conform to the ABI. This
596 592 * flag makes gcc work more like Studio with -xmemalign=4.
597 593 */
598 594 newae(ctx->i_ae, "-mno-integer-ldd-std");
599 595 #endif
600 596
601 597 /*
602 598 * This is needed because 'u' is defined
603 599 * under a conditional on 'sun'. Should
604 600 * probably just remove the conditional,
605 601 * or make it be dependent on '__sun'.
606 602 *
607 603 * -Dunix is also missing in enhanced ANSI mode
608 604 */
609 605 newae(ctx->i_ae, "-D__sun");
610 606
611 607 if (asprintf(&nameflag, "-_%s=", ctx->i_compiler->c_name) == -1)
612 608 nomem();
613 609
614 610 /*
615 611 * Walk the argument list, translating as we go ..
616 612 */
617 613 while (--ctx->i_oldargc > 0) {
618 614 char *arg = *++ctx->i_oldargv;
619 615 size_t arglen = strlen(arg);
620 616
621 617 if (*arg == '-') {
622 618 arglen--;
623 619 } else {
624 620 /*
625 621 * Discard inline files that gcc doesn't grok
626 622 */
627 623 if (!in_output && arglen > 3 &&
628 624 strcmp(arg + arglen - 3, ".il") == 0)
629 625 continue;
630 626
631 627 if (!in_output && arglen > 2 &&
632 628 arg[arglen - 2] == '.' &&
633 629 (arg[arglen - 1] == 'S' || arg[arglen - 1] == 's' ||
634 630 arg[arglen - 1] == 'c' || arg[arglen - 1] == 'i'))
635 631 c_files++;
636 632
637 633 /*
638 634 * Otherwise, filenames and partial arguments
639 635 * are passed through for gcc to chew on. However,
640 636 * output is always discarded for the secondary
641 637 * compiler.
642 638 */
643 639 if ((ctx->i_flags & CW_F_SHADOW) && in_output)
644 640 newae(ctx->i_ae, ctx->i_discard);
645 641 else
646 642 newae(ctx->i_ae, arg);
647 643 in_output = 0;
648 644 continue;
649 645 }
650 646
651 647 if (ctx->i_flags & CW_F_CXX) {
652 648 if (strncmp(arg, "-_g++=", 6) == 0) {
653 649 newae(ctx->i_ae, strchr(arg, '=') + 1);
654 650 continue;
655 651 }
656 652 if (strncmp(arg, "-compat=", 8) == 0) {
657 653 /* discard -compat=4 and -compat=5 */
658 654 continue;
659 655 }
660 656 if (strcmp(arg, "-Qoption") == 0) {
661 657 /* discard -Qoption and its two arguments */
662 658 if (ctx->i_oldargc < 3)
663 659 error(arg);
664 660 ctx->i_oldargc -= 2;
665 661 ctx->i_oldargv += 2;
666 662 continue;
667 663 }
668 664 if (strcmp(arg, "-xwe") == 0) {
669 665 /* turn warnings into errors */
670 666 newae(ctx->i_ae, "-Werror");
671 667 continue;
672 668 }
673 669 if (strcmp(arg, "-norunpath") == 0) {
674 670 /* gcc has no corresponding option */
675 671 continue;
676 672 }
677 673 if (strcmp(arg, "-nolib") == 0) {
678 674 /* -nodefaultlibs is on by default */
679 675 nolibc = 1;
680 676 continue;
681 677 }
682 678 #if defined(__sparc)
683 679 if (strcmp(arg, "-cg92") == 0) {
684 680 mflag |= xlate_xtb(ctx->i_ae, "v8");
685 681 xlate(ctx->i_ae, "super", xchip_tbl);
686 682 continue;
687 683 }
688 684 #endif /* __sparc */
689 685 }
690 686
691 687 switch ((c = arg[1])) {
692 688 case '_':
693 689 if ((strncmp(arg, nameflag, strlen(nameflag)) == 0) ||
694 690 (strncmp(arg, "-_gcc=", 6) == 0) ||
695 691 (strncmp(arg, "-_gnu=", 6) == 0)) {
↓ open down ↓ |
115 lines elided |
↑ open up ↑ |
696 692 newae(ctx->i_ae, strchr(arg, '=') + 1);
697 693 }
698 694 break;
699 695 case '#':
700 696 if (arglen == 1) {
701 697 newae(ctx->i_ae, "-v");
702 698 break;
703 699 }
704 700 error(arg);
705 701 break;
702 + case 'f':
703 + if ((strcmp(arg, "-fpic") == 0) ||
704 + (strcmp(arg, "-fPIC") == 0)) {
705 + newae(ctx->i_ae, arg);
706 + break;
707 + }
708 + error(arg);
709 + break;
706 710 case 'g':
707 711 newae(ctx->i_ae, "-gdwarf-2");
708 712 break;
709 713 case 'E':
710 714 if (arglen == 1) {
711 715 newae(ctx->i_ae, "-xc");
712 716 newae(ctx->i_ae, arg);
713 717 op = CW_O_PREPROCESS;
714 718 nolibc = 1;
715 719 break;
716 720 }
717 721 error(arg);
718 722 break;
719 723 case 'c':
720 724 case 'S':
721 725 if (arglen == 1) {
722 726 op = CW_O_COMPILE;
723 727 nolibc = 1;
724 728 }
725 729 /* FALLTHROUGH */
726 730 case 'C':
727 731 case 'H':
728 732 case 'p':
729 733 if (arglen == 1) {
730 734 newae(ctx->i_ae, arg);
731 735 break;
732 736 }
733 737 error(arg);
734 738 break;
735 739 case 'A':
736 740 case 'h':
737 741 case 'I':
738 742 case 'i':
739 743 case 'L':
740 744 case 'l':
741 745 case 'R':
742 746 case 'U':
743 747 case 'u':
744 748 case 'w':
745 749 newae(ctx->i_ae, arg);
746 750 break;
747 751 case 'o':
748 752 seen_o = 1;
749 753 if (arglen == 1) {
750 754 in_output = 1;
751 755 newae(ctx->i_ae, arg);
752 756 } else if (ctx->i_flags & CW_F_SHADOW) {
753 757 newae(ctx->i_ae, "-o");
754 758 newae(ctx->i_ae, ctx->i_discard);
755 759 } else {
756 760 newae(ctx->i_ae, arg);
757 761 }
758 762 break;
759 763 case 'D':
760 764 newae(ctx->i_ae, arg);
761 765 /*
762 766 * XXX Clearly a hack ... do we need _KADB too?
763 767 */
764 768 if (strcmp(arg, "-D_KERNEL") == 0 ||
765 769 strcmp(arg, "-D_BOOT") == 0)
766 770 newae(ctx->i_ae, "-ffreestanding");
767 771 break;
768 772 case 'd':
769 773 if (arglen == 2) {
770 774 if (strcmp(arg, "-dy") == 0) {
771 775 newae(ctx->i_ae, "-Wl,-dy");
772 776 break;
773 777 }
774 778 if (strcmp(arg, "-dn") == 0) {
775 779 newae(ctx->i_ae, "-Wl,-dn");
776 780 break;
777 781 }
778 782 }
779 783 if (strcmp(arg, "-dalign") == 0) {
780 784 /*
781 785 * -dalign forces alignment in some cases;
782 786 * gcc does not need any flag to do this.
783 787 */
784 788 break;
785 789 }
786 790 error(arg);
787 791 break;
788 792 case 'e':
789 793 if (strcmp(arg,
790 794 "-erroff=E_EMPTY_TRANSLATION_UNIT") == 0) {
791 795 /*
792 796 * Accept but ignore this -- gcc doesn't
793 797 * seem to complain about empty translation
794 798 * units
795 799 */
796 800 break;
797 801 }
798 802 /* XX64 -- ignore all -erroff= options, for now */
799 803 if (strncmp(arg, "-erroff=", 8) == 0)
800 804 break;
801 805 if (strcmp(arg, "-errtags=yes") == 0) {
802 806 warnings(ctx->i_ae);
803 807 break;
804 808 }
805 809 if (strcmp(arg, "-errwarn=%all") == 0) {
806 810 newae(ctx->i_ae, "-Werror");
807 811 break;
808 812 }
809 813 error(arg);
810 814 break;
811 815 case 'G':
↓ open down ↓ |
96 lines elided |
↑ open up ↑ |
812 816 newae(ctx->i_ae, "-shared");
813 817 nolibc = 1;
814 818 break;
815 819 case 'k':
816 820 if (strcmp(arg, "-keeptmp") == 0) {
817 821 newae(ctx->i_ae, "-save-temps");
818 822 break;
819 823 }
820 824 error(arg);
821 825 break;
822 - case 'K':
823 - if (arglen == 1) {
824 - if ((arg = *++ctx->i_oldargv) == NULL ||
825 - *arg == '\0')
826 - error("-K");
827 - ctx->i_oldargc--;
828 - } else {
829 - arg += 2;
830 - }
831 - if (strcmp(arg, "pic") == 0) {
832 - newae(ctx->i_ae, "-fpic");
833 - pic = 1;
834 - break;
835 - }
836 - if (strcmp(arg, "PIC") == 0) {
837 - newae(ctx->i_ae, "-fPIC");
838 - pic = 1;
839 - break;
840 - }
841 - error("-K");
842 - break;
843 826 case 'm':
844 827 if (strcmp(arg, "-mt") == 0) {
845 828 newae(ctx->i_ae, "-D_REENTRANT");
846 829 break;
847 830 }
848 831 if (strcmp(arg, "-m64") == 0) {
849 832 newae(ctx->i_ae, "-m64");
850 833 #if defined(__x86)
851 834 newae(ctx->i_ae, "-mtune=opteron");
852 835 #endif
853 836 mflag |= M64;
854 837 break;
855 838 }
856 839 if (strcmp(arg, "-m32") == 0) {
857 840 newae(ctx->i_ae, "-m32");
858 841 mflag |= M32;
859 842 break;
860 843 }
861 844 error(arg);
862 845 break;
863 846 case 'B': /* linker options */
864 847 case 'M':
865 848 case 'z':
866 849 {
867 850 char *opt;
868 851 size_t len;
869 852 char *s;
870 853
871 854 if (arglen == 1) {
872 855 opt = *++ctx->i_oldargv;
873 856 if (opt == NULL || *opt == '\0')
874 857 error(arg);
875 858 ctx->i_oldargc--;
876 859 } else {
877 860 opt = arg + 2;
878 861 }
879 862 len = strlen(opt) + 7;
880 863 if ((s = malloc(len)) == NULL)
881 864 nomem();
882 865 (void) snprintf(s, len, "-Wl,-%c%s", c, opt);
883 866 newae(ctx->i_ae, s);
884 867 free(s);
885 868 }
886 869 break;
887 870 case 'O':
888 871 if (arglen == 1) {
889 872 newae(ctx->i_ae, "-O");
890 873 break;
891 874 }
892 875 error(arg);
893 876 break;
894 877 case 'P':
895 878 /*
896 879 * We could do '-E -o filename.i', but that's hard,
897 880 * and we don't need it for the case that's triggering
898 881 * this addition. We'll require the user to specify
899 882 * -o in the Makefile. If they don't they'll find out
900 883 * in a hurry.
901 884 */
902 885 newae(ctx->i_ae, "-E");
903 886 op = CW_O_PREPROCESS;
904 887 nolibc = 1;
905 888 break;
906 889 case 's':
907 890 if (arglen == 1) {
908 891 newae(ctx->i_ae, "-Wl,-s");
909 892 break;
910 893 }
911 894 error(arg);
912 895 break;
913 896 case 't':
914 897 if (arglen == 1) {
915 898 newae(ctx->i_ae, "-Wl,-t");
916 899 break;
917 900 }
918 901 error(arg);
919 902 break;
920 903 case 'V':
921 904 if (arglen == 1) {
922 905 ctx->i_flags &= ~CW_F_ECHO;
923 906 newae(ctx->i_ae, "--version");
924 907 break;
925 908 }
926 909 error(arg);
927 910 break;
928 911 case 'v':
929 912 if (arglen == 1) {
930 913 warnings(ctx->i_ae);
931 914 break;
932 915 }
933 916 error(arg);
934 917 break;
935 918 case 'W':
936 919 if (strncmp(arg, "-Wp,-xc99", 9) == 0) {
937 920 /*
938 921 * gcc's preprocessor will accept c99
939 922 * regardless, so accept and ignore.
940 923 */
941 924 break;
942 925 }
943 926 if (strncmp(arg, "-Wa,", 4) == 0 ||
944 927 strncmp(arg, "-Wp,", 4) == 0 ||
945 928 strncmp(arg, "-Wl,", 4) == 0) {
946 929 newae(ctx->i_ae, arg);
947 930 break;
948 931 }
949 932 if (strcmp(arg, "-W0,-noglobal") == 0 ||
950 933 strcmp(arg, "-W0,-xglobalstatic") == 0) {
951 934 /*
952 935 * gcc doesn't prefix local symbols
953 936 * in debug mode, so this is not needed.
954 937 */
955 938 break;
956 939 }
957 940 if (strcmp(arg, "-W0,-Lt") == 0) {
958 941 /*
959 942 * Generate tests at the top of loops.
960 943 * There is no direct gcc equivalent, ignore.
961 944 */
962 945 break;
963 946 }
964 947 if (strcmp(arg, "-W0,-xdbggen=no%usedonly") == 0) {
965 948 newae(ctx->i_ae,
966 949 "-fno-eliminate-unused-debug-symbols");
967 950 newae(ctx->i_ae,
968 951 "-fno-eliminate-unused-debug-types");
969 952 break;
970 953 }
971 954 if (strcmp(arg, "-W2,-xwrap_int") == 0) {
972 955 /*
973 956 * Use the legacy behaviour (pre-SS11)
974 957 * for integer wrapping.
975 958 * gcc does not need this.
976 959 */
977 960 break;
978 961 }
↓ open down ↓ |
126 lines elided |
↑ open up ↑ |
979 962 if (strcmp(arg, "-Wd,-xsafe=unboundsym") == 0) {
980 963 /*
981 964 * Prevents optimizing away checks for
982 965 * unbound weak symbol addresses. gcc does
983 966 * not do this, so it's not needed.
984 967 */
985 968 break;
986 969 }
987 970 if (strncmp(arg, "-Wc,-xcode=", 11) == 0) {
988 971 xlate(ctx->i_ae, arg + 11, xcode_tbl);
989 - if (strncmp(arg + 11, "pic", 3) == 0)
990 - pic = 1;
991 972 break;
992 973 }
993 974 if (strncmp(arg, "-Wc,-Qiselect", 13) == 0) {
994 975 /*
995 976 * Prevents insertion of register symbols.
996 977 * gcc doesn't do this, so ignore it.
997 978 */
998 979 break;
999 980 }
1000 981 if (strcmp(arg, "-Wc,-Qassembler-ounrefsym=0") == 0) {
1001 982 /*
1002 983 * Prevents optimizing away of static variables.
1003 984 * gcc does not do this, so it's not needed.
1004 985 */
1005 986 break;
1006 987 }
1007 988 #if defined(__x86)
1008 989 if (strcmp(arg, "-Wu,-save_args") == 0) {
1009 990 newae(ctx->i_ae, "-msave-args");
1010 991 break;
1011 992 }
1012 993 #endif /* __x86 */
1013 994 error(arg);
1014 995 break;
1015 996 case 'X':
1016 997 if (strcmp(arg, "-Xa") == 0 ||
1017 998 strcmp(arg, "-Xt") == 0) {
1018 999 Xamode(ctx->i_ae);
1019 1000 break;
1020 1001 }
1021 1002 if (strcmp(arg, "-Xs") == 0) {
1022 1003 Xsmode(ctx->i_ae);
1023 1004 break;
1024 1005 }
1025 1006 error(arg);
1026 1007 break;
1027 1008 case 'x':
1028 1009 if (arglen == 1)
1029 1010 error(arg);
1030 1011 switch (arg[2]) {
1031 1012 case 'a':
1032 1013 if (strncmp(arg, "-xarch=", 7) == 0) {
1033 1014 mflag |= xlate_xtb(ctx->i_ae, arg + 7);
1034 1015 break;
1035 1016 }
1036 1017 error(arg);
1037 1018 break;
1038 1019 case 'b':
1039 1020 if (strncmp(arg, "-xbuiltin=", 10) == 0) {
1040 1021 if (strcmp(arg + 10, "%all"))
1041 1022 newae(ctx->i_ae, "-fbuiltin");
1042 1023 break;
1043 1024 }
1044 1025 error(arg);
1045 1026 break;
1046 1027 case 'C':
1047 1028 /* Accept C++ style comments -- ignore */
1048 1029 if (strcmp(arg, "-xCC") == 0)
1049 1030 break;
1050 1031 error(arg);
1051 1032 break;
1052 1033 case 'c':
1053 1034 if (strncmp(arg, "-xc99=%all", 10) == 0) {
1054 1035 newae(ctx->i_ae, "-std=gnu99");
1055 1036 break;
1056 1037 }
↓ open down ↓ |
56 lines elided |
↑ open up ↑ |
1057 1038 if (strncmp(arg, "-xc99=%none", 11) == 0) {
1058 1039 newae(ctx->i_ae, "-std=gnu89");
1059 1040 break;
1060 1041 }
1061 1042 if (strncmp(arg, "-xchip=", 7) == 0) {
1062 1043 xlate(ctx->i_ae, arg + 7, xchip_tbl);
1063 1044 break;
1064 1045 }
1065 1046 if (strncmp(arg, "-xcode=", 7) == 0) {
1066 1047 xlate(ctx->i_ae, arg + 7, xcode_tbl);
1067 - if (strncmp(arg + 7, "pic", 3) == 0)
1068 - pic = 1;
1069 1048 break;
1070 1049 }
1071 1050 if (strncmp(arg, "-xcrossfile", 11) == 0)
1072 1051 break;
1073 1052 error(arg);
1074 1053 break;
1075 1054 case 'd':
1076 1055 if (strncmp(arg, "-xdebugformat=", 14) == 0)
1077 1056 break;
1078 1057 error(arg);
1079 1058 break;
1080 1059 case 'F':
1081 1060 /*
1082 1061 * Compile for mapfile reordering, or unused
1083 1062 * section elimination, syntax can be -xF or
1084 1063 * more complex, like -xF=%all -- ignore.
1085 1064 */
1086 1065 if (strncmp(arg, "-xF", 3) == 0)
1087 1066 break;
1088 1067 error(arg);
1089 1068 break;
1090 1069 case 'i':
1091 1070 if (strncmp(arg, "-xinline", 8) == 0)
1092 1071 /* No inlining; ignore */
1093 1072 break;
1094 1073 if (strcmp(arg, "-xildon") == 0 ||
1095 1074 strcmp(arg, "-xildoff") == 0)
1096 1075 /* No incremental linking; ignore */
1097 1076 break;
1098 1077 error(arg);
1099 1078 break;
1100 1079 #if defined(__x86)
1101 1080 case 'm':
1102 1081 if (strcmp(arg, "-xmodel=kernel") == 0) {
1103 1082 newae(ctx->i_ae, "-ffreestanding");
1104 1083 newae(ctx->i_ae, "-mno-red-zone");
1105 1084 model = "-mcmodel=kernel";
1106 1085 nolibc = 1;
1107 1086 break;
1108 1087 }
1109 1088 error(arg);
1110 1089 break;
1111 1090 #endif /* __x86 */
1112 1091 case 'O':
1113 1092 if (strncmp(arg, "-xO", 3) == 0) {
1114 1093 size_t len = strlen(arg);
1115 1094 char *s = NULL;
1116 1095 int c = *(arg + 3);
1117 1096 int level;
1118 1097
1119 1098 if (len != 4 || !isdigit(c))
1120 1099 error(arg);
1121 1100
1122 1101 level = atoi(arg + 3);
1123 1102 if (level > 5)
1124 1103 error(arg);
1125 1104 if (level >= 2) {
1126 1105 /*
1127 1106 * For gcc-3.4.x at -O2 we
1128 1107 * need to disable optimizations
1129 1108 * that break ON.
1130 1109 */
1131 1110 optim_disable(ctx->i_ae, level);
1132 1111 /*
1133 1112 * limit -xO3 to -O2 as well.
1134 1113 */
1135 1114 level = 2;
1136 1115 }
1137 1116 if (asprintf(&s, "-O%d", level) == -1)
1138 1117 nomem();
1139 1118 newae(ctx->i_ae, s);
1140 1119 free(s);
1141 1120 break;
1142 1121 }
1143 1122 error(arg);
1144 1123 break;
1145 1124 case 'r':
1146 1125 if (strncmp(arg, "-xregs=", 7) == 0) {
1147 1126 xlate(ctx->i_ae, arg + 7, xregs_tbl);
1148 1127 break;
1149 1128 }
1150 1129 error(arg);
1151 1130 break;
1152 1131 case 's':
1153 1132 if (strcmp(arg, "-xs") == 0 ||
1154 1133 strcmp(arg, "-xspace") == 0 ||
1155 1134 strcmp(arg, "-xstrconst") == 0)
1156 1135 break;
1157 1136 error(arg);
1158 1137 break;
1159 1138 case 't':
1160 1139 if (strncmp(arg, "-xtarget=", 9) == 0) {
1161 1140 xlate(ctx->i_ae, arg + 9, xtarget_tbl);
1162 1141 break;
1163 1142 }
1164 1143 error(arg);
1165 1144 break;
1166 1145 case 'e':
1167 1146 case 'h':
1168 1147 case 'l':
1169 1148 default:
1170 1149 error(arg);
1171 1150 break;
1172 1151 }
1173 1152 break;
1174 1153 case 'Y':
1175 1154 if (arglen == 1) {
1176 1155 if ((arg = *++ctx->i_oldargv) == NULL ||
1177 1156 *arg == '\0')
1178 1157 error("-Y");
1179 1158 ctx->i_oldargc--;
1180 1159 arglen = strlen(arg + 1);
1181 1160 } else {
1182 1161 arg += 2;
1183 1162 }
1184 1163 /* Just ignore -YS,... for now */
1185 1164 if (strncmp(arg, "S,", 2) == 0)
1186 1165 break;
1187 1166 if (strncmp(arg, "l,", 2) == 0) {
1188 1167 char *s = strdup(arg);
1189 1168 s[0] = '-';
1190 1169 s[1] = 'B';
1191 1170 newae(ctx->i_ae, s);
1192 1171 free(s);
1193 1172 break;
1194 1173 }
1195 1174 if (strncmp(arg, "I,", 2) == 0) {
1196 1175 char *s = strdup(arg);
1197 1176 s[0] = '-';
1198 1177 s[1] = 'I';
1199 1178 newae(ctx->i_ae, "-nostdinc");
1200 1179 newae(ctx->i_ae, s);
1201 1180 free(s);
1202 1181 break;
1203 1182 }
1204 1183 error(arg);
1205 1184 break;
1206 1185 case 'Q':
1207 1186 /*
1208 1187 * We could map -Qy into -Wl,-Qy etc.
1209 1188 */
1210 1189 default:
1211 1190 error(arg);
1212 1191 break;
1213 1192 }
1214 1193 }
1215 1194
1216 1195 free(nameflag);
1217 1196
1218 1197 if (c_files > 1 && (ctx->i_flags & CW_F_SHADOW) &&
1219 1198 op != CW_O_PREPROCESS) {
1220 1199 errx(2, "multiple source files are "
1221 1200 "allowed only with -E or -P");
1222 1201 }
1223 1202
1224 1203 /*
1225 1204 * Make sure that we do not have any unintended interactions between
1226 1205 * the xarch options passed in and the version of the Studio compiler
1227 1206 * used.
1228 1207 */
1229 1208 if ((mflag & (SS11|SS12)) == (SS11|SS12)) {
1230 1209 errx(2,
1231 1210 "Conflicting \"-xarch=\" flags (both Studio 11 and 12)\n");
1232 1211 }
1233 1212
1234 1213 switch (mflag) {
1235 1214 case 0:
1236 1215 /* FALLTHROUGH */
1237 1216 case M32:
1238 1217 #if defined(__sparc)
1239 1218 /*
1240 1219 * Only -m32 is defined and so put in the missing xarch
1241 1220 * translation.
1242 1221 */
1243 1222 newae(ctx->i_ae, "-mcpu=v8");
1244 1223 newae(ctx->i_ae, "-mno-v8plus");
1245 1224 #endif
1246 1225 break;
1247 1226 case M64:
1248 1227 #if defined(__sparc)
1249 1228 /*
1250 1229 * Only -m64 is defined and so put in the missing xarch
1251 1230 * translation.
1252 1231 */
1253 1232 newae(ctx->i_ae, "-mcpu=v9");
1254 1233 #endif
1255 1234 break;
1256 1235 case SS12:
1257 1236 #if defined(__sparc)
1258 1237 /* no -m32/-m64 flag used - this is an error for sparc builds */
1259 1238 (void) fprintf(stderr, "No -m32/-m64 flag defined\n");
1260 1239 exit(2);
1261 1240 #endif
1262 1241 break;
1263 1242 case SS11:
1264 1243 /* FALLTHROUGH */
1265 1244 case (SS11|M32):
1266 1245 case (SS11|M64):
1267 1246 break;
1268 1247 case (SS12|M32):
1269 1248 #if defined(__sparc)
1270 1249 /*
1271 1250 * Need to add in further 32 bit options because with SS12
1272 1251 * the xarch=sparcvis option can be applied to 32 or 64
1273 1252 * bit, and so the translatation table (xtbl) cannot handle
1274 1253 * that.
1275 1254 */
1276 1255 newae(ctx->i_ae, "-mv8plus");
1277 1256 #endif
1278 1257 break;
1279 1258 case (SS12|M64):
1280 1259 break;
↓ open down ↓ |
202 lines elided |
↑ open up ↑ |
1281 1260 default:
1282 1261 (void) fprintf(stderr,
1283 1262 "Incompatible -xarch= and/or -m32/-m64 options used.\n");
1284 1263 exit(2);
1285 1264 }
1286 1265
1287 1266 if ((op == CW_O_LINK || op == CW_O_PREPROCESS) &&
1288 1267 (ctx->i_flags & CW_F_SHADOW))
1289 1268 exit(0);
1290 1269
1291 - if (model && !pic)
1270 + if (model != NULL)
1292 1271 newae(ctx->i_ae, model);
1293 1272 if (!nolibc)
1294 1273 newae(ctx->i_ae, "-lc");
1295 1274 if (!seen_o && (ctx->i_flags & CW_F_SHADOW)) {
1296 1275 newae(ctx->i_ae, "-o");
1297 1276 newae(ctx->i_ae, ctx->i_discard);
1298 1277 }
1299 1278 }
1300 1279
1301 1280 static void
1302 1281 do_cc(cw_ictx_t *ctx)
1303 1282 {
1304 1283 int in_output = 0, seen_o = 0;
1305 1284 cw_op_t op = CW_O_LINK;
1306 1285 char *nameflag;
1307 1286
1308 1287 if (ctx->i_flags & CW_F_PROG) {
1309 1288 newae(ctx->i_ae, "-V");
1310 1289 return;
1311 1290 }
1312 1291
1313 1292 if (asprintf(&nameflag, "-_%s=", ctx->i_compiler->c_name) == -1)
1314 1293 nomem();
1315 1294
1316 1295 while (--ctx->i_oldargc > 0) {
1317 1296 char *arg = *++ctx->i_oldargv;
1318 1297
1319 1298 if (strncmp(arg, "-_CC=", 5) == 0) {
1320 1299 newae(ctx->i_ae, strchr(arg, '=') + 1);
1321 1300 continue;
1322 1301 }
1323 1302
1324 1303 if (*arg != '-') {
1325 1304 if (in_output == 0 || !(ctx->i_flags & CW_F_SHADOW)) {
1326 1305 newae(ctx->i_ae, arg);
1327 1306 } else {
1328 1307 in_output = 0;
1329 1308 newae(ctx->i_ae, ctx->i_discard);
1330 1309 }
1331 1310 continue;
1332 1311 }
1333 1312 switch (*(arg + 1)) {
1334 1313 case '_':
1335 1314 if ((strncmp(arg, nameflag, strlen(nameflag)) == 0) ||
1336 1315 (strncmp(arg, "-_cc=", 5) == 0) ||
1337 1316 (strncmp(arg, "-_sun=", 6) == 0)) {
1338 1317 newae(ctx->i_ae, strchr(arg, '=') + 1);
1339 1318 }
1340 1319 break;
1341 1320
1342 1321 case 'V':
1343 1322 ctx->i_flags &= ~CW_F_ECHO;
1344 1323 newae(ctx->i_ae, arg);
1345 1324 break;
1346 1325 case 'o':
1347 1326 seen_o = 1;
1348 1327 if (strlen(arg) == 2) {
1349 1328 in_output = 1;
1350 1329 newae(ctx->i_ae, arg);
1351 1330 } else if (ctx->i_flags & CW_F_SHADOW) {
1352 1331 newae(ctx->i_ae, "-o");
1353 1332 newae(ctx->i_ae, ctx->i_discard);
1354 1333 } else {
1355 1334 newae(ctx->i_ae, arg);
1356 1335 }
1357 1336 break;
1358 1337 case 'c':
1359 1338 case 'S':
1360 1339 if (strlen(arg) == 2)
1361 1340 op = CW_O_COMPILE;
1362 1341 newae(ctx->i_ae, arg);
1363 1342 break;
1364 1343 case 'E':
1365 1344 case 'P':
1366 1345 if (strlen(arg) == 2)
1367 1346 op = CW_O_PREPROCESS;
1368 1347 /*FALLTHROUGH*/
1369 1348 default:
1370 1349 newae(ctx->i_ae, arg);
1371 1350 }
1372 1351 }
1373 1352
1374 1353 free(nameflag);
1375 1354
1376 1355 if ((op == CW_O_LINK || op == CW_O_PREPROCESS) &&
1377 1356 (ctx->i_flags & CW_F_SHADOW))
1378 1357 exit(0);
1379 1358
1380 1359 if (!seen_o && (ctx->i_flags & CW_F_SHADOW)) {
1381 1360 newae(ctx->i_ae, "-o");
1382 1361 newae(ctx->i_ae, ctx->i_discard);
1383 1362 }
1384 1363 }
1385 1364
1386 1365 static void
1387 1366 prepctx(cw_ictx_t *ctx)
1388 1367 {
1389 1368 newae(ctx->i_ae, ctx->i_compiler->c_path);
1390 1369
1391 1370 if (ctx->i_flags & CW_F_PROG) {
1392 1371 (void) printf("%s: %s\n", (ctx->i_flags & CW_F_SHADOW) ?
1393 1372 "shadow" : "primary", ctx->i_compiler->c_path);
1394 1373 (void) fflush(stdout);
1395 1374 }
1396 1375
1397 1376 if (!(ctx->i_flags & CW_F_XLATE))
1398 1377 return;
1399 1378
1400 1379 switch (ctx->i_compiler->c_style) {
1401 1380 case SUN:
1402 1381 do_cc(ctx);
1403 1382 break;
1404 1383 case GNU:
1405 1384 do_gcc(ctx);
1406 1385 break;
1407 1386 }
1408 1387 }
1409 1388
1410 1389 static int
1411 1390 invoke(cw_ictx_t *ctx)
1412 1391 {
1413 1392 char **newargv;
1414 1393 int ac;
1415 1394 struct ae *a;
1416 1395
1417 1396 if ((newargv = calloc(sizeof (*newargv), ctx->i_ae->ael_argc + 1)) ==
1418 1397 NULL)
1419 1398 nomem();
1420 1399
1421 1400 if (ctx->i_flags & CW_F_ECHO)
1422 1401 (void) fprintf(stderr, "+ ");
1423 1402
1424 1403 for (ac = 0, a = ctx->i_ae->ael_head; a; a = a->ae_next, ac++) {
1425 1404 newargv[ac] = a->ae_arg;
1426 1405 if (ctx->i_flags & CW_F_ECHO)
1427 1406 (void) fprintf(stderr, "%s ", a->ae_arg);
1428 1407 if (a == ctx->i_ae->ael_tail)
1429 1408 break;
1430 1409 }
1431 1410
1432 1411 if (ctx->i_flags & CW_F_ECHO) {
1433 1412 (void) fprintf(stderr, "\n");
1434 1413 (void) fflush(stderr);
1435 1414 }
1436 1415
1437 1416 if (!(ctx->i_flags & CW_F_EXEC))
1438 1417 return (0);
1439 1418
1440 1419 /*
1441 1420 * We must fix up the environment here so that the dependency files are
1442 1421 * not trampled by the shadow compiler. Also take care of GCC
1443 1422 * environment variables that will throw off gcc. This assumes a primary
1444 1423 * gcc.
1445 1424 */
1446 1425 if ((ctx->i_flags & CW_F_SHADOW) &&
1447 1426 (unsetenv("SUNPRO_DEPENDENCIES") != 0 ||
1448 1427 unsetenv("DEPENDENCIES_OUTPUT") != 0 ||
1449 1428 unsetenv("GCC_ROOT") != 0)) {
1450 1429 (void) fprintf(stderr, "error: environment setup failed: %s\n",
1451 1430 strerror(errno));
1452 1431 return (-1);
1453 1432 }
1454 1433
1455 1434 (void) execv(newargv[0], newargv);
1456 1435 warn("couldn't run %s", newargv[0]);
1457 1436
1458 1437 return (-1);
1459 1438 }
1460 1439
1461 1440 static int
1462 1441 reap(cw_ictx_t *ctx)
1463 1442 {
1464 1443 int status, ret = 0;
1465 1444 char buf[1024];
1466 1445 struct stat s;
1467 1446
1468 1447 /*
1469 1448 * Only wait for one specific child.
1470 1449 */
1471 1450 if (ctx->i_pid <= 0)
1472 1451 return (-1);
1473 1452
1474 1453 do {
1475 1454 if (waitpid(ctx->i_pid, &status, 0) < 0) {
1476 1455 warn("cannot reap child");
1477 1456 return (-1);
1478 1457 }
1479 1458 if (status != 0) {
1480 1459 if (WIFSIGNALED(status)) {
1481 1460 ret = -WTERMSIG(status);
1482 1461 break;
1483 1462 } else if (WIFEXITED(status)) {
1484 1463 ret = WEXITSTATUS(status);
1485 1464 break;
1486 1465 }
1487 1466 }
1488 1467 } while (!WIFEXITED(status) && !WIFSIGNALED(status));
1489 1468
1490 1469 (void) unlink(ctx->i_discard);
1491 1470
1492 1471 if (stat(ctx->i_stderr, &s) < 0) {
1493 1472 warn("stat failed on child cleanup");
1494 1473 return (-1);
1495 1474 }
1496 1475 if (s.st_size != 0) {
1497 1476 FILE *f;
1498 1477
1499 1478 if ((f = fopen(ctx->i_stderr, "r")) != NULL) {
1500 1479 while (fgets(buf, sizeof (buf), f))
1501 1480 (void) fprintf(stderr, "%s", buf);
1502 1481 (void) fflush(stderr);
1503 1482 (void) fclose(f);
1504 1483 }
1505 1484 }
1506 1485 (void) unlink(ctx->i_stderr);
1507 1486 free(ctx->i_stderr);
1508 1487
1509 1488 /*
1510 1489 * cc returns an error code when given -V; we want that to succeed.
1511 1490 */
1512 1491 if (ctx->i_flags & CW_F_PROG)
1513 1492 return (0);
1514 1493
1515 1494 return (ret);
1516 1495 }
1517 1496
1518 1497 static int
1519 1498 exec_ctx(cw_ictx_t *ctx, int block)
1520 1499 {
1521 1500 char *file;
1522 1501
1523 1502 /*
1524 1503 * To avoid offending cc's sensibilities, the name of its output
1525 1504 * file must end in '.o'.
1526 1505 */
1527 1506 if ((file = tempnam(NULL, ".cw")) == NULL) {
1528 1507 nomem();
1529 1508 return (-1);
1530 1509 }
1531 1510 (void) strlcpy(ctx->i_discard, file, MAXPATHLEN);
1532 1511 (void) strlcat(ctx->i_discard, ".o", MAXPATHLEN);
1533 1512 free(file);
1534 1513
1535 1514 if ((ctx->i_stderr = tempnam(NULL, ".cw")) == NULL) {
1536 1515 nomem();
1537 1516 return (-1);
1538 1517 }
1539 1518
1540 1519 if ((ctx->i_pid = fork()) == 0) {
1541 1520 int fd;
1542 1521
1543 1522 (void) fclose(stderr);
1544 1523 if ((fd = open(ctx->i_stderr, O_WRONLY | O_CREAT | O_EXCL,
1545 1524 0666)) < 0) {
1546 1525 err(1, "open failed for standard error");
1547 1526 }
1548 1527 if (dup2(fd, 2) < 0) {
1549 1528 err(1, "dup2 failed for standard error");
1550 1529 }
1551 1530 if (fd != 2)
1552 1531 (void) close(fd);
1553 1532 if (freopen("/dev/fd/2", "w", stderr) == NULL) {
1554 1533 err(1, "freopen failed for /dev/fd/2");
1555 1534 }
1556 1535
1557 1536 prepctx(ctx);
1558 1537 exit(invoke(ctx));
1559 1538 }
1560 1539
1561 1540 if (ctx->i_pid < 0) {
1562 1541 err(1, "fork failed");
1563 1542 }
1564 1543
1565 1544 if (block)
1566 1545 return (reap(ctx));
1567 1546
1568 1547 return (0);
1569 1548 }
1570 1549
1571 1550 static void
1572 1551 parse_compiler(const char *spec, cw_compiler_t *compiler)
1573 1552 {
1574 1553 char *tspec, *token;
1575 1554
1576 1555 if ((tspec = strdup(spec)) == NULL)
1577 1556 nomem();
1578 1557
1579 1558 if ((token = strsep(&tspec, ",")) == NULL)
1580 1559 errx(1, "Compiler is missing a name: %s", spec);
1581 1560 compiler->c_name = token;
1582 1561
1583 1562 if ((token = strsep(&tspec, ",")) == NULL)
1584 1563 errx(1, "Compiler is missing a path: %s", spec);
1585 1564 compiler->c_path = token;
1586 1565
1587 1566 if ((token = strsep(&tspec, ",")) == NULL)
1588 1567 errx(1, "Compiler is missing a style: %s", spec);
1589 1568
1590 1569 if ((strcasecmp(token, "gnu") == 0) ||
1591 1570 (strcasecmp(token, "gcc") == 0))
1592 1571 compiler->c_style = GNU;
1593 1572 else if ((strcasecmp(token, "sun") == 0) ||
1594 1573 (strcasecmp(token, "cc") == 0))
1595 1574 compiler->c_style = SUN;
1596 1575 else
1597 1576 errx(1, "unknown compiler style: %s", token);
1598 1577
1599 1578 if (tspec != NULL)
1600 1579 errx(1, "Excess tokens in compiler: %s", spec);
1601 1580 }
1602 1581
1603 1582 int
1604 1583 main(int argc, char **argv)
1605 1584 {
1606 1585 int ch;
1607 1586 cw_compiler_t primary = { NULL, NULL, 0 };
1608 1587 cw_compiler_t shadows[10];
1609 1588 int nshadows = 0;
1610 1589 int ret = 0;
1611 1590 boolean_t do_serial = B_FALSE;
1612 1591 boolean_t do_exec = B_FALSE;
1613 1592 boolean_t vflg = B_FALSE;
1614 1593 boolean_t Cflg = B_FALSE;
1615 1594 boolean_t cflg = B_FALSE;
1616 1595 boolean_t nflg = B_FALSE;
1617 1596
1618 1597 cw_ictx_t *main_ctx;
1619 1598
1620 1599 static struct option longopts[] = {
1621 1600 { "compiler", no_argument, NULL, 'c' },
1622 1601 { "noecho", no_argument, NULL, 'n' },
1623 1602 { "primary", required_argument, NULL, 'p' },
1624 1603 { "shadow", required_argument, NULL, 's' },
1625 1604 { "versions", no_argument, NULL, 'v' },
1626 1605 { NULL, 0, NULL, 0 },
1627 1606 };
1628 1607
1629 1608
1630 1609 if ((main_ctx = newictx()) == NULL)
1631 1610 nomem();
1632 1611
1633 1612 while ((ch = getopt_long(argc, argv, "C", longopts, NULL)) != -1) {
1634 1613 switch (ch) {
1635 1614 case 'c':
1636 1615 cflg = B_TRUE;
1637 1616 break;
1638 1617 case 'C':
1639 1618 Cflg = B_TRUE;
1640 1619 break;
1641 1620 case 'n':
1642 1621 nflg = B_TRUE;
1643 1622 break;
1644 1623 case 'p':
1645 1624 if (primary.c_path != NULL) {
1646 1625 warnx("Only one primary compiler may "
1647 1626 "be specified");
1648 1627 usage();
1649 1628 }
1650 1629
1651 1630 parse_compiler(optarg, &primary);
1652 1631 break;
1653 1632 case 's':
1654 1633 if (nshadows >= 10)
1655 1634 errx(1, "May only use 10 shadows at "
1656 1635 "the moment");
1657 1636 parse_compiler(optarg, &shadows[nshadows]);
1658 1637 nshadows++;
1659 1638 break;
1660 1639 case 'v':
1661 1640 vflg = B_TRUE;
1662 1641 break;
1663 1642 default:
1664 1643 (void) fprintf(stderr, "Did you forget '--'?\n");
1665 1644 usage();
1666 1645 }
1667 1646 }
1668 1647
1669 1648 if (primary.c_path == NULL) {
1670 1649 warnx("A primary compiler must be specified");
1671 1650 usage();
1672 1651 }
1673 1652
1674 1653 do_serial = (getenv("CW_SHADOW_SERIAL") == NULL) ? B_FALSE : B_TRUE;
1675 1654 do_exec = (getenv("CW_NO_EXEC") == NULL) ? B_TRUE : B_FALSE;
1676 1655
1677 1656 /* Leave room for argv[0] */
1678 1657 argc -= (optind - 1);
1679 1658 argv += (optind - 1);
1680 1659
1681 1660 main_ctx->i_oldargc = argc;
1682 1661 main_ctx->i_oldargv = argv;
1683 1662 main_ctx->i_flags = CW_F_XLATE;
1684 1663 if (nflg == 0)
1685 1664 main_ctx->i_flags |= CW_F_ECHO;
1686 1665 if (do_exec)
1687 1666 main_ctx->i_flags |= CW_F_EXEC;
1688 1667 if (Cflg)
1689 1668 main_ctx->i_flags |= CW_F_CXX;
1690 1669 main_ctx->i_compiler = &primary;
1691 1670
1692 1671 if (cflg) {
1693 1672 (void) fputs(primary.c_path, stdout);
1694 1673 }
1695 1674
1696 1675 if (vflg) {
1697 1676 (void) printf("cw version %s\n", CW_VERSION);
1698 1677 (void) fflush(stdout);
1699 1678 main_ctx->i_flags &= ~CW_F_ECHO;
1700 1679 main_ctx->i_flags |= CW_F_PROG | CW_F_EXEC;
1701 1680 do_serial = 1;
1702 1681 }
1703 1682
1704 1683 ret |= exec_ctx(main_ctx, do_serial);
1705 1684
1706 1685 for (int i = 0; i < nshadows; i++) {
1707 1686 int r;
1708 1687 cw_ictx_t *shadow_ctx;
1709 1688
1710 1689 if ((shadow_ctx = newictx()) == NULL)
1711 1690 nomem();
1712 1691
1713 1692 memcpy(shadow_ctx, main_ctx, sizeof (cw_ictx_t));
1714 1693
1715 1694 shadow_ctx->i_flags |= CW_F_SHADOW;
1716 1695 shadow_ctx->i_compiler = &shadows[i];
1717 1696
1718 1697 r = exec_ctx(shadow_ctx, do_serial);
1719 1698 if (r == 0) {
1720 1699 shadow_ctx->i_next = main_ctx->i_next;
1721 1700 main_ctx->i_next = shadow_ctx;
1722 1701 }
1723 1702 ret |= r;
1724 1703 }
1725 1704
1726 1705 if (!do_serial) {
1727 1706 cw_ictx_t *next = main_ctx;
1728 1707 while (next != NULL) {
1729 1708 cw_ictx_t *toreap = next;
1730 1709 next = next->i_next;
1731 1710 ret |= reap(toreap);
1732 1711 }
1733 1712 }
1734 1713
1735 1714 return (ret);
1736 1715 }
↓ open down ↓ |
435 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX