From 6b1b7cf165b14fda0c8e543ca9c5f70d822350c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Motiejus=20Jak=C5=A1tys?= Date: Wed, 18 May 2022 15:09:58 +0300 Subject: [PATCH] [Elf] fix linker z_args I can't get the current `-Wl,-z<...>` pass to the linker. Assume any C file that has `int main`: $ zig cc -Wl,-znow ./test.c -o test warning: unsupported linker arg: -znow And, surely, the linker line did not have `-z now`. Cross-checking with clang/gcc: $ clang-13 -v -Wl,-znow ./test.c -o test |& tail -1 "/usr/bin/ld" --hash-style=both --build-id --eh-frame-hdr -m elf_x86_64 <...> -znow -zrelro <...> Same for -zrelro, -znoexecstack and others. After this commit zig does the right thing: observe `-z now` and `-z relro` in the linker line: $ ~/code/zig/build/zig cc -v -Wl,-zrelro -Wl,-znow ./test.c -o test |& tail -1 ld.lld -error-limit=0 -O0 -z stack-size=16777216 --gc-sections --eh-frame-hdr -z now -z relro <...> --- src/main.zig | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/main.zig b/src/main.zig index bd923ed85f6b..d34035e19721 100644 --- a/src/main.zig +++ b/src/main.zig @@ -1655,12 +1655,20 @@ fn buildOutputType( linker_global_base = parseIntSuffix(arg, "--global-base=".len); } else if (mem.startsWith(u8, arg, "--export=")) { try linker_export_symbol_names.append(arg["--export=".len..]); - } else if (mem.eql(u8, arg, "-z")) { - i += 1; - if (i >= linker_args.items.len) { - fatal("expected linker extension flag after '{s}'", .{arg}); - } - const z_arg = linker_args.items[i]; + } else if (mem.startsWith(u8, arg, "-z")) { + // -z param and -zparam are both supported. z_arg is whatever + // comes after `-z` in either case. + const z_arg = blk: { + if (mem.eql(u8, arg, "-z")) { + i += 1; + if (i >= linker_args.items.len) + fatal("expected linker extension flag after '{s}'", .{arg}); + break :blk linker_args.items[i]; + } else { + break :blk arg[2..]; + } + }; + if (mem.eql(u8, z_arg, "nodelete")) { linker_z_nodelete = true; } else if (mem.eql(u8, z_arg, "notext")) {