authorgravatar for kenta@lithdew.netKenta Iwasaki <kenta@lithdew.net> 2021-10-29 18:03:55+09:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-10-29 19:18:44-04:00
log2cdffc97f062feb898f4c8268f1ec6e252077e96
tree4e173d722842737d1e995592f45d9e8577fbd091
parent83a4bb6e6957325b744a08e16cab6b2a4a045f3e

zig: expose linker options and include '-z notext'

Add an option to allow the '-z notext' option to be passed to the linker via. the compiler frontend, which is a flag that tells the linker that relocations in read-only sections are permitted. Certain targets such as Solana BPF rely on this flag. Expose all linker options i.e. '-z nodelete', '-z now', '-z relro' in the compiler frontend. Usage documentation has been updated accordingly. Expose the '-z notext' flag in the standard library build runner.

5 files changed, 50 insertions(+), 0 deletions(-)

lib/std/build.zig+7
...@@ -1489,6 +1489,9 @@ pub const LibExeObjStep = struct {...@@ -1489,6 +1489,9 @@ pub const LibExeObjStep = struct {
14891489
1490 linker_allow_shlib_undefined: ?bool = null,1490 linker_allow_shlib_undefined: ?bool = null,
14911491
1492 /// Permit read-only relocations in read-only segments. Disallowed by default.
1493 link_z_notext: bool = false,
1494
1492 /// Uses system Wine installation to run cross compiled Windows build artifacts.1495 /// Uses system Wine installation to run cross compiled Windows build artifacts.
1493 enable_wine: bool = false,1496 enable_wine: bool = false,
14941497
...@@ -2354,6 +2357,10 @@ pub const LibExeObjStep = struct {...@@ -2354,6 +2357,10 @@ pub const LibExeObjStep = struct {
2354 if (self.linker_allow_shlib_undefined) |x| {2357 if (self.linker_allow_shlib_undefined) |x| {
2355 try zig_args.append(if (x) "-fallow-shlib-undefined" else "-fno-allow-shlib-undefined");2358 try zig_args.append(if (x) "-fallow-shlib-undefined" else "-fno-allow-shlib-undefined");
2356 }2359 }
2360 if (self.link_z_notext) {
2361 try zig_args.append("-z");
2362 try zig_args.append("notext");
2363 }
2357 if (self.single_threaded) {2364 if (self.single_threaded) {
2358 try zig_args.append("--single-threaded");2365 try zig_args.append("--single-threaded");
2359 }2366 }
src/Compilation.zig+2
...@@ -718,6 +718,7 @@ pub const InitOptions = struct {...@@ -718,6 +718,7 @@ pub const InitOptions = struct {
718 each_lib_rpath: ?bool = null,718 each_lib_rpath: ?bool = null,
719 disable_c_depfile: bool = false,719 disable_c_depfile: bool = false,
720 linker_z_nodelete: bool = false,720 linker_z_nodelete: bool = false,
721 linker_z_notext: bool = false,
721 linker_z_defs: bool = false,722 linker_z_defs: bool = false,
722 linker_z_origin: bool = false,723 linker_z_origin: bool = false,
723 linker_z_noexecstack: bool = false,724 linker_z_noexecstack: bool = false,
...@@ -1400,6 +1401,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {...@@ -1400,6 +1401,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
1400 .allow_shlib_undefined = options.linker_allow_shlib_undefined,1401 .allow_shlib_undefined = options.linker_allow_shlib_undefined,
1401 .bind_global_refs_locally = options.linker_bind_global_refs_locally orelse false,1402 .bind_global_refs_locally = options.linker_bind_global_refs_locally orelse false,
1402 .z_nodelete = options.linker_z_nodelete,1403 .z_nodelete = options.linker_z_nodelete,
1404 .z_notext = options.linker_z_notext,
1403 .z_defs = options.linker_z_defs,1405 .z_defs = options.linker_z_defs,
1404 .z_origin = options.linker_z_origin,1406 .z_origin = options.linker_z_origin,
1405 .z_noexecstack = options.linker_z_noexecstack,1407 .z_noexecstack = options.linker_z_noexecstack,
src/link.zig+1
...@@ -72,6 +72,7 @@ pub const Options = struct {...@@ -72,6 +72,7 @@ pub const Options = struct {
72 emit_relocs: bool,72 emit_relocs: bool,
73 rdynamic: bool,73 rdynamic: bool,
74 z_nodelete: bool,74 z_nodelete: bool,
75 z_notext: bool,
75 z_defs: bool,76 z_defs: bool,
76 z_origin: bool,77 z_origin: bool,
77 z_noexecstack: bool,78 z_noexecstack: bool,
src/link/Elf.zig+5
...@@ -1332,6 +1332,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {...@@ -1332,6 +1332,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
1332 man.hash.add(self.base.options.each_lib_rpath);1332 man.hash.add(self.base.options.each_lib_rpath);
1333 man.hash.add(self.base.options.skip_linker_dependencies);1333 man.hash.add(self.base.options.skip_linker_dependencies);
1334 man.hash.add(self.base.options.z_nodelete);1334 man.hash.add(self.base.options.z_nodelete);
1335 man.hash.add(self.base.options.z_notext);
1335 man.hash.add(self.base.options.z_defs);1336 man.hash.add(self.base.options.z_defs);
1336 man.hash.add(self.base.options.z_origin);1337 man.hash.add(self.base.options.z_origin);
1337 man.hash.add(self.base.options.z_noexecstack);1338 man.hash.add(self.base.options.z_noexecstack);
...@@ -1470,6 +1471,10 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {...@@ -1470,6 +1471,10 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
1470 try argv.append("-z");1471 try argv.append("-z");
1471 try argv.append("nodelete");1472 try argv.append("nodelete");
1472 }1473 }
1474 if (self.base.options.z_notext) {
1475 try argv.append("-z");
1476 try argv.append("notext");
1477 }
1473 if (self.base.options.z_defs) {1478 if (self.base.options.z_defs) {
1474 try argv.append("-z");1479 try argv.append("-z");
1475 try argv.append("defs");1480 try argv.append("defs");
src/main.zig+35
...@@ -401,6 +401,14 @@ const usage_build_generic =...@@ -401,6 +401,14 @@ const usage_build_generic =
401 \\ -fno-allow-shlib-undefined Disallows undefined symbols in shared libraries401 \\ -fno-allow-shlib-undefined Disallows undefined symbols in shared libraries
402 \\ --eh-frame-hdr Enable C++ exception handling by passing --eh-frame-hdr to linker402 \\ --eh-frame-hdr Enable C++ exception handling by passing --eh-frame-hdr to linker
403 \\ --emit-relocs Enable output of relocation sections for post build tools403 \\ --emit-relocs Enable output of relocation sections for post build tools
404 \\ -z [arg] Append linker arguments
405 \\ nodelete Indicate that the object cannot be deleted from a process
406 \\ notext Permit read-only relocations in read-only segments
407 \\ defs Force a fatal error if any undefined symbols remain
408 \\ origin Indicate that the object must have its origin processed
409 \\ noexecstack Indicate that the object requires an executable stack
410 \\ now Force all relocations to be processed on load
411 \\ relro Force all relocations to be resolved and be read-only on load
404 \\ -dynamic Force output to be dynamically linked412 \\ -dynamic Force output to be dynamically linked
405 \\ -static Force output to be statically linked413 \\ -static Force output to be statically linked
406 \\ -Bsymbolic Bind global references locally414 \\ -Bsymbolic Bind global references locally
...@@ -595,6 +603,7 @@ fn buildOutputType(...@@ -595,6 +603,7 @@ fn buildOutputType(
595 var linker_allow_shlib_undefined: ?bool = null;603 var linker_allow_shlib_undefined: ?bool = null;
596 var linker_bind_global_refs_locally: ?bool = null;604 var linker_bind_global_refs_locally: ?bool = null;
597 var linker_z_nodelete = false;605 var linker_z_nodelete = false;
606 var linker_z_notext = false;
598 var linker_z_defs = false;607 var linker_z_defs = false;
599 var linker_z_origin = false;608 var linker_z_origin = false;
600 var linker_z_noexecstack = false;609 var linker_z_noexecstack = false;
...@@ -1086,6 +1095,29 @@ fn buildOutputType(...@@ -1086,6 +1095,29 @@ fn buildOutputType(
1086 linker_allow_shlib_undefined = true;1095 linker_allow_shlib_undefined = true;
1087 } else if (mem.eql(u8, arg, "-fno-allow-shlib-undefined")) {1096 } else if (mem.eql(u8, arg, "-fno-allow-shlib-undefined")) {
1088 linker_allow_shlib_undefined = false;1097 linker_allow_shlib_undefined = false;
1098 } else if (mem.eql(u8, arg, "-z")) {
1099 i += 1;
1100 if (i >= args.len) {
1101 fatal("expected linker arg after '{s}'", .{arg});
1102 }
1103 const z_arg = args[i];
1104 if (mem.eql(u8, z_arg, "nodelete")) {
1105 linker_z_nodelete = true;
1106 } else if (mem.eql(u8, z_arg, "notext")) {
1107 linker_z_notext = true;
1108 } else if (mem.eql(u8, z_arg, "defs")) {
1109 linker_z_defs = true;
1110 } else if (mem.eql(u8, z_arg, "origin")) {
1111 linker_z_origin = true;
1112 } else if (mem.eql(u8, z_arg, "noexecstack")) {
1113 linker_z_noexecstack = true;
1114 } else if (mem.eql(u8, z_arg, "now")) {
1115 linker_z_now = true;
1116 } else if (mem.eql(u8, z_arg, "relro")) {
1117 linker_z_relro = true;
1118 } else {
1119 warn("unsupported linker arg: -z {s}", .{z_arg});
1120 }
1089 } else if (mem.eql(u8, arg, "-Bsymbolic")) {1121 } else if (mem.eql(u8, arg, "-Bsymbolic")) {
1090 linker_bind_global_refs_locally = true;1122 linker_bind_global_refs_locally = true;
1091 } else if (mem.eql(u8, arg, "--debug-compile-errors")) {1123 } else if (mem.eql(u8, arg, "--debug-compile-errors")) {
...@@ -1422,6 +1454,8 @@ fn buildOutputType(...@@ -1422,6 +1454,8 @@ fn buildOutputType(
1422 const z_arg = linker_args.items[i];1454 const z_arg = linker_args.items[i];
1423 if (mem.eql(u8, z_arg, "nodelete")) {1455 if (mem.eql(u8, z_arg, "nodelete")) {
1424 linker_z_nodelete = true;1456 linker_z_nodelete = true;
1457 } else if (mem.eql(u8, z_arg, "notext")) {
1458 linker_z_notext = true;
1425 } else if (mem.eql(u8, z_arg, "defs")) {1459 } else if (mem.eql(u8, z_arg, "defs")) {
1426 linker_z_defs = true;1460 linker_z_defs = true;
1427 } else if (mem.eql(u8, z_arg, "origin")) {1461 } else if (mem.eql(u8, z_arg, "origin")) {
...@@ -2108,6 +2142,7 @@ fn buildOutputType(...@@ -2108,6 +2142,7 @@ fn buildOutputType(
2108 .linker_allow_shlib_undefined = linker_allow_shlib_undefined,2142 .linker_allow_shlib_undefined = linker_allow_shlib_undefined,
2109 .linker_bind_global_refs_locally = linker_bind_global_refs_locally,2143 .linker_bind_global_refs_locally = linker_bind_global_refs_locally,
2110 .linker_z_nodelete = linker_z_nodelete,2144 .linker_z_nodelete = linker_z_nodelete,
2145 .linker_z_notext = linker_z_notext,
2111 .linker_z_defs = linker_z_defs,2146 .linker_z_defs = linker_z_defs,
2112 .linker_z_origin = linker_z_origin,2147 .linker_z_origin = linker_z_origin,
2113 .linker_z_noexecstack = linker_z_noexecstack,2148 .linker_z_noexecstack = linker_z_noexecstack,