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 {
14891489
14901490 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
14921495 /// Uses system Wine installation to run cross compiled Windows build artifacts.
14931496 enable_wine: bool = false,
14941497
......@@ -2354,6 +2357,10 @@ pub const LibExeObjStep = struct {
23542357 if (self.linker_allow_shlib_undefined) |x| {
23552358 try zig_args.append(if (x) "-fallow-shlib-undefined" else "-fno-allow-shlib-undefined");
23562359 }
2360 if (self.link_z_notext) {
2361 try zig_args.append("-z");
2362 try zig_args.append("notext");
2363 }
23572364 if (self.single_threaded) {
23582365 try zig_args.append("--single-threaded");
23592366 }
src/Compilation.zig+2
......@@ -718,6 +718,7 @@ pub const InitOptions = struct {
718718 each_lib_rpath: ?bool = null,
719719 disable_c_depfile: bool = false,
720720 linker_z_nodelete: bool = false,
721 linker_z_notext: bool = false,
721722 linker_z_defs: bool = false,
722723 linker_z_origin: bool = false,
723724 linker_z_noexecstack: bool = false,
......@@ -1400,6 +1401,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
14001401 .allow_shlib_undefined = options.linker_allow_shlib_undefined,
14011402 .bind_global_refs_locally = options.linker_bind_global_refs_locally orelse false,
14021403 .z_nodelete = options.linker_z_nodelete,
1404 .z_notext = options.linker_z_notext,
14031405 .z_defs = options.linker_z_defs,
14041406 .z_origin = options.linker_z_origin,
14051407 .z_noexecstack = options.linker_z_noexecstack,
src/link.zig+1
......@@ -72,6 +72,7 @@ pub const Options = struct {
7272 emit_relocs: bool,
7373 rdynamic: bool,
7474 z_nodelete: bool,
75 z_notext: bool,
7576 z_defs: bool,
7677 z_origin: bool,
7778 z_noexecstack: bool,
src/link/Elf.zig+5
......@@ -1332,6 +1332,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
13321332 man.hash.add(self.base.options.each_lib_rpath);
13331333 man.hash.add(self.base.options.skip_linker_dependencies);
13341334 man.hash.add(self.base.options.z_nodelete);
1335 man.hash.add(self.base.options.z_notext);
13351336 man.hash.add(self.base.options.z_defs);
13361337 man.hash.add(self.base.options.z_origin);
13371338 man.hash.add(self.base.options.z_noexecstack);
......@@ -1470,6 +1471,10 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
14701471 try argv.append("-z");
14711472 try argv.append("nodelete");
14721473 }
1474 if (self.base.options.z_notext) {
1475 try argv.append("-z");
1476 try argv.append("notext");
1477 }
14731478 if (self.base.options.z_defs) {
14741479 try argv.append("-z");
14751480 try argv.append("defs");
src/main.zig+35
......@@ -401,6 +401,14 @@ const usage_build_generic =
401401 \\ -fno-allow-shlib-undefined Disallows undefined symbols in shared libraries
402402 \\ --eh-frame-hdr Enable C++ exception handling by passing --eh-frame-hdr to linker
403403 \\ --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
404412 \\ -dynamic Force output to be dynamically linked
405413 \\ -static Force output to be statically linked
406414 \\ -Bsymbolic Bind global references locally
......@@ -595,6 +603,7 @@ fn buildOutputType(
595603 var linker_allow_shlib_undefined: ?bool = null;
596604 var linker_bind_global_refs_locally: ?bool = null;
597605 var linker_z_nodelete = false;
606 var linker_z_notext = false;
598607 var linker_z_defs = false;
599608 var linker_z_origin = false;
600609 var linker_z_noexecstack = false;
......@@ -1086,6 +1095,29 @@ fn buildOutputType(
10861095 linker_allow_shlib_undefined = true;
10871096 } else if (mem.eql(u8, arg, "-fno-allow-shlib-undefined")) {
10881097 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 }
10891121 } else if (mem.eql(u8, arg, "-Bsymbolic")) {
10901122 linker_bind_global_refs_locally = true;
10911123 } else if (mem.eql(u8, arg, "--debug-compile-errors")) {
......@@ -1422,6 +1454,8 @@ fn buildOutputType(
14221454 const z_arg = linker_args.items[i];
14231455 if (mem.eql(u8, z_arg, "nodelete")) {
14241456 linker_z_nodelete = true;
1457 } else if (mem.eql(u8, z_arg, "notext")) {
1458 linker_z_notext = true;
14251459 } else if (mem.eql(u8, z_arg, "defs")) {
14261460 linker_z_defs = true;
14271461 } else if (mem.eql(u8, z_arg, "origin")) {
......@@ -2108,6 +2142,7 @@ fn buildOutputType(
21082142 .linker_allow_shlib_undefined = linker_allow_shlib_undefined,
21092143 .linker_bind_global_refs_locally = linker_bind_global_refs_locally,
21102144 .linker_z_nodelete = linker_z_nodelete,
2145 .linker_z_notext = linker_z_notext,
21112146 .linker_z_defs = linker_z_defs,
21122147 .linker_z_origin = linker_z_origin,
21132148 .linker_z_noexecstack = linker_z_noexecstack,