authorgravatar for me@dha.shdhash <me@dha.sh> 2023-09-29 13:38:54-04:00
committergravatar for carl@astholm.seCarl Åstholm <carl@astholm.se> 2024-01-09 17:24:11+01:00
log9bb643031864c8c3c2d4ac52aecb175283e335e3
tree20e8fa8787aa7e29e9771edff9d20f8a404ea70b
parent60094cc3fc979df0928c412c9fded457172f2060

Add support for `--(no-)undefined-version`

Co-authored-by: Motiejus Jakštys <motiejus@jakstys.lt> Co-authored-by: Jakub Konka <kubkon@jakubkonka.com> Co-authored-by: Samuel Cantero <scanterog@gmail.com> Co-authored-by: Giorgos Georgiou <giorgos.georgiou@datadoghq.com> Co-authored-by: Carl Åstholm <carl@astholm.se>

8 files changed, 37 insertions(+), 7 deletions(-)

lib/std/Build/Step/Compile.zig+6
......@@ -110,6 +110,9 @@ linker_dynamicbase: bool = true,
110110
111111linker_allow_shlib_undefined: ?bool = null,
112112
113/// Allow version scripts to refer to undefined symbols.
114linker_allow_undefined_version: ?bool = null,
115
113116/// Permit read-only relocations in read-only segments. Disallowed by default.
114117link_z_notext: bool = false,
115118
......@@ -1451,6 +1454,9 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
14511454 try zig_args.append("--version-script");
14521455 try zig_args.append(version_script.getPath(b));
14531456 }
1457 if (self.linker_allow_undefined_version) |x| {
1458 try zig_args.append(if (x) "--undefined-version" else "--no-undefined-version");
1459 }
14541460
14551461 if (self.kind == .@"test") {
14561462 if (self.exec_cmd_args) |exec_cmd_args| {
src/Compilation.zig+5-2
......@@ -1033,6 +1033,7 @@ pub const CreateOptions = struct {
10331033 link_emit_relocs: bool = false,
10341034 linker_script: ?[]const u8 = null,
10351035 version_script: ?[]const u8 = null,
1036 linker_allow_undefined_version: bool = false,
10361037 soname: ?[]const u8 = null,
10371038 linker_gc_sections: ?bool = null,
10381039 linker_allow_shlib_undefined: ?bool = null,
......@@ -1572,6 +1573,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
15721573 .stack_size = options.stack_size,
15731574 .image_base = options.image_base,
15741575 .version_script = options.version_script,
1576 .allow_undefined_version = options.linker_allow_undefined_version,
15751577 .gc_sections = options.linker_gc_sections,
15761578 .emit_relocs = options.link_emit_relocs,
15771579 .soname = options.soname,
......@@ -2458,7 +2460,7 @@ fn prepareWholeEmitSubPath(arena: Allocator, opt_emit: ?EmitLoc) error{OutOfMemo
24582460/// to remind the programmer to update multiple related pieces of code that
24592461/// are in different locations. Bump this number when adding or deleting
24602462/// anything from the link cache manifest.
2461pub const link_hash_implementation_version = 10;
2463pub const link_hash_implementation_version = 11;
24622464
24632465fn addNonIncrementalStuffToCacheManifest(
24642466 comp: *Compilation,
......@@ -2467,7 +2469,7 @@ fn addNonIncrementalStuffToCacheManifest(
24672469) !void {
24682470 const gpa = comp.gpa;
24692471
2470 comptime assert(link_hash_implementation_version == 10);
2472 comptime assert(link_hash_implementation_version == 11);
24712473
24722474 if (comp.module) |mod| {
24732475 const main_zig_file = try mod.main_mod.root.joinString(arena, mod.main_mod.root_src_path);
......@@ -2541,6 +2543,7 @@ fn addNonIncrementalStuffToCacheManifest(
25412543
25422544 try man.addOptionalFile(opts.linker_script);
25432545 try man.addOptionalFile(opts.version_script);
2546 man.hash.add(opts.allow_undefined_version);
25442547
25452548 man.hash.addOptional(opts.stack_size);
25462549 man.hash.addOptional(opts.image_base);
src/link.zig+1
......@@ -113,6 +113,7 @@ pub const File = struct {
113113 minor_subsystem_version: ?u16,
114114 gc_sections: ?bool,
115115 allow_shlib_undefined: ?bool,
116 allow_undefined_version: bool,
116117 subsystem: ?std.Target.SubSystem,
117118 linker_script: ?[]const u8,
118119 version_script: ?[]const u8,
src/link/Coff/lld.zig+1-1
......@@ -70,7 +70,7 @@ pub fn linkWithLLD(self: *Coff, arena: Allocator, prog_node: *std.Progress.Node)
7070 man = comp.cache_parent.obtain();
7171 self.base.releaseLock();
7272
73 comptime assert(Compilation.link_hash_implementation_version == 10);
73 comptime assert(Compilation.link_hash_implementation_version == 11);
7474
7575 for (comp.objects) |obj| {
7676 _ = try man.addFile(obj.path, null);
src/link/Elf.zig+9-1
......@@ -22,6 +22,7 @@ soname: ?[]const u8,
2222bind_global_refs_locally: bool,
2323linker_script: ?[]const u8,
2424version_script: ?[]const u8,
25allow_undefined_version: bool,
2526print_icf_sections: bool,
2627print_map: bool,
2728entry_name: ?[]const u8,
......@@ -325,6 +326,7 @@ pub fn createEmpty(
325326 .bind_global_refs_locally = options.bind_global_refs_locally,
326327 .linker_script = options.linker_script,
327328 .version_script = options.version_script,
329 .allow_undefined_version = options.allow_undefined_version,
328330 .print_icf_sections = options.print_icf_sections,
329331 .print_map = options.print_map,
330332 };
......@@ -2410,10 +2412,11 @@ fn linkWithLLD(self: *Elf, arena: Allocator, prog_node: *std.Progress.Node) !voi
24102412 // We are about to obtain this lock, so here we give other processes a chance first.
24112413 self.base.releaseLock();
24122414
2413 comptime assert(Compilation.link_hash_implementation_version == 10);
2415 comptime assert(Compilation.link_hash_implementation_version == 11);
24142416
24152417 try man.addOptionalFile(self.linker_script);
24162418 try man.addOptionalFile(self.version_script);
2419 man.hash.add(self.allow_undefined_version);
24172420 for (comp.objects) |obj| {
24182421 _ = try man.addFile(obj.path, null);
24192422 man.hash.add(obj.must_link);
......@@ -2789,6 +2792,11 @@ fn linkWithLLD(self: *Elf, arena: Allocator, prog_node: *std.Progress.Node) !voi
27892792 try argv.append("-version-script");
27902793 try argv.append(version_script);
27912794 }
2795 if (self.allow_undefined_version) {
2796 try argv.append("--undefined-version");
2797 } else {
2798 try argv.append("--no-undefined-version");
2799 }
27922800 }
27932801
27942802 // Positional arguments to the linker such as object files.
src/link/MachO/zld.zig+1-1
......@@ -55,7 +55,7 @@ pub fn linkWithZld(
5555 // We are about to obtain this lock, so here we give other processes a chance first.
5656 macho_file.base.releaseLock();
5757
58 comptime assert(Compilation.link_hash_implementation_version == 10);
58 comptime assert(Compilation.link_hash_implementation_version == 11);
5959
6060 for (objects) |obj| {
6161 _ = try man.addFile(obj.path, null);
src/link/Wasm.zig+2-2
......@@ -3547,7 +3547,7 @@ fn linkWithZld(wasm: *Wasm, arena: Allocator, prog_node: *std.Progress.Node) lin
35473547 // We are about to obtain this lock, so here we give other processes a chance first.
35483548 wasm.base.releaseLock();
35493549
3550 comptime assert(Compilation.link_hash_implementation_version == 10);
3550 comptime assert(Compilation.link_hash_implementation_version == 11);
35513551
35523552 for (objects) |obj| {
35533553 _ = try man.addFile(obj.path, null);
......@@ -4633,7 +4633,7 @@ fn linkWithLLD(wasm: *Wasm, arena: Allocator, prog_node: *std.Progress.Node) !vo
46334633 // We are about to obtain this lock, so here we give other processes a chance first.
46344634 wasm.base.releaseLock();
46354635
4636 comptime assert(Compilation.link_hash_implementation_version == 10);
4636 comptime assert(Compilation.link_hash_implementation_version == 11);
46374637
46384638 for (comp.objects) |obj| {
46394639 _ = try man.addFile(obj.path, null);
src/main.zig+12
......@@ -500,6 +500,8 @@ const usage_build_generic =
500500 \\Global Link Options:
501501 \\ -T[script], --script [script] Use a custom linker script
502502 \\ --version-script [path] Provide a version .map file
503 \\ --undefined-version Allow version scripts to refer to undefined symbols
504 \\ --no-undefined-version (default) Disallow version scripts from referring to undefined symbols
503505 \\ --dynamic-linker [path] Set the dynamic interpreter path (usually ld.so)
504506 \\ --sysroot [path] Set the system root directory (usually /)
505507 \\ --version [ver] Dynamic library semver
......@@ -826,6 +828,7 @@ fn buildOutputType(
826828 var want_compiler_rt: ?bool = null;
827829 var linker_script: ?[]const u8 = null;
828830 var version_script: ?[]const u8 = null;
831 var linker_allow_undefined_version: bool = false;
829832 var disable_c_depfile = false;
830833 var linker_sort_section: ?link.File.Elf.SortSection = null;
831834 var linker_gc_sections: ?bool = null;
......@@ -1200,6 +1203,10 @@ fn buildOutputType(
12001203 linker_script = args_iter.nextOrFatal();
12011204 } else if (mem.eql(u8, arg, "-version-script") or mem.eql(u8, arg, "--version-script")) {
12021205 version_script = args_iter.nextOrFatal();
1206 } else if (mem.eql(u8, arg, "--undefined-version")) {
1207 linker_allow_undefined_version = true;
1208 } else if (mem.eql(u8, arg, "--no-undefined-version")) {
1209 linker_allow_undefined_version = false;
12031210 } else if (mem.eql(u8, arg, "--library") or mem.eql(u8, arg, "-l")) {
12041211 // We don't know whether this library is part of libc
12051212 // or libc++ until we resolve the target, so we append
......@@ -2153,6 +2160,10 @@ fn buildOutputType(
21532160 create_module.opts.rdynamic = true;
21542161 } else if (mem.eql(u8, arg, "-version-script") or mem.eql(u8, arg, "--version-script")) {
21552162 version_script = linker_args_it.nextOrFatal();
2163 } else if (mem.eql(u8, arg, "--undefined-version")) {
2164 linker_allow_undefined_version = true;
2165 } else if (mem.eql(u8, arg, "--no-undefined-version")) {
2166 linker_allow_undefined_version = false;
21562167 } else if (mem.eql(u8, arg, "-O")) {
21572168 linker_optimization = linker_args_it.nextOrFatal();
21582169 } else if (mem.startsWith(u8, arg, "-O")) {
......@@ -3166,6 +3177,7 @@ fn buildOutputType(
31663177 .hash_style = hash_style,
31673178 .linker_script = linker_script,
31683179 .version_script = version_script,
3180 .linker_allow_undefined_version = linker_allow_undefined_version,
31693181 .disable_c_depfile = disable_c_depfile,
31703182 .soname = resolved_soname,
31713183 .linker_sort_section = linker_sort_section,