authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2024-07-26 21:05:40+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-07-28 14:37:03+02:00
log642cd730c8b588778d8c1d6953134408b30dfab3
tree430fe8e39eb8ea0b7d3f3c07cde56c523f02f79b
parent91c17979f10db4fdc6639b176c0563718f060f47

link: Accept `-Brepro` linker option and pass it to LLD.

Enable it by default when building Zig code in release modes. Contributes to #9432.

7 files changed, 20 insertions(+), 5 deletions(-)

src/Compilation.zig+5-2
...@@ -1122,6 +1122,7 @@ pub const CreateOptions = struct {...@@ -1122,6 +1122,7 @@ pub const CreateOptions = struct {
1122 linker_enable_new_dtags: ?bool = null,1122 linker_enable_new_dtags: ?bool = null,
1123 soname: ?[]const u8 = null,1123 soname: ?[]const u8 = null,
1124 linker_gc_sections: ?bool = null,1124 linker_gc_sections: ?bool = null,
1125 linker_repro: ?bool = null,
1125 linker_allow_shlib_undefined: ?bool = null,1126 linker_allow_shlib_undefined: ?bool = null,
1126 linker_bind_global_refs_locally: ?bool = null,1127 linker_bind_global_refs_locally: ?bool = null,
1127 linker_import_symbols: bool = false,1128 linker_import_symbols: bool = false,
...@@ -1602,6 +1603,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil...@@ -1602,6 +1603,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
1602 .framework_dirs = options.framework_dirs,1603 .framework_dirs = options.framework_dirs,
1603 .rpath_list = options.rpath_list,1604 .rpath_list = options.rpath_list,
1604 .symbol_wrap_set = options.symbol_wrap_set,1605 .symbol_wrap_set = options.symbol_wrap_set,
1606 .repro = options.linker_repro orelse (options.root_mod.optimize_mode != .Debug),
1605 .allow_shlib_undefined = options.linker_allow_shlib_undefined,1607 .allow_shlib_undefined = options.linker_allow_shlib_undefined,
1606 .bind_global_refs_locally = options.linker_bind_global_refs_locally orelse false,1608 .bind_global_refs_locally = options.linker_bind_global_refs_locally orelse false,
1607 .compress_debug_sections = options.linker_compress_debug_sections orelse .none,1609 .compress_debug_sections = options.linker_compress_debug_sections orelse .none,
...@@ -2560,7 +2562,7 @@ fn prepareWholeEmitSubPath(arena: Allocator, opt_emit: ?EmitLoc) error{OutOfMemo...@@ -2560,7 +2562,7 @@ fn prepareWholeEmitSubPath(arena: Allocator, opt_emit: ?EmitLoc) error{OutOfMemo
2560/// to remind the programmer to update multiple related pieces of code that2562/// to remind the programmer to update multiple related pieces of code that
2561/// are in different locations. Bump this number when adding or deleting2563/// are in different locations. Bump this number when adding or deleting
2562/// anything from the link cache manifest.2564/// anything from the link cache manifest.
2563pub const link_hash_implementation_version = 13;2565pub const link_hash_implementation_version = 14;
25642566
2565fn addNonIncrementalStuffToCacheManifest(2567fn addNonIncrementalStuffToCacheManifest(
2566 comp: *Compilation,2568 comp: *Compilation,
...@@ -2569,7 +2571,7 @@ fn addNonIncrementalStuffToCacheManifest(...@@ -2569,7 +2571,7 @@ fn addNonIncrementalStuffToCacheManifest(
2569) !void {2571) !void {
2570 const gpa = comp.gpa;2572 const gpa = comp.gpa;
25712573
2572 comptime assert(link_hash_implementation_version == 13);2574 comptime assert(link_hash_implementation_version == 14);
25732575
2574 if (comp.module) |mod| {2576 if (comp.module) |mod| {
2575 try addModuleTableToCacheHash(gpa, arena, &man.hash, mod.root_mod, mod.main_mod, .{ .files = man });2577 try addModuleTableToCacheHash(gpa, arena, &man.hash, mod.root_mod, mod.main_mod, .{ .files = man });
...@@ -2660,6 +2662,7 @@ fn addNonIncrementalStuffToCacheManifest(...@@ -2660,6 +2662,7 @@ fn addNonIncrementalStuffToCacheManifest(
2660 }2662 }
2661 man.hash.addOptionalBytes(target.dynamic_linker.get());2663 man.hash.addOptionalBytes(target.dynamic_linker.get());
2662 }2664 }
2665 man.hash.add(opts.repro);
2663 man.hash.addOptional(opts.allow_shlib_undefined);2666 man.hash.addOptional(opts.allow_shlib_undefined);
2664 man.hash.add(opts.bind_global_refs_locally);2667 man.hash.add(opts.bind_global_refs_locally);
26652668
src/link.zig+1
...@@ -114,6 +114,7 @@ pub const File = struct {...@@ -114,6 +114,7 @@ pub const File = struct {
114 major_subsystem_version: ?u16,114 major_subsystem_version: ?u16,
115 minor_subsystem_version: ?u16,115 minor_subsystem_version: ?u16,
116 gc_sections: ?bool,116 gc_sections: ?bool,
117 repro: bool,
117 allow_shlib_undefined: ?bool,118 allow_shlib_undefined: ?bool,
118 allow_undefined_version: bool,119 allow_undefined_version: bool,
119 enable_new_dtags: ?bool,120 enable_new_dtags: ?bool,
src/link/Coff.zig+2
...@@ -21,6 +21,7 @@ entry: link.File.OpenOptions.Entry,...@@ -21,6 +21,7 @@ entry: link.File.OpenOptions.Entry,
21entry_addr: ?u32,21entry_addr: ?u32,
22module_definition_file: ?[]const u8,22module_definition_file: ?[]const u8,
23pdb_out_path: ?[]const u8,23pdb_out_path: ?[]const u8,
24repro: bool,
2425
25ptr_width: PtrWidth,26ptr_width: PtrWidth,
26page_size: u32,27page_size: u32,
...@@ -319,6 +320,7 @@ pub fn createEmpty(...@@ -319,6 +320,7 @@ pub fn createEmpty(
319 return error.EntryAddressTooBig,320 return error.EntryAddressTooBig,
320 .module_definition_file = options.module_definition_file,321 .module_definition_file = options.module_definition_file,
321 .pdb_out_path = options.pdb_out_path,322 .pdb_out_path = options.pdb_out_path,
323 .repro = options.repro,
322 };324 };
323 if (use_llvm and comp.config.have_zcu) {325 if (use_llvm and comp.config.have_zcu) {
324 self.llvm_object = try LlvmObject.create(arena, comp);326 self.llvm_object = try LlvmObject.create(arena, comp);
src/link/Coff/lld.zig+6-1
...@@ -71,7 +71,7 @@ pub fn linkWithLLD(self: *Coff, arena: Allocator, tid: Zcu.PerThread.Id, prog_no...@@ -71,7 +71,7 @@ pub fn linkWithLLD(self: *Coff, arena: Allocator, tid: Zcu.PerThread.Id, prog_no
71 man = comp.cache_parent.obtain();71 man = comp.cache_parent.obtain();
72 self.base.releaseLock();72 self.base.releaseLock();
7373
74 comptime assert(Compilation.link_hash_implementation_version == 13);74 comptime assert(Compilation.link_hash_implementation_version == 14);
7575
76 for (comp.objects) |obj| {76 for (comp.objects) |obj| {
77 _ = try man.addFile(obj.path, null);77 _ = try man.addFile(obj.path, null);
...@@ -110,6 +110,7 @@ pub fn linkWithLLD(self: *Coff, arena: Allocator, tid: Zcu.PerThread.Id, prog_no...@@ -110,6 +110,7 @@ pub fn linkWithLLD(self: *Coff, arena: Allocator, tid: Zcu.PerThread.Id, prog_no
110 // strip does not need to go into the linker hash because it is part of the hash namespace110 // strip does not need to go into the linker hash because it is part of the hash namespace
111 man.hash.add(self.major_subsystem_version);111 man.hash.add(self.major_subsystem_version);
112 man.hash.add(self.minor_subsystem_version);112 man.hash.add(self.minor_subsystem_version);
113 man.hash.add(self.repro);
113 man.hash.addOptional(comp.version);114 man.hash.addOptional(comp.version);
114 try man.addOptionalFile(self.module_definition_file);115 try man.addOptionalFile(self.module_definition_file);
115116
...@@ -227,6 +228,10 @@ pub fn linkWithLLD(self: *Coff, arena: Allocator, tid: Zcu.PerThread.Id, prog_no...@@ -227,6 +228,10 @@ pub fn linkWithLLD(self: *Coff, arena: Allocator, tid: Zcu.PerThread.Id, prog_no
227 try argv.append(try allocPrint(arena, "-ENTRY:{s}", .{name}));228 try argv.append(try allocPrint(arena, "-ENTRY:{s}", .{name}));
228 }229 }
229230
231 if (self.repro) {
232 try argv.append("-BREPRO");
233 }
234
230 if (self.tsaware) {235 if (self.tsaware) {
231 try argv.append("-tsaware");236 try argv.append("-tsaware");
232 }237 }
src/link/Elf.zig+1-1
...@@ -2270,7 +2270,7 @@ fn linkWithLLD(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: s...@@ -2270,7 +2270,7 @@ fn linkWithLLD(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: s
2270 // We are about to obtain this lock, so here we give other processes a chance first.2270 // We are about to obtain this lock, so here we give other processes a chance first.
2271 self.base.releaseLock();2271 self.base.releaseLock();
22722272
2273 comptime assert(Compilation.link_hash_implementation_version == 13);2273 comptime assert(Compilation.link_hash_implementation_version == 14);
22742274
2275 try man.addOptionalFile(self.linker_script);2275 try man.addOptionalFile(self.linker_script);
2276 try man.addOptionalFile(self.version_script);2276 try man.addOptionalFile(self.version_script);
src/link/Wasm.zig+1-1
...@@ -3393,7 +3393,7 @@ fn linkWithLLD(wasm: *Wasm, arena: Allocator, tid: Zcu.PerThread.Id, prog_node:...@@ -3393,7 +3393,7 @@ fn linkWithLLD(wasm: *Wasm, arena: Allocator, tid: Zcu.PerThread.Id, prog_node:
3393 // We are about to obtain this lock, so here we give other processes a chance first.3393 // We are about to obtain this lock, so here we give other processes a chance first.
3394 wasm.base.releaseLock();3394 wasm.base.releaseLock();
33953395
3396 comptime assert(Compilation.link_hash_implementation_version == 13);3396 comptime assert(Compilation.link_hash_implementation_version == 14);
33973397
3398 for (comp.objects) |obj| {3398 for (comp.objects) |obj| {
3399 _ = try man.addFile(obj.path, null);3399 _ = try man.addFile(obj.path, null);
src/main.zig+4
...@@ -860,6 +860,7 @@ fn buildOutputType(...@@ -860,6 +860,7 @@ fn buildOutputType(
860 var want_compiler_rt: ?bool = null;860 var want_compiler_rt: ?bool = null;
861 var linker_script: ?[]const u8 = null;861 var linker_script: ?[]const u8 = null;
862 var version_script: ?[]const u8 = null;862 var version_script: ?[]const u8 = null;
863 var linker_repro: ?bool = null;
863 var linker_allow_undefined_version: bool = false;864 var linker_allow_undefined_version: bool = false;
864 var linker_enable_new_dtags: ?bool = null;865 var linker_enable_new_dtags: ?bool = null;
865 var disable_c_depfile = false;866 var disable_c_depfile = false;
...@@ -2481,6 +2482,8 @@ fn buildOutputType(...@@ -2481,6 +2482,8 @@ fn buildOutputType(
2481 {2482 {
2482 emit_implib = .{ .yes = linker_args_it.nextOrFatal() };2483 emit_implib = .{ .yes = linker_args_it.nextOrFatal() };
2483 emit_implib_arg_provided = true;2484 emit_implib_arg_provided = true;
2485 } else if (mem.eql(u8, arg, "-Brepro") or mem.eql(u8, arg, "/Brepro")) {
2486 linker_repro = true;
2484 } else if (mem.eql(u8, arg, "-undefined")) {2487 } else if (mem.eql(u8, arg, "-undefined")) {
2485 const lookup_type = linker_args_it.nextOrFatal();2488 const lookup_type = linker_args_it.nextOrFatal();
2486 if (mem.eql(u8, "dynamic_lookup", lookup_type)) {2489 if (mem.eql(u8, "dynamic_lookup", lookup_type)) {
...@@ -3315,6 +3318,7 @@ fn buildOutputType(...@@ -3315,6 +3318,7 @@ fn buildOutputType(
3315 .soname = resolved_soname,3318 .soname = resolved_soname,
3316 .linker_sort_section = linker_sort_section,3319 .linker_sort_section = linker_sort_section,
3317 .linker_gc_sections = linker_gc_sections,3320 .linker_gc_sections = linker_gc_sections,
3321 .linker_repro = linker_repro,
3318 .linker_allow_shlib_undefined = linker_allow_shlib_undefined,3322 .linker_allow_shlib_undefined = linker_allow_shlib_undefined,
3319 .linker_bind_global_refs_locally = linker_bind_global_refs_locally,3323 .linker_bind_global_refs_locally = linker_bind_global_refs_locally,
3320 .linker_import_symbols = linker_import_symbols,3324 .linker_import_symbols = linker_import_symbols,