10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5580Swesolows * Common Development and Distribution License (the "License").
6580Swesolows * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate */
21580Swesolows
220Sstevel@tonic-gate /*
23*11997SScott.Rotondo@Sun.COM * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
240Sstevel@tonic-gate * Use is subject to license terms.
250Sstevel@tonic-gate */
260Sstevel@tonic-gate
270Sstevel@tonic-gate /*
280Sstevel@tonic-gate * Wrapper for the GNU C compiler to make it accept the Sun C compiler
290Sstevel@tonic-gate * arguments where possible.
300Sstevel@tonic-gate *
310Sstevel@tonic-gate * Since the translation is inexact, this is something of a work-in-progress.
327298SMark.J.Nelson@Sun.COM *
330Sstevel@tonic-gate */
340Sstevel@tonic-gate
357298SMark.J.Nelson@Sun.COM /* If you modify this file, you must increment CW_VERSION */
36*11997SScott.Rotondo@Sun.COM #define CW_VERSION "1.29"
377298SMark.J.Nelson@Sun.COM
380Sstevel@tonic-gate /*
390Sstevel@tonic-gate * -# Verbose mode
400Sstevel@tonic-gate * -### Show compiler commands built by driver, no compilation
410Sstevel@tonic-gate * -A<name[(tokens)]> Preprocessor predicate assertion
420Sstevel@tonic-gate * -B<[static|dynamic]> Specify dynamic or static binding
430Sstevel@tonic-gate * -C Prevent preprocessor from removing comments
440Sstevel@tonic-gate * -c Compile only - produce .o files, suppress linking
450Sstevel@tonic-gate * -cg92 Alias for -xtarget=ss1000
460Sstevel@tonic-gate * -D<name[=token]> Associate name with token as if by #define
470Sstevel@tonic-gate * -d[y|n] dynamic [-dy] or static [-dn] option to linker
480Sstevel@tonic-gate * -E Compile source through preprocessor only, output to stdout
490Sstevel@tonic-gate * -erroff=<t> Suppress warnings specified by tags t(%none, %all, <tag list>)
500Sstevel@tonic-gate * -errtags=<a> Display messages with tags a(no, yes)
510Sstevel@tonic-gate * -errwarn=<t> Treats warnings specified by tags t(%none, %all, <tag list>)
520Sstevel@tonic-gate * as errors
530Sstevel@tonic-gate * -fast Optimize using a selection of options
540Sstevel@tonic-gate * -fd Report old-style function definitions and declarations
557771SMark.Logan@Sun.COM * -features=zla Allow zero-length arrays
560Sstevel@tonic-gate * -flags Show this summary of compiler options
570Sstevel@tonic-gate * -fnonstd Initialize floating-point hardware to non-standard preferences
580Sstevel@tonic-gate * -fns[=<yes|no>] Select non-standard floating point mode
590Sstevel@tonic-gate * -fprecision=<p> Set FP rounding precision mode p(single, double, extended)
600Sstevel@tonic-gate * -fround=<r> Select the IEEE rounding mode in effect at startup
610Sstevel@tonic-gate * -fsimple[=<n>] Select floating-point optimization preferences <n>
620Sstevel@tonic-gate * -fsingle Use single-precision arithmetic (-Xt and -Xs modes only)
630Sstevel@tonic-gate * -ftrap=<t> Select floating-point trapping mode in effect at startup
640Sstevel@tonic-gate * -fstore force floating pt. values to target precision on assignment
650Sstevel@tonic-gate * -G Build a dynamic shared library
660Sstevel@tonic-gate * -g Compile for debugging
670Sstevel@tonic-gate * -H Print path name of each file included during compilation
680Sstevel@tonic-gate * -h <name> Assign <name> to generated dynamic shared library
690Sstevel@tonic-gate * -I<dir> Add <dir> to preprocessor #include file search path
700Sstevel@tonic-gate * -i Passed to linker to ignore any LD_LIBRARY_PATH setting
710Sstevel@tonic-gate * -keeptmp Keep temporary files created during compilation
720Sstevel@tonic-gate * -KPIC Compile position independent code with 32-bit addresses
730Sstevel@tonic-gate * -Kpic Compile position independent code
740Sstevel@tonic-gate * -L<dir> Pass to linker to add <dir> to the library search path
750Sstevel@tonic-gate * -l<name> Link with library lib<name>.a or lib<name>.so
760Sstevel@tonic-gate * -mc Remove duplicate strings from .comment section of output files
770Sstevel@tonic-gate * -mr Remove all strings from .comment section of output files
780Sstevel@tonic-gate * -mr,"string" Remove all strings and append "string" to .comment section
790Sstevel@tonic-gate * -mt Specify options needed when compiling multi-threaded code
800Sstevel@tonic-gate * -native Find available processor, generate code accordingly
810Sstevel@tonic-gate * -nofstore Do not force floating pt. values to target precision
820Sstevel@tonic-gate * on assignment
830Sstevel@tonic-gate * -nolib Same as -xnolib
840Sstevel@tonic-gate * -noqueue Disable queuing of compiler license requests
850Sstevel@tonic-gate * -norunpath Do not build in a runtime path for shared libraries
86282Ssherrym * -O Use default optimization level (-xO2 or -xO3. Check man page.)
870Sstevel@tonic-gate * -o <outputfile> Set name of output file to <outputfile>
880Sstevel@tonic-gate * -P Compile source through preprocessor only, output to .i file
890Sstevel@tonic-gate * -PIC Alias for -KPIC or -xcode=pic32
900Sstevel@tonic-gate * -p Compile for profiling with prof
910Sstevel@tonic-gate * -pic Alias for -Kpic or -xcode=pic13
920Sstevel@tonic-gate * -Q[y|n] Emit/don't emit identification info to output file
930Sstevel@tonic-gate * -qp Compile for profiling with prof
940Sstevel@tonic-gate * -R<dir[:dir]> Build runtime search path list into executable
950Sstevel@tonic-gate * -S Compile and only generate assembly code (.s)
960Sstevel@tonic-gate * -s Strip symbol table from the executable file
97376Swesolows * -t Turn off duplicate symbol warnings when linking
980Sstevel@tonic-gate * -U<name> Delete initial definition of preprocessor symbol <name>
990Sstevel@tonic-gate * -V Report version number of each compilation phase
1000Sstevel@tonic-gate * -v Do stricter semantic checking
1010Sstevel@tonic-gate * -W<c>,<arg> Pass <arg> to specified component <c> (a,l,m,p,0,2,h,i,u)
1020Sstevel@tonic-gate * -w Suppress compiler warning messages
1030Sstevel@tonic-gate * -Xa Compile assuming ANSI C conformance, allow K & R extensions
1040Sstevel@tonic-gate * (default mode)
1050Sstevel@tonic-gate * -Xc Compile assuming strict ANSI C conformance
1060Sstevel@tonic-gate * -Xs Compile assuming (pre-ANSI) K & R C style code
1070Sstevel@tonic-gate * -Xt Compile assuming K & R conformance, allow ANSI C
1080Sstevel@tonic-gate * -x386 Generate code for the 80386 processor
1090Sstevel@tonic-gate * -x486 Generate code for the 80486 processor
1100Sstevel@tonic-gate * -xarch=<a> Specify target architecture instruction set
1110Sstevel@tonic-gate * -xbuiltin[=<b>] When profitable inline, or substitute intrinisic functions
1120Sstevel@tonic-gate * for system functions, b={%all,%none}
1130Sstevel@tonic-gate * -xCC Accept C++ style comments
1140Sstevel@tonic-gate * -xchar_byte_order=<o> Specify multi-char byte order <o> (default, high, low)
1150Sstevel@tonic-gate * -xchip=<c> Specify the target processor for use by the optimizer
1160Sstevel@tonic-gate * -xcode=<c> Generate different code for forming addresses
1170Sstevel@tonic-gate * -xcrossfile[=<n>] Enable optimization and inlining across source files,
1180Sstevel@tonic-gate * n={0|1}
1190Sstevel@tonic-gate * -xe Perform only syntax/semantic checking, no code generation
1205605Srie * -xF Compile for later mapfile reordering or unused section
1215605Srie * elimination
1220Sstevel@tonic-gate * -xhelp=<f> Display on-line help information f(flags, readme, errors)
1230Sstevel@tonic-gate * -xildoff Cancel -xildon
1240Sstevel@tonic-gate * -xildon Enable use of the incremental linker, ild
1250Sstevel@tonic-gate * -xinline=[<a>,...,<a>] Attempt inlining of specified user routines,
1260Sstevel@tonic-gate * <a>={%auto,func,no%func}
1270Sstevel@tonic-gate * -xlibmieee Force IEEE 754 return values for math routines in
1280Sstevel@tonic-gate * exceptional cases
1290Sstevel@tonic-gate * -xlibmil Inline selected libm math routines for optimization
1300Sstevel@tonic-gate * -xlic_lib=sunperf Link in the Sun supplied performance libraries
1310Sstevel@tonic-gate * -xlicinfo Show license server information
1320Sstevel@tonic-gate * -xM Generate makefile dependencies
1330Sstevel@tonic-gate * -xM1 Generate makefile dependencies, but exclude /usr/include
1340Sstevel@tonic-gate * -xmaxopt=[off,1,2,3,4,5] maximum optimization level allowed on #pragma opt
1350Sstevel@tonic-gate * -xnolib Do not link with default system libraries
1360Sstevel@tonic-gate * -xnolibmil Cancel -xlibmil on command line
1370Sstevel@tonic-gate * -xO<n> Generate optimized code (n={1|2|3|4|5})
1380Sstevel@tonic-gate * -xP Print prototypes for function definitions
1390Sstevel@tonic-gate * -xpentium Generate code for the pentium processor
1400Sstevel@tonic-gate * -xpg Compile for profiling with gprof
1410Sstevel@tonic-gate * -xprofile=<p> Collect data for a profile or use a profile to optimize
1420Sstevel@tonic-gate * <p>={{collect,use}[:<path>],tcov}
1430Sstevel@tonic-gate * -xregs=<r> Control register allocation
1440Sstevel@tonic-gate * -xs Allow debugging without object (.o) files
1450Sstevel@tonic-gate * -xsb Compile for use with the WorkShop source browser
1460Sstevel@tonic-gate * -xsbfast Generate only WorkShop source browser info, no compilation
1470Sstevel@tonic-gate * -xsfpconst Represent unsuffixed floating point constants as single
1480Sstevel@tonic-gate * precision
1490Sstevel@tonic-gate * -xspace Do not do optimizations that increase code size
1500Sstevel@tonic-gate * -xstrconst Place string literals into read-only data segment
1510Sstevel@tonic-gate * -xtarget=<t> Specify target system for optimization
1520Sstevel@tonic-gate * -xtemp=<dir> Set directory for temporary files to <dir>
1530Sstevel@tonic-gate * -xtime Report the execution time for each compilation phase
1540Sstevel@tonic-gate * -xtransition Emit warnings for differences between K&R C and ANSI C
1550Sstevel@tonic-gate * -xtrigraphs[=<yes|no>] Enable|disable trigraph translation
1560Sstevel@tonic-gate * -xunroll=n Enable unrolling loops n times where possible
1570Sstevel@tonic-gate * -Y<c>,<dir> Specify <dir> for location of component <c> (a,l,m,p,0,h,i,u)
1580Sstevel@tonic-gate * -YA,<dir> Change default directory searched for components
1590Sstevel@tonic-gate * -YI,<dir> Change default directory searched for include files
1600Sstevel@tonic-gate * -YP,<dir> Change default directory for finding libraries files
1610Sstevel@tonic-gate * -YS,<dir> Change default directory for startup object files
1620Sstevel@tonic-gate */
1630Sstevel@tonic-gate
1640Sstevel@tonic-gate /*
1650Sstevel@tonic-gate * Translation table:
1660Sstevel@tonic-gate */
1670Sstevel@tonic-gate /*
1680Sstevel@tonic-gate * -# -v
1690Sstevel@tonic-gate * -### error
1700Sstevel@tonic-gate * -A<name[(tokens)]> pass-thru
1710Sstevel@tonic-gate * -B<[static|dynamic]> pass-thru (syntax error for anything else)
1720Sstevel@tonic-gate * -C pass-thru
1730Sstevel@tonic-gate * -c pass-thru
1740Sstevel@tonic-gate * -cg92 -m32 -mcpu=v8 -mtune=supersparc (SPARC only)
1750Sstevel@tonic-gate * -D<name[=token]> pass-thru
1760Sstevel@tonic-gate * -dy or -dn -Wl,-dy or -Wl,-dn
1770Sstevel@tonic-gate * -E pass-thru
1780Sstevel@tonic-gate * -erroff=E_EMPTY_TRANSLATION_UNIT ignore
1790Sstevel@tonic-gate * -errtags=%all -Wall
1800Sstevel@tonic-gate * -errwarn=%all -Werror else -Wno-error
1810Sstevel@tonic-gate * -fast error
1820Sstevel@tonic-gate * -fd error
1837771SMark.Logan@Sun.COM * -features=zla ignore
1840Sstevel@tonic-gate * -flags --help
1850Sstevel@tonic-gate * -fnonstd error
1860Sstevel@tonic-gate * -fns[=<yes|no>] error
1870Sstevel@tonic-gate * -fprecision=<p> error
1880Sstevel@tonic-gate * -fround=<r> error
1890Sstevel@tonic-gate * -fsimple[=<n>] error
1900Sstevel@tonic-gate * -fsingle[=<n>] error
1910Sstevel@tonic-gate * -ftrap=<t> error
1920Sstevel@tonic-gate * -fstore error
1930Sstevel@tonic-gate * -G pass-thru
1940Sstevel@tonic-gate * -g pass-thru
1950Sstevel@tonic-gate * -H pass-thru
1960Sstevel@tonic-gate * -h <name> pass-thru
1970Sstevel@tonic-gate * -I<dir> pass-thru
1980Sstevel@tonic-gate * -i pass-thru
1990Sstevel@tonic-gate * -keeptmp -save-temps
2000Sstevel@tonic-gate * -KPIC -fPIC
2010Sstevel@tonic-gate * -Kpic -fpic
2020Sstevel@tonic-gate * -L<dir> pass-thru
2030Sstevel@tonic-gate * -l<name> pass-thru
2040Sstevel@tonic-gate * -mc error
2050Sstevel@tonic-gate * -mr error
2060Sstevel@tonic-gate * -mr,"string" error
2070Sstevel@tonic-gate * -mt -D_REENTRANT
2080Sstevel@tonic-gate * -native error
2090Sstevel@tonic-gate * -nofstore error
2100Sstevel@tonic-gate * -nolib -nodefaultlibs
2110Sstevel@tonic-gate * -noqueue ignore
2120Sstevel@tonic-gate * -norunpath ignore
213282Ssherrym * -O -O1 (Check the man page to be certain)
2140Sstevel@tonic-gate * -o <outputfile> pass-thru
2150Sstevel@tonic-gate * -P -E -o filename.i (or error)
2160Sstevel@tonic-gate * -PIC -fPIC (C++ only)
2170Sstevel@tonic-gate * -p pass-thru
2180Sstevel@tonic-gate * -pic -fpic (C++ only)
2190Sstevel@tonic-gate * -Q[y|n] error
2200Sstevel@tonic-gate * -qp -p
2210Sstevel@tonic-gate * -R<dir[:dir]> pass-thru
2220Sstevel@tonic-gate * -S pass-thru
2230Sstevel@tonic-gate * -s -Wl,-s
224376Swesolows * -t -Wl,-t
2250Sstevel@tonic-gate * -U<name> pass-thru
2260Sstevel@tonic-gate * -V --version
2270Sstevel@tonic-gate * -v -Wall
2280Sstevel@tonic-gate * -Wa,<arg> pass-thru
2290Sstevel@tonic-gate * -Wp,<arg> pass-thru except -xc99=<a>
2300Sstevel@tonic-gate * -Wl,<arg> pass-thru
2310Sstevel@tonic-gate * -W{m,0,2,h,i,u> error/ignore
2320Sstevel@tonic-gate * -Wu,-xmodel=kernel -ffreestanding -mcmodel=kernel -mno-red-zone
2332886Spetede * -xmodel=kernel -ffreestanding -mcmodel=kernel -mno-red-zone
234325Ssherrym * -Wu,-save_args -msave-args
2350Sstevel@tonic-gate * -w pass-thru
2360Sstevel@tonic-gate * -Xa -std=iso9899:199409 or -ansi
2370Sstevel@tonic-gate * -Xc -ansi -pedantic
2380Sstevel@tonic-gate * -Xt error
2390Sstevel@tonic-gate * -Xs -traditional -std=c89
2400Sstevel@tonic-gate * -x386 -march=i386 (x86 only)
2410Sstevel@tonic-gate * -x486 -march=i486 (x86 only)
2420Sstevel@tonic-gate * -xarch=<a> table
243580Swesolows * -xbuiltin[=<b>] -fbuiltin (-fno-builtin otherwise)
2440Sstevel@tonic-gate * -xCC ignore
2450Sstevel@tonic-gate * -xchar_byte_order=<o> error
2460Sstevel@tonic-gate * -xchip=<c> table
2470Sstevel@tonic-gate * -xcode=<c> table
248379Ssherrym * -xdebugformat=<format> ignore (always use dwarf-2 for gcc)
249376Swesolows * -xcrossfile[=<n>] ignore
2500Sstevel@tonic-gate * -xe error
2510Sstevel@tonic-gate * -xF error
2520Sstevel@tonic-gate * -xhelp=<f> error
2530Sstevel@tonic-gate * -xildoff ignore
2540Sstevel@tonic-gate * -xildon ignore
2550Sstevel@tonic-gate * -xinline ignore
2560Sstevel@tonic-gate * -xlibmieee error
2570Sstevel@tonic-gate * -xlibmil error
2580Sstevel@tonic-gate * -xlic_lib=sunperf error
2590Sstevel@tonic-gate * -xM -M
2600Sstevel@tonic-gate * -xM1 -MM
2610Sstevel@tonic-gate * -xmaxopt=[...] error
2620Sstevel@tonic-gate * -xnolib -nodefaultlibs
2630Sstevel@tonic-gate * -xnolibmil error
2640Sstevel@tonic-gate * -xO<n> -O<n>
2650Sstevel@tonic-gate * -xP error
2660Sstevel@tonic-gate * -xpentium -march=pentium (x86 only)
2670Sstevel@tonic-gate * -xpg error
2680Sstevel@tonic-gate * -xprofile=<p> error
2690Sstevel@tonic-gate * -xregs=<r> table
2700Sstevel@tonic-gate * -xs error
2710Sstevel@tonic-gate * -xsb error
2720Sstevel@tonic-gate * -xsbfast error
2730Sstevel@tonic-gate * -xsfpconst error
2740Sstevel@tonic-gate * -xspace ignore (-not -Os)
2750Sstevel@tonic-gate * -xstrconst ignore
2760Sstevel@tonic-gate * -xtarget=<t> table
2770Sstevel@tonic-gate * -xtemp=<dir> error
2780Sstevel@tonic-gate * -xtime error
2790Sstevel@tonic-gate * -xtransition -Wtransition
2800Sstevel@tonic-gate * -xtrigraphs=<yes|no> -trigraphs -notrigraphs
2810Sstevel@tonic-gate * -xunroll=n error
282379Ssherrym * -W0,-xdbggen=no%usedonly -fno-eliminate-unused-debug-symbols
283379Ssherrym * -fno-eliminate-unused-debug-types
2840Sstevel@tonic-gate * -Y<c>,<dir> error
2850Sstevel@tonic-gate * -YA,<dir> error
2860Sstevel@tonic-gate * -YI,<dir> -nostdinc -I<dir>
2870Sstevel@tonic-gate * -YP,<dir> error
2880Sstevel@tonic-gate * -YS,<dir> error
2890Sstevel@tonic-gate */
2900Sstevel@tonic-gate
2910Sstevel@tonic-gate #include <stdio.h>
2920Sstevel@tonic-gate #include <sys/types.h>
2930Sstevel@tonic-gate #include <unistd.h>
2940Sstevel@tonic-gate #include <string.h>
2950Sstevel@tonic-gate #include <stdlib.h>
2960Sstevel@tonic-gate #include <ctype.h>
2971717Swesolows #include <fcntl.h>
2981717Swesolows #include <errno.h>
2991717Swesolows #include <stdarg.h>
3000Sstevel@tonic-gate #include <sys/utsname.h>
3010Sstevel@tonic-gate #include <sys/param.h>
3020Sstevel@tonic-gate #include <sys/isa_defs.h>
3031717Swesolows #include <sys/wait.h>
3041717Swesolows #include <sys/stat.h>
3050Sstevel@tonic-gate
3061717Swesolows #define CW_F_CXX 0x01
3071717Swesolows #define CW_F_SHADOW 0x02
3081717Swesolows #define CW_F_EXEC 0x04
3091717Swesolows #define CW_F_ECHO 0x08
3101717Swesolows #define CW_F_XLATE 0x10
3111792Swesolows #define CW_F_PROG 0x20
3121717Swesolows
3131717Swesolows typedef enum cw_compiler {
3141717Swesolows CW_C_CC = 0,
3151717Swesolows CW_C_GCC
3161717Swesolows } cw_compiler_t;
3171717Swesolows
3181717Swesolows static const char *cmds[] = {
3191717Swesolows "cc", "CC",
3201717Swesolows "gcc", "g++"
3211717Swesolows };
3221717Swesolows
323*11997SScott.Rotondo@Sun.COM static char default_dir[2][MAXPATHLEN] = {
324*11997SScott.Rotondo@Sun.COM DEFAULT_CC_DIR,
325*11997SScott.Rotondo@Sun.COM DEFAULT_GCC_DIR,
3261717Swesolows };
3271717Swesolows
3281717Swesolows #define CC(ctx) \
3291717Swesolows (((ctx)->i_flags & CW_F_SHADOW) ? \
3301717Swesolows ((ctx)->i_compiler == CW_C_CC ? CW_C_GCC : CW_C_CC) : \
3311717Swesolows (ctx)->i_compiler)
3320Sstevel@tonic-gate
3331717Swesolows #define CIDX(compiler, flags) \
3341717Swesolows ((int)(compiler) << 1) + ((flags) & CW_F_CXX ? 1 : 0)
3351717Swesolows
3361717Swesolows typedef enum cw_op {
3371717Swesolows CW_O_NONE = 0,
3381717Swesolows CW_O_PREPROCESS,
3391717Swesolows CW_O_COMPILE,
3401717Swesolows CW_O_LINK
3411717Swesolows } cw_op_t;
3420Sstevel@tonic-gate
3431717Swesolows struct aelist {
3441717Swesolows struct ae {
3451717Swesolows struct ae *ae_next;
3461717Swesolows char *ae_arg;
3471717Swesolows } *ael_head, *ael_tail;
3481717Swesolows int ael_argc;
3491717Swesolows };
3501717Swesolows
3511717Swesolows typedef struct cw_ictx {
3521717Swesolows cw_compiler_t i_compiler;
3531717Swesolows struct aelist *i_ae;
3541717Swesolows uint32_t i_flags;
3551717Swesolows int i_oldargc;
3561717Swesolows char **i_oldargv;
3571717Swesolows pid_t i_pid;
3581717Swesolows char i_discard[MAXPATHLEN];
3591792Swesolows char *i_stderr;
3601717Swesolows } cw_ictx_t;
3611717Swesolows
3625534Spetede /*
3635534Spetede * Status values to indicate which Studio compiler and associated
3645534Spetede * flags are being used.
3655534Spetede */
3665534Spetede #define M32 0x01 /* -m32 - only on Studio 12 */
3675534Spetede #define M64 0x02 /* -m64 - only on Studio 12 */
3685534Spetede #define SS11 0x100 /* Studio 11 */
3695534Spetede #define SS12 0x200 /* Studio 12 */
3700Sstevel@tonic-gate
3715534Spetede #define TRANS_ENTRY 5
3725534Spetede /*
3735534Spetede * Translation table definition for the -xarch= flag. The "x_arg"
3745534Spetede * value is translated into the appropriate gcc flags according
3755534Spetede * to the values in x_trans[n]. The x_flags indicates what compiler
3765534Spetede * is being used and what flags have been set via the use of
3775534Spetede * "x_arg".
3785534Spetede */
3795534Spetede typedef struct xarch_table {
3805534Spetede char *x_arg;
3815534Spetede int x_flags;
3825534Spetede char *x_trans[TRANS_ENTRY];
3835534Spetede } xarch_table_t;
3845534Spetede
3855534Spetede /*
3865534Spetede * The translation table for the -xarch= flag used in the Studio compilers.
3875534Spetede */
3885534Spetede static const xarch_table_t xtbl[] = {
3890Sstevel@tonic-gate #if defined(__x86)
3905534Spetede { "generic", SS11 },
3915548Spetede { "generic64", (SS11|M64), { "-m64", "-mtune=opteron" } },
3925548Spetede { "amd64", (SS11|M64), { "-m64", "-mtune=opteron" } },
3935548Spetede { "386", SS11, { "-march=i386" } },
3945548Spetede { "pentium_pro", SS11, { "-march=pentiumpro" } },
3950Sstevel@tonic-gate #elif defined(__sparc)
3965548Spetede { "generic", (SS11|M32), { "-m32", "-mcpu=v8" } },
3975548Spetede { "generic64", (SS11|M64), { "-m64", "-mcpu=v9" } },
3985548Spetede { "v8", (SS11|M32), { "-m32", "-mcpu=v8", "-mno-v8plus" } },
3995548Spetede { "v8plus", (SS11|M32), { "-m32", "-mcpu=v9", "-mv8plus" } },
4005548Spetede { "v8plusa", (SS11|M32), { "-m32", "-mcpu=ultrasparc", "-mv8plus",
4015548Spetede "-mvis" } },
4025548Spetede { "v8plusb", (SS11|M32), { "-m32", "-mcpu=ultrasparc3", "-mv8plus",
4035548Spetede "-mvis" } },
4045548Spetede { "v9", (SS11|M64), { "-m64", "-mcpu=v9" } },
4055548Spetede { "v9a", (SS11|M64), { "-m64", "-mcpu=ultrasparc", "-mvis" } },
4065548Spetede { "v9b", (SS11|M64), { "-m64", "-mcpu=ultrasparc3", "-mvis" } },
4075548Spetede { "sparc", SS12, { "-mcpu=v9", "-mv8plus" } },
4085548Spetede { "sparcvis", SS12, { "-mcpu=ultrasparc", "-mvis" } },
4095548Spetede { "sparcvis2", SS12, { "-mcpu=ultrasparc3", "-mvis" } }
4100Sstevel@tonic-gate #endif
4110Sstevel@tonic-gate };
4120Sstevel@tonic-gate
4135534Spetede static int xtbl_size = sizeof (xtbl) / sizeof (xarch_table_t);
4145534Spetede
4155534Spetede static const char *progname;
4165534Spetede
4170Sstevel@tonic-gate static const char *xchip_tbl[] = {
4180Sstevel@tonic-gate #if defined(__x86)
4190Sstevel@tonic-gate "386", "-mtune=i386", NULL,
4200Sstevel@tonic-gate "486", "-mtune=i486", NULL,
4210Sstevel@tonic-gate "pentium", "-mtune=pentium", NULL,
4220Sstevel@tonic-gate "pentium_pro", "-mtune=pentiumpro", NULL,
4230Sstevel@tonic-gate #elif defined(__sparc)
4240Sstevel@tonic-gate "super", "-mtune=supersparc", NULL,
4250Sstevel@tonic-gate "ultra", "-mtune=ultrasparc", NULL,
4260Sstevel@tonic-gate "ultra3", "-mtune=ultrasparc3", NULL,
4270Sstevel@tonic-gate #endif
4280Sstevel@tonic-gate NULL, NULL
4290Sstevel@tonic-gate };
4300Sstevel@tonic-gate
4310Sstevel@tonic-gate static const char *xcode_tbl[] = {
4320Sstevel@tonic-gate #if defined(__sparc)
4330Sstevel@tonic-gate "abs32", "-fno-pic", "-mcmodel=medlow", NULL,
4340Sstevel@tonic-gate "abs44", "-fno-pic", "-mcmodel=medmid", NULL,
4350Sstevel@tonic-gate "abs64", "-fno-pic", "-mcmodel=medany", NULL,
4360Sstevel@tonic-gate "pic13", "-fpic", NULL,
4370Sstevel@tonic-gate "pic32", "-fPIC", NULL,
4380Sstevel@tonic-gate #endif
4390Sstevel@tonic-gate NULL, NULL
4400Sstevel@tonic-gate };
4410Sstevel@tonic-gate
4420Sstevel@tonic-gate static const char *xtarget_tbl[] = {
4430Sstevel@tonic-gate #if defined(__x86)
4440Sstevel@tonic-gate "pentium_pro", "-march=pentiumpro", NULL,
4450Sstevel@tonic-gate #endif /* __x86 */
4460Sstevel@tonic-gate NULL, NULL
4470Sstevel@tonic-gate };
4480Sstevel@tonic-gate
4490Sstevel@tonic-gate static const char *xregs_tbl[] = {
4500Sstevel@tonic-gate #if defined(__sparc)
4510Sstevel@tonic-gate "appl", "-mapp-regs", NULL,
4520Sstevel@tonic-gate "no%appl", "-mno-app-regs", NULL,
4530Sstevel@tonic-gate "float", "-mfpu", NULL,
4540Sstevel@tonic-gate "no%float", "-mno-fpu", NULL,
4550Sstevel@tonic-gate #endif /* __sparc */
4560Sstevel@tonic-gate NULL, NULL
4570Sstevel@tonic-gate };
4580Sstevel@tonic-gate
4591717Swesolows static void
nomem(void)4601717Swesolows nomem(void)
4611717Swesolows {
4621717Swesolows (void) fprintf(stderr, "%s: error: out of memory\n", progname);
4631717Swesolows exit(1);
4641717Swesolows }
4650Sstevel@tonic-gate
4661717Swesolows static void
cw_perror(const char * fmt,...)4671717Swesolows cw_perror(const char *fmt, ...)
4680Sstevel@tonic-gate {
4691717Swesolows va_list ap;
4701717Swesolows int saved_errno = errno;
4711717Swesolows
4721717Swesolows (void) fprintf(stderr, "%s: error: ", progname);
4731717Swesolows
4741717Swesolows va_start(ap, fmt);
4751717Swesolows (void) vfprintf(stderr, fmt, ap);
4761717Swesolows va_end(ap);
4771717Swesolows
4781717Swesolows (void) fprintf(stderr, " (%s)\n", strerror(saved_errno));
4790Sstevel@tonic-gate }
4800Sstevel@tonic-gate
4810Sstevel@tonic-gate static void
newae(struct aelist * ael,const char * arg)4820Sstevel@tonic-gate newae(struct aelist *ael, const char *arg)
4830Sstevel@tonic-gate {
4840Sstevel@tonic-gate struct ae *ae;
4850Sstevel@tonic-gate
4861717Swesolows if ((ae = calloc(sizeof (*ae), 1)) == NULL)
4871717Swesolows nomem();
4880Sstevel@tonic-gate ae->ae_arg = strdup(arg);
4890Sstevel@tonic-gate if (ael->ael_tail == NULL)
4900Sstevel@tonic-gate ael->ael_head = ae;
4910Sstevel@tonic-gate else
4920Sstevel@tonic-gate ael->ael_tail->ae_next = ae;
4930Sstevel@tonic-gate ael->ael_tail = ae;
4941717Swesolows ael->ael_argc++;
4951717Swesolows }
4961717Swesolows
4971717Swesolows static cw_ictx_t *
newictx(void)4981717Swesolows newictx(void)
4991717Swesolows {
5001717Swesolows cw_ictx_t *ctx = calloc(sizeof (cw_ictx_t), 1);
5011717Swesolows if (ctx)
5021717Swesolows if ((ctx->i_ae = calloc(sizeof (struct aelist), 1)) == NULL) {
5031717Swesolows free(ctx);
5041717Swesolows return (NULL);
5051717Swesolows }
5061717Swesolows
5071717Swesolows return (ctx);
5080Sstevel@tonic-gate }
5090Sstevel@tonic-gate
5100Sstevel@tonic-gate static void
error(const char * arg)5110Sstevel@tonic-gate error(const char *arg)
5120Sstevel@tonic-gate {
5130Sstevel@tonic-gate (void) fprintf(stderr,
5141717Swesolows "%s: error: mapping failed at or near arg '%s'\n", progname, arg);
5150Sstevel@tonic-gate exit(2);
5160Sstevel@tonic-gate }
5170Sstevel@tonic-gate
5180Sstevel@tonic-gate /*
5190Sstevel@tonic-gate * Add the current favourite set of warnings to the gcc invocation.
5200Sstevel@tonic-gate */
5210Sstevel@tonic-gate static void
warnings(struct aelist * h)5220Sstevel@tonic-gate warnings(struct aelist *h)
5230Sstevel@tonic-gate {
5240Sstevel@tonic-gate static int warningsonce;
5250Sstevel@tonic-gate
5260Sstevel@tonic-gate if (warningsonce++)
5270Sstevel@tonic-gate return;
5280Sstevel@tonic-gate
5290Sstevel@tonic-gate newae(h, "-Wall");
5300Sstevel@tonic-gate newae(h, "-Wno-unknown-pragmas");
5310Sstevel@tonic-gate newae(h, "-Wno-missing-braces");
5320Sstevel@tonic-gate newae(h, "-Wno-sign-compare");
5330Sstevel@tonic-gate newae(h, "-Wno-parentheses");
5340Sstevel@tonic-gate newae(h, "-Wno-uninitialized");
5350Sstevel@tonic-gate newae(h, "-Wno-implicit-function-declaration");
5360Sstevel@tonic-gate newae(h, "-Wno-unused");
5370Sstevel@tonic-gate newae(h, "-Wno-trigraphs");
5380Sstevel@tonic-gate newae(h, "-Wno-char-subscripts");
5390Sstevel@tonic-gate newae(h, "-Wno-switch");
5400Sstevel@tonic-gate }
5410Sstevel@tonic-gate
5420Sstevel@tonic-gate static void
optim_disable(struct aelist * h,int level)5430Sstevel@tonic-gate optim_disable(struct aelist *h, int level)
5440Sstevel@tonic-gate {
5450Sstevel@tonic-gate if (level >= 2) {
5460Sstevel@tonic-gate newae(h, "-fno-strict-aliasing");
5470Sstevel@tonic-gate newae(h, "-fno-unit-at-a-time");
5480Sstevel@tonic-gate newae(h, "-fno-optimize-sibling-calls");
5490Sstevel@tonic-gate }
5500Sstevel@tonic-gate }
5510Sstevel@tonic-gate
5520Sstevel@tonic-gate /* ARGSUSED */
5530Sstevel@tonic-gate static void
Xamode(struct aelist * h)5540Sstevel@tonic-gate Xamode(struct aelist *h)
5550Sstevel@tonic-gate {
5560Sstevel@tonic-gate }
5570Sstevel@tonic-gate
5580Sstevel@tonic-gate static void
Xcmode(struct aelist * h)5590Sstevel@tonic-gate Xcmode(struct aelist *h)
5600Sstevel@tonic-gate {
5610Sstevel@tonic-gate static int xconce;
5620Sstevel@tonic-gate
5630Sstevel@tonic-gate if (xconce++)
5640Sstevel@tonic-gate return;
5650Sstevel@tonic-gate
5660Sstevel@tonic-gate newae(h, "-ansi");
5670Sstevel@tonic-gate newae(h, "-pedantic-errors");
5680Sstevel@tonic-gate }
5690Sstevel@tonic-gate
5700Sstevel@tonic-gate static void
Xsmode(struct aelist * h)5710Sstevel@tonic-gate Xsmode(struct aelist *h)
5720Sstevel@tonic-gate {
5730Sstevel@tonic-gate static int xsonce;
5740Sstevel@tonic-gate
5750Sstevel@tonic-gate if (xsonce++)
5760Sstevel@tonic-gate return;
5770Sstevel@tonic-gate
5780Sstevel@tonic-gate newae(h, "-traditional");
5790Sstevel@tonic-gate newae(h, "-traditional-cpp");
5800Sstevel@tonic-gate }
5810Sstevel@tonic-gate
5820Sstevel@tonic-gate static void
usage()5830Sstevel@tonic-gate usage()
5840Sstevel@tonic-gate {
5850Sstevel@tonic-gate (void) fprintf(stderr,
5860Sstevel@tonic-gate "usage: %s { -_cc | -_gcc | -_CC | -_g++ } [ -_compiler | ... ]\n",
5870Sstevel@tonic-gate progname);
5880Sstevel@tonic-gate exit(2);
5890Sstevel@tonic-gate }
5900Sstevel@tonic-gate
5915534Spetede static int
xlate_xtb(struct aelist * h,const char * xarg)5925534Spetede xlate_xtb(struct aelist *h, const char *xarg)
5935534Spetede {
5945534Spetede int i, j;
5955534Spetede
5965534Spetede for (i = 0; i < xtbl_size; i++) {
5975534Spetede if (strcmp(xtbl[i].x_arg, xarg) == 0)
5985534Spetede break;
5995534Spetede }
6005534Spetede
6015534Spetede /*
6025534Spetede * At the end of the table and so no matching "arg" entry
6035534Spetede * found and so this must be a bad -xarch= flag.
6045534Spetede */
6055534Spetede if (i == xtbl_size)
6065534Spetede error(xarg);
6075534Spetede
6085534Spetede for (j = 0; j < TRANS_ENTRY; j++) {
6095534Spetede if (xtbl[i].x_trans[j] != NULL)
6105534Spetede newae(h, xtbl[i].x_trans[j]);
6115534Spetede else
6125534Spetede break;
6135534Spetede }
6145534Spetede return (xtbl[i].x_flags);
6155534Spetede
6165534Spetede }
6175534Spetede
6180Sstevel@tonic-gate static void
xlate(struct aelist * h,const char * xarg,const char ** table)6190Sstevel@tonic-gate xlate(struct aelist *h, const char *xarg, const char **table)
6200Sstevel@tonic-gate {
6210Sstevel@tonic-gate while (*table != NULL && strcmp(xarg, *table) != 0) {
6220Sstevel@tonic-gate while (*table != NULL)
6230Sstevel@tonic-gate table++;
6240Sstevel@tonic-gate table++;
6250Sstevel@tonic-gate }
6260Sstevel@tonic-gate
6270Sstevel@tonic-gate if (*table == NULL)
6280Sstevel@tonic-gate error(xarg);
6290Sstevel@tonic-gate
6300Sstevel@tonic-gate table++;
6310Sstevel@tonic-gate
6320Sstevel@tonic-gate while (*table != NULL) {
6330Sstevel@tonic-gate newae(h, *table);
6340Sstevel@tonic-gate table++;
6350Sstevel@tonic-gate }
6360Sstevel@tonic-gate }
6370Sstevel@tonic-gate
6380Sstevel@tonic-gate static void
do_gcc(cw_ictx_t * ctx)6391717Swesolows do_gcc(cw_ictx_t *ctx)
6400Sstevel@tonic-gate {
6410Sstevel@tonic-gate int c;
6421717Swesolows int pic = 0, nolibc = 0;
6431717Swesolows int in_output = 0, seen_o = 0, c_files = 0;
6441717Swesolows cw_op_t op = CW_O_LINK;
6450Sstevel@tonic-gate char *model = NULL;
6465534Spetede int mflag = 0;
6470Sstevel@tonic-gate
6481792Swesolows if (ctx->i_flags & CW_F_PROG) {
6491792Swesolows newae(ctx->i_ae, "--version");
6501792Swesolows return;
6511792Swesolows }
6521792Swesolows
6531717Swesolows newae(ctx->i_ae, "-fident");
6541717Swesolows newae(ctx->i_ae, "-finline");
6551717Swesolows newae(ctx->i_ae, "-fno-inline-functions");
6561717Swesolows newae(ctx->i_ae, "-fno-builtin");
6571717Swesolows newae(ctx->i_ae, "-fno-asm");
6581717Swesolows newae(ctx->i_ae, "-nodefaultlibs");
6590Sstevel@tonic-gate
660580Swesolows #if defined(__sparc)
661580Swesolows /*
662580Swesolows * The SPARC ldd and std instructions require 8-byte alignment of
663580Swesolows * their address operand. gcc correctly uses them only when the
664580Swesolows * ABI requires 8-byte alignment; unfortunately we have a number of
665580Swesolows * pieces of buggy code that doesn't conform to the ABI. This
666580Swesolows * flag makes gcc work more like Studio with -xmemalign=4.
667580Swesolows */
6681717Swesolows newae(ctx->i_ae, "-mno-integer-ldd-std");
669580Swesolows #endif
670580Swesolows
6710Sstevel@tonic-gate /*
6720Sstevel@tonic-gate * This is needed because 'u' is defined
6730Sstevel@tonic-gate * under a conditional on 'sun'. Should
6740Sstevel@tonic-gate * probably just remove the conditional,
6750Sstevel@tonic-gate * or make it be dependent on '__sun'.
6760Sstevel@tonic-gate *
6770Sstevel@tonic-gate * -Dunix is also missing in enhanced ANSI mode
6780Sstevel@tonic-gate */
6791717Swesolows newae(ctx->i_ae, "-D__sun");
6800Sstevel@tonic-gate
6810Sstevel@tonic-gate /*
6820Sstevel@tonic-gate * Walk the argument list, translating as we go ..
6830Sstevel@tonic-gate */
6840Sstevel@tonic-gate
6851717Swesolows while (--ctx->i_oldargc > 0) {
6861717Swesolows char *arg = *++ctx->i_oldargv;
6870Sstevel@tonic-gate size_t arglen = strlen(arg);
6880Sstevel@tonic-gate
6891717Swesolows if (*arg == '-') {
6900Sstevel@tonic-gate arglen--;
6911717Swesolows } else {
6920Sstevel@tonic-gate /*
6930Sstevel@tonic-gate * Discard inline files that gcc doesn't grok
6940Sstevel@tonic-gate */
6951717Swesolows if (!in_output && arglen > 3 &&
6960Sstevel@tonic-gate strcmp(arg + arglen - 3, ".il") == 0)
6970Sstevel@tonic-gate continue;
6980Sstevel@tonic-gate
6991717Swesolows if (!in_output && arglen > 2 &&
7001717Swesolows arg[arglen - 2] == '.' &&
7011717Swesolows (arg[arglen - 1] == 'S' || arg[arglen - 1] == 's' ||
7021717Swesolows arg[arglen - 1] == 'c' || arg[arglen - 1] == 'i'))
7031717Swesolows c_files++;
7041717Swesolows
7050Sstevel@tonic-gate /*
7061717Swesolows * Otherwise, filenames and partial arguments
7071717Swesolows * are passed through for gcc to chew on. However,
7081717Swesolows * output is always discarded for the secondary
7091717Swesolows * compiler.
7100Sstevel@tonic-gate */
7111717Swesolows if ((ctx->i_flags & CW_F_SHADOW) && in_output)
7121717Swesolows newae(ctx->i_ae, ctx->i_discard);
7131717Swesolows else
7141717Swesolows newae(ctx->i_ae, arg);
7151717Swesolows in_output = 0;
7160Sstevel@tonic-gate continue;
7170Sstevel@tonic-gate }
7180Sstevel@tonic-gate
7191717Swesolows if (ctx->i_flags & CW_F_CXX) {
7200Sstevel@tonic-gate if (strncmp(arg, "-compat=", 8) == 0) {
7210Sstevel@tonic-gate /* discard -compat=4 and -compat=5 */
7220Sstevel@tonic-gate continue;
7230Sstevel@tonic-gate }
7240Sstevel@tonic-gate if (strcmp(arg, "-Qoption") == 0) {
7250Sstevel@tonic-gate /* discard -Qoption and its two arguments */
7261717Swesolows if (ctx->i_oldargc < 3)
7270Sstevel@tonic-gate error(arg);
7281717Swesolows ctx->i_oldargc -= 2;
7291717Swesolows ctx->i_oldargv += 2;
7300Sstevel@tonic-gate continue;
7310Sstevel@tonic-gate }
7320Sstevel@tonic-gate if (strcmp(arg, "-xwe") == 0) {
7330Sstevel@tonic-gate /* turn warnings into errors */
7341717Swesolows newae(ctx->i_ae, "-Werror");
7350Sstevel@tonic-gate continue;
7360Sstevel@tonic-gate }
7370Sstevel@tonic-gate if (strcmp(arg, "-noex") == 0) {
7380Sstevel@tonic-gate /* no exceptions */
7391717Swesolows newae(ctx->i_ae, "-fno-exceptions");
7400Sstevel@tonic-gate /* no run time type descriptor information */
7411717Swesolows newae(ctx->i_ae, "-fno-rtti");
7420Sstevel@tonic-gate continue;
7430Sstevel@tonic-gate }
7440Sstevel@tonic-gate if (strcmp(arg, "-pic") == 0) {
7451717Swesolows newae(ctx->i_ae, "-fpic");
7460Sstevel@tonic-gate pic = 1;
7470Sstevel@tonic-gate continue;
7480Sstevel@tonic-gate }
7490Sstevel@tonic-gate if (strcmp(arg, "-PIC") == 0) {
7501717Swesolows newae(ctx->i_ae, "-fPIC");
7510Sstevel@tonic-gate pic = 1;
7520Sstevel@tonic-gate continue;
7530Sstevel@tonic-gate }
7540Sstevel@tonic-gate if (strcmp(arg, "-norunpath") == 0) {
7550Sstevel@tonic-gate /* gcc has no corresponding option */
7560Sstevel@tonic-gate continue;
7570Sstevel@tonic-gate }
7580Sstevel@tonic-gate if (strcmp(arg, "-nolib") == 0) {
7590Sstevel@tonic-gate /* -nodefaultlibs is on by default */
7600Sstevel@tonic-gate nolibc = 1;
7610Sstevel@tonic-gate continue;
7620Sstevel@tonic-gate }
7630Sstevel@tonic-gate #if defined(__sparc)
7640Sstevel@tonic-gate if (strcmp(arg, "-cg92") == 0) {
7655534Spetede mflag |= xlate_xtb(ctx->i_ae, "v8");
7661717Swesolows xlate(ctx->i_ae, "super", xchip_tbl);
7670Sstevel@tonic-gate continue;
7680Sstevel@tonic-gate }
7690Sstevel@tonic-gate #endif /* __sparc */
7700Sstevel@tonic-gate }
7710Sstevel@tonic-gate
7720Sstevel@tonic-gate switch ((c = arg[1])) {
7730Sstevel@tonic-gate case '_':
7740Sstevel@tonic-gate if (strcmp(arg, "-_noecho") == 0)
7751717Swesolows ctx->i_flags &= ~CW_F_ECHO;
7760Sstevel@tonic-gate else if (strncmp(arg, "-_cc=", 5) == 0 ||
7770Sstevel@tonic-gate strncmp(arg, "-_CC=", 5) == 0)
7780Sstevel@tonic-gate /* EMPTY */;
7790Sstevel@tonic-gate else if (strncmp(arg, "-_gcc=", 6) == 0 ||
7800Sstevel@tonic-gate strncmp(arg, "-_g++=", 6) == 0)
7811717Swesolows newae(ctx->i_ae, arg + 6);
7821717Swesolows else
7830Sstevel@tonic-gate error(arg);
7840Sstevel@tonic-gate break;
7850Sstevel@tonic-gate case '#':
7860Sstevel@tonic-gate if (arglen == 1) {
7871717Swesolows newae(ctx->i_ae, "-v");
7880Sstevel@tonic-gate break;
7890Sstevel@tonic-gate }
7900Sstevel@tonic-gate error(arg);
7910Sstevel@tonic-gate break;
7920Sstevel@tonic-gate case 'g':
7931717Swesolows newae(ctx->i_ae, "-gdwarf-2");
7940Sstevel@tonic-gate break;
7950Sstevel@tonic-gate case 'E':
7960Sstevel@tonic-gate if (arglen == 1) {
7971717Swesolows newae(ctx->i_ae, "-xc");
7981717Swesolows newae(ctx->i_ae, arg);
7991717Swesolows op = CW_O_PREPROCESS;
8000Sstevel@tonic-gate nolibc = 1;
8010Sstevel@tonic-gate break;
8020Sstevel@tonic-gate }
8030Sstevel@tonic-gate error(arg);
8040Sstevel@tonic-gate break;
8050Sstevel@tonic-gate case 'c':
8060Sstevel@tonic-gate case 'S':
8071717Swesolows if (arglen == 1) {
8081717Swesolows op = CW_O_COMPILE;
8090Sstevel@tonic-gate nolibc = 1;
8101717Swesolows }
8110Sstevel@tonic-gate /* FALLTHROUGH */
8120Sstevel@tonic-gate case 'C':
8130Sstevel@tonic-gate case 'H':
8140Sstevel@tonic-gate case 'p':
8150Sstevel@tonic-gate if (arglen == 1) {
8161717Swesolows newae(ctx->i_ae, arg);
8170Sstevel@tonic-gate break;
8180Sstevel@tonic-gate }
8190Sstevel@tonic-gate error(arg);
8200Sstevel@tonic-gate break;
8210Sstevel@tonic-gate case 'A':
8220Sstevel@tonic-gate case 'h':
8230Sstevel@tonic-gate case 'I':
8240Sstevel@tonic-gate case 'i':
8250Sstevel@tonic-gate case 'L':
8260Sstevel@tonic-gate case 'l':
8270Sstevel@tonic-gate case 'R':
8280Sstevel@tonic-gate case 'U':
8290Sstevel@tonic-gate case 'u':
8300Sstevel@tonic-gate case 'w':
8311717Swesolows newae(ctx->i_ae, arg);
8321717Swesolows break;
8331717Swesolows case 'o':
8341717Swesolows seen_o = 1;
8351717Swesolows if (arglen == 1) {
8361717Swesolows in_output = 1;
8371717Swesolows newae(ctx->i_ae, arg);
8381717Swesolows } else if (ctx->i_flags & CW_F_SHADOW) {
8391717Swesolows newae(ctx->i_ae, "-o");
8401717Swesolows newae(ctx->i_ae, ctx->i_discard);
8411717Swesolows } else {
8421717Swesolows newae(ctx->i_ae, arg);
8431717Swesolows }
8440Sstevel@tonic-gate break;
8450Sstevel@tonic-gate case 'D':
8461717Swesolows newae(ctx->i_ae, arg);
8470Sstevel@tonic-gate /*
8480Sstevel@tonic-gate * XXX Clearly a hack ... do we need _KADB too?
8490Sstevel@tonic-gate */
8500Sstevel@tonic-gate if (strcmp(arg, "-D_KERNEL") == 0 ||
8510Sstevel@tonic-gate strcmp(arg, "-D_BOOT") == 0)
8521717Swesolows newae(ctx->i_ae, "-ffreestanding");
8530Sstevel@tonic-gate break;
8540Sstevel@tonic-gate case 'd':
8550Sstevel@tonic-gate if (arglen == 2) {
8560Sstevel@tonic-gate if (strcmp(arg, "-dy") == 0) {
8571717Swesolows newae(ctx->i_ae, "-Wl,-dy");
8580Sstevel@tonic-gate break;
8590Sstevel@tonic-gate }
8600Sstevel@tonic-gate if (strcmp(arg, "-dn") == 0) {
8611717Swesolows newae(ctx->i_ae, "-Wl,-dn");
8620Sstevel@tonic-gate break;
8630Sstevel@tonic-gate }
8640Sstevel@tonic-gate }
8650Sstevel@tonic-gate if (strcmp(arg, "-dalign") == 0) {
8660Sstevel@tonic-gate /*
8670Sstevel@tonic-gate * -dalign forces alignment in some cases;
8680Sstevel@tonic-gate * gcc does not need any flag to do this.
8690Sstevel@tonic-gate */
8700Sstevel@tonic-gate break;
8710Sstevel@tonic-gate }
8720Sstevel@tonic-gate error(arg);
8730Sstevel@tonic-gate break;
8740Sstevel@tonic-gate case 'e':
8750Sstevel@tonic-gate if (strcmp(arg,
8760Sstevel@tonic-gate "-erroff=E_EMPTY_TRANSLATION_UNIT") == 0) {
8770Sstevel@tonic-gate /*
8780Sstevel@tonic-gate * Accept but ignore this -- gcc doesn't
8790Sstevel@tonic-gate * seem to complain about empty translation
8800Sstevel@tonic-gate * units
8810Sstevel@tonic-gate */
8820Sstevel@tonic-gate break;
8830Sstevel@tonic-gate }
8840Sstevel@tonic-gate /* XX64 -- ignore all -erroff= options, for now */
8850Sstevel@tonic-gate if (strncmp(arg, "-erroff=", 8) == 0)
8860Sstevel@tonic-gate break;
8870Sstevel@tonic-gate if (strcmp(arg, "-errtags=yes") == 0) {
8881717Swesolows warnings(ctx->i_ae);
8890Sstevel@tonic-gate break;
8900Sstevel@tonic-gate }
8910Sstevel@tonic-gate if (strcmp(arg, "-errwarn=%all") == 0) {
8921717Swesolows newae(ctx->i_ae, "-Werror");
8930Sstevel@tonic-gate break;
8940Sstevel@tonic-gate }
8950Sstevel@tonic-gate error(arg);
8960Sstevel@tonic-gate break;
8970Sstevel@tonic-gate case 'f':
8980Sstevel@tonic-gate if (strcmp(arg, "-flags") == 0) {
8991717Swesolows newae(ctx->i_ae, "--help");
9000Sstevel@tonic-gate break;
9010Sstevel@tonic-gate }
9027771SMark.Logan@Sun.COM if (strncmp(arg, "-features=zla", 13) == 0) {
9037771SMark.Logan@Sun.COM /*
9047771SMark.Logan@Sun.COM * Accept but ignore this -- gcc allows
9057771SMark.Logan@Sun.COM * zero length arrays.
9067771SMark.Logan@Sun.COM */
9077771SMark.Logan@Sun.COM break;
9087771SMark.Logan@Sun.COM }
9090Sstevel@tonic-gate error(arg);
9100Sstevel@tonic-gate break;
9110Sstevel@tonic-gate case 'G':
9121717Swesolows newae(ctx->i_ae, "-shared");
9130Sstevel@tonic-gate nolibc = 1;
9140Sstevel@tonic-gate break;
9150Sstevel@tonic-gate case 'k':
9160Sstevel@tonic-gate if (strcmp(arg, "-keeptmp") == 0) {
9171717Swesolows newae(ctx->i_ae, "-save-temps");
9180Sstevel@tonic-gate break;
9190Sstevel@tonic-gate }
9200Sstevel@tonic-gate error(arg);
9210Sstevel@tonic-gate break;
9220Sstevel@tonic-gate case 'K':
9230Sstevel@tonic-gate if (arglen == 1) {
9241717Swesolows if ((arg = *++ctx->i_oldargv) == NULL ||
9251717Swesolows *arg == '\0')
9260Sstevel@tonic-gate error("-K");
9271717Swesolows ctx->i_oldargc--;
9280Sstevel@tonic-gate } else {
9290Sstevel@tonic-gate arg += 2;
9300Sstevel@tonic-gate }
9310Sstevel@tonic-gate if (strcmp(arg, "pic") == 0) {
9321717Swesolows newae(ctx->i_ae, "-fpic");
9330Sstevel@tonic-gate pic = 1;
9340Sstevel@tonic-gate break;
9350Sstevel@tonic-gate }
9360Sstevel@tonic-gate if (strcmp(arg, "PIC") == 0) {
9371717Swesolows newae(ctx->i_ae, "-fPIC");
9380Sstevel@tonic-gate pic = 1;
9390Sstevel@tonic-gate break;
9400Sstevel@tonic-gate }
9410Sstevel@tonic-gate error("-K");
9420Sstevel@tonic-gate break;
9430Sstevel@tonic-gate case 'm':
9440Sstevel@tonic-gate if (strcmp(arg, "-mt") == 0) {
9451717Swesolows newae(ctx->i_ae, "-D_REENTRANT");
9460Sstevel@tonic-gate break;
9470Sstevel@tonic-gate }
9485534Spetede if (strcmp(arg, "-m64") == 0) {
9495534Spetede newae(ctx->i_ae, "-m64");
9505534Spetede #if defined(__x86)
9515534Spetede newae(ctx->i_ae, "-mtune=opteron");
9525534Spetede #endif
9535534Spetede mflag |= M64;
9545534Spetede break;
9555534Spetede }
9565534Spetede if (strcmp(arg, "-m32") == 0) {
9575534Spetede newae(ctx->i_ae, "-m32");
9585534Spetede mflag |= M32;
9595534Spetede break;
9605534Spetede }
9610Sstevel@tonic-gate error(arg);
9620Sstevel@tonic-gate break;
9630Sstevel@tonic-gate case 'B': /* linker options */
9640Sstevel@tonic-gate case 'M':
9650Sstevel@tonic-gate case 'z':
9660Sstevel@tonic-gate {
9670Sstevel@tonic-gate char *opt;
9680Sstevel@tonic-gate size_t len;
9690Sstevel@tonic-gate char *s;
9700Sstevel@tonic-gate
9710Sstevel@tonic-gate if (arglen == 1) {
9721717Swesolows opt = *++ctx->i_oldargv;
9730Sstevel@tonic-gate if (opt == NULL || *opt == '\0')
9740Sstevel@tonic-gate error(arg);
9751717Swesolows ctx->i_oldargc--;
9760Sstevel@tonic-gate } else {
9770Sstevel@tonic-gate opt = arg + 2;
9780Sstevel@tonic-gate }
9790Sstevel@tonic-gate len = strlen(opt) + 7;
9801717Swesolows if ((s = malloc(len)) == NULL)
9811717Swesolows nomem();
9820Sstevel@tonic-gate (void) snprintf(s, len, "-Wl,-%c%s", c, opt);
9831717Swesolows newae(ctx->i_ae, s);
9840Sstevel@tonic-gate free(s);
9850Sstevel@tonic-gate }
9860Sstevel@tonic-gate break;
9870Sstevel@tonic-gate case 'n':
9880Sstevel@tonic-gate if (strcmp(arg, "-noqueue") == 0) {
9890Sstevel@tonic-gate /*
9900Sstevel@tonic-gate * Horrid license server stuff - n/a
9910Sstevel@tonic-gate */
9920Sstevel@tonic-gate break;
9930Sstevel@tonic-gate }
9940Sstevel@tonic-gate error(arg);
9950Sstevel@tonic-gate break;
9960Sstevel@tonic-gate case 'O':
9970Sstevel@tonic-gate if (arglen == 1) {
9981717Swesolows newae(ctx->i_ae, "-O");
9990Sstevel@tonic-gate break;
10000Sstevel@tonic-gate }
10010Sstevel@tonic-gate error(arg);
10020Sstevel@tonic-gate break;
10030Sstevel@tonic-gate case 'P':
10040Sstevel@tonic-gate /*
10050Sstevel@tonic-gate * We could do '-E -o filename.i', but that's hard,
10060Sstevel@tonic-gate * and we don't need it for the case that's triggering
10070Sstevel@tonic-gate * this addition. We'll require the user to specify
10080Sstevel@tonic-gate * -o in the Makefile. If they don't they'll find out
10090Sstevel@tonic-gate * in a hurry.
10100Sstevel@tonic-gate */
10111717Swesolows newae(ctx->i_ae, "-E");
10121717Swesolows op = CW_O_PREPROCESS;
10130Sstevel@tonic-gate nolibc = 1;
10140Sstevel@tonic-gate break;
10150Sstevel@tonic-gate case 'q':
10160Sstevel@tonic-gate if (strcmp(arg, "-qp") == 0) {
10171717Swesolows newae(ctx->i_ae, "-p");
10180Sstevel@tonic-gate break;
10190Sstevel@tonic-gate }
10200Sstevel@tonic-gate error(arg);
10210Sstevel@tonic-gate break;
10220Sstevel@tonic-gate case 's':
10230Sstevel@tonic-gate if (arglen == 1) {
10241717Swesolows newae(ctx->i_ae, "-Wl,-s");
10250Sstevel@tonic-gate break;
10260Sstevel@tonic-gate }
10270Sstevel@tonic-gate error(arg);
10280Sstevel@tonic-gate break;
1029376Swesolows case 't':
1030376Swesolows if (arglen == 1) {
10311717Swesolows newae(ctx->i_ae, "-Wl,-t");
1032376Swesolows break;
1033376Swesolows }
1034376Swesolows error(arg);
1035376Swesolows break;
10360Sstevel@tonic-gate case 'V':
10370Sstevel@tonic-gate if (arglen == 1) {
10381717Swesolows ctx->i_flags &= ~CW_F_ECHO;
10391717Swesolows newae(ctx->i_ae, "--version");
10400Sstevel@tonic-gate break;
10410Sstevel@tonic-gate }
10420Sstevel@tonic-gate error(arg);
10430Sstevel@tonic-gate break;
10440Sstevel@tonic-gate case 'v':
10450Sstevel@tonic-gate if (arglen == 1) {
10461717Swesolows warnings(ctx->i_ae);
10470Sstevel@tonic-gate break;
10480Sstevel@tonic-gate }
10490Sstevel@tonic-gate error(arg);
10500Sstevel@tonic-gate break;
10510Sstevel@tonic-gate case 'W':
10520Sstevel@tonic-gate if (strncmp(arg, "-Wp,-xc99", 9) == 0) {
10530Sstevel@tonic-gate /*
10540Sstevel@tonic-gate * gcc's preprocessor will accept c99
10550Sstevel@tonic-gate * regardless, so accept and ignore.
10560Sstevel@tonic-gate */
10570Sstevel@tonic-gate break;
10580Sstevel@tonic-gate }
10590Sstevel@tonic-gate if (strncmp(arg, "-Wa,", 4) == 0 ||
10600Sstevel@tonic-gate strncmp(arg, "-Wp,", 4) == 0 ||
10610Sstevel@tonic-gate strncmp(arg, "-Wl,", 4) == 0) {
10621717Swesolows newae(ctx->i_ae, arg);
10630Sstevel@tonic-gate break;
10640Sstevel@tonic-gate }
10650Sstevel@tonic-gate if (strcmp(arg, "-W0,-xc99=pragma") == 0) {
10660Sstevel@tonic-gate /* (undocumented) enables _Pragma */
10670Sstevel@tonic-gate break;
10680Sstevel@tonic-gate }
10690Sstevel@tonic-gate if (strcmp(arg, "-W0,-xc99=%none") == 0) {
10700Sstevel@tonic-gate /*
10710Sstevel@tonic-gate * This is a polite way of saying
10720Sstevel@tonic-gate * "no c99 constructs allowed!"
10730Sstevel@tonic-gate * For now, just accept and ignore this.
10740Sstevel@tonic-gate */
10750Sstevel@tonic-gate break;
10760Sstevel@tonic-gate }
10772374Sesaxe if (strcmp(arg, "-W0,-noglobal") == 0 ||
10782374Sesaxe strcmp(arg, "-W0,-xglobalstatic") == 0) {
10790Sstevel@tonic-gate /*
10800Sstevel@tonic-gate * gcc doesn't prefix local symbols
10810Sstevel@tonic-gate * in debug mode, so this is not needed.
10820Sstevel@tonic-gate */
10830Sstevel@tonic-gate break;
10840Sstevel@tonic-gate }
10850Sstevel@tonic-gate if (strcmp(arg, "-W0,-Lt") == 0) {
10860Sstevel@tonic-gate /*
10870Sstevel@tonic-gate * Generate tests at the top of loops.
10880Sstevel@tonic-gate * There is no direct gcc equivalent, ignore.
10890Sstevel@tonic-gate */
10900Sstevel@tonic-gate break;
10910Sstevel@tonic-gate }
1092379Ssherrym if (strcmp(arg, "-W0,-xdbggen=no%usedonly") == 0) {
10931717Swesolows newae(ctx->i_ae,
10941717Swesolows "-fno-eliminate-unused-debug-symbols");
10951717Swesolows newae(ctx->i_ae,
10961717Swesolows "-fno-eliminate-unused-debug-types");
1097379Ssherrym break;
1098379Ssherrym }
10992437Spetede if (strcmp(arg, "-W2,-xwrap_int") == 0) {
11002437Spetede /*
11012437Spetede * Use the legacy behaviour (pre-SS11)
11022437Spetede * for integer wrapping.
11032437Spetede * gcc does not need this.
11042437Spetede */
11052437Spetede break;
11062437Spetede }
11070Sstevel@tonic-gate if (strcmp(arg, "-W2,-Rcond_elim") == 0) {
11080Sstevel@tonic-gate /*
11090Sstevel@tonic-gate * Elimination and expansion of conditionals;
11100Sstevel@tonic-gate * gcc has no direct equivalent.
11110Sstevel@tonic-gate */
11120Sstevel@tonic-gate break;
11130Sstevel@tonic-gate }
11140Sstevel@tonic-gate if (strcmp(arg, "-Wd,-xsafe=unboundsym") == 0) {
11150Sstevel@tonic-gate /*
11160Sstevel@tonic-gate * Prevents optimizing away checks for
11170Sstevel@tonic-gate * unbound weak symbol addresses. gcc does
11180Sstevel@tonic-gate * not do this, so it's not needed.
11190Sstevel@tonic-gate */
11200Sstevel@tonic-gate break;
11210Sstevel@tonic-gate }
11220Sstevel@tonic-gate if (strncmp(arg, "-Wc,-xcode=", 11) == 0) {
11231717Swesolows xlate(ctx->i_ae, arg + 11, xcode_tbl);
11240Sstevel@tonic-gate if (strncmp(arg + 11, "pic", 3) == 0)
11250Sstevel@tonic-gate pic = 1;
11260Sstevel@tonic-gate break;
11270Sstevel@tonic-gate }
11280Sstevel@tonic-gate if (strncmp(arg, "-Wc,-Qiselect", 13) == 0) {
11290Sstevel@tonic-gate /*
11300Sstevel@tonic-gate * Prevents insertion of register symbols.
11310Sstevel@tonic-gate * gcc doesn't do this, so ignore it.
11320Sstevel@tonic-gate */
11330Sstevel@tonic-gate break;
11340Sstevel@tonic-gate }
11352437Spetede if (strcmp(arg, "-Wc,-Qassembler-ounrefsym=0") == 0) {
11362437Spetede /*
11372437Spetede * Prevents optimizing away of static variables.
11382437Spetede * gcc does not do this, so it's not needed.
11392437Spetede */
11402437Spetede break;
11412437Spetede }
11420Sstevel@tonic-gate #if defined(__x86)
11430Sstevel@tonic-gate if (strcmp(arg, "-Wu,-no_got_reloc") == 0) {
11441717Swesolows newae(ctx->i_ae, "-fno-jump-tables");
11451717Swesolows newae(ctx->i_ae, "-fno-constant-pools");
11460Sstevel@tonic-gate break;
11470Sstevel@tonic-gate }
11480Sstevel@tonic-gate if (strcmp(arg, "-Wu,-xmodel=kernel") == 0) {
11491717Swesolows newae(ctx->i_ae, "-ffreestanding");
11501717Swesolows newae(ctx->i_ae, "-mno-red-zone");
11510Sstevel@tonic-gate model = "-mcmodel=kernel";
11520Sstevel@tonic-gate nolibc = 1;
11530Sstevel@tonic-gate break;
11540Sstevel@tonic-gate }
1155325Ssherrym if (strcmp(arg, "-Wu,-save_args") == 0) {
11561717Swesolows newae(ctx->i_ae, "-msave-args");
1157325Ssherrym break;
1158325Ssherrym }
11590Sstevel@tonic-gate #endif /* __x86 */
11600Sstevel@tonic-gate error(arg);
11610Sstevel@tonic-gate break;
11620Sstevel@tonic-gate case 'X':
11630Sstevel@tonic-gate if (strcmp(arg, "-Xa") == 0 ||
11640Sstevel@tonic-gate strcmp(arg, "-Xt") == 0) {
11651717Swesolows Xamode(ctx->i_ae);
11660Sstevel@tonic-gate break;
11670Sstevel@tonic-gate }
11680Sstevel@tonic-gate if (strcmp(arg, "-Xc") == 0) {
11691717Swesolows Xcmode(ctx->i_ae);
11700Sstevel@tonic-gate break;
11710Sstevel@tonic-gate }
11720Sstevel@tonic-gate if (strcmp(arg, "-Xs") == 0) {
11731717Swesolows Xsmode(ctx->i_ae);
11740Sstevel@tonic-gate break;
11750Sstevel@tonic-gate }
11760Sstevel@tonic-gate error(arg);
11770Sstevel@tonic-gate break;
11780Sstevel@tonic-gate case 'x':
11790Sstevel@tonic-gate if (arglen == 1)
11800Sstevel@tonic-gate error(arg);
11810Sstevel@tonic-gate switch (arg[2]) {
11820Sstevel@tonic-gate #if defined(__x86)
11830Sstevel@tonic-gate case '3':
11840Sstevel@tonic-gate if (strcmp(arg, "-x386") == 0) {
11851717Swesolows newae(ctx->i_ae, "-march=i386");
11860Sstevel@tonic-gate break;
11870Sstevel@tonic-gate }
11880Sstevel@tonic-gate error(arg);
11890Sstevel@tonic-gate break;
11900Sstevel@tonic-gate case '4':
11910Sstevel@tonic-gate if (strcmp(arg, "-x486") == 0) {
11921717Swesolows newae(ctx->i_ae, "-march=i486");
11930Sstevel@tonic-gate break;
11940Sstevel@tonic-gate }
11950Sstevel@tonic-gate error(arg);
11960Sstevel@tonic-gate break;
11970Sstevel@tonic-gate #endif /* __x86 */
11980Sstevel@tonic-gate case 'a':
11990Sstevel@tonic-gate if (strncmp(arg, "-xarch=", 7) == 0) {
12005534Spetede mflag |= xlate_xtb(ctx->i_ae, arg + 7);
12010Sstevel@tonic-gate break;
12020Sstevel@tonic-gate }
12030Sstevel@tonic-gate error(arg);
12040Sstevel@tonic-gate break;
1205580Swesolows case 'b':
1206580Swesolows if (strncmp(arg, "-xbuiltin=", 10) == 0) {
1207580Swesolows if (strcmp(arg + 10, "%all"))
12081717Swesolows newae(ctx->i_ae, "-fbuiltin");
1209580Swesolows break;
1210580Swesolows }
1211580Swesolows error(arg);
1212580Swesolows break;
12130Sstevel@tonic-gate case 'C':
12140Sstevel@tonic-gate /* Accept C++ style comments -- ignore */
12150Sstevel@tonic-gate if (strcmp(arg, "-xCC") == 0)
12160Sstevel@tonic-gate break;
12170Sstevel@tonic-gate error(arg);
12180Sstevel@tonic-gate break;
12190Sstevel@tonic-gate case 'c':
12200Sstevel@tonic-gate if (strncmp(arg, "-xc99=%all", 10) == 0) {
12211717Swesolows newae(ctx->i_ae, "-std=gnu99");
12220Sstevel@tonic-gate break;
12230Sstevel@tonic-gate }
12240Sstevel@tonic-gate if (strncmp(arg, "-xc99=%none", 11) == 0) {
12251717Swesolows newae(ctx->i_ae, "-std=gnu89");
12260Sstevel@tonic-gate break;
12270Sstevel@tonic-gate }
12280Sstevel@tonic-gate if (strncmp(arg, "-xchip=", 7) == 0) {
12291717Swesolows xlate(ctx->i_ae, arg + 7, xchip_tbl);
12300Sstevel@tonic-gate break;
12310Sstevel@tonic-gate }
12320Sstevel@tonic-gate if (strncmp(arg, "-xcode=", 7) == 0) {
12331717Swesolows xlate(ctx->i_ae, arg + 7, xcode_tbl);
12340Sstevel@tonic-gate if (strncmp(arg + 7, "pic", 3) == 0)
12350Sstevel@tonic-gate pic = 1;
12360Sstevel@tonic-gate break;
12370Sstevel@tonic-gate }
12380Sstevel@tonic-gate if (strncmp(arg, "-xcache=", 8) == 0)
12390Sstevel@tonic-gate break;
1240376Swesolows if (strncmp(arg, "-xcrossfile", 11) == 0)
1241376Swesolows break;
12420Sstevel@tonic-gate error(arg);
12430Sstevel@tonic-gate break;
12440Sstevel@tonic-gate case 'd':
12450Sstevel@tonic-gate if (strcmp(arg, "-xdepend") == 0)
12460Sstevel@tonic-gate break;
1247379Ssherrym if (strncmp(arg, "-xdebugformat=", 14) == 0)
1248379Ssherrym break;
12490Sstevel@tonic-gate error(arg);
12500Sstevel@tonic-gate break;
12510Sstevel@tonic-gate case 'F':
12525605Srie /*
12535605Srie * Compile for mapfile reordering, or unused
12545605Srie * section elimination, syntax can be -xF or
12555605Srie * more complex, like -xF=%all -- ignore.
12565605Srie */
12575605Srie if (strncmp(arg, "-xF", 3) == 0)
12580Sstevel@tonic-gate break;
12590Sstevel@tonic-gate error(arg);
12600Sstevel@tonic-gate break;
12610Sstevel@tonic-gate case 'i':
12620Sstevel@tonic-gate if (strncmp(arg, "-xinline", 8) == 0)
12630Sstevel@tonic-gate /* No inlining; ignore */
12640Sstevel@tonic-gate break;
12650Sstevel@tonic-gate if (strcmp(arg, "-xildon") == 0 ||
12660Sstevel@tonic-gate strcmp(arg, "-xildoff") == 0)
12670Sstevel@tonic-gate /* No incremental linking; ignore */
12680Sstevel@tonic-gate break;
12690Sstevel@tonic-gate error(arg);
12700Sstevel@tonic-gate break;
12712886Spetede #if defined(__x86)
12722886Spetede case 'm':
12732886Spetede if (strcmp(arg, "-xmodel=kernel") == 0) {
12742886Spetede newae(ctx->i_ae, "-ffreestanding");
12752886Spetede newae(ctx->i_ae, "-mno-red-zone");
12762886Spetede model = "-mcmodel=kernel";
12772886Spetede nolibc = 1;
12782886Spetede break;
12792886Spetede }
12802886Spetede error(arg);
12812886Spetede break;
12822886Spetede #endif /* __x86 */
12830Sstevel@tonic-gate case 'M':
12840Sstevel@tonic-gate if (strcmp(arg, "-xM") == 0) {
12851717Swesolows newae(ctx->i_ae, "-M");
12860Sstevel@tonic-gate break;
12870Sstevel@tonic-gate }
12880Sstevel@tonic-gate if (strcmp(arg, "-xM1") == 0) {
12891717Swesolows newae(ctx->i_ae, "-MM");
12900Sstevel@tonic-gate break;
12910Sstevel@tonic-gate }
12920Sstevel@tonic-gate error(arg);
12930Sstevel@tonic-gate break;
12940Sstevel@tonic-gate case 'n':
12950Sstevel@tonic-gate if (strcmp(arg, "-xnolib") == 0) {
12960Sstevel@tonic-gate nolibc = 1;
12970Sstevel@tonic-gate break;
12980Sstevel@tonic-gate }
12990Sstevel@tonic-gate error(arg);
13000Sstevel@tonic-gate break;
13010Sstevel@tonic-gate case 'O':
13020Sstevel@tonic-gate if (strncmp(arg, "-xO", 3) == 0) {
13030Sstevel@tonic-gate size_t len = strlen(arg);
13041717Swesolows char *s;
13050Sstevel@tonic-gate int c = *(arg + 3);
13060Sstevel@tonic-gate int level;
13070Sstevel@tonic-gate
13080Sstevel@tonic-gate if (len != 4 || !isdigit(c))
13090Sstevel@tonic-gate error(arg);
13100Sstevel@tonic-gate
13111717Swesolows if ((s = malloc(len)) == NULL)
13121717Swesolows nomem();
13131717Swesolows
13140Sstevel@tonic-gate level = atoi(arg + 3);
13150Sstevel@tonic-gate if (level > 5)
13160Sstevel@tonic-gate error(arg);
13170Sstevel@tonic-gate if (level >= 2) {
13180Sstevel@tonic-gate /*
13190Sstevel@tonic-gate * For gcc-3.4.x at -O2 we
13200Sstevel@tonic-gate * need to disable optimizations
13210Sstevel@tonic-gate * that break ON.
13220Sstevel@tonic-gate */
13231717Swesolows optim_disable(ctx->i_ae, level);
13240Sstevel@tonic-gate /*
13250Sstevel@tonic-gate * limit -xO3 to -O2 as well.
13260Sstevel@tonic-gate */
13270Sstevel@tonic-gate level = 2;
13280Sstevel@tonic-gate }
13290Sstevel@tonic-gate (void) snprintf(s, len, "-O%d", level);
13301717Swesolows newae(ctx->i_ae, s);
13310Sstevel@tonic-gate free(s);
13320Sstevel@tonic-gate break;
13330Sstevel@tonic-gate }
13340Sstevel@tonic-gate error(arg);
13350Sstevel@tonic-gate break;
13360Sstevel@tonic-gate case 'p':
13370Sstevel@tonic-gate if (strcmp(arg, "-xpentium") == 0) {
13381717Swesolows newae(ctx->i_ae, "-march=pentium");
13390Sstevel@tonic-gate break;
13400Sstevel@tonic-gate }
13410Sstevel@tonic-gate if (strcmp(arg, "-xpg") == 0) {
13421717Swesolows newae(ctx->i_ae, "-pg");
13430Sstevel@tonic-gate break;
13440Sstevel@tonic-gate }
13450Sstevel@tonic-gate error(arg);
13460Sstevel@tonic-gate break;
13470Sstevel@tonic-gate case 'r':
13480Sstevel@tonic-gate if (strncmp(arg, "-xregs=", 7) == 0) {
13491717Swesolows xlate(ctx->i_ae, arg + 7, xregs_tbl);
13500Sstevel@tonic-gate break;
13510Sstevel@tonic-gate }
13520Sstevel@tonic-gate error(arg);
13530Sstevel@tonic-gate break;
13540Sstevel@tonic-gate case 's':
13550Sstevel@tonic-gate if (strcmp(arg, "-xs") == 0 ||
13560Sstevel@tonic-gate strcmp(arg, "-xspace") == 0 ||
13570Sstevel@tonic-gate strcmp(arg, "-xstrconst") == 0)
13580Sstevel@tonic-gate break;
13590Sstevel@tonic-gate error(arg);
13600Sstevel@tonic-gate break;
13610Sstevel@tonic-gate case 't':
13620Sstevel@tonic-gate if (strcmp(arg, "-xtransition") == 0) {
13631717Swesolows newae(ctx->i_ae, "-Wtransition");
13640Sstevel@tonic-gate break;
13650Sstevel@tonic-gate }
13660Sstevel@tonic-gate if (strcmp(arg, "-xtrigraphs=yes") == 0) {
13671717Swesolows newae(ctx->i_ae, "-trigraphs");
13680Sstevel@tonic-gate break;
13690Sstevel@tonic-gate }
13700Sstevel@tonic-gate if (strcmp(arg, "-xtrigraphs=no") == 0) {
13711717Swesolows newae(ctx->i_ae, "-notrigraphs");
13720Sstevel@tonic-gate break;
13730Sstevel@tonic-gate }
13740Sstevel@tonic-gate if (strncmp(arg, "-xtarget=", 9) == 0) {
13751717Swesolows xlate(ctx->i_ae, arg + 9, xtarget_tbl);
13760Sstevel@tonic-gate break;
13770Sstevel@tonic-gate }
13780Sstevel@tonic-gate error(arg);
13790Sstevel@tonic-gate break;
13800Sstevel@tonic-gate case 'e':
13810Sstevel@tonic-gate case 'h':
13820Sstevel@tonic-gate case 'l':
13830Sstevel@tonic-gate default:
13840Sstevel@tonic-gate error(arg);
13850Sstevel@tonic-gate break;
13860Sstevel@tonic-gate }
13870Sstevel@tonic-gate break;
13880Sstevel@tonic-gate case 'Y':
13890Sstevel@tonic-gate if (arglen == 1) {
13901717Swesolows if ((arg = *++ctx->i_oldargv) == NULL ||
13911717Swesolows *arg == '\0')
13920Sstevel@tonic-gate error("-Y");
13931717Swesolows ctx->i_oldargc--;
13940Sstevel@tonic-gate arglen = strlen(arg + 1);
13950Sstevel@tonic-gate } else {
13960Sstevel@tonic-gate arg += 2;
13970Sstevel@tonic-gate }
13980Sstevel@tonic-gate /* Just ignore -YS,... for now */
13990Sstevel@tonic-gate if (strncmp(arg, "S,", 2) == 0)
14000Sstevel@tonic-gate break;
14010Sstevel@tonic-gate if (strncmp(arg, "l,", 2) == 0) {
14020Sstevel@tonic-gate char *s = strdup(arg);
14030Sstevel@tonic-gate s[0] = '-';
14040Sstevel@tonic-gate s[1] = 'B';
14051717Swesolows newae(ctx->i_ae, s);
14060Sstevel@tonic-gate free(s);
14070Sstevel@tonic-gate break;
14080Sstevel@tonic-gate }
14090Sstevel@tonic-gate if (strncmp(arg, "I,", 2) == 0) {
14100Sstevel@tonic-gate char *s = strdup(arg);
14110Sstevel@tonic-gate s[0] = '-';
14120Sstevel@tonic-gate s[1] = 'I';
14131717Swesolows newae(ctx->i_ae, "-nostdinc");
14141717Swesolows newae(ctx->i_ae, s);
14150Sstevel@tonic-gate free(s);
14160Sstevel@tonic-gate break;
14170Sstevel@tonic-gate }
14180Sstevel@tonic-gate error(arg);
14190Sstevel@tonic-gate break;
14200Sstevel@tonic-gate case 'Q':
14210Sstevel@tonic-gate /*
14220Sstevel@tonic-gate * We could map -Qy into -Wl,-Qy etc.
14230Sstevel@tonic-gate */
14240Sstevel@tonic-gate default:
14250Sstevel@tonic-gate error(arg);
14260Sstevel@tonic-gate break;
14270Sstevel@tonic-gate }
14280Sstevel@tonic-gate }
14290Sstevel@tonic-gate
14301717Swesolows if (c_files > 1 && (ctx->i_flags & CW_F_SHADOW) &&
14311717Swesolows op != CW_O_PREPROCESS) {
14321717Swesolows (void) fprintf(stderr, "%s: error: multiple source files are "
14331717Swesolows "allowed only with -E or -P\n", progname);
14341717Swesolows exit(2);
14351717Swesolows }
14365534Spetede
14375534Spetede /*
14385534Spetede * Make sure that we do not have any unintended interactions between
14395534Spetede * the xarch options passed in and the version of the Studio compiler
14405534Spetede * used.
14415534Spetede */
14425534Spetede if ((mflag & (SS11|SS12)) == (SS11|SS12)) {
14435534Spetede (void) fprintf(stderr,
14445534Spetede "Conflicting \"-xarch=\" flags (both Studio 11 and 12)\n");
14455534Spetede exit(2);
14465534Spetede }
14475534Spetede
14485534Spetede switch (mflag) {
14495534Spetede case 0:
14505534Spetede /* FALLTHROUGH */
14515534Spetede case M32:
14525534Spetede #if defined(__sparc)
14535534Spetede /*
14545534Spetede * Only -m32 is defined and so put in the missing xarch
14555534Spetede * translation.
14565534Spetede */
14575534Spetede newae(ctx->i_ae, "-mcpu=v8");
14585534Spetede newae(ctx->i_ae, "-mno-v8plus");
14595534Spetede #endif
14605534Spetede break;
14615534Spetede case M64:
14625534Spetede #if defined(__sparc)
14635534Spetede /*
14645534Spetede * Only -m64 is defined and so put in the missing xarch
14655534Spetede * translation.
14665534Spetede */
14675534Spetede newae(ctx->i_ae, "-mcpu=v9");
14685534Spetede #endif
14695534Spetede break;
14705534Spetede case SS12:
14715534Spetede #if defined(__sparc)
14725534Spetede /* no -m32/-m64 flag used - this is an error for sparc builds */
14735534Spetede (void) fprintf(stderr, "No -m32/-m64 flag defined\n");
14745534Spetede exit(2);
14755534Spetede #endif
14765534Spetede break;
14775534Spetede case SS11:
14785534Spetede /* FALLTHROUGH */
14795534Spetede case (SS11|M32):
14805534Spetede case (SS11|M64):
14815534Spetede break;
14825534Spetede case (SS12|M32):
14835534Spetede #if defined(__sparc)
14845534Spetede /*
14855534Spetede * Need to add in further 32 bit options because with SS12
14865534Spetede * the xarch=sparcvis option can be applied to 32 or 64
14875534Spetede * bit, and so the translatation table (xtbl) cannot handle
14885534Spetede * that.
14895534Spetede */
14905534Spetede newae(ctx->i_ae, "-mv8plus");
14915534Spetede #endif
14925534Spetede break;
14935534Spetede case (SS12|M64):
14945534Spetede break;
14955534Spetede default:
14965534Spetede (void) fprintf(stderr,
14975548Spetede "Incompatible -xarch= and/or -m32/-m64 options used.\n");
14985534Spetede exit(2);
14995534Spetede }
15001717Swesolows if (op == CW_O_LINK && (ctx->i_flags & CW_F_SHADOW))
15011717Swesolows exit(0);
15021717Swesolows
15030Sstevel@tonic-gate if (model && !pic)
15041717Swesolows newae(ctx->i_ae, model);
15050Sstevel@tonic-gate if (!nolibc)
15061717Swesolows newae(ctx->i_ae, "-lc");
15071717Swesolows if (!seen_o && (ctx->i_flags & CW_F_SHADOW)) {
15081717Swesolows newae(ctx->i_ae, "-o");
15091717Swesolows newae(ctx->i_ae, ctx->i_discard);
15101717Swesolows }
15110Sstevel@tonic-gate }
15120Sstevel@tonic-gate
15130Sstevel@tonic-gate static void
do_cc(cw_ictx_t * ctx)15141717Swesolows do_cc(cw_ictx_t *ctx)
15150Sstevel@tonic-gate {
15161717Swesolows int in_output = 0, seen_o = 0;
15171717Swesolows cw_op_t op = CW_O_LINK;
15181717Swesolows
15191792Swesolows if (ctx->i_flags & CW_F_PROG) {
15201792Swesolows newae(ctx->i_ae, "-V");
15211792Swesolows return;
15221792Swesolows }
15231792Swesolows
15241717Swesolows while (--ctx->i_oldargc > 0) {
15251717Swesolows char *arg = *++ctx->i_oldargv;
15261717Swesolows
15271717Swesolows if (*arg != '-') {
15281717Swesolows if (in_output == 0 || !(ctx->i_flags & CW_F_SHADOW)) {
15291717Swesolows newae(ctx->i_ae, arg);
15301717Swesolows } else {
15311717Swesolows in_output = 0;
15321717Swesolows newae(ctx->i_ae, ctx->i_discard);
15331717Swesolows }
15341717Swesolows continue;
15351717Swesolows }
15361717Swesolows switch (*(arg + 1)) {
15371717Swesolows case '_':
15381717Swesolows if (strcmp(arg, "-_noecho") == 0) {
15391717Swesolows ctx->i_flags &= ~CW_F_ECHO;
15401717Swesolows } else if (strncmp(arg, "-_cc=", 5) == 0 ||
15411717Swesolows strncmp(arg, "-_CC=", 5) == 0) {
15421717Swesolows newae(ctx->i_ae, arg + 5);
15431717Swesolows } else if (strncmp(arg, "-_gcc=", 6) != 0 &&
15441717Swesolows strncmp(arg, "-_g++=", 6) != 0) {
15451717Swesolows (void) fprintf(stderr,
15461717Swesolows "%s: invalid argument '%s'\n", progname,
15471717Swesolows arg);
15481717Swesolows exit(2);
15491717Swesolows }
15501717Swesolows break;
15511717Swesolows case 'V':
15521717Swesolows ctx->i_flags &= ~CW_F_ECHO;
15531717Swesolows newae(ctx->i_ae, arg);
15541717Swesolows break;
15551717Swesolows case 'o':
15561717Swesolows seen_o = 1;
15571717Swesolows if (strlen(arg) == 2) {
15581717Swesolows in_output = 1;
15591717Swesolows newae(ctx->i_ae, arg);
15601717Swesolows } else if (ctx->i_flags & CW_F_SHADOW) {
15611717Swesolows newae(ctx->i_ae, "-o");
15621717Swesolows newae(ctx->i_ae, ctx->i_discard);
15631717Swesolows } else {
15641717Swesolows newae(ctx->i_ae, arg);
15651717Swesolows }
15661717Swesolows break;
15671717Swesolows case 'c':
15681717Swesolows case 'S':
15694032Srie if (strlen(arg) == 2)
15704032Srie op = CW_O_COMPILE;
15711717Swesolows newae(ctx->i_ae, arg);
15721717Swesolows break;
15731717Swesolows case 'E':
15741717Swesolows case 'P':
15754032Srie if (strlen(arg) == 2)
15764032Srie op = CW_O_PREPROCESS;
15771717Swesolows /*FALLTHROUGH*/
15781717Swesolows default:
15791717Swesolows newae(ctx->i_ae, arg);
15801717Swesolows }
15811717Swesolows }
15821717Swesolows
15831717Swesolows if ((op == CW_O_LINK || op == CW_O_PREPROCESS) &&
15841717Swesolows (ctx->i_flags & CW_F_SHADOW))
15851717Swesolows exit(0);
15860Sstevel@tonic-gate
15871717Swesolows if (!seen_o && (ctx->i_flags & CW_F_SHADOW)) {
15881717Swesolows newae(ctx->i_ae, "-o");
15891717Swesolows newae(ctx->i_ae, ctx->i_discard);
15901717Swesolows }
15911717Swesolows }
15921717Swesolows
15931717Swesolows static void
prepctx(cw_ictx_t * ctx)15941717Swesolows prepctx(cw_ictx_t *ctx)
15951717Swesolows {
1596*11997SScott.Rotondo@Sun.COM const char *dir = NULL, *cmd;
1597*11997SScott.Rotondo@Sun.COM char *program = NULL;
15981717Swesolows size_t len;
15991717Swesolows
1600*11997SScott.Rotondo@Sun.COM switch (CIDX(CC(ctx), ctx->i_flags)) {
1601*11997SScott.Rotondo@Sun.COM case CIDX(CW_C_CC, 0):
1602*11997SScott.Rotondo@Sun.COM program = getenv("CW_CC");
1603*11997SScott.Rotondo@Sun.COM dir = getenv("CW_CC_DIR");
1604*11997SScott.Rotondo@Sun.COM break;
1605*11997SScott.Rotondo@Sun.COM case CIDX(CW_C_CC, CW_F_CXX):
1606*11997SScott.Rotondo@Sun.COM program = getenv("CW_CPLUSPLUS");
1607*11997SScott.Rotondo@Sun.COM dir = getenv("CW_CPLUSPLUS_DIR");
1608*11997SScott.Rotondo@Sun.COM break;
1609*11997SScott.Rotondo@Sun.COM case CIDX(CW_C_GCC, 0):
1610*11997SScott.Rotondo@Sun.COM program = getenv("CW_GCC");
1611*11997SScott.Rotondo@Sun.COM dir = getenv("CW_GCC_DIR");
1612*11997SScott.Rotondo@Sun.COM break;
1613*11997SScott.Rotondo@Sun.COM case CIDX(CW_C_GCC, CW_F_CXX):
1614*11997SScott.Rotondo@Sun.COM program = getenv("CW_GPLUSPLUS");
1615*11997SScott.Rotondo@Sun.COM dir = getenv("CW_GPLUSPLUS_DIR");
1616*11997SScott.Rotondo@Sun.COM break;
1617*11997SScott.Rotondo@Sun.COM }
1618*11997SScott.Rotondo@Sun.COM
1619*11997SScott.Rotondo@Sun.COM if (program == NULL) {
1620*11997SScott.Rotondo@Sun.COM if (dir == NULL)
1621*11997SScott.Rotondo@Sun.COM dir = default_dir[CC(ctx)];
1622*11997SScott.Rotondo@Sun.COM cmd = cmds[CIDX(CC(ctx), ctx->i_flags)];
1623*11997SScott.Rotondo@Sun.COM len = strlen(dir) + strlen(cmd) + 2;
1624*11997SScott.Rotondo@Sun.COM if ((program = malloc(len)) == NULL)
1625*11997SScott.Rotondo@Sun.COM nomem();
1626*11997SScott.Rotondo@Sun.COM (void) snprintf(program, len, "%s/%s", dir, cmd);
1627*11997SScott.Rotondo@Sun.COM }
16280Sstevel@tonic-gate
16291717Swesolows newae(ctx->i_ae, program);
16301717Swesolows
16311792Swesolows if (ctx->i_flags & CW_F_PROG) {
16321792Swesolows (void) printf("%s: %s\n", (ctx->i_flags & CW_F_SHADOW) ?
16331792Swesolows "shadow" : "primary", program);
16341792Swesolows (void) fflush(stdout);
16351792Swesolows }
16361792Swesolows
16371717Swesolows if (!(ctx->i_flags & CW_F_XLATE))
16381717Swesolows return;
16391717Swesolows
16401717Swesolows switch (CC(ctx)) {
16411717Swesolows case CW_C_CC:
16421717Swesolows do_cc(ctx);
16431717Swesolows break;
16441717Swesolows case CW_C_GCC:
16451717Swesolows do_gcc(ctx);
16461717Swesolows break;
16471717Swesolows }
16481717Swesolows }
16491717Swesolows
16501717Swesolows static int
invoke(cw_ictx_t * ctx)16511717Swesolows invoke(cw_ictx_t *ctx)
16521717Swesolows {
16531717Swesolows char **newargv;
16541717Swesolows int ac;
16551717Swesolows struct ae *a;
16561717Swesolows
16571717Swesolows if ((newargv = calloc(sizeof (*newargv), ctx->i_ae->ael_argc + 1)) ==
16581717Swesolows NULL)
16591717Swesolows nomem();
16601717Swesolows
16611717Swesolows if (ctx->i_flags & CW_F_ECHO)
16621717Swesolows (void) fprintf(stderr, "+ ");
16631717Swesolows
16641717Swesolows for (ac = 0, a = ctx->i_ae->ael_head; a; a = a->ae_next, ac++) {
16651717Swesolows newargv[ac] = a->ae_arg;
16661717Swesolows if (ctx->i_flags & CW_F_ECHO)
16671717Swesolows (void) fprintf(stderr, "%s ", a->ae_arg);
16681717Swesolows if (a == ctx->i_ae->ael_tail)
16691717Swesolows break;
16701717Swesolows }
16711717Swesolows
16721717Swesolows if (ctx->i_flags & CW_F_ECHO) {
16731717Swesolows (void) fprintf(stderr, "\n");
16741717Swesolows (void) fflush(stderr);
16751717Swesolows }
16761717Swesolows
16771717Swesolows if (!(ctx->i_flags & CW_F_EXEC))
16781717Swesolows return (0);
16791717Swesolows
16800Sstevel@tonic-gate /*
16811717Swesolows * We must fix up the environment here so that the
16821717Swesolows * dependency files are not trampled by the shadow compiler.
16830Sstevel@tonic-gate */
16841717Swesolows if ((ctx->i_flags & CW_F_SHADOW) &&
16851717Swesolows (unsetenv("SUNPRO_DEPENDENCIES") != 0 ||
16861717Swesolows unsetenv("DEPENDENCIES_OUTPUT") != 0)) {
16871717Swesolows (void) fprintf(stderr, "error: environment setup failed: %s\n",
16881717Swesolows strerror(errno));
16891717Swesolows return (-1);
16901717Swesolows }
16911717Swesolows
16921717Swesolows (void) execv(newargv[0], newargv);
16931717Swesolows cw_perror("couldn't run %s", newargv[0]);
16941717Swesolows
16951717Swesolows return (-1);
16961717Swesolows }
16971717Swesolows
16981717Swesolows static int
reap(cw_ictx_t * ctx)16991717Swesolows reap(cw_ictx_t *ctx)
17001717Swesolows {
17011792Swesolows int status, ret = 0;
17021717Swesolows char buf[1024];
17031717Swesolows struct stat s;
17040Sstevel@tonic-gate
170511207SPeter.Dennis@Sun.COM /*
170611207SPeter.Dennis@Sun.COM * Only wait for one specific child.
170711207SPeter.Dennis@Sun.COM */
170811207SPeter.Dennis@Sun.COM if (ctx->i_pid <= 0)
170911207SPeter.Dennis@Sun.COM return (-1);
171011207SPeter.Dennis@Sun.COM
17111717Swesolows do {
171211207SPeter.Dennis@Sun.COM if (waitpid(ctx->i_pid, &status, 0) < 0) {
171311207SPeter.Dennis@Sun.COM cw_perror("cannot reap child");
171411207SPeter.Dennis@Sun.COM return (-1);
171511207SPeter.Dennis@Sun.COM }
17161792Swesolows if (status != 0) {
17171792Swesolows if (WIFSIGNALED(status)) {
17181792Swesolows ret = -WTERMSIG(status);
17191717Swesolows break;
17201792Swesolows } else if (WIFEXITED(status)) {
17211792Swesolows ret = WEXITSTATUS(status);
17221717Swesolows break;
17231717Swesolows }
17241717Swesolows }
17251792Swesolows } while (!WIFEXITED(status) && !WIFSIGNALED(status));
17261717Swesolows
17271717Swesolows (void) unlink(ctx->i_discard);
17281717Swesolows
17291792Swesolows if (stat(ctx->i_stderr, &s) < 0) {
17301717Swesolows cw_perror("stat failed on child cleanup");
17311717Swesolows return (-1);
17321717Swesolows }
17331717Swesolows if (s.st_size != 0) {
17341792Swesolows FILE *f;
17350Sstevel@tonic-gate
17361792Swesolows if ((f = fopen(ctx->i_stderr, "r")) != NULL) {
17371792Swesolows while (fgets(buf, sizeof (buf), f))
17381792Swesolows (void) fprintf(stderr, "%s", buf);
17391792Swesolows (void) fflush(stderr);
17401792Swesolows (void) fclose(f);
17411792Swesolows }
17421717Swesolows }
17431792Swesolows (void) unlink(ctx->i_stderr);
17441792Swesolows free(ctx->i_stderr);
17451792Swesolows
17461792Swesolows /*
17471792Swesolows * cc returns an error code when given -V; we want that to succeed.
17481792Swesolows */
17491792Swesolows if (ctx->i_flags & CW_F_PROG)
17501792Swesolows return (0);
17511717Swesolows
17521717Swesolows return (ret);
17531717Swesolows }
17541717Swesolows
17551717Swesolows static int
exec_ctx(cw_ictx_t * ctx,int block)17561717Swesolows exec_ctx(cw_ictx_t *ctx, int block)
17571717Swesolows {
17581717Swesolows char *file;
17591717Swesolows
17601717Swesolows /*
17611717Swesolows * To avoid offending cc's sensibilities, the name of its output
17621717Swesolows * file must end in '.o'.
17631717Swesolows */
17641717Swesolows if ((file = tempnam(NULL, ".cw")) == NULL) {
17651717Swesolows nomem();
17661717Swesolows return (-1);
17671717Swesolows }
17681717Swesolows (void) strlcpy(ctx->i_discard, file, MAXPATHLEN);
17691717Swesolows (void) strlcat(ctx->i_discard, ".o", MAXPATHLEN);
17701717Swesolows free(file);
17711717Swesolows
17721792Swesolows if ((ctx->i_stderr = tempnam(NULL, ".cw")) == NULL) {
17731792Swesolows nomem();
17741717Swesolows return (-1);
17751717Swesolows }
17761717Swesolows
17771717Swesolows if ((ctx->i_pid = fork()) == 0) {
17781792Swesolows int fd;
17791792Swesolows
17801717Swesolows (void) fclose(stderr);
17811792Swesolows if ((fd = open(ctx->i_stderr, O_WRONLY | O_CREAT | O_EXCL,
17821792Swesolows 0666)) < 0) {
17831792Swesolows cw_perror("open failed for standard error");
17841792Swesolows exit(1);
17851792Swesolows }
17861792Swesolows if (dup2(fd, 2) < 0) {
17871717Swesolows cw_perror("dup2 failed for standard error");
17881717Swesolows exit(1);
17890Sstevel@tonic-gate }
17901792Swesolows if (fd != 2)
17911792Swesolows (void) close(fd);
17921717Swesolows if (freopen("/dev/fd/2", "w", stderr) == NULL) {
17931717Swesolows cw_perror("freopen failed for /dev/fd/2");
17941717Swesolows exit(1);
17951717Swesolows }
17961717Swesolows prepctx(ctx);
17971717Swesolows exit(invoke(ctx));
17980Sstevel@tonic-gate }
17991717Swesolows
18001717Swesolows if (ctx->i_pid < 0) {
18011717Swesolows cw_perror("fork failed");
18021717Swesolows return (1);
18031717Swesolows }
18041717Swesolows
18051717Swesolows if (block)
18061717Swesolows return (reap(ctx));
18071717Swesolows
18081717Swesolows return (0);
18090Sstevel@tonic-gate }
18100Sstevel@tonic-gate
18110Sstevel@tonic-gate int
main(int argc,char ** argv)18120Sstevel@tonic-gate main(int argc, char **argv)
18130Sstevel@tonic-gate {
18141717Swesolows cw_ictx_t *ctx = newictx();
18151717Swesolows cw_ictx_t *ctx_shadow = newictx();
18160Sstevel@tonic-gate const char *dir;
18171717Swesolows int do_serial, do_shadow;
18181717Swesolows int ret = 0;
18190Sstevel@tonic-gate
18200Sstevel@tonic-gate if ((progname = strrchr(argv[0], '/')) == NULL)
18210Sstevel@tonic-gate progname = argv[0];
18220Sstevel@tonic-gate else
18230Sstevel@tonic-gate progname++;
18240Sstevel@tonic-gate
18251717Swesolows if (ctx == NULL || ctx_shadow == NULL)
18261717Swesolows nomem();
18271717Swesolows
18281717Swesolows ctx->i_flags = CW_F_ECHO|CW_F_XLATE;
18290Sstevel@tonic-gate
18300Sstevel@tonic-gate /*
18310Sstevel@tonic-gate * Figure out where to get our tools from. This depends on
18320Sstevel@tonic-gate * the environment variables set at run time.
18330Sstevel@tonic-gate */
18340Sstevel@tonic-gate if ((dir = getenv("SPRO_VROOT")) != NULL) {
1835*11997SScott.Rotondo@Sun.COM (void) snprintf(default_dir[CW_C_CC], MAXPATHLEN,
1836*11997SScott.Rotondo@Sun.COM "%s/bin", dir);
18370Sstevel@tonic-gate } else if ((dir = getenv("SPRO_ROOT")) != NULL) {
1838*11997SScott.Rotondo@Sun.COM (void) snprintf(default_dir[CW_C_CC], MAXPATHLEN,
1839*11997SScott.Rotondo@Sun.COM "%s/SS12/bin", dir);
18400Sstevel@tonic-gate } else if ((dir = getenv("BUILD_TOOLS")) != NULL) {
1841*11997SScott.Rotondo@Sun.COM (void) snprintf(default_dir[CW_C_CC], MAXPATHLEN,
18427684SNick.Todd@Sun.COM "%s/SUNWspro/SS12/bin", dir);
18430Sstevel@tonic-gate }
18440Sstevel@tonic-gate
18450Sstevel@tonic-gate if ((dir = getenv("GNU_ROOT")) != NULL) {
1846*11997SScott.Rotondo@Sun.COM (void) snprintf(default_dir[CW_C_GCC], MAXPATHLEN,
1847*11997SScott.Rotondo@Sun.COM "%s/bin", dir);
18480Sstevel@tonic-gate }
18490Sstevel@tonic-gate
18501717Swesolows do_shadow = (getenv("CW_NO_SHADOW") ? 0 : 1);
18511717Swesolows do_serial = (getenv("CW_SHADOW_SERIAL") ? 1 : 0);
18521717Swesolows
18531717Swesolows if (getenv("CW_NO_EXEC") == NULL)
18541717Swesolows ctx->i_flags |= CW_F_EXEC;
18550Sstevel@tonic-gate
18560Sstevel@tonic-gate /*
18570Sstevel@tonic-gate * The first argument must be one of "-_cc", "-_gcc", "-_CC", or "-_g++"
18580Sstevel@tonic-gate */
18590Sstevel@tonic-gate if (argc == 1)
18600Sstevel@tonic-gate usage();
18610Sstevel@tonic-gate argc--;
18620Sstevel@tonic-gate argv++;
18630Sstevel@tonic-gate if (strcmp(argv[0], "-_cc") == 0) {
18641717Swesolows ctx->i_compiler = CW_C_CC;
18650Sstevel@tonic-gate } else if (strcmp(argv[0], "-_gcc") == 0) {
18661717Swesolows ctx->i_compiler = CW_C_GCC;
18670Sstevel@tonic-gate } else if (strcmp(argv[0], "-_CC") == 0) {
18681717Swesolows ctx->i_compiler = CW_C_CC;
18691717Swesolows ctx->i_flags |= CW_F_CXX;
18700Sstevel@tonic-gate } else if (strcmp(argv[0], "-_g++") == 0) {
18711717Swesolows ctx->i_compiler = CW_C_GCC;
18721717Swesolows ctx->i_flags |= CW_F_CXX;
18730Sstevel@tonic-gate } else {
18740Sstevel@tonic-gate /* assume "-_gcc" by default */
18750Sstevel@tonic-gate argc++;
18760Sstevel@tonic-gate argv--;
18771717Swesolows ctx->i_compiler = CW_C_GCC;
18780Sstevel@tonic-gate }
18790Sstevel@tonic-gate
18801792Swesolows /*
18811792Swesolows * -_compiler - tell us the path to the primary compiler only
18821792Swesolows */
18831717Swesolows if (argc > 1 && strcmp(argv[1], "-_compiler") == 0) {
18841717Swesolows ctx->i_flags &= ~CW_F_XLATE;
18851717Swesolows prepctx(ctx);
18861717Swesolows (void) printf("%s\n", ctx->i_ae->ael_head->ae_arg);
18871717Swesolows return (0);
18880Sstevel@tonic-gate }
18890Sstevel@tonic-gate
18901792Swesolows /*
18911792Swesolows * -_versions - tell us the cw version, paths to all compilers, and
18921792Swesolows * ask each for its version if we know how.
18931792Swesolows */
18941792Swesolows if (argc > 1 && strcmp(argv[1], "-_versions") == 0) {
18957298SMark.J.Nelson@Sun.COM (void) printf("cw version %s", CW_VERSION);
18961792Swesolows if (!do_shadow)
18971792Swesolows (void) printf(" (SHADOW MODE DISABLED)");
18981792Swesolows (void) printf("\n");
18991792Swesolows (void) fflush(stdout);
19001792Swesolows ctx->i_flags &= ~CW_F_ECHO;
19011792Swesolows ctx->i_flags |= CW_F_PROG|CW_F_EXEC;
19021792Swesolows argc--;
19031792Swesolows argv++;
19041792Swesolows do_serial = 1;
19051792Swesolows }
19061792Swesolows
19071792Swesolows ctx->i_oldargc = argc;
19081792Swesolows ctx->i_oldargv = argv;
19091792Swesolows
19101717Swesolows ret |= exec_ctx(ctx, do_serial);
19111717Swesolows
19121717Swesolows if (do_shadow) {
19131717Swesolows (void) memcpy(ctx_shadow, ctx, sizeof (cw_ictx_t));
19141717Swesolows ctx_shadow->i_flags |= CW_F_SHADOW;
19151717Swesolows ret |= exec_ctx(ctx_shadow, 1);
19160Sstevel@tonic-gate }
19170Sstevel@tonic-gate
19181717Swesolows if (!do_serial)
19191717Swesolows ret |= reap(ctx);
19200Sstevel@tonic-gate
19211717Swesolows return (ret);
19220Sstevel@tonic-gate }
1923