Skip to content

Commit 05ba619

Browse files
committed
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.
1 parent bbe4a9f commit 05ba619

File tree

5 files changed

+50
-0
lines changed

5 files changed

+50
-0
lines changed

lib/std/build.zig

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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 [flag] Linker flags
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,

0 commit comments

Comments
 (0)