9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22
23 /*
24 * Copyright 2018, Richard Lowe.
25 */
26 /*
27 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
28 * Use is subject to license terms.
29 */
30
31 /*
32 * Wrapper for the GNU C compiler to make it accept the Sun C compiler
33 * arguments where possible.
34 *
35 * Since the translation is inexact, this is something of a work-in-progress.
36 *
37 */
38
39 /* If you modify this file, you must increment CW_VERSION */
40 #define CW_VERSION "3.0"
41
42 /*
43 * -# Verbose mode
44 * -### Show compiler commands built by driver, no compilation
45 * -A<name[(tokens)]> Preprocessor predicate assertion
46 * -B<[static|dynamic]> Specify dynamic or static binding
47 * -C Prevent preprocessor from removing comments
48 * -c Compile only - produce .o files, suppress linking
274 #define CW_F_XLATE 0x10
275 #define CW_F_PROG 0x20
276
277 typedef enum cw_op {
278 CW_O_NONE = 0,
279 CW_O_PREPROCESS,
280 CW_O_COMPILE,
281 CW_O_LINK
282 } cw_op_t;
283
284 struct aelist {
285 struct ae {
286 struct ae *ae_next;
287 char *ae_arg;
288 } *ael_head, *ael_tail;
289 int ael_argc;
290 };
291
292 typedef enum {
293 GNU,
294 SUN
295 } compiler_style_t;
296
297 typedef struct {
298 char *c_name;
299 char *c_path;
300 compiler_style_t c_style;
301 } cw_compiler_t;
302
303 typedef struct cw_ictx {
304 struct cw_ictx *i_next;
305 cw_compiler_t *i_compiler;
306 struct aelist *i_ae;
307 uint32_t i_flags;
308 int i_oldargc;
309 char **i_oldargv;
310 pid_t i_pid;
311 char i_discard[MAXPATHLEN];
312 char *i_stderr;
313 } cw_ictx_t;
314
1254 (void) fprintf(stderr,
1255 "Incompatible -xarch= and/or -m32/-m64 options used.\n");
1256 exit(2);
1257 }
1258
1259 if ((op == CW_O_LINK || op == CW_O_PREPROCESS) &&
1260 (ctx->i_flags & CW_F_SHADOW))
1261 exit(0);
1262
1263 if (model != NULL)
1264 newae(ctx->i_ae, model);
1265 if (!nolibc)
1266 newae(ctx->i_ae, "-lc");
1267 if (!seen_o && (ctx->i_flags & CW_F_SHADOW)) {
1268 newae(ctx->i_ae, "-o");
1269 newae(ctx->i_ae, ctx->i_discard);
1270 }
1271 }
1272
1273 static void
1274 do_cc(cw_ictx_t *ctx)
1275 {
1276 int in_output = 0, seen_o = 0;
1277 cw_op_t op = CW_O_LINK;
1278 char *nameflag;
1279
1280 if (ctx->i_flags & CW_F_PROG) {
1281 newae(ctx->i_ae, "-V");
1282 return;
1283 }
1284
1285 if (asprintf(&nameflag, "-_%s=", ctx->i_compiler->c_name) == -1)
1286 nomem();
1287
1288 while (--ctx->i_oldargc > 0) {
1289 char *arg = *++ctx->i_oldargv;
1290
1291 if (strncmp(arg, "-_CC=", 5) == 0) {
1292 newae(ctx->i_ae, strchr(arg, '=') + 1);
1293 continue;
1359 prepctx(cw_ictx_t *ctx)
1360 {
1361 newae(ctx->i_ae, ctx->i_compiler->c_path);
1362
1363 if (ctx->i_flags & CW_F_PROG) {
1364 (void) printf("%s: %s\n", (ctx->i_flags & CW_F_SHADOW) ?
1365 "shadow" : "primary", ctx->i_compiler->c_path);
1366 (void) fflush(stdout);
1367 }
1368
1369 if (!(ctx->i_flags & CW_F_XLATE))
1370 return;
1371
1372 switch (ctx->i_compiler->c_style) {
1373 case SUN:
1374 do_cc(ctx);
1375 break;
1376 case GNU:
1377 do_gcc(ctx);
1378 break;
1379 }
1380 }
1381
1382 static int
1383 invoke(cw_ictx_t *ctx)
1384 {
1385 char **newargv;
1386 int ac;
1387 struct ae *a;
1388
1389 if ((newargv = calloc(sizeof (*newargv), ctx->i_ae->ael_argc + 1)) ==
1390 NULL)
1391 nomem();
1392
1393 if (ctx->i_flags & CW_F_ECHO)
1394 (void) fprintf(stderr, "+ ");
1395
1396 for (ac = 0, a = ctx->i_ae->ael_head; a; a = a->ae_next, ac++) {
1397 newargv[ac] = a->ae_arg;
1398 if (ctx->i_flags & CW_F_ECHO)
1543 static void
1544 parse_compiler(const char *spec, cw_compiler_t *compiler)
1545 {
1546 char *tspec, *token;
1547
1548 if ((tspec = strdup(spec)) == NULL)
1549 nomem();
1550
1551 if ((token = strsep(&tspec, ",")) == NULL)
1552 errx(1, "Compiler is missing a name: %s", spec);
1553 compiler->c_name = token;
1554
1555 if ((token = strsep(&tspec, ",")) == NULL)
1556 errx(1, "Compiler is missing a path: %s", spec);
1557 compiler->c_path = token;
1558
1559 if ((token = strsep(&tspec, ",")) == NULL)
1560 errx(1, "Compiler is missing a style: %s", spec);
1561
1562 if ((strcasecmp(token, "gnu") == 0) ||
1563 (strcasecmp(token, "gcc") == 0))
1564 compiler->c_style = GNU;
1565 else if ((strcasecmp(token, "sun") == 0) ||
1566 (strcasecmp(token, "cc") == 0))
1567 compiler->c_style = SUN;
1568 else
1569 errx(1, "unknown compiler style: %s", token);
1570
1571 if (tspec != NULL)
1572 errx(1, "Excess tokens in compiler: %s", spec);
1573 }
1574
1575 int
1576 main(int argc, char **argv)
1577 {
1578 int ch;
1579 cw_compiler_t primary = { NULL, NULL, 0 };
1580 cw_compiler_t shadows[10];
1581 int nshadows = 0;
1582 int ret = 0;
1583 boolean_t do_serial = B_FALSE;
1584 boolean_t do_exec = B_FALSE;
1585 boolean_t vflg = B_FALSE;
1586 boolean_t Cflg = B_FALSE;
1587 boolean_t cflg = B_FALSE;
1588 boolean_t nflg = B_FALSE;
1589
|
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22
23 /*
24 * Copyright 2018, Richard Lowe.
25 */
26 /*
27 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
28 * Use is subject to license terms.
29 *
30 * Copyright 2018 Joyent, Inc.
31 */
32
33 /*
34 * Wrapper for the GNU C compiler to make it accept the Sun C compiler
35 * arguments where possible.
36 *
37 * Since the translation is inexact, this is something of a work-in-progress.
38 *
39 */
40
41 /* If you modify this file, you must increment CW_VERSION */
42 #define CW_VERSION "3.0"
43
44 /*
45 * -# Verbose mode
46 * -### Show compiler commands built by driver, no compilation
47 * -A<name[(tokens)]> Preprocessor predicate assertion
48 * -B<[static|dynamic]> Specify dynamic or static binding
49 * -C Prevent preprocessor from removing comments
50 * -c Compile only - produce .o files, suppress linking
276 #define CW_F_XLATE 0x10
277 #define CW_F_PROG 0x20
278
279 typedef enum cw_op {
280 CW_O_NONE = 0,
281 CW_O_PREPROCESS,
282 CW_O_COMPILE,
283 CW_O_LINK
284 } cw_op_t;
285
286 struct aelist {
287 struct ae {
288 struct ae *ae_next;
289 char *ae_arg;
290 } *ael_head, *ael_tail;
291 int ael_argc;
292 };
293
294 typedef enum {
295 GNU,
296 SUN,
297 SMATCH
298 } compiler_style_t;
299
300 typedef struct {
301 char *c_name;
302 char *c_path;
303 compiler_style_t c_style;
304 } cw_compiler_t;
305
306 typedef struct cw_ictx {
307 struct cw_ictx *i_next;
308 cw_compiler_t *i_compiler;
309 struct aelist *i_ae;
310 uint32_t i_flags;
311 int i_oldargc;
312 char **i_oldargv;
313 pid_t i_pid;
314 char i_discard[MAXPATHLEN];
315 char *i_stderr;
316 } cw_ictx_t;
317
1257 (void) fprintf(stderr,
1258 "Incompatible -xarch= and/or -m32/-m64 options used.\n");
1259 exit(2);
1260 }
1261
1262 if ((op == CW_O_LINK || op == CW_O_PREPROCESS) &&
1263 (ctx->i_flags & CW_F_SHADOW))
1264 exit(0);
1265
1266 if (model != NULL)
1267 newae(ctx->i_ae, model);
1268 if (!nolibc)
1269 newae(ctx->i_ae, "-lc");
1270 if (!seen_o && (ctx->i_flags & CW_F_SHADOW)) {
1271 newae(ctx->i_ae, "-o");
1272 newae(ctx->i_ae, ctx->i_discard);
1273 }
1274 }
1275
1276 static void
1277 do_smatch(cw_ictx_t *ctx)
1278 {
1279 if (ctx->i_flags & CW_F_PROG) {
1280 newae(ctx->i_ae, "--version");
1281 return;
1282 }
1283
1284 /*
1285 * Some sources shouldn't run smatch at all.
1286 */
1287 for (int i = 0; i < ctx->i_oldargc; i++) {
1288 char *arg = ctx->i_oldargv[i];
1289
1290 if (strcmp(arg, "-_smatch=off") == 0) {
1291 ctx->i_flags &= ~ (CW_F_EXEC | CW_F_ECHO);
1292 return;
1293 }
1294 }
1295
1296 /*
1297 * smatch can handle gcc's options.
1298 */
1299 do_gcc(ctx);
1300 }
1301
1302 static void
1303 do_cc(cw_ictx_t *ctx)
1304 {
1305 int in_output = 0, seen_o = 0;
1306 cw_op_t op = CW_O_LINK;
1307 char *nameflag;
1308
1309 if (ctx->i_flags & CW_F_PROG) {
1310 newae(ctx->i_ae, "-V");
1311 return;
1312 }
1313
1314 if (asprintf(&nameflag, "-_%s=", ctx->i_compiler->c_name) == -1)
1315 nomem();
1316
1317 while (--ctx->i_oldargc > 0) {
1318 char *arg = *++ctx->i_oldargv;
1319
1320 if (strncmp(arg, "-_CC=", 5) == 0) {
1321 newae(ctx->i_ae, strchr(arg, '=') + 1);
1322 continue;
1388 prepctx(cw_ictx_t *ctx)
1389 {
1390 newae(ctx->i_ae, ctx->i_compiler->c_path);
1391
1392 if (ctx->i_flags & CW_F_PROG) {
1393 (void) printf("%s: %s\n", (ctx->i_flags & CW_F_SHADOW) ?
1394 "shadow" : "primary", ctx->i_compiler->c_path);
1395 (void) fflush(stdout);
1396 }
1397
1398 if (!(ctx->i_flags & CW_F_XLATE))
1399 return;
1400
1401 switch (ctx->i_compiler->c_style) {
1402 case SUN:
1403 do_cc(ctx);
1404 break;
1405 case GNU:
1406 do_gcc(ctx);
1407 break;
1408 case SMATCH:
1409 do_smatch(ctx);
1410 break;
1411 }
1412 }
1413
1414 static int
1415 invoke(cw_ictx_t *ctx)
1416 {
1417 char **newargv;
1418 int ac;
1419 struct ae *a;
1420
1421 if ((newargv = calloc(sizeof (*newargv), ctx->i_ae->ael_argc + 1)) ==
1422 NULL)
1423 nomem();
1424
1425 if (ctx->i_flags & CW_F_ECHO)
1426 (void) fprintf(stderr, "+ ");
1427
1428 for (ac = 0, a = ctx->i_ae->ael_head; a; a = a->ae_next, ac++) {
1429 newargv[ac] = a->ae_arg;
1430 if (ctx->i_flags & CW_F_ECHO)
1575 static void
1576 parse_compiler(const char *spec, cw_compiler_t *compiler)
1577 {
1578 char *tspec, *token;
1579
1580 if ((tspec = strdup(spec)) == NULL)
1581 nomem();
1582
1583 if ((token = strsep(&tspec, ",")) == NULL)
1584 errx(1, "Compiler is missing a name: %s", spec);
1585 compiler->c_name = token;
1586
1587 if ((token = strsep(&tspec, ",")) == NULL)
1588 errx(1, "Compiler is missing a path: %s", spec);
1589 compiler->c_path = token;
1590
1591 if ((token = strsep(&tspec, ",")) == NULL)
1592 errx(1, "Compiler is missing a style: %s", spec);
1593
1594 if ((strcasecmp(token, "gnu") == 0) ||
1595 (strcasecmp(token, "gcc") == 0)) {
1596 compiler->c_style = GNU;
1597 } else if ((strcasecmp(token, "sun") == 0) ||
1598 (strcasecmp(token, "cc") == 0)) {
1599 compiler->c_style = SUN;
1600 } else if ((strcasecmp(token, "smatch") == 0)) {
1601 compiler->c_style = SMATCH;
1602 } else {
1603 errx(1, "unknown compiler style: %s", token);
1604 }
1605
1606 if (tspec != NULL)
1607 errx(1, "Excess tokens in compiler: %s", spec);
1608 }
1609
1610 int
1611 main(int argc, char **argv)
1612 {
1613 int ch;
1614 cw_compiler_t primary = { NULL, NULL, 0 };
1615 cw_compiler_t shadows[10];
1616 int nshadows = 0;
1617 int ret = 0;
1618 boolean_t do_serial = B_FALSE;
1619 boolean_t do_exec = B_FALSE;
1620 boolean_t vflg = B_FALSE;
1621 boolean_t Cflg = B_FALSE;
1622 boolean_t cflg = B_FALSE;
1623 boolean_t nflg = B_FALSE;
1624
|