authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-09-24 16:44:45-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-09-25 10:50:41-07:00
log513389bc5bd709ee5cccdf93e2881a62aca6eced
tree64c383c5e6bb6d2fff187eca8ba2e5de4f2536db
parentac4d79e3227cf7bc5ec88e1dce6f879b1208bd8e

CLI: exploit std.mem.chompPrefix

fixes a bug in how -fstructured-cfg and -fno-structured-cfg are handled.

1 files changed, 101 insertions(+), 120 deletions(-)

src/main.zig+101-120
...@@ -1037,10 +1037,9 @@ fn buildOutputType(...@@ -1037,10 +1037,9 @@ fn buildOutputType(
10371037
1038 var file_ext: ?Compilation.FileExt = null;1038 var file_ext: ?Compilation.FileExt = null;
1039 args_loop: while (args_iter.next()) |arg| {1039 args_loop: while (args_iter.next()) |arg| {
1040 if (mem.startsWith(u8, arg, "@")) {1040 if (mem.chompPrefix(u8, arg, "@")) |resp_file_path| {
1041 // This is a "compiler response file". We must parse the file and treat its1041 // This is a "compiler response file". We must parse the file and treat its
1042 // contents as command line parameters.1042 // contents as command line parameters.
1043 const resp_file_path = arg[1..];
1044 args_iter.resp_file = initArgIteratorResponseFile(arena, resp_file_path) catch |err| {1043 args_iter.resp_file = initArgIteratorResponseFile(arena, resp_file_path) catch |err| {
1045 fatal("unable to read response file '{s}': {s}", .{ resp_file_path, @errorName(err) });1044 fatal("unable to read response file '{s}': {s}", .{ resp_file_path, @errorName(err) });
1046 };1045 };
...@@ -1077,8 +1076,8 @@ fn buildOutputType(...@@ -1077,8 +1076,8 @@ fn buildOutputType(
1077 .key = key,1076 .key = key,
1078 .value = value,1077 .value = value,
1079 });1078 });
1080 } else if (mem.startsWith(u8, arg, "-M")) {1079 } else if (mem.chompPrefix(u8, arg, "-M")) |rest| {
1081 var it = mem.splitScalar(u8, arg["-M".len..], '=');1080 var it = mem.splitScalar(u8, rest, '=');
1082 const mod_name = it.first();1081 const mod_name = it.first();
1083 const root_src_orig = if (it.peek() != null) it.rest() else null;1082 const root_src_orig = if (it.peek() != null) it.rest() else null;
1084 try handleModArg(1083 try handleModArg(
...@@ -1111,8 +1110,8 @@ fn buildOutputType(...@@ -1111,8 +1110,8 @@ fn buildOutputType(
1111 }1110 }
1112 } else if (mem.eql(u8, arg, "-rcincludes")) {1111 } else if (mem.eql(u8, arg, "-rcincludes")) {
1113 rc_includes = parseRcIncludes(args_iter.nextOrFatal());1112 rc_includes = parseRcIncludes(args_iter.nextOrFatal());
1114 } else if (mem.startsWith(u8, arg, "-rcincludes=")) {1113 } else if (mem.chompPrefix(u8, arg, "-rcincludes=")) |rest| {
1115 rc_includes = parseRcIncludes(arg["-rcincludes=".len..]);1114 rc_includes = parseRcIncludes(rest);
1116 } else if (mem.eql(u8, arg, "-rcflags")) {1115 } else if (mem.eql(u8, arg, "-rcflags")) {
1117 extra_rcflags.shrinkRetainingCapacity(0);1116 extra_rcflags.shrinkRetainingCapacity(0);
1118 while (true) {1117 while (true) {
...@@ -1122,9 +1121,9 @@ fn buildOutputType(...@@ -1122,9 +1121,9 @@ fn buildOutputType(
1122 if (mem.eql(u8, next_arg, "--")) break;1121 if (mem.eql(u8, next_arg, "--")) break;
1123 try extra_rcflags.append(arena, next_arg);1122 try extra_rcflags.append(arena, next_arg);
1124 }1123 }
1125 } else if (mem.startsWith(u8, arg, "-fstructured-cfg")) {1124 } else if (mem.eql(u8, arg, "-fstructured-cfg")) {
1126 mod_opts.structured_cfg = true;1125 mod_opts.structured_cfg = true;
1127 } else if (mem.startsWith(u8, arg, "-fno-structured-cfg")) {1126 } else if (mem.eql(u8, arg, "-fno-structured-cfg")) {
1128 mod_opts.structured_cfg = false;1127 mod_opts.structured_cfg = false;
1129 } else if (mem.eql(u8, arg, "--color")) {1128 } else if (mem.eql(u8, arg, "--color")) {
1130 const next_arg = args_iter.next() orelse {1129 const next_arg = args_iter.next() orelse {
...@@ -1133,8 +1132,7 @@ fn buildOutputType(...@@ -1133,8 +1132,7 @@ fn buildOutputType(
1133 color = std.meta.stringToEnum(Color, next_arg) orelse {1132 color = std.meta.stringToEnum(Color, next_arg) orelse {
1134 fatal("expected [auto|on|off] after --color, found '{s}'", .{next_arg});1133 fatal("expected [auto|on|off] after --color, found '{s}'", .{next_arg});
1135 };1134 };
1136 } else if (mem.startsWith(u8, arg, "-j")) {1135 } else if (mem.chompPrefix(u8, arg, "-j")) |str| {
1137 const str = arg["-j".len..];
1138 const num = std.fmt.parseUnsigned(u32, str, 10) catch |err| {1136 const num = std.fmt.parseUnsigned(u32, str, 10) catch |err| {
1139 fatal("unable to parse jobs count '{s}': {s}", .{1137 fatal("unable to parse jobs count '{s}': {s}", .{
1140 str, @errorName(err),1138 str, @errorName(err),
...@@ -1148,8 +1146,8 @@ fn buildOutputType(...@@ -1148,8 +1146,8 @@ fn buildOutputType(
1148 subsystem = try parseSubSystem(args_iter.nextOrFatal());1146 subsystem = try parseSubSystem(args_iter.nextOrFatal());
1149 } else if (mem.eql(u8, arg, "-O")) {1147 } else if (mem.eql(u8, arg, "-O")) {
1150 mod_opts.optimize_mode = parseOptimizeMode(args_iter.nextOrFatal());1148 mod_opts.optimize_mode = parseOptimizeMode(args_iter.nextOrFatal());
1151 } else if (mem.startsWith(u8, arg, "-fentry=")) {1149 } else if (mem.chompPrefix(u8, arg, "-fentry=")) |rest| {
1152 entry = .{ .named = arg["-fentry=".len..] };1150 entry = .{ .named = rest };
1153 } else if (mem.eql(u8, arg, "--force_undefined")) {1151 } else if (mem.eql(u8, arg, "--force_undefined")) {
1154 try force_undefined_symbols.put(arena, args_iter.nextOrFatal(), {});1152 try force_undefined_symbols.put(arena, args_iter.nextOrFatal(), {});
1155 } else if (mem.eql(u8, arg, "--discard-all")) {1153 } else if (mem.eql(u8, arg, "--discard-all")) {
...@@ -1176,8 +1174,7 @@ fn buildOutputType(...@@ -1176,8 +1174,7 @@ fn buildOutputType(
1176 try create_module.frameworks.put(arena, args_iter.nextOrFatal(), .{ .needed = true });1174 try create_module.frameworks.put(arena, args_iter.nextOrFatal(), .{ .needed = true });
1177 } else if (mem.eql(u8, arg, "-install_name")) {1175 } else if (mem.eql(u8, arg, "-install_name")) {
1178 install_name = args_iter.nextOrFatal();1176 install_name = args_iter.nextOrFatal();
1179 } else if (mem.startsWith(u8, arg, "--compress-debug-sections=")) {1177 } else if (mem.chompPrefix(u8, arg, "--compress-debug-sections=")) |param| {
1180 const param = arg["--compress-debug-sections=".len..];
1181 linker_compress_debug_sections = std.meta.stringToEnum(link.File.Lld.Elf.CompressDebugSections, param) orelse {1178 linker_compress_debug_sections = std.meta.stringToEnum(link.File.Lld.Elf.CompressDebugSections, param) orelse {
1182 fatal("expected --compress-debug-sections=[none|zlib|zstd], found '{s}'", .{param});1179 fatal("expected --compress-debug-sections=[none|zlib|zstd], found '{s}'", .{param});
1183 };1180 };
...@@ -1275,8 +1272,8 @@ fn buildOutputType(...@@ -1275,8 +1272,8 @@ fn buildOutputType(
1275 try cc_argv.appendSlice(arena, &.{ arg, args_iter.nextOrFatal() });1272 try cc_argv.appendSlice(arena, &.{ arg, args_iter.nextOrFatal() });
1276 } else if (mem.eql(u8, arg, "-I")) {1273 } else if (mem.eql(u8, arg, "-I")) {
1277 try cssan.addIncludePath(arena, &cc_argv, .I, arg, args_iter.nextOrFatal(), false);1274 try cssan.addIncludePath(arena, &cc_argv, .I, arg, args_iter.nextOrFatal(), false);
1278 } else if (mem.startsWith(u8, arg, "--embed-dir=")) {1275 } else if (mem.chompPrefix(u8, arg, "--embed-dir=")) |rest| {
1279 try cssan.addIncludePath(arena, &cc_argv, .embed_dir, arg, arg["--embed-dir=".len..], true);1276 try cssan.addIncludePath(arena, &cc_argv, .embed_dir, arg, rest, true);
1280 } else if (mem.eql(u8, arg, "-isystem")) {1277 } else if (mem.eql(u8, arg, "-isystem")) {
1281 try cssan.addIncludePath(arena, &cc_argv, .isystem, arg, args_iter.nextOrFatal(), false);1278 try cssan.addIncludePath(arena, &cc_argv, .isystem, arg, args_iter.nextOrFatal(), false);
1282 } else if (mem.eql(u8, arg, "-iwithsysroot")) {1279 } else if (mem.eql(u8, arg, "-iwithsysroot")) {
...@@ -1303,14 +1300,14 @@ fn buildOutputType(...@@ -1303,14 +1300,14 @@ fn buildOutputType(
1303 target_mcpu = args_iter.nextOrFatal();1300 target_mcpu = args_iter.nextOrFatal();
1304 } else if (mem.eql(u8, arg, "-mcmodel")) {1301 } else if (mem.eql(u8, arg, "-mcmodel")) {
1305 mod_opts.code_model = parseCodeModel(args_iter.nextOrFatal());1302 mod_opts.code_model = parseCodeModel(args_iter.nextOrFatal());
1306 } else if (mem.startsWith(u8, arg, "-mcmodel=")) {1303 } else if (mem.chompPrefix(u8, arg, "-mcmodel=")) |rest| {
1307 mod_opts.code_model = parseCodeModel(arg["-mcmodel=".len..]);1304 mod_opts.code_model = parseCodeModel(rest);
1308 } else if (mem.startsWith(u8, arg, "-ofmt=")) {1305 } else if (mem.chompPrefix(u8, arg, "-ofmt=")) |rest| {
1309 create_module.object_format = arg["-ofmt=".len..];1306 create_module.object_format = rest;
1310 } else if (mem.startsWith(u8, arg, "-mcpu=")) {1307 } else if (mem.chompPrefix(u8, arg, "-mcpu=")) |rest| {
1311 target_mcpu = arg["-mcpu=".len..];1308 target_mcpu = rest;
1312 } else if (mem.startsWith(u8, arg, "-O")) {1309 } else if (mem.chompPrefix(u8, arg, "-O")) |rest| {
1313 mod_opts.optimize_mode = parseOptimizeMode(arg["-O".len..]);1310 mod_opts.optimize_mode = parseOptimizeMode(rest);
1314 } else if (mem.eql(u8, arg, "--dynamic-linker")) {1311 } else if (mem.eql(u8, arg, "--dynamic-linker")) {
1315 create_module.dynamic_linker = args_iter.nextOrFatal();1312 create_module.dynamic_linker = args_iter.nextOrFatal();
1316 } else if (mem.eql(u8, arg, "--sysroot")) {1313 } else if (mem.eql(u8, arg, "--sysroot")) {
...@@ -1408,8 +1405,7 @@ fn buildOutputType(...@@ -1408,8 +1405,7 @@ fn buildOutputType(
1408 create_module.opts.pie = false;1405 create_module.opts.pie = false;
1409 } else if (mem.eql(u8, arg, "-flto")) {1406 } else if (mem.eql(u8, arg, "-flto")) {
1410 create_module.opts.lto = .full;1407 create_module.opts.lto = .full;
1411 } else if (mem.startsWith(u8, arg, "-flto=")) {1408 } else if (mem.chompPrefix(u8, arg, "-flto=")) |mode| {
1412 const mode = arg["-flto=".len..];
1413 if (mem.eql(u8, mode, "full")) {1409 if (mem.eql(u8, mode, "full")) {
1414 create_module.opts.lto = .full;1410 create_module.opts.lto = .full;
1415 } else if (mem.eql(u8, mode, "thin")) {1411 } else if (mem.eql(u8, mode, "thin")) {
...@@ -1443,8 +1439,7 @@ fn buildOutputType(...@@ -1443,8 +1439,7 @@ fn buildOutputType(
1443 mod_opts.omit_frame_pointer = false;1439 mod_opts.omit_frame_pointer = false;
1444 } else if (mem.eql(u8, arg, "-fsanitize-c")) {1440 } else if (mem.eql(u8, arg, "-fsanitize-c")) {
1445 mod_opts.sanitize_c = .full;1441 mod_opts.sanitize_c = .full;
1446 } else if (mem.startsWith(u8, arg, "-fsanitize-c=")) {1442 } else if (mem.chompPrefix(u8, arg, "-fsanitize-c=")) |mode| {
1447 const mode = arg["-fsanitize-c=".len..];
1448 if (mem.eql(u8, mode, "trap")) {1443 if (mem.eql(u8, mode, "trap")) {
1449 mod_opts.sanitize_c = .trap;1444 mod_opts.sanitize_c = .trap;
1450 } else if (mem.eql(u8, mode, "full")) {1445 } else if (mem.eql(u8, mode, "full")) {
...@@ -1492,8 +1487,7 @@ fn buildOutputType(...@@ -1492,8 +1487,7 @@ fn buildOutputType(
1492 create_module.opts.san_cov_trace_pc_guard = false;1487 create_module.opts.san_cov_trace_pc_guard = false;
1493 } else if (mem.eql(u8, arg, "-freference-trace")) {1488 } else if (mem.eql(u8, arg, "-freference-trace")) {
1494 reference_trace = 256;1489 reference_trace = 256;
1495 } else if (mem.startsWith(u8, arg, "-freference-trace=")) {1490 } else if (mem.chompPrefix(u8, arg, "-freference-trace=")) |num| {
1496 const num = arg["-freference-trace=".len..];
1497 reference_trace = std.fmt.parseUnsigned(u32, num, 10) catch |err| {1491 reference_trace = std.fmt.parseUnsigned(u32, num, 10) catch |err| {
1498 fatal("unable to parse reference_trace count '{s}': {s}", .{ num, @errorName(err) });1492 fatal("unable to parse reference_trace count '{s}': {s}", .{ num, @errorName(err) });
1499 };1493 };
...@@ -1507,51 +1501,51 @@ fn buildOutputType(...@@ -1507,51 +1501,51 @@ fn buildOutputType(
1507 create_module.opts.rdynamic = true;1501 create_module.opts.rdynamic = true;
1508 } else if (mem.eql(u8, arg, "-fsoname")) {1502 } else if (mem.eql(u8, arg, "-fsoname")) {
1509 soname = .yes_default_value;1503 soname = .yes_default_value;
1510 } else if (mem.startsWith(u8, arg, "-fsoname=")) {1504 } else if (mem.chompPrefix(u8, arg, "-fsoname=")) |rest| {
1511 soname = .{ .yes = arg["-fsoname=".len..] };1505 soname = .{ .yes = rest };
1512 } else if (mem.eql(u8, arg, "-fno-soname")) {1506 } else if (mem.eql(u8, arg, "-fno-soname")) {
1513 soname = .no;1507 soname = .no;
1514 } else if (mem.eql(u8, arg, "-femit-bin")) {1508 } else if (mem.eql(u8, arg, "-femit-bin")) {
1515 emit_bin = .yes_default_path;1509 emit_bin = .yes_default_path;
1516 } else if (mem.startsWith(u8, arg, "-femit-bin=")) {1510 } else if (mem.chompPrefix(u8, arg, "-femit-bin=")) |rest| {
1517 emit_bin = .{ .yes = arg["-femit-bin=".len..] };1511 emit_bin = .{ .yes = rest };
1518 } else if (mem.eql(u8, arg, "-fno-emit-bin")) {1512 } else if (mem.eql(u8, arg, "-fno-emit-bin")) {
1519 emit_bin = .no;1513 emit_bin = .no;
1520 } else if (mem.eql(u8, arg, "-femit-h")) {1514 } else if (mem.eql(u8, arg, "-femit-h")) {
1521 emit_h = .yes_default_path;1515 emit_h = .yes_default_path;
1522 } else if (mem.startsWith(u8, arg, "-femit-h=")) {1516 } else if (mem.chompPrefix(u8, arg, "-femit-h=")) |rest| {
1523 emit_h = .{ .yes = arg["-femit-h=".len..] };1517 emit_h = .{ .yes = rest };
1524 } else if (mem.eql(u8, arg, "-fno-emit-h")) {1518 } else if (mem.eql(u8, arg, "-fno-emit-h")) {
1525 emit_h = .no;1519 emit_h = .no;
1526 } else if (mem.eql(u8, arg, "-femit-asm")) {1520 } else if (mem.eql(u8, arg, "-femit-asm")) {
1527 emit_asm = .yes_default_path;1521 emit_asm = .yes_default_path;
1528 } else if (mem.startsWith(u8, arg, "-femit-asm=")) {1522 } else if (mem.chompPrefix(u8, arg, "-femit-asm=")) |rest| {
1529 emit_asm = .{ .yes = arg["-femit-asm=".len..] };1523 emit_asm = .{ .yes = rest };
1530 } else if (mem.eql(u8, arg, "-fno-emit-asm")) {1524 } else if (mem.eql(u8, arg, "-fno-emit-asm")) {
1531 emit_asm = .no;1525 emit_asm = .no;
1532 } else if (mem.eql(u8, arg, "-femit-llvm-ir")) {1526 } else if (mem.eql(u8, arg, "-femit-llvm-ir")) {
1533 emit_llvm_ir = .yes_default_path;1527 emit_llvm_ir = .yes_default_path;
1534 } else if (mem.startsWith(u8, arg, "-femit-llvm-ir=")) {1528 } else if (mem.chompPrefix(u8, arg, "-femit-llvm-ir=")) |rest| {
1535 emit_llvm_ir = .{ .yes = arg["-femit-llvm-ir=".len..] };1529 emit_llvm_ir = .{ .yes = rest };
1536 } else if (mem.eql(u8, arg, "-fno-emit-llvm-ir")) {1530 } else if (mem.eql(u8, arg, "-fno-emit-llvm-ir")) {
1537 emit_llvm_ir = .no;1531 emit_llvm_ir = .no;
1538 } else if (mem.eql(u8, arg, "-femit-llvm-bc")) {1532 } else if (mem.eql(u8, arg, "-femit-llvm-bc")) {
1539 emit_llvm_bc = .yes_default_path;1533 emit_llvm_bc = .yes_default_path;
1540 } else if (mem.startsWith(u8, arg, "-femit-llvm-bc=")) {1534 } else if (mem.chompPrefix(u8, arg, "-femit-llvm-bc=")) |rest| {
1541 emit_llvm_bc = .{ .yes = arg["-femit-llvm-bc=".len..] };1535 emit_llvm_bc = .{ .yes = rest };
1542 } else if (mem.eql(u8, arg, "-fno-emit-llvm-bc")) {1536 } else if (mem.eql(u8, arg, "-fno-emit-llvm-bc")) {
1543 emit_llvm_bc = .no;1537 emit_llvm_bc = .no;
1544 } else if (mem.eql(u8, arg, "-femit-docs")) {1538 } else if (mem.eql(u8, arg, "-femit-docs")) {
1545 emit_docs = .yes_default_path;1539 emit_docs = .yes_default_path;
1546 } else if (mem.startsWith(u8, arg, "-femit-docs=")) {1540 } else if (mem.chompPrefix(u8, arg, "-femit-docs=")) |rest| {
1547 emit_docs = .{ .yes = arg["-femit-docs=".len..] };1541 emit_docs = .{ .yes = rest };
1548 } else if (mem.eql(u8, arg, "-fno-emit-docs")) {1542 } else if (mem.eql(u8, arg, "-fno-emit-docs")) {
1549 emit_docs = .no;1543 emit_docs = .no;
1550 } else if (mem.eql(u8, arg, "-femit-implib")) {1544 } else if (mem.eql(u8, arg, "-femit-implib")) {
1551 emit_implib = .yes_default_path;1545 emit_implib = .yes_default_path;
1552 emit_implib_arg_provided = true;1546 emit_implib_arg_provided = true;
1553 } else if (mem.startsWith(u8, arg, "-femit-implib=")) {1547 } else if (mem.chompPrefix(u8, arg, "-femit-implib=")) |rest| {
1554 emit_implib = .{ .yes = arg["-femit-implib=".len..] };1548 emit_implib = .{ .yes = rest };
1555 emit_implib_arg_provided = true;1549 emit_implib_arg_provided = true;
1556 } else if (mem.eql(u8, arg, "-fno-emit-implib")) {1550 } else if (mem.eql(u8, arg, "-fno-emit-implib")) {
1557 emit_implib = .no;1551 emit_implib = .no;
...@@ -1601,8 +1595,7 @@ fn buildOutputType(...@@ -1601,8 +1595,7 @@ fn buildOutputType(
1601 mod_opts.no_builtin = false;1595 mod_opts.no_builtin = false;
1602 } else if (mem.eql(u8, arg, "-fno-builtin")) {1596 } else if (mem.eql(u8, arg, "-fno-builtin")) {
1603 mod_opts.no_builtin = true;1597 mod_opts.no_builtin = true;
1604 } else if (mem.startsWith(u8, arg, "-fopt-bisect-limit=")) {1598 } else if (mem.chompPrefix(u8, arg, "-fopt-bisect-limit=")) |next_arg| {
1605 const next_arg = arg["-fopt-bisect-limit=".len..];
1606 llvm_opt_bisect_limit = std.fmt.parseInt(c_int, next_arg, 0) catch |err|1599 llvm_opt_bisect_limit = std.fmt.parseInt(c_int, next_arg, 0) catch |err|
1607 fatal("unable to parse '{s}': {s}", .{ arg, @errorName(err) });1600 fatal("unable to parse '{s}': {s}", .{ arg, @errorName(err) });
1608 } else if (mem.eql(u8, arg, "--eh-frame-hdr")) {1601 } else if (mem.eql(u8, arg, "--eh-frame-hdr")) {
...@@ -1645,10 +1638,10 @@ fn buildOutputType(...@@ -1645,10 +1638,10 @@ fn buildOutputType(
1645 linker_z_relro = true;1638 linker_z_relro = true;
1646 } else if (mem.eql(u8, z_arg, "norelro")) {1639 } else if (mem.eql(u8, z_arg, "norelro")) {
1647 linker_z_relro = false;1640 linker_z_relro = false;
1648 } else if (mem.startsWith(u8, z_arg, "common-page-size=")) {1641 } else if (mem.chompPrefix(u8, z_arg, "common-page-size=")) |rest| {
1649 linker_z_common_page_size = parseIntSuffix(z_arg, "common-page-size=".len);1642 linker_z_common_page_size = parseIntSuffix(rest, 0);
1650 } else if (mem.startsWith(u8, z_arg, "max-page-size=")) {1643 } else if (mem.chompPrefix(u8, z_arg, "max-page-size=")) |rest| {
1651 linker_z_max_page_size = parseIntSuffix(z_arg, "max-page-size=".len);1644 linker_z_max_page_size = parseIntSuffix(rest, 0);
1652 } else {1645 } else {
1653 fatal("unsupported linker extension flag: -z {s}", .{z_arg});1646 fatal("unsupported linker extension flag: -z {s}", .{z_arg});
1654 }1647 }
...@@ -1669,16 +1662,16 @@ fn buildOutputType(...@@ -1669,16 +1662,16 @@ fn buildOutputType(
1669 linker_import_table = true;1662 linker_import_table = true;
1670 } else if (mem.eql(u8, arg, "--export-table")) {1663 } else if (mem.eql(u8, arg, "--export-table")) {
1671 linker_export_table = true;1664 linker_export_table = true;
1672 } else if (mem.startsWith(u8, arg, "--initial-memory=")) {1665 } else if (mem.chompPrefix(u8, arg, "--initial-memory=")) |rest| {
1673 linker_initial_memory = parseIntSuffix(arg, "--initial-memory=".len);1666 linker_initial_memory = parseIntSuffix(rest, 0);
1674 } else if (mem.startsWith(u8, arg, "--max-memory=")) {1667 } else if (mem.chompPrefix(u8, arg, "--max-memory=")) |rest| {
1675 linker_max_memory = parseIntSuffix(arg, "--max-memory=".len);1668 linker_max_memory = parseIntSuffix(rest, 0);
1676 } else if (mem.eql(u8, arg, "--shared-memory")) {1669 } else if (mem.eql(u8, arg, "--shared-memory")) {
1677 create_module.opts.shared_memory = true;1670 create_module.opts.shared_memory = true;
1678 } else if (mem.startsWith(u8, arg, "--global-base=")) {1671 } else if (mem.chompPrefix(u8, arg, "--global-base=")) |rest| {
1679 linker_global_base = parseIntSuffix(arg, "--global-base=".len);1672 linker_global_base = parseIntSuffix(rest, 0);
1680 } else if (mem.startsWith(u8, arg, "--export=")) {1673 } else if (mem.chompPrefix(u8, arg, "--export=")) |rest| {
1681 try linker_export_symbol_names.append(arena, arg["--export=".len..]);1674 try linker_export_symbol_names.append(arena, rest);
1682 } else if (mem.eql(u8, arg, "-Bsymbolic")) {1675 } else if (mem.eql(u8, arg, "-Bsymbolic")) {
1683 linker_bind_global_refs_locally = true;1676 linker_bind_global_refs_locally = true;
1684 } else if (mem.eql(u8, arg, "--gc-sections")) {1677 } else if (mem.eql(u8, arg, "--gc-sections")) {
...@@ -1687,8 +1680,7 @@ fn buildOutputType(...@@ -1687,8 +1680,7 @@ fn buildOutputType(
1687 linker_gc_sections = false;1680 linker_gc_sections = false;
1688 } else if (mem.eql(u8, arg, "--build-id")) {1681 } else if (mem.eql(u8, arg, "--build-id")) {
1689 build_id = .fast;1682 build_id = .fast;
1690 } else if (mem.startsWith(u8, arg, "--build-id=")) {1683 } else if (mem.chompPrefix(u8, arg, "--build-id=")) |style| {
1691 const style = arg["--build-id=".len..];
1692 build_id = std.zig.BuildId.parse(style) catch |err| {1684 build_id = std.zig.BuildId.parse(style) catch |err| {
1693 fatal("unable to parse --build-id style '{s}': {s}", .{1685 fatal("unable to parse --build-id style '{s}': {s}", .{
1694 style, @errorName(err),1686 style, @errorName(err),
...@@ -1712,26 +1704,26 @@ fn buildOutputType(...@@ -1712,26 +1704,26 @@ fn buildOutputType(
1712 verbose_generic_instances = true;1704 verbose_generic_instances = true;
1713 } else if (mem.eql(u8, arg, "--verbose-llvm-ir")) {1705 } else if (mem.eql(u8, arg, "--verbose-llvm-ir")) {
1714 verbose_llvm_ir = "-";1706 verbose_llvm_ir = "-";
1715 } else if (mem.startsWith(u8, arg, "--verbose-llvm-ir=")) {1707 } else if (mem.chompPrefix(u8, arg, "--verbose-llvm-ir=")) |rest| {
1716 verbose_llvm_ir = arg["--verbose-llvm-ir=".len..];1708 verbose_llvm_ir = rest;
1717 } else if (mem.startsWith(u8, arg, "--verbose-llvm-bc=")) {1709 } else if (mem.chompPrefix(u8, arg, "--verbose-llvm-bc=")) |rest| {
1718 verbose_llvm_bc = arg["--verbose-llvm-bc=".len..];1710 verbose_llvm_bc = rest;
1719 } else if (mem.eql(u8, arg, "--verbose-cimport")) {1711 } else if (mem.eql(u8, arg, "--verbose-cimport")) {
1720 verbose_cimport = true;1712 verbose_cimport = true;
1721 } else if (mem.eql(u8, arg, "--verbose-llvm-cpu-features")) {1713 } else if (mem.eql(u8, arg, "--verbose-llvm-cpu-features")) {
1722 verbose_llvm_cpu_features = true;1714 verbose_llvm_cpu_features = true;
1723 } else if (mem.startsWith(u8, arg, "-T")) {1715 } else if (mem.chompPrefix(u8, arg, "-T")) |rest| {
1724 linker_script = arg[2..];1716 linker_script = rest;
1725 } else if (mem.startsWith(u8, arg, "-L")) {1717 } else if (mem.chompPrefix(u8, arg, "-L")) |rest| {
1726 try create_module.lib_dir_args.append(arena, arg[2..]);1718 try create_module.lib_dir_args.append(arena, rest);
1727 } else if (mem.startsWith(u8, arg, "-F")) {1719 } else if (mem.chompPrefix(u8, arg, "-F")) |rest| {
1728 try create_module.framework_dirs.append(arena, arg[2..]);1720 try create_module.framework_dirs.append(arena, rest);
1729 } else if (mem.startsWith(u8, arg, "-l")) {1721 } else if (mem.chompPrefix(u8, arg, "-l")) |name| {
1730 // We don't know whether this library is part of libc1722 // We don't know whether this library is part of libc
1731 // or libc++ until we resolve the target, so we append1723 // or libc++ until we resolve the target, so we append
1732 // to the list for now.1724 // to the list for now.
1733 try create_module.cli_link_inputs.append(arena, .{ .name_query = .{1725 try create_module.cli_link_inputs.append(arena, .{ .name_query = .{
1734 .name = arg["-l".len..],1726 .name = name,
1735 .query = .{1727 .query = .{
1736 .needed = false,1728 .needed = false,
1737 .weak = false,1729 .weak = false,
...@@ -1740,9 +1732,9 @@ fn buildOutputType(...@@ -1740,9 +1732,9 @@ fn buildOutputType(
1740 .allow_so_scripts = allow_so_scripts,1732 .allow_so_scripts = allow_so_scripts,
1741 },1733 },
1742 } });1734 } });
1743 } else if (mem.startsWith(u8, arg, "-needed-l")) {1735 } else if (mem.chompPrefix(u8, arg, "-needed-l")) |name| {
1744 try create_module.cli_link_inputs.append(arena, .{ .name_query = .{1736 try create_module.cli_link_inputs.append(arena, .{ .name_query = .{
1745 .name = arg["-needed-l".len..],1737 .name = name,
1746 .query = .{1738 .query = .{
1747 .needed = true,1739 .needed = true,
1748 .weak = false,1740 .weak = false,
...@@ -1751,9 +1743,9 @@ fn buildOutputType(...@@ -1751,9 +1743,9 @@ fn buildOutputType(
1751 .allow_so_scripts = allow_so_scripts,1743 .allow_so_scripts = allow_so_scripts,
1752 },1744 },
1753 } });1745 } });
1754 } else if (mem.startsWith(u8, arg, "-weak-l")) {1746 } else if (mem.chompPrefix(u8, arg, "-weak-l")) |name| {
1755 try create_module.cli_link_inputs.append(arena, .{ .name_query = .{1747 try create_module.cli_link_inputs.append(arena, .{ .name_query = .{
1756 .name = arg["-weak-l".len..],1748 .name = name,
1757 .query = .{1749 .query = .{
1758 .needed = false,1750 .needed = false,
1759 .weak = true,1751 .weak = true,
...@@ -1764,13 +1756,10 @@ fn buildOutputType(...@@ -1764,13 +1756,10 @@ fn buildOutputType(
1764 } });1756 } });
1765 } else if (mem.startsWith(u8, arg, "-D")) {1757 } else if (mem.startsWith(u8, arg, "-D")) {
1766 try cc_argv.append(arena, arg);1758 try cc_argv.append(arena, arg);
1767 } else if (mem.startsWith(u8, arg, "-I")) {1759 } else if (mem.chompPrefix(u8, arg, "-I")) |rest| {
1768 try cssan.addIncludePath(arena, &cc_argv, .I, arg, arg[2..], true);1760 try cssan.addIncludePath(arena, &cc_argv, .I, arg, rest, true);
1769 } else if (mem.startsWith(u8, arg, "-x")) {1761 } else if (mem.chompPrefix(u8, arg, "-x")) |rest| {
1770 const lang = if (arg.len == "-x".len)1762 const lang = if (rest.len == 0) args_iter.nextOrFatal() else rest;
1771 args_iter.nextOrFatal()
1772 else
1773 arg["-x".len..];
1774 if (mem.eql(u8, lang, "none")) {1763 if (mem.eql(u8, lang, "none")) {
1775 file_ext = null;1764 file_ext = null;
1776 } else if (Compilation.LangToExt.get(lang)) |got_ext| {1765 } else if (Compilation.LangToExt.get(lang)) |got_ext| {
...@@ -1778,8 +1767,8 @@ fn buildOutputType(...@@ -1778,8 +1767,8 @@ fn buildOutputType(
1778 } else {1767 } else {
1779 fatal("language not recognized: '{s}'", .{lang});1768 fatal("language not recognized: '{s}'", .{lang});
1780 }1769 }
1781 } else if (mem.startsWith(u8, arg, "-mexec-model=")) {1770 } else if (mem.chompPrefix(u8, arg, "-mexec-model=")) |rest| {
1782 create_module.opts.wasi_exec_model = parseWasiExecModel(arg["-mexec-model=".len..]);1771 create_module.opts.wasi_exec_model = parseWasiExecModel(rest);
1783 } else if (mem.eql(u8, arg, "-municode")) {1772 } else if (mem.eql(u8, arg, "-municode")) {
1784 mingw_unicode_entry_point = true;1773 mingw_unicode_entry_point = true;
1785 } else {1774 } else {
...@@ -2457,8 +2446,8 @@ fn buildOutputType(...@@ -2457,8 +2446,8 @@ fn buildOutputType(
2457 linker_enable_new_dtags = false;2446 linker_enable_new_dtags = false;
2458 } else if (mem.eql(u8, arg, "-O")) {2447 } else if (mem.eql(u8, arg, "-O")) {
2459 linker_optimization = linker_args_it.nextOrFatal();2448 linker_optimization = linker_args_it.nextOrFatal();
2460 } else if (mem.startsWith(u8, arg, "-O")) {2449 } else if (mem.chompPrefix(u8, arg, "-O")) |rest| {
2461 linker_optimization = arg["-O".len..];2450 linker_optimization = rest;
2462 } else if (mem.eql(u8, arg, "-pagezero_size")) {2451 } else if (mem.eql(u8, arg, "-pagezero_size")) {
2463 const next_arg = linker_args_it.nextOrFatal();2452 const next_arg = linker_args_it.nextOrFatal();
2464 pagezero_size = std.fmt.parseUnsigned(u64, eatIntPrefix(next_arg, 16), 16) catch |err| {2453 pagezero_size = std.fmt.parseUnsigned(u64, eatIntPrefix(next_arg, 16), 16) catch |err| {
...@@ -2540,11 +2529,8 @@ fn buildOutputType(...@@ -2540,11 +2529,8 @@ fn buildOutputType(
2540 linker_compress_debug_sections = std.meta.stringToEnum(link.File.Lld.Elf.CompressDebugSections, arg1) orelse {2529 linker_compress_debug_sections = std.meta.stringToEnum(link.File.Lld.Elf.CompressDebugSections, arg1) orelse {
2541 fatal("expected [none|zlib|zstd] after --compress-debug-sections, found '{s}'", .{arg1});2530 fatal("expected [none|zlib|zstd] after --compress-debug-sections, found '{s}'", .{arg1});
2542 };2531 };
2543 } else if (mem.startsWith(u8, arg, "-z")) {2532 } else if (mem.chompPrefix(u8, arg, "-z")) |z_rest| {
2544 var z_arg = arg[2..];2533 const z_arg = if (z_rest.len == 0) linker_args_it.nextOrFatal() else z_rest;
2545 if (z_arg.len == 0) {
2546 z_arg = linker_args_it.nextOrFatal();
2547 }
2548 if (mem.eql(u8, z_arg, "nodelete")) {2534 if (mem.eql(u8, z_arg, "nodelete")) {
2549 linker_z_nodelete = true;2535 linker_z_nodelete = true;
2550 } else if (mem.eql(u8, z_arg, "notext")) {2536 } else if (mem.eql(u8, z_arg, "notext")) {
...@@ -2567,12 +2553,12 @@ fn buildOutputType(...@@ -2567,12 +2553,12 @@ fn buildOutputType(
2567 linker_z_relro = true;2553 linker_z_relro = true;
2568 } else if (mem.eql(u8, z_arg, "norelro")) {2554 } else if (mem.eql(u8, z_arg, "norelro")) {
2569 linker_z_relro = false;2555 linker_z_relro = false;
2570 } else if (mem.startsWith(u8, z_arg, "stack-size=")) {2556 } else if (mem.chompPrefix(u8, z_arg, "stack-size=")) |rest| {
2571 stack_size = parseStackSize(z_arg["stack-size=".len..]);2557 stack_size = parseStackSize(rest);
2572 } else if (mem.startsWith(u8, z_arg, "common-page-size=")) {2558 } else if (mem.chompPrefix(u8, z_arg, "common-page-size=")) |rest| {
2573 linker_z_common_page_size = parseIntSuffix(z_arg, "common-page-size=".len);2559 linker_z_common_page_size = parseIntSuffix(rest, 0);
2574 } else if (mem.startsWith(u8, z_arg, "max-page-size=")) {2560 } else if (mem.chompPrefix(u8, z_arg, "max-page-size=")) |rest| {
2575 linker_z_max_page_size = parseIntSuffix(z_arg, "max-page-size=".len);2561 linker_z_max_page_size = parseIntSuffix(rest, 0);
2576 } else {2562 } else {
2577 fatal("unsupported linker extension flag: -z {s}", .{z_arg});2563 fatal("unsupported linker extension flag: -z {s}", .{z_arg});
2578 }2564 }
...@@ -2686,9 +2672,9 @@ fn buildOutputType(...@@ -2686,9 +2672,9 @@ fn buildOutputType(
2686 .allow_so_scripts = allow_so_scripts,2672 .allow_so_scripts = allow_so_scripts,
2687 },2673 },
2688 } });2674 } });
2689 } else if (mem.startsWith(u8, arg, "-weak-l")) {2675 } else if (mem.chompPrefix(u8, arg, "-weak-l")) |rest| {
2690 try create_module.cli_link_inputs.append(arena, .{ .name_query = .{2676 try create_module.cli_link_inputs.append(arena, .{ .name_query = .{
2691 .name = arg["-weak-l".len..],2677 .name = rest,
2692 .query = .{2678 .query = .{
2693 .weak = true,2679 .weak = true,
2694 .needed = false,2680 .needed = false,
...@@ -3783,8 +3769,7 @@ fn createModule(...@@ -3783,8 +3769,7 @@ fn createModule(
3783 try mcpu_buffer.appendSlice(cli_mod.target_mcpu orelse "baseline");3769 try mcpu_buffer.appendSlice(cli_mod.target_mcpu orelse "baseline");
37843770
3785 for (create_module.llvm_m_args.items) |llvm_m_arg| {3771 for (create_module.llvm_m_args.items) |llvm_m_arg| {
3786 if (mem.startsWith(u8, llvm_m_arg, "mno-")) {3772 if (mem.chompPrefix(u8, llvm_m_arg, "mno-")) |llvm_name| {
3787 const llvm_name = llvm_m_arg["mno-".len..];
3788 const zig_name = llvm_to_zig_name.get(llvm_name) orelse {3773 const zig_name = llvm_to_zig_name.get(llvm_name) orelse {
3789 fatal("target architecture {s} has no LLVM CPU feature named '{s}'", .{3774 fatal("target architecture {s} has no LLVM CPU feature named '{s}'", .{
3790 @tagName(cpu_arch), llvm_name,3775 @tagName(cpu_arch), llvm_name,
...@@ -3792,8 +3777,7 @@ fn createModule(...@@ -3792,8 +3777,7 @@ fn createModule(
3792 };3777 };
3793 try mcpu_buffer.append('-');3778 try mcpu_buffer.append('-');
3794 try mcpu_buffer.appendSlice(zig_name);3779 try mcpu_buffer.appendSlice(zig_name);
3795 } else if (mem.startsWith(u8, llvm_m_arg, "m")) {3780 } else if (mem.chompPrefix(u8, llvm_m_arg, "m")) |llvm_name| {
3796 const llvm_name = llvm_m_arg["m".len..];
3797 const zig_name = llvm_to_zig_name.get(llvm_name) orelse {3781 const zig_name = llvm_to_zig_name.get(llvm_name) orelse {
3798 fatal("target architecture {s} has no LLVM CPU feature named '{s}'", .{3782 fatal("target architecture {s} has no LLVM CPU feature named '{s}'", .{
3799 @tagName(cpu_arch), llvm_name,3783 @tagName(cpu_arch), llvm_name,
...@@ -4980,9 +4964,8 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {...@@ -4980,9 +4964,8 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
4980 reference_trace = 256;4964 reference_trace = 256;
4981 } else if (mem.eql(u8, arg, "--fetch")) {4965 } else if (mem.eql(u8, arg, "--fetch")) {
4982 fetch_only = true;4966 fetch_only = true;
4983 } else if (mem.startsWith(u8, arg, "--fetch=")) {4967 } else if (mem.chompPrefix(u8, arg, "--fetch=")) |sub_arg| {
4984 fetch_only = true;4968 fetch_only = true;
4985 const sub_arg = arg["--fetch=".len..];
4986 fetch_mode = std.meta.stringToEnum(Package.Fetch.JobQueue.Mode, sub_arg) orelse4969 fetch_mode = std.meta.stringToEnum(Package.Fetch.JobQueue.Mode, sub_arg) orelse
4987 fatal("expected [needed|all] after '--fetch=', found '{s}'", .{4970 fatal("expected [needed|all] after '--fetch=', found '{s}'", .{
4988 sub_arg,4971 sub_arg,
...@@ -4993,8 +4976,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {...@@ -4993,8 +4976,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
4993 system_pkg_dir_path = args[i];4976 system_pkg_dir_path = args[i];
4994 try child_argv.append("--system");4977 try child_argv.append("--system");
4995 continue;4978 continue;
4996 } else if (mem.startsWith(u8, arg, "-freference-trace=")) {4979 } else if (mem.chompPrefix(u8, arg, "-freference-trace=")) |num| {
4997 const num = arg["-freference-trace=".len..];
4998 reference_trace = std.fmt.parseUnsigned(u32, num, 10) catch |err| {4980 reference_trace = std.fmt.parseUnsigned(u32, num, 10) catch |err| {
4999 fatal("unable to parse reference_trace count '{s}': {s}", .{ num, @errorName(err) });4981 fatal("unable to parse reference_trace count '{s}': {s}", .{ num, @errorName(err) });
5000 };4982 };
...@@ -5044,10 +5026,10 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {...@@ -5044,10 +5026,10 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
5044 verbose_generic_instances = true;5026 verbose_generic_instances = true;
5045 } else if (mem.eql(u8, arg, "--verbose-llvm-ir")) {5027 } else if (mem.eql(u8, arg, "--verbose-llvm-ir")) {
5046 verbose_llvm_ir = "-";5028 verbose_llvm_ir = "-";
5047 } else if (mem.startsWith(u8, arg, "--verbose-llvm-ir=")) {5029 } else if (mem.chompPrefix(u8, arg, "--verbose-llvm-ir=")) |rest| {
5048 verbose_llvm_ir = arg["--verbose-llvm-ir=".len..];5030 verbose_llvm_ir = rest;
5049 } else if (mem.startsWith(u8, arg, "--verbose-llvm-bc=")) {5031 } else if (mem.chompPrefix(u8, arg, "--verbose-llvm-bc=")) |rest| {
5050 verbose_llvm_bc = arg["--verbose-llvm-bc=".len..];5032 verbose_llvm_bc = rest;
5051 } else if (mem.eql(u8, arg, "--verbose-cimport")) {5033 } else if (mem.eql(u8, arg, "--verbose-cimport")) {
5052 verbose_cimport = true;5034 verbose_cimport = true;
5053 } else if (mem.eql(u8, arg, "--verbose-llvm-cpu-features")) {5035 } else if (mem.eql(u8, arg, "--verbose-llvm-cpu-features")) {
...@@ -5060,8 +5042,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {...@@ -5060,8 +5042,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
5060 };5042 };
5061 try child_argv.appendSlice(&.{ arg, args[i] });5043 try child_argv.appendSlice(&.{ arg, args[i] });
5062 continue;5044 continue;
5063 } else if (mem.startsWith(u8, arg, "-j")) {5045 } else if (mem.chompPrefix(u8, arg, "-j")) |str| {
5064 const str = arg["-j".len..];
5065 const num = std.fmt.parseUnsigned(u32, str, 10) catch |err| {5046 const num = std.fmt.parseUnsigned(u32, str, 10) catch |err| {
5066 fatal("unable to parse jobs count '{s}': {s}", .{5047 fatal("unable to parse jobs count '{s}': {s}", .{
5067 str, @errorName(err),5048 str, @errorName(err),
...@@ -6966,12 +6947,12 @@ fn cmdFetch(...@@ -6966,12 +6947,12 @@ fn cmdFetch(
6966 debug_hash = true;6947 debug_hash = true;
6967 } else if (mem.eql(u8, arg, "--save")) {6948 } else if (mem.eql(u8, arg, "--save")) {
6968 save = .{ .yes = null };6949 save = .{ .yes = null };
6969 } else if (mem.startsWith(u8, arg, "--save=")) {6950 } else if (mem.chompPrefix(u8, arg, "--save=")) |rest| {
6970 save = .{ .yes = arg["--save=".len..] };6951 save = .{ .yes = rest };
6971 } else if (mem.eql(u8, arg, "--save-exact")) {6952 } else if (mem.eql(u8, arg, "--save-exact")) {
6972 save = .{ .exact = null };6953 save = .{ .exact = null };
6973 } else if (mem.startsWith(u8, arg, "--save-exact=")) {6954 } else if (mem.chompPrefix(u8, arg, "--save-exact=")) |rest| {
6974 save = .{ .exact = arg["--save-exact=".len..] };6955 save = .{ .exact = rest };
6975 } else {6956 } else {
6976 fatal("unrecognized parameter: '{s}'", .{arg});6957 fatal("unrecognized parameter: '{s}'", .{arg});
6977 }6958 }