| author | |
| committer | |
| log | 2cdffc97f062feb898f4c8268f1ec6e252077e96 |
| tree | 4e173d722842737d1e995592f45d9e8577fbd091 |
| parent | 83a4bb6e6957325b744a08e16cab6b2a4a045f3e |
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 { |
| 1489 | 1489 | ||
| 1490 | linker_allow_shlib_undefined: ?bool = null, | 1490 | linker_allow_shlib_undefined: ?bool = null, |
| 1491 | 1491 | ||
| 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, |
| 1494 | 1497 | ||
| ... | @@ -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 libraries | 401 | \\ -fno-allow-shlib-undefined Disallows undefined symbols in shared libraries |
| 402 | \\ --eh-frame-hdr Enable C++ exception handling by passing --eh-frame-hdr to linker | 402 | \\ --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 tools | 403 | \\ --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 linked | 412 | \\ -dynamic Force output to be dynamically linked |
| 405 | \\ -static Force output to be statically linked | 413 | \\ -static Force output to be statically linked |
| 406 | \\ -Bsymbolic Bind global references locally | 414 | \\ -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, |