diff --git a/src/Compilation.zig b/src/Compilation.zig index 687b0a6dc6..7ac1e49196 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -764,6 +764,7 @@ pub const InitOptions = struct { linker_z_noexecstack: bool = false, linker_z_now: bool = false, linker_z_relro: bool = false, + linker_z_nocopyreloc: bool = false, linker_tsaware: bool = false, linker_nxcompat: bool = false, linker_dynamicbase: bool = false, @@ -1597,6 +1598,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { .z_notext = options.linker_z_notext, .z_defs = options.linker_z_defs, .z_origin = options.linker_z_origin, + .z_nocopyreloc = options.linker_z_nocopyreloc, .z_noexecstack = options.linker_z_noexecstack, .z_now = options.linker_z_now, .z_relro = options.linker_z_relro, @@ -2255,7 +2257,7 @@ fn prepareWholeEmitSubPath(arena: Allocator, opt_emit: ?EmitLoc) error{OutOfMemo /// to remind the programmer to update multiple related pieces of code that /// are in different locations. Bump this number when adding or deleting /// anything from the link cache manifest. -pub const link_hash_implementation_version = 2; +pub const link_hash_implementation_version = 3; fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifest) !void { const gpa = comp.gpa; @@ -2265,7 +2267,7 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes defer arena_allocator.deinit(); const arena = arena_allocator.allocator(); - comptime assert(link_hash_implementation_version == 2); + comptime assert(link_hash_implementation_version == 3); if (comp.bin_file.options.module) |mod| { const main_zig_file = try mod.main_pkg.root_src_directory.join(arena, &[_][]const u8{ @@ -2333,6 +2335,7 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes man.hash.add(comp.bin_file.options.z_notext); man.hash.add(comp.bin_file.options.z_defs); man.hash.add(comp.bin_file.options.z_origin); + man.hash.add(comp.bin_file.options.z_nocopyreloc); man.hash.add(comp.bin_file.options.z_noexecstack); man.hash.add(comp.bin_file.options.z_now); man.hash.add(comp.bin_file.options.z_relro); diff --git a/src/link.zig b/src/link.zig index ebcec92ac1..8647259651 100644 --- a/src/link.zig +++ b/src/link.zig @@ -112,6 +112,7 @@ pub const Options = struct { z_notext: bool, z_defs: bool, z_origin: bool, + z_nocopyreloc: bool, z_noexecstack: bool, z_now: bool, z_relro: bool, diff --git a/src/link/Coff.zig b/src/link/Coff.zig index 178a6ab6b4..37ec8d0758 100644 --- a/src/link/Coff.zig +++ b/src/link/Coff.zig @@ -969,7 +969,7 @@ fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Node) ! man = comp.cache_parent.obtain(); self.base.releaseLock(); - comptime assert(Compilation.link_hash_implementation_version == 2); + comptime assert(Compilation.link_hash_implementation_version == 3); for (self.base.options.objects) |obj| { _ = try man.addFile(obj.path, null); diff --git a/src/link/Elf.zig b/src/link/Elf.zig index be366076b4..06b241eb4d 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -1294,7 +1294,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v // We are about to obtain this lock, so here we give other processes a chance first. self.base.releaseLock(); - comptime assert(Compilation.link_hash_implementation_version == 2); + comptime assert(Compilation.link_hash_implementation_version == 3); try man.addOptionalFile(self.base.options.linker_script); try man.addOptionalFile(self.base.options.version_script); @@ -1325,6 +1325,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v man.hash.add(self.base.options.z_notext); man.hash.add(self.base.options.z_defs); man.hash.add(self.base.options.z_origin); + man.hash.add(self.base.options.z_nocopyreloc); man.hash.add(self.base.options.z_noexecstack); man.hash.add(self.base.options.z_now); man.hash.add(self.base.options.z_relro); @@ -1496,6 +1497,10 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v try argv.append("-z"); try argv.append("origin"); } + if (self.base.options.z_nocopyreloc) { + try argv.append("-z"); + try argv.append("nocopyreloc"); + } if (self.base.options.z_noexecstack) { try argv.append("-z"); try argv.append("noexecstack"); diff --git a/src/link/MachO.zig b/src/link/MachO.zig index 964279c5d1..853d62bdce 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -527,7 +527,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No // We are about to obtain this lock, so here we give other processes a chance first. self.base.releaseLock(); - comptime assert(Compilation.link_hash_implementation_version == 2); + comptime assert(Compilation.link_hash_implementation_version == 3); for (self.base.options.objects) |obj| { _ = try man.addFile(obj.path, null); diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig index d8c87703a6..2b4b9bb089 100644 --- a/src/link/Wasm.zig +++ b/src/link/Wasm.zig @@ -2274,7 +2274,7 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) ! // We are about to obtain this lock, so here we give other processes a chance first. self.base.releaseLock(); - comptime assert(Compilation.link_hash_implementation_version == 2); + comptime assert(Compilation.link_hash_implementation_version == 3); for (self.base.options.objects) |obj| { _ = try man.addFile(obj.path, null); diff --git a/src/main.zig b/src/main.zig index bd923ed85f..55def40d96 100644 --- a/src/main.zig +++ b/src/main.zig @@ -430,6 +430,7 @@ const usage_build_generic = \\ notext Permit read-only relocations in read-only segments \\ defs Force a fatal error if any undefined symbols remain \\ origin Indicate that the object must have its origin processed + \\ nocopyreloc Disable the creation of copy relocations \\ noexecstack Indicate that the object requires an executable stack \\ now Force all relocations to be processed on load \\ relro Force all relocations to be resolved and be read-only on load