17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*24b9abbaSab196087 * Common Development and Distribution License (the "License"). 6*24b9abbaSab196087 * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 22*24b9abbaSab196087 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 277c478bd9Sstevel@tonic-gate 287c478bd9Sstevel@tonic-gate /* 297c478bd9Sstevel@tonic-gate * Wrapper for the GNU assembler to make it accept the Sun assembler 307c478bd9Sstevel@tonic-gate * arguments where possible. 317c478bd9Sstevel@tonic-gate * 327c478bd9Sstevel@tonic-gate * There are several limitations; the Sun assembler takes multiple 337c478bd9Sstevel@tonic-gate * source files, we only take one. 347c478bd9Sstevel@tonic-gate * 357c478bd9Sstevel@tonic-gate * -b, -s, -xF, -T plain not supported. 367c478bd9Sstevel@tonic-gate * -S isn't supported either, because while GNU as does generate 377c478bd9Sstevel@tonic-gate * listings with -a, there's no obvious mapping between sub-options. 387c478bd9Sstevel@tonic-gate * -K pic, -K PIC not supported either, though it's not clear what 397c478bd9Sstevel@tonic-gate * these actually do .. 407c478bd9Sstevel@tonic-gate * -Qy (not supported) adds a string to the .comment section 417c478bd9Sstevel@tonic-gate * describing the assembler version, while 427c478bd9Sstevel@tonic-gate * -Qn (supported) suppresses the string (also the default). 437c478bd9Sstevel@tonic-gate * 447c478bd9Sstevel@tonic-gate * We also add '-#' support to see invocation lines.. 457c478bd9Sstevel@tonic-gate * We also add '-xarch=amd64' in case we need to feed the assembler 467c478bd9Sstevel@tonic-gate * something different (or in case we need to invoke a different binary 477c478bd9Sstevel@tonic-gate * altogether!) 487c478bd9Sstevel@tonic-gate */ 497c478bd9Sstevel@tonic-gate 507c478bd9Sstevel@tonic-gate #include <sys/types.h> 517c478bd9Sstevel@tonic-gate #include <sys/wait.h> 527c478bd9Sstevel@tonic-gate #include <stdio.h> 537c478bd9Sstevel@tonic-gate #include <unistd.h> 547c478bd9Sstevel@tonic-gate #include <string.h> 557c478bd9Sstevel@tonic-gate #include <stdlib.h> 56*24b9abbaSab196087 #include <sys/param.h> 577c478bd9Sstevel@tonic-gate 587c478bd9Sstevel@tonic-gate static const char *progname; 597c478bd9Sstevel@tonic-gate static int verbose; 607c478bd9Sstevel@tonic-gate 617c478bd9Sstevel@tonic-gate struct aelist { 627c478bd9Sstevel@tonic-gate int ael_argc; 637c478bd9Sstevel@tonic-gate struct ae { 647c478bd9Sstevel@tonic-gate struct ae *ae_next; 657c478bd9Sstevel@tonic-gate char *ae_arg; 667c478bd9Sstevel@tonic-gate } *ael_head, *ael_tail; 677c478bd9Sstevel@tonic-gate }; 687c478bd9Sstevel@tonic-gate 697c478bd9Sstevel@tonic-gate static struct aelist * 707c478bd9Sstevel@tonic-gate newael(void) 717c478bd9Sstevel@tonic-gate { 727c478bd9Sstevel@tonic-gate return (calloc(sizeof (struct aelist), 1)); 737c478bd9Sstevel@tonic-gate } 747c478bd9Sstevel@tonic-gate 757c478bd9Sstevel@tonic-gate static void 767c478bd9Sstevel@tonic-gate newae(struct aelist *ael, const char *arg) 777c478bd9Sstevel@tonic-gate { 787c478bd9Sstevel@tonic-gate struct ae *ae; 797c478bd9Sstevel@tonic-gate 807c478bd9Sstevel@tonic-gate ae = calloc(sizeof (*ae), 1); 817c478bd9Sstevel@tonic-gate ae->ae_arg = strdup(arg); 827c478bd9Sstevel@tonic-gate if (ael->ael_tail == NULL) 837c478bd9Sstevel@tonic-gate ael->ael_head = ae; 847c478bd9Sstevel@tonic-gate else 857c478bd9Sstevel@tonic-gate ael->ael_tail->ae_next = ae; 867c478bd9Sstevel@tonic-gate ael->ael_tail = ae; 877c478bd9Sstevel@tonic-gate ael->ael_argc++; 887c478bd9Sstevel@tonic-gate } 897c478bd9Sstevel@tonic-gate 907c478bd9Sstevel@tonic-gate static void 917c478bd9Sstevel@tonic-gate fixae_arg(struct ae *ae, const char *newarg) 927c478bd9Sstevel@tonic-gate { 937c478bd9Sstevel@tonic-gate free(ae->ae_arg); 947c478bd9Sstevel@tonic-gate ae->ae_arg = strdup(newarg); 957c478bd9Sstevel@tonic-gate } 967c478bd9Sstevel@tonic-gate 977c478bd9Sstevel@tonic-gate static char ** 987c478bd9Sstevel@tonic-gate aeltoargv(struct aelist *ael) 997c478bd9Sstevel@tonic-gate { 1007c478bd9Sstevel@tonic-gate struct ae *ae; 1017c478bd9Sstevel@tonic-gate char **argv; 1027c478bd9Sstevel@tonic-gate int argc; 1037c478bd9Sstevel@tonic-gate 1047c478bd9Sstevel@tonic-gate argv = calloc(sizeof (*argv), ael->ael_argc + 1); 1057c478bd9Sstevel@tonic-gate 1067c478bd9Sstevel@tonic-gate for (argc = 0, ae = ael->ael_head; ae; ae = ae->ae_next, argc++) { 1077c478bd9Sstevel@tonic-gate argv[argc] = ae->ae_arg; 1087c478bd9Sstevel@tonic-gate if (ae == ael->ael_tail) 1097c478bd9Sstevel@tonic-gate break; 1107c478bd9Sstevel@tonic-gate } 1117c478bd9Sstevel@tonic-gate 1127c478bd9Sstevel@tonic-gate return (argv); 1137c478bd9Sstevel@tonic-gate } 1147c478bd9Sstevel@tonic-gate 1157c478bd9Sstevel@tonic-gate static int 1167c478bd9Sstevel@tonic-gate error(const char *arg) 1177c478bd9Sstevel@tonic-gate { 1187c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 1197c478bd9Sstevel@tonic-gate "%s: as->gas mapping failed at or near arg '%s'\n", progname, arg); 1207c478bd9Sstevel@tonic-gate return (2); 1217c478bd9Sstevel@tonic-gate } 1227c478bd9Sstevel@tonic-gate 1237c478bd9Sstevel@tonic-gate static int 1247c478bd9Sstevel@tonic-gate usage(const char *arg) 1257c478bd9Sstevel@tonic-gate { 1267c478bd9Sstevel@tonic-gate if (arg != NULL) 1277c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "error: %s\n", arg); 1287c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "Usage: %s [-V] [-#]\n" 1297c478bd9Sstevel@tonic-gate "\t[-xarch=architecture]\n" 1307c478bd9Sstevel@tonic-gate "\t[-o objfile] [-L]\n" 1317c478bd9Sstevel@tonic-gate "\t[-P [[-Ipath] [-Dname] [-Dname=def] [-Uname]]...]\n" 1327c478bd9Sstevel@tonic-gate "\t[-m] [-n] file.s ...\n", progname); 1337c478bd9Sstevel@tonic-gate return (3); 1347c478bd9Sstevel@tonic-gate } 1357c478bd9Sstevel@tonic-gate 1367c478bd9Sstevel@tonic-gate static void 1377c478bd9Sstevel@tonic-gate copyuntil(FILE *in, FILE *out, int termchar) 1387c478bd9Sstevel@tonic-gate { 1397c478bd9Sstevel@tonic-gate int c; 1407c478bd9Sstevel@tonic-gate 1417c478bd9Sstevel@tonic-gate while ((c = fgetc(in)) != EOF) { 1427c478bd9Sstevel@tonic-gate if (out && fputc(c, out) == EOF) 1437c478bd9Sstevel@tonic-gate exit(1); 1447c478bd9Sstevel@tonic-gate if (c == termchar) 1457c478bd9Sstevel@tonic-gate break; 1467c478bd9Sstevel@tonic-gate } 1477c478bd9Sstevel@tonic-gate } 1487c478bd9Sstevel@tonic-gate 1497c478bd9Sstevel@tonic-gate /* 150*24b9abbaSab196087 * Variant of copyuntil(), used for copying the path used 151*24b9abbaSab196087 * for .file directives. This version removes the workspace 152*24b9abbaSab196087 * from the head of the path, or failing that, attempts to remove 153*24b9abbaSab196087 * /usr/include. This is a workaround for the way gas handles 154*24b9abbaSab196087 * these directives. The objects produced by gas contain STT_FILE 155*24b9abbaSab196087 * symbols for every .file directive. These FILE symbols contain our 156*24b9abbaSab196087 * workspace paths, leading to wsdiff incorrectly flagging them as 157*24b9abbaSab196087 * having changed. By clipping off the workspace from these paths, 158*24b9abbaSab196087 * we eliminate these false positives. 159*24b9abbaSab196087 */ 160*24b9abbaSab196087 static void 161*24b9abbaSab196087 copyuntil_path(FILE *in, FILE *out, int termchar, 162*24b9abbaSab196087 const char *wspace, size_t wspace_len) 163*24b9abbaSab196087 { 164*24b9abbaSab196087 #define PROTO_INC "/proto/root_i386/usr/include/" 165*24b9abbaSab196087 #define SYS_INC "/usr/include/" 166*24b9abbaSab196087 167*24b9abbaSab196087 static const proto_inc_len = sizeof (PROTO_INC) - 1; 168*24b9abbaSab196087 static const sys_inc_len = sizeof (SYS_INC) - 1; 169*24b9abbaSab196087 170*24b9abbaSab196087 /* 171*24b9abbaSab196087 * Dynamically sized buffer for reading paths. Retained 172*24b9abbaSab196087 * and reused between calls. 173*24b9abbaSab196087 */ 174*24b9abbaSab196087 static char *buf = NULL; 175*24b9abbaSab196087 static char bufsize = 0; 176*24b9abbaSab196087 177*24b9abbaSab196087 int bufcnt = 0; 178*24b9abbaSab196087 char *bufptr; 179*24b9abbaSab196087 int c; 180*24b9abbaSab196087 181*24b9abbaSab196087 /* Read the path into the buffer */ 182*24b9abbaSab196087 while ((c = fgetc(in)) != EOF) { 183*24b9abbaSab196087 /* 184*24b9abbaSab196087 * If we need a buffer, or need a larger buffer, 185*24b9abbaSab196087 * fix that here. 186*24b9abbaSab196087 */ 187*24b9abbaSab196087 if (bufcnt >= bufsize) { 188*24b9abbaSab196087 bufsize = (bufsize == 0) ? MAXPATHLEN : (bufsize *= 2); 189*24b9abbaSab196087 buf = realloc(buf, bufsize + 1); /* + room for NULL */ 190*24b9abbaSab196087 if (buf == NULL) { 191*24b9abbaSab196087 perror("realloc"); 192*24b9abbaSab196087 exit(1); 193*24b9abbaSab196087 } 194*24b9abbaSab196087 } 195*24b9abbaSab196087 196*24b9abbaSab196087 buf[bufcnt++] = c; 197*24b9abbaSab196087 if (c == termchar) 198*24b9abbaSab196087 break; 199*24b9abbaSab196087 } 200*24b9abbaSab196087 if (bufcnt == 0) 201*24b9abbaSab196087 return; 202*24b9abbaSab196087 203*24b9abbaSab196087 /* 204*24b9abbaSab196087 * We have a non-empty buffer, and thus the opportunity 205*24b9abbaSab196087 * to do some surgery on it before passing it to the output. 206*24b9abbaSab196087 */ 207*24b9abbaSab196087 buf[bufcnt] = '\0'; 208*24b9abbaSab196087 bufptr = buf; 209*24b9abbaSab196087 210*24b9abbaSab196087 /* 211*24b9abbaSab196087 * If our workspace is at the start, remove it. 212*24b9abbaSab196087 * If not, then look for the system /usr/include instead. 213*24b9abbaSab196087 */ 214*24b9abbaSab196087 if ((wspace_len > 0) && (wspace_len < bufcnt) && 215*24b9abbaSab196087 (strncmp(bufptr, wspace, wspace_len) == 0)) { 216*24b9abbaSab196087 bufptr += wspace_len; 217*24b9abbaSab196087 bufcnt -= wspace_len; 218*24b9abbaSab196087 219*24b9abbaSab196087 /* 220*24b9abbaSab196087 * Further opportunity: Also clip the prefix 221*24b9abbaSab196087 * that leads to /usr/include in the proto. 222*24b9abbaSab196087 */ 223*24b9abbaSab196087 if ((proto_inc_len < bufcnt) && 224*24b9abbaSab196087 (strncmp(bufptr, PROTO_INC, proto_inc_len) == 0)) { 225*24b9abbaSab196087 bufptr += proto_inc_len; 226*24b9abbaSab196087 bufcnt -= proto_inc_len; 227*24b9abbaSab196087 } 228*24b9abbaSab196087 } else if ((sys_inc_len < bufcnt) && 229*24b9abbaSab196087 (strncmp(bufptr, SYS_INC, sys_inc_len) == 0)) { 230*24b9abbaSab196087 bufptr += sys_inc_len; 231*24b9abbaSab196087 bufcnt -= sys_inc_len; 232*24b9abbaSab196087 } 233*24b9abbaSab196087 234*24b9abbaSab196087 /* Output whatever is left */ 235*24b9abbaSab196087 if (out && (fwrite(bufptr, 1, bufcnt, out) != bufcnt)) { 236*24b9abbaSab196087 perror("fwrite"); 237*24b9abbaSab196087 exit(1); 238*24b9abbaSab196087 } 239*24b9abbaSab196087 240*24b9abbaSab196087 #undef PROTO_INC 241*24b9abbaSab196087 #undef SYS_INC 242*24b9abbaSab196087 } 243*24b9abbaSab196087 244*24b9abbaSab196087 /* 2457c478bd9Sstevel@tonic-gate * The idea here is to take directives like this emitted 2467c478bd9Sstevel@tonic-gate * by cpp: 2477c478bd9Sstevel@tonic-gate * 2487c478bd9Sstevel@tonic-gate * # num 2497c478bd9Sstevel@tonic-gate * 2507c478bd9Sstevel@tonic-gate * and convert them to directives like this that are 2517c478bd9Sstevel@tonic-gate * understood by the GNU assembler: 2527c478bd9Sstevel@tonic-gate * 2537c478bd9Sstevel@tonic-gate * .line num 2547c478bd9Sstevel@tonic-gate * 2557c478bd9Sstevel@tonic-gate * and similarly: 2567c478bd9Sstevel@tonic-gate * 2577c478bd9Sstevel@tonic-gate * # num "string" optional stuff 2587c478bd9Sstevel@tonic-gate * 2597c478bd9Sstevel@tonic-gate * is converted to 2607c478bd9Sstevel@tonic-gate * 2617c478bd9Sstevel@tonic-gate * .line num 2627c478bd9Sstevel@tonic-gate * .file "string" 2637c478bd9Sstevel@tonic-gate * 2647c478bd9Sstevel@tonic-gate * While this could be done with a sequence of sed 2657c478bd9Sstevel@tonic-gate * commands, this is simpler and faster.. 2667c478bd9Sstevel@tonic-gate */ 2677c478bd9Sstevel@tonic-gate static pid_t 2687c478bd9Sstevel@tonic-gate filter(int pipein, int pipeout) 2697c478bd9Sstevel@tonic-gate { 2707c478bd9Sstevel@tonic-gate pid_t pid; 2717c478bd9Sstevel@tonic-gate FILE *in, *out; 272*24b9abbaSab196087 char *wspace; 273*24b9abbaSab196087 size_t wspace_len; 2747c478bd9Sstevel@tonic-gate 2757c478bd9Sstevel@tonic-gate if (verbose) 2767c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "{#line filter} "); 2777c478bd9Sstevel@tonic-gate 2787c478bd9Sstevel@tonic-gate switch (pid = fork()) { 2797c478bd9Sstevel@tonic-gate case 0: 2807c478bd9Sstevel@tonic-gate if (dup2(pipein, 0) == -1 || 2817c478bd9Sstevel@tonic-gate dup2(pipeout, 1) == -1) { 2827c478bd9Sstevel@tonic-gate perror("dup2"); 2837c478bd9Sstevel@tonic-gate exit(1); 2847c478bd9Sstevel@tonic-gate } 2857c478bd9Sstevel@tonic-gate closefrom(3); 2867c478bd9Sstevel@tonic-gate break; 2877c478bd9Sstevel@tonic-gate case -1: 2887c478bd9Sstevel@tonic-gate perror("fork"); 2897c478bd9Sstevel@tonic-gate default: 2907c478bd9Sstevel@tonic-gate return (pid); 2917c478bd9Sstevel@tonic-gate } 2927c478bd9Sstevel@tonic-gate 2937c478bd9Sstevel@tonic-gate in = fdopen(0, "r"); 2947c478bd9Sstevel@tonic-gate out = fdopen(1, "w"); 2957c478bd9Sstevel@tonic-gate 296*24b9abbaSab196087 /* 297*24b9abbaSab196087 * Key off the CODEMGR_WS environment variable to detect 298*24b9abbaSab196087 * if we're in an activated workspace, and to get the 299*24b9abbaSab196087 * path to the workspace. 300*24b9abbaSab196087 */ 301*24b9abbaSab196087 wspace = getenv("CODEMGR_WS"); 302*24b9abbaSab196087 if (wspace != NULL) 303*24b9abbaSab196087 wspace_len = strlen(wspace); 304*24b9abbaSab196087 3057c478bd9Sstevel@tonic-gate while (!feof(in)) { 3067c478bd9Sstevel@tonic-gate int c, num; 3077c478bd9Sstevel@tonic-gate 3087c478bd9Sstevel@tonic-gate switch (c = fgetc(in)) { 3097c478bd9Sstevel@tonic-gate case '#': 3107c478bd9Sstevel@tonic-gate switch (fscanf(in, " %d", &num)) { 3117c478bd9Sstevel@tonic-gate case 0: 3127c478bd9Sstevel@tonic-gate /* 3137c478bd9Sstevel@tonic-gate * discard comment lines completely 3147c478bd9Sstevel@tonic-gate * discard ident strings completely too. 3157c478bd9Sstevel@tonic-gate * (GNU as politely ignores them..) 3167c478bd9Sstevel@tonic-gate */ 3177c478bd9Sstevel@tonic-gate copyuntil(in, NULL, '\n'); 3187c478bd9Sstevel@tonic-gate break; 3197c478bd9Sstevel@tonic-gate default: 3207c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "fscanf botch?"); 3217c478bd9Sstevel@tonic-gate /*FALLTHROUGH*/ 3227c478bd9Sstevel@tonic-gate case EOF: 3237c478bd9Sstevel@tonic-gate exit(1); 3247c478bd9Sstevel@tonic-gate /*NOTREACHED*/ 3257c478bd9Sstevel@tonic-gate case 1: 3267c478bd9Sstevel@tonic-gate /* 3277c478bd9Sstevel@tonic-gate * This line has a number at the beginning; 3287c478bd9Sstevel@tonic-gate * if it has a string after the number, then 3297c478bd9Sstevel@tonic-gate * it's a filename. 330*24b9abbaSab196087 * 331*24b9abbaSab196087 * If this is an activated workspace, use 332*24b9abbaSab196087 * copyuntil_path() to do path rewriting 333*24b9abbaSab196087 * that will prevent workspace paths from 334*24b9abbaSab196087 * being burned into the resulting object. 335*24b9abbaSab196087 * If not in an activated workspace, then 336*24b9abbaSab196087 * copy the existing path straight through 337*24b9abbaSab196087 * without interpretation. 3387c478bd9Sstevel@tonic-gate */ 3397c478bd9Sstevel@tonic-gate if (fgetc(in) == ' ' && fgetc(in) == '"') { 3407c478bd9Sstevel@tonic-gate (void) fprintf(out, "\t.file \""); 341*24b9abbaSab196087 if (wspace != NULL) 342*24b9abbaSab196087 copyuntil_path(in, out, '"', 343*24b9abbaSab196087 wspace, wspace_len); 344*24b9abbaSab196087 else 3457c478bd9Sstevel@tonic-gate copyuntil(in, out, '"'); 3467c478bd9Sstevel@tonic-gate (void) fputc('\n', out); 3477c478bd9Sstevel@tonic-gate } 3487c478bd9Sstevel@tonic-gate (void) fprintf(out, "\t.line %d\n", num - 1); 3497c478bd9Sstevel@tonic-gate /* 3507c478bd9Sstevel@tonic-gate * discard the rest of the line 3517c478bd9Sstevel@tonic-gate */ 3527c478bd9Sstevel@tonic-gate copyuntil(in, NULL, '\n'); 3537c478bd9Sstevel@tonic-gate break; 3547c478bd9Sstevel@tonic-gate } 3557c478bd9Sstevel@tonic-gate break; 3567c478bd9Sstevel@tonic-gate case '\n': 3577c478bd9Sstevel@tonic-gate /* 3587c478bd9Sstevel@tonic-gate * preserve newlines 3597c478bd9Sstevel@tonic-gate */ 3607c478bd9Sstevel@tonic-gate (void) fputc(c, out); 3617c478bd9Sstevel@tonic-gate break; 3627c478bd9Sstevel@tonic-gate case EOF: 3637c478bd9Sstevel@tonic-gate /* 3647c478bd9Sstevel@tonic-gate * don't write EOF! 3657c478bd9Sstevel@tonic-gate */ 3667c478bd9Sstevel@tonic-gate break; 3677c478bd9Sstevel@tonic-gate default: 3687c478bd9Sstevel@tonic-gate /* 3697c478bd9Sstevel@tonic-gate * lines that don't begin with '#' are copied 3707c478bd9Sstevel@tonic-gate */ 3717c478bd9Sstevel@tonic-gate (void) fputc(c, out); 3727c478bd9Sstevel@tonic-gate copyuntil(in, out, '\n'); 3737c478bd9Sstevel@tonic-gate break; 3747c478bd9Sstevel@tonic-gate } 3757c478bd9Sstevel@tonic-gate 3767c478bd9Sstevel@tonic-gate if (ferror(out)) 3777c478bd9Sstevel@tonic-gate exit(1); 3787c478bd9Sstevel@tonic-gate } 3797c478bd9Sstevel@tonic-gate 3807c478bd9Sstevel@tonic-gate exit(0); 3817c478bd9Sstevel@tonic-gate /*NOTREACHED*/ 3827c478bd9Sstevel@tonic-gate } 3837c478bd9Sstevel@tonic-gate 3847c478bd9Sstevel@tonic-gate static pid_t 3857c478bd9Sstevel@tonic-gate invoke(char **argv, int pipein, int pipeout) 3867c478bd9Sstevel@tonic-gate { 3877c478bd9Sstevel@tonic-gate pid_t pid; 3887c478bd9Sstevel@tonic-gate 3897c478bd9Sstevel@tonic-gate if (verbose) { 3907c478bd9Sstevel@tonic-gate char **dargv = argv; 3917c478bd9Sstevel@tonic-gate 3927c478bd9Sstevel@tonic-gate while (*dargv) 3937c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "%s ", *dargv++); 3947c478bd9Sstevel@tonic-gate } 3957c478bd9Sstevel@tonic-gate 3967c478bd9Sstevel@tonic-gate switch (pid = fork()) { 3977c478bd9Sstevel@tonic-gate case 0: 3987c478bd9Sstevel@tonic-gate if (pipein >= 0 && dup2(pipein, 0) == -1) { 3997c478bd9Sstevel@tonic-gate perror("dup2"); 4007c478bd9Sstevel@tonic-gate exit(1); 4017c478bd9Sstevel@tonic-gate } 4027c478bd9Sstevel@tonic-gate if (pipeout >= 0 && dup2(pipeout, 1) == -1) { 4037c478bd9Sstevel@tonic-gate perror("dup2"); 4047c478bd9Sstevel@tonic-gate exit(1); 4057c478bd9Sstevel@tonic-gate } 4067c478bd9Sstevel@tonic-gate closefrom(3); 4077c478bd9Sstevel@tonic-gate (void) execvp(argv[0], argv); 4087c478bd9Sstevel@tonic-gate perror("execvp"); 4097c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "%s: couldn't run %s\n", 4107c478bd9Sstevel@tonic-gate progname, argv[0]); 4117c478bd9Sstevel@tonic-gate break; 4127c478bd9Sstevel@tonic-gate case -1: 4137c478bd9Sstevel@tonic-gate perror("fork"); 4147c478bd9Sstevel@tonic-gate default: 4157c478bd9Sstevel@tonic-gate return (pid); 4167c478bd9Sstevel@tonic-gate } 4177c478bd9Sstevel@tonic-gate exit(2); 4187c478bd9Sstevel@tonic-gate /*NOTREACHED*/ 4197c478bd9Sstevel@tonic-gate } 4207c478bd9Sstevel@tonic-gate 4217c478bd9Sstevel@tonic-gate static int 4227c478bd9Sstevel@tonic-gate pipeline(char **ppargv, char **asargv) 4237c478bd9Sstevel@tonic-gate { 4247c478bd9Sstevel@tonic-gate int pipedes[4]; 4257c478bd9Sstevel@tonic-gate int active = 0; 4267c478bd9Sstevel@tonic-gate int rval = 0; 4277c478bd9Sstevel@tonic-gate pid_t pid_pp, pid_f, pid_as; 4287c478bd9Sstevel@tonic-gate 4297c478bd9Sstevel@tonic-gate if (pipe(pipedes) == -1 || pipe(pipedes + 2) == -1) { 4307c478bd9Sstevel@tonic-gate perror("pipe"); 4317c478bd9Sstevel@tonic-gate return (4); 4327c478bd9Sstevel@tonic-gate } 4337c478bd9Sstevel@tonic-gate 4347c478bd9Sstevel@tonic-gate if ((pid_pp = invoke(ppargv, -1, pipedes[0])) > 0) 4357c478bd9Sstevel@tonic-gate active++; 4367c478bd9Sstevel@tonic-gate 4377c478bd9Sstevel@tonic-gate if (verbose) 4387c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "| "); 4397c478bd9Sstevel@tonic-gate 4407c478bd9Sstevel@tonic-gate if ((pid_f = filter(pipedes[1], pipedes[2])) > 0) 4417c478bd9Sstevel@tonic-gate active++; 4427c478bd9Sstevel@tonic-gate 4437c478bd9Sstevel@tonic-gate if (verbose) 4447c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "| "); 4457c478bd9Sstevel@tonic-gate 4467c478bd9Sstevel@tonic-gate if ((pid_as = invoke(asargv, pipedes[3], -1)) > 0) 4477c478bd9Sstevel@tonic-gate active++; 4487c478bd9Sstevel@tonic-gate 4497c478bd9Sstevel@tonic-gate if (verbose) { 4507c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "\n"); 4517c478bd9Sstevel@tonic-gate (void) fflush(stderr); 4527c478bd9Sstevel@tonic-gate } 4537c478bd9Sstevel@tonic-gate 4547c478bd9Sstevel@tonic-gate closefrom(3); 4557c478bd9Sstevel@tonic-gate 4567c478bd9Sstevel@tonic-gate if (active != 3) 4577c478bd9Sstevel@tonic-gate return (5); 4587c478bd9Sstevel@tonic-gate 4597c478bd9Sstevel@tonic-gate while (active != 0) { 4607c478bd9Sstevel@tonic-gate pid_t pid; 4617c478bd9Sstevel@tonic-gate int stat; 4627c478bd9Sstevel@tonic-gate 4637c478bd9Sstevel@tonic-gate if ((pid = wait(&stat)) == -1) { 4647c478bd9Sstevel@tonic-gate rval++; 4657c478bd9Sstevel@tonic-gate break; 4667c478bd9Sstevel@tonic-gate } 4677c478bd9Sstevel@tonic-gate 4687c478bd9Sstevel@tonic-gate if (!WIFEXITED(stat)) 4697c478bd9Sstevel@tonic-gate continue; 4707c478bd9Sstevel@tonic-gate 4717c478bd9Sstevel@tonic-gate if (pid == pid_pp || pid == pid_f || pid == pid_as) { 4727c478bd9Sstevel@tonic-gate active--; 4737c478bd9Sstevel@tonic-gate if (WEXITSTATUS(stat) != 0) 4747c478bd9Sstevel@tonic-gate rval++; 4757c478bd9Sstevel@tonic-gate } 4767c478bd9Sstevel@tonic-gate } 4777c478bd9Sstevel@tonic-gate 4787c478bd9Sstevel@tonic-gate return (rval); 4797c478bd9Sstevel@tonic-gate } 4807c478bd9Sstevel@tonic-gate 4817c478bd9Sstevel@tonic-gate int 4827c478bd9Sstevel@tonic-gate main(int argc, char *argv[]) 4837c478bd9Sstevel@tonic-gate { 4847c478bd9Sstevel@tonic-gate struct aelist *cpp = NULL; 4857c478bd9Sstevel@tonic-gate struct aelist *m4 = NULL; 4867c478bd9Sstevel@tonic-gate struct aelist *as = newael(); 4877c478bd9Sstevel@tonic-gate char **asargv; 4887c478bd9Sstevel@tonic-gate char *outfile = NULL; 4897c478bd9Sstevel@tonic-gate char *srcfile = NULL; 4907c478bd9Sstevel@tonic-gate const char *as_dir, *as64_dir, *m4_dir, *m4_lib_dir, *cpp_dir; 4917c478bd9Sstevel@tonic-gate char *as_pgm, *as64_pgm, *m4_pgm, *m4_cmdefs, *cpp_pgm; 492*24b9abbaSab196087 size_t bufsize; 4937c478bd9Sstevel@tonic-gate int as64 = 0; 4947c478bd9Sstevel@tonic-gate int code; 4957c478bd9Sstevel@tonic-gate 4967c478bd9Sstevel@tonic-gate if ((progname = strrchr(argv[0], '/')) == NULL) 4977c478bd9Sstevel@tonic-gate progname = argv[0]; 4987c478bd9Sstevel@tonic-gate else 4997c478bd9Sstevel@tonic-gate progname++; 5007c478bd9Sstevel@tonic-gate 5017c478bd9Sstevel@tonic-gate /* 5027c478bd9Sstevel@tonic-gate * Helpful when debugging, or when changing tool versions.. 5037c478bd9Sstevel@tonic-gate */ 5047c478bd9Sstevel@tonic-gate if ((as_dir = getenv("AW_AS_DIR")) == NULL) 5057c478bd9Sstevel@tonic-gate as_dir = DEFAULT_AS_DIR; /* /usr/sfw/bin */ 506*24b9abbaSab196087 bufsize = strlen(as_dir) + strlen("/gas") + 1; 507*24b9abbaSab196087 as_pgm = malloc(bufsize); 508*24b9abbaSab196087 (void) snprintf(as_pgm, bufsize, "%s/gas", as_dir); 5097c478bd9Sstevel@tonic-gate 5107c478bd9Sstevel@tonic-gate if ((as64_dir = getenv("AW_AS64_DIR")) == NULL) 5117c478bd9Sstevel@tonic-gate as64_dir = DEFAULT_AS64_DIR; /* /usr/sfw/bin */ 512*24b9abbaSab196087 bufsize = strlen(as64_dir) + strlen("/gas") + 1; 513*24b9abbaSab196087 as64_pgm = malloc(bufsize); 514*24b9abbaSab196087 (void) snprintf(as64_pgm, bufsize, "%s/gas", as64_dir); 5157c478bd9Sstevel@tonic-gate 5167c478bd9Sstevel@tonic-gate if ((m4_dir = getenv("AW_M4_DIR")) == NULL) 5177c478bd9Sstevel@tonic-gate m4_dir = DEFAULT_M4_DIR; /* /usr/ccs/bin */ 518*24b9abbaSab196087 bufsize = strlen(m4_dir) + strlen("/m4") + 1; 519*24b9abbaSab196087 m4_pgm = malloc(bufsize); 520*24b9abbaSab196087 (void) snprintf(m4_pgm, bufsize, "%s/m4", m4_dir); 5217c478bd9Sstevel@tonic-gate 5227c478bd9Sstevel@tonic-gate if ((m4_lib_dir = getenv("AW_M4LIB_DIR")) == NULL) 5237c478bd9Sstevel@tonic-gate m4_lib_dir = DEFAULT_M4LIB_DIR; /* /usr/ccs/lib */ 524*24b9abbaSab196087 bufsize = strlen(m4_lib_dir) + strlen("/cmdefs") + 1; 525*24b9abbaSab196087 m4_cmdefs = malloc(bufsize); 526*24b9abbaSab196087 (void) snprintf(m4_cmdefs, bufsize, "%s/cmdefs", m4_lib_dir); 5277c478bd9Sstevel@tonic-gate 5287c478bd9Sstevel@tonic-gate if ((cpp_dir = getenv("AW_CPP_DIR")) == NULL) 5297c478bd9Sstevel@tonic-gate cpp_dir = DEFAULT_CPP_DIR; /* /usr/ccs/lib */ 530*24b9abbaSab196087 bufsize = strlen(cpp_dir) + strlen("/cpp") + 1; 531*24b9abbaSab196087 cpp_pgm = malloc(bufsize); 532*24b9abbaSab196087 (void) snprintf(cpp_pgm, bufsize, "%s/cpp", cpp_dir); 5337c478bd9Sstevel@tonic-gate 5347c478bd9Sstevel@tonic-gate newae(as, as_pgm); 5357c478bd9Sstevel@tonic-gate newae(as, "--warn"); 5367c478bd9Sstevel@tonic-gate newae(as, "--fatal-warnings"); 5377c478bd9Sstevel@tonic-gate newae(as, "--traditional-format"); 5387c478bd9Sstevel@tonic-gate 5397c478bd9Sstevel@tonic-gate /* 5407c478bd9Sstevel@tonic-gate * This is a support hack to rewrite code for the compiler 5417c478bd9Sstevel@tonic-gate * which should probably cause an assembler programmer to recode 5427c478bd9Sstevel@tonic-gate * - so, generate a warning in this case. 5437c478bd9Sstevel@tonic-gate */ 5447c478bd9Sstevel@tonic-gate newae(as, "-K"); 5457c478bd9Sstevel@tonic-gate 5467c478bd9Sstevel@tonic-gate /* 5477c478bd9Sstevel@tonic-gate * Walk the argument list, translating as we go .. 5487c478bd9Sstevel@tonic-gate */ 5497c478bd9Sstevel@tonic-gate while (--argc > 0) { 5507c478bd9Sstevel@tonic-gate char *arg; 5517c478bd9Sstevel@tonic-gate int arglen; 5527c478bd9Sstevel@tonic-gate 5537c478bd9Sstevel@tonic-gate arg = *++argv; 5547c478bd9Sstevel@tonic-gate arglen = strlen(arg); 5557c478bd9Sstevel@tonic-gate 5567c478bd9Sstevel@tonic-gate if (*arg != '-') { 5577c478bd9Sstevel@tonic-gate char *filename; 5587c478bd9Sstevel@tonic-gate 5597c478bd9Sstevel@tonic-gate /* 5607c478bd9Sstevel@tonic-gate * filenames ending in '.s' are taken to be 5617c478bd9Sstevel@tonic-gate * assembler files, and provide the default 5627c478bd9Sstevel@tonic-gate * basename of the output file. 5637c478bd9Sstevel@tonic-gate * 5647c478bd9Sstevel@tonic-gate * other files are passed through to the 5657c478bd9Sstevel@tonic-gate * preprocessor, if present, or to gas if not. 5667c478bd9Sstevel@tonic-gate */ 5677c478bd9Sstevel@tonic-gate filename = arg; 5687c478bd9Sstevel@tonic-gate if (arglen > 2 && 5697c478bd9Sstevel@tonic-gate strcmp(arg + arglen - 2, ".s") == 0) { 5707c478bd9Sstevel@tonic-gate /* 5717c478bd9Sstevel@tonic-gate * Though 'as' allows multiple assembler 5727c478bd9Sstevel@tonic-gate * files to be processed in one invocation 5737c478bd9Sstevel@tonic-gate * of the assembler, ON only processes one 5747c478bd9Sstevel@tonic-gate * file at a time, which makes things a lot 5757c478bd9Sstevel@tonic-gate * simpler! 5767c478bd9Sstevel@tonic-gate */ 5777c478bd9Sstevel@tonic-gate if (srcfile == NULL) 5787c478bd9Sstevel@tonic-gate srcfile = arg; 5797c478bd9Sstevel@tonic-gate else 5807c478bd9Sstevel@tonic-gate return (usage( 5817c478bd9Sstevel@tonic-gate "one assembler file at a time")); 5827c478bd9Sstevel@tonic-gate 5837c478bd9Sstevel@tonic-gate /* 5847c478bd9Sstevel@tonic-gate * If we haven't seen a -o option yet, 5857c478bd9Sstevel@tonic-gate * default the output to the basename 5867c478bd9Sstevel@tonic-gate * of the input, substituting a .o on the end 5877c478bd9Sstevel@tonic-gate */ 5887c478bd9Sstevel@tonic-gate if (outfile == NULL) { 5897c478bd9Sstevel@tonic-gate char *argcopy; 5907c478bd9Sstevel@tonic-gate 5917c478bd9Sstevel@tonic-gate argcopy = strdup(arg); 5927c478bd9Sstevel@tonic-gate argcopy[arglen - 1] = 'o'; 5937c478bd9Sstevel@tonic-gate 5947c478bd9Sstevel@tonic-gate if ((outfile = strrchr( 5957c478bd9Sstevel@tonic-gate argcopy, '/')) == NULL) 5967c478bd9Sstevel@tonic-gate outfile = argcopy; 5977c478bd9Sstevel@tonic-gate else 5987c478bd9Sstevel@tonic-gate outfile++; 5997c478bd9Sstevel@tonic-gate } 6007c478bd9Sstevel@tonic-gate } 6017c478bd9Sstevel@tonic-gate if (cpp) 6027c478bd9Sstevel@tonic-gate newae(cpp, filename); 6037c478bd9Sstevel@tonic-gate else if (m4) 6047c478bd9Sstevel@tonic-gate newae(m4, filename); 6057c478bd9Sstevel@tonic-gate else 6067c478bd9Sstevel@tonic-gate newae(as, filename); 6077c478bd9Sstevel@tonic-gate continue; 6087c478bd9Sstevel@tonic-gate } else 6097c478bd9Sstevel@tonic-gate arglen--; 6107c478bd9Sstevel@tonic-gate 6117c478bd9Sstevel@tonic-gate switch (arg[1]) { 6127c478bd9Sstevel@tonic-gate case 'K': 6137c478bd9Sstevel@tonic-gate /* 6147c478bd9Sstevel@tonic-gate * -K pic 6157c478bd9Sstevel@tonic-gate * -K PIC 6167c478bd9Sstevel@tonic-gate */ 6177c478bd9Sstevel@tonic-gate if (arglen == 1) { 6187c478bd9Sstevel@tonic-gate if ((arg = *++argv) == NULL || *arg == '\0') 6197c478bd9Sstevel@tonic-gate return (usage("malformed -K")); 6207c478bd9Sstevel@tonic-gate argc--; 6217c478bd9Sstevel@tonic-gate } else { 6227c478bd9Sstevel@tonic-gate arg += 2; 6237c478bd9Sstevel@tonic-gate } 6247c478bd9Sstevel@tonic-gate if (strcmp(arg, "PIC") != 0 && strcmp(arg, "pic") != 0) 6257c478bd9Sstevel@tonic-gate return (usage("malformed -K")); 6267c478bd9Sstevel@tonic-gate break; /* just ignore -Kpic for gcc */ 6277c478bd9Sstevel@tonic-gate case 'Q': 6287c478bd9Sstevel@tonic-gate if (strcmp(arg, "-Qn") == 0) 6297c478bd9Sstevel@tonic-gate break; 6307c478bd9Sstevel@tonic-gate /*FALLTHROUGH*/ 6317c478bd9Sstevel@tonic-gate case 'b': 6327c478bd9Sstevel@tonic-gate case 's': 6337c478bd9Sstevel@tonic-gate case 'T': 6347c478bd9Sstevel@tonic-gate /* 6357c478bd9Sstevel@tonic-gate * -b Extra symbol table for source browser .. 6367c478bd9Sstevel@tonic-gate * not relevant to gas, thus should error. 6377c478bd9Sstevel@tonic-gate * -s Put stabs in .stabs section not stabs.excl 6387c478bd9Sstevel@tonic-gate * not clear if there's an equivalent 6397c478bd9Sstevel@tonic-gate * -T 4.x migration option 6407c478bd9Sstevel@tonic-gate */ 6417c478bd9Sstevel@tonic-gate default: 6427c478bd9Sstevel@tonic-gate return (error(arg)); 6437c478bd9Sstevel@tonic-gate case 'x': 6447c478bd9Sstevel@tonic-gate /* 6457c478bd9Sstevel@tonic-gate * Accept -xarch special case to invoke alternate 6467c478bd9Sstevel@tonic-gate * assemblers or assembler flags for different 6477c478bd9Sstevel@tonic-gate * architectures. 6487c478bd9Sstevel@tonic-gate */ 6497c478bd9Sstevel@tonic-gate if (strcmp(arg, "-xarch=amd64") == 0 || 6507c478bd9Sstevel@tonic-gate strcmp(arg, "-xarch=generic64") == 0) { 6517c478bd9Sstevel@tonic-gate as64++; 6527c478bd9Sstevel@tonic-gate fixae_arg(as->ael_head, as64_pgm); 6537c478bd9Sstevel@tonic-gate break; 6547c478bd9Sstevel@tonic-gate } 6557c478bd9Sstevel@tonic-gate /* 6567c478bd9Sstevel@tonic-gate * XX64: Is this useful to gas? 6577c478bd9Sstevel@tonic-gate */ 6587c478bd9Sstevel@tonic-gate if (strcmp(arg, "-xmodel=kernel") == 0) 6597c478bd9Sstevel@tonic-gate break; 6607c478bd9Sstevel@tonic-gate 6617c478bd9Sstevel@tonic-gate /* 6627c478bd9Sstevel@tonic-gate * -xF Generates performance analysis data 6637c478bd9Sstevel@tonic-gate * no equivalent 6647c478bd9Sstevel@tonic-gate */ 6657c478bd9Sstevel@tonic-gate return (error(arg)); 6667c478bd9Sstevel@tonic-gate case 'V': 6677c478bd9Sstevel@tonic-gate newae(as, arg); 6687c478bd9Sstevel@tonic-gate break; 6697c478bd9Sstevel@tonic-gate case '#': 6707c478bd9Sstevel@tonic-gate verbose++; 6717c478bd9Sstevel@tonic-gate break; 6727c478bd9Sstevel@tonic-gate case 'L': 6737c478bd9Sstevel@tonic-gate newae(as, "--keep-locals"); 6747c478bd9Sstevel@tonic-gate break; 6757c478bd9Sstevel@tonic-gate case 'n': 6767c478bd9Sstevel@tonic-gate newae(as, "--no-warn"); 6777c478bd9Sstevel@tonic-gate break; 6787c478bd9Sstevel@tonic-gate case 'o': 6797c478bd9Sstevel@tonic-gate if (arglen != 1) 6807c478bd9Sstevel@tonic-gate return (usage("bad -o flag")); 6817c478bd9Sstevel@tonic-gate if ((arg = *++argv) == NULL || *arg == '\0') 6827c478bd9Sstevel@tonic-gate return (usage("bad -o flag")); 6837c478bd9Sstevel@tonic-gate outfile = arg; 6847c478bd9Sstevel@tonic-gate argc--; 6857c478bd9Sstevel@tonic-gate arglen = strlen(arg + 1); 6867c478bd9Sstevel@tonic-gate break; 6877c478bd9Sstevel@tonic-gate case 'm': 6887c478bd9Sstevel@tonic-gate if (cpp) 6897c478bd9Sstevel@tonic-gate return (usage("-m conflicts with -P")); 6907c478bd9Sstevel@tonic-gate if (m4 == NULL) { 6917c478bd9Sstevel@tonic-gate m4 = newael(); 6927c478bd9Sstevel@tonic-gate newae(m4, m4_pgm); 6937c478bd9Sstevel@tonic-gate newae(m4, m4_cmdefs); 6947c478bd9Sstevel@tonic-gate } 6957c478bd9Sstevel@tonic-gate break; 6967c478bd9Sstevel@tonic-gate case 'P': 6977c478bd9Sstevel@tonic-gate if (m4) 6987c478bd9Sstevel@tonic-gate return (usage("-P conflicts with -m")); 6997c478bd9Sstevel@tonic-gate if (cpp == NULL) { 7007c478bd9Sstevel@tonic-gate cpp = newael(); 7017c478bd9Sstevel@tonic-gate newae(cpp, cpp_pgm); 7027c478bd9Sstevel@tonic-gate newae(cpp, "-D__GNUC_AS__"); 7037c478bd9Sstevel@tonic-gate } 7047c478bd9Sstevel@tonic-gate break; 7057c478bd9Sstevel@tonic-gate case 'D': 7067c478bd9Sstevel@tonic-gate case 'U': 7077c478bd9Sstevel@tonic-gate if (cpp) 7087c478bd9Sstevel@tonic-gate newae(cpp, arg); 7097c478bd9Sstevel@tonic-gate else if (m4) 7107c478bd9Sstevel@tonic-gate newae(m4, arg); 7117c478bd9Sstevel@tonic-gate else 7127c478bd9Sstevel@tonic-gate newae(as, arg); 7137c478bd9Sstevel@tonic-gate break; 7147c478bd9Sstevel@tonic-gate case 'I': 7157c478bd9Sstevel@tonic-gate if (cpp) 7167c478bd9Sstevel@tonic-gate newae(cpp, arg); 7177c478bd9Sstevel@tonic-gate else 7187c478bd9Sstevel@tonic-gate newae(as, arg); 7197c478bd9Sstevel@tonic-gate break; 7207c478bd9Sstevel@tonic-gate case '-': /* a gas-specific option */ 7217c478bd9Sstevel@tonic-gate newae(as, arg); 7227c478bd9Sstevel@tonic-gate break; 7237c478bd9Sstevel@tonic-gate } 7247c478bd9Sstevel@tonic-gate } 7257c478bd9Sstevel@tonic-gate 7267c478bd9Sstevel@tonic-gate #if defined(__i386) 7277c478bd9Sstevel@tonic-gate if (as64) 7287c478bd9Sstevel@tonic-gate newae(as, "--64"); 7297c478bd9Sstevel@tonic-gate else 7307c478bd9Sstevel@tonic-gate newae(as, "--32"); 7317c478bd9Sstevel@tonic-gate #endif 7327c478bd9Sstevel@tonic-gate 7337c478bd9Sstevel@tonic-gate if (srcfile == NULL) 7347c478bd9Sstevel@tonic-gate return (usage("no source file(s) specified")); 7357c478bd9Sstevel@tonic-gate if (outfile == NULL) 7367c478bd9Sstevel@tonic-gate outfile = "a.out"; 7377c478bd9Sstevel@tonic-gate newae(as, "-o"); 7387c478bd9Sstevel@tonic-gate newae(as, outfile); 7397c478bd9Sstevel@tonic-gate 7407c478bd9Sstevel@tonic-gate asargv = aeltoargv(as); 7417c478bd9Sstevel@tonic-gate if (cpp) { 7427c478bd9Sstevel@tonic-gate #if defined(__sparc) 7437c478bd9Sstevel@tonic-gate newae(cpp, "-Dsparc"); 7447c478bd9Sstevel@tonic-gate newae(cpp, "-D__sparc"); 7457c478bd9Sstevel@tonic-gate if (as64) 7467c478bd9Sstevel@tonic-gate newae(cpp, "-D__sparcv9"); 7477c478bd9Sstevel@tonic-gate else 7487c478bd9Sstevel@tonic-gate newae(cpp, "-D__sparcv8"); 7497c478bd9Sstevel@tonic-gate #elif defined(__i386) || defined(__x86) 7507c478bd9Sstevel@tonic-gate if (as64) { 7517c478bd9Sstevel@tonic-gate newae(cpp, "-D__x86_64"); 7527c478bd9Sstevel@tonic-gate newae(cpp, "-D__amd64"); 7537c478bd9Sstevel@tonic-gate } else { 7547c478bd9Sstevel@tonic-gate newae(cpp, "-Di386"); 7557c478bd9Sstevel@tonic-gate newae(cpp, "-D__i386"); 7567c478bd9Sstevel@tonic-gate } 7577c478bd9Sstevel@tonic-gate #else 7587c478bd9Sstevel@tonic-gate #error "need isa-dependent defines" 7597c478bd9Sstevel@tonic-gate #endif 7607c478bd9Sstevel@tonic-gate code = pipeline(aeltoargv(cpp), asargv); 7617c478bd9Sstevel@tonic-gate } else if (m4) 7627c478bd9Sstevel@tonic-gate code = pipeline(aeltoargv(m4), asargv); 7637c478bd9Sstevel@tonic-gate else { 7647c478bd9Sstevel@tonic-gate /* 7657c478bd9Sstevel@tonic-gate * XXX should arrange to fork/exec so that we 7667c478bd9Sstevel@tonic-gate * can unlink the output file if errors are 7677c478bd9Sstevel@tonic-gate * detected.. 7687c478bd9Sstevel@tonic-gate */ 7697c478bd9Sstevel@tonic-gate (void) execvp(asargv[0], asargv); 7707c478bd9Sstevel@tonic-gate perror("execvp"); 7717c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "%s: couldn't run %s\n", 7727c478bd9Sstevel@tonic-gate progname, asargv[0]); 7737c478bd9Sstevel@tonic-gate code = 7; 7747c478bd9Sstevel@tonic-gate } 7757c478bd9Sstevel@tonic-gate if (code != 0) 7767c478bd9Sstevel@tonic-gate (void) unlink(outfile); 7777c478bd9Sstevel@tonic-gate return (code); 7787c478bd9Sstevel@tonic-gate } 779