diff --git a/src/Compilation.zig b/src/Compilation.zig index 03d7962ccc771bb412f0d1c72fe7e5074fb354f5..353a2f1ca3492899f3d724092b45d869603f64eb 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -1165,9 +1165,6 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { break :blk false; } else if (options.c_source_files.len == 0) { break :blk false; - } else if (options.target.os.tag == .windows and link_libcpp) { - // https://github.com/ziglang/zig/issues/8531 - break :blk false; } else if (options.target.cpu.arch.isRISCV()) { // Clang and LLVM currently don't support RISC-V target-abi for LTO. // Compiling with LTO may fail or produce undesired results. @@ -1793,6 +1790,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { .headerpad_size = options.headerpad_size, .headerpad_max_install_names = options.headerpad_max_install_names, .dead_strip_dylibs = options.dead_strip_dylibs, + .force_undefined_symbols = .{}, }); errdefer bin_file.destroy(); comp.* = .{ @@ -1943,6 +1941,10 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { for (mingw.always_link_libs) |name| { try comp.bin_file.options.system_libs.put(comp.gpa, name, .{}); } + + // LLD might drop some symbols as unused during LTO and GCing, therefore, + // we force mark them for resolution here. + try comp.bin_file.options.force_undefined_symbols.put(comp.gpa, "_tls_index", {}); } // Generate Windows import libs. if (target.os.tag == .windows) { diff --git a/src/link.zig b/src/link.zig index a85969d61eb7bf6d9f30f79c4caabe00e2dc1737..b46ea51013b7957684bf8d9d8e650dbac0d2fce9 100644 --- a/src/link.zig +++ b/src/link.zig @@ -175,6 +175,12 @@ pub const Options = struct { lib_dirs: []const []const u8, rpath_list: []const []const u8, + /// List of symbols forced as undefined in the symbol table + /// thus forcing their resolution by the linker. + /// Corresponds to `-u ` for ELF and `/include:` for COFF/PE. + /// TODO add handling for MachO. + force_undefined_symbols: std.StringArrayHashMapUnmanaged(void), + version: ?std.builtin.Version, compatibility_version: ?std.builtin.Version, libc_installation: ?*const LibCInstallation, diff --git a/src/link/Coff.zig b/src/link/Coff.zig index 6536fbd1ace38753f65630f0f07bd7f436ed04f0..c30544d3b7c7296dfdbf86c192fb5707c9b2f11f 100644 --- a/src/link/Coff.zig +++ b/src/link/Coff.zig @@ -1133,6 +1133,10 @@ fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Node) ! } } + for (self.base.options.force_undefined_symbols.keys()) |symbol| { + try argv.append(try allocPrint(arena, "-INCLUDE:{s}", .{symbol})); + } + if (is_dyn_lib) { try argv.append("-DLL"); } diff --git a/src/link/Elf.zig b/src/link/Elf.zig index ade4f62f91e21e2a1e8fd366316f9f6496089418..293771dd2a8fcc83fc889f66b83e7b0729788a4b 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -1448,6 +1448,11 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v try argv.append(entry); } + for (self.base.options.force_undefined_symbols.keys()) |symbol| { + try argv.append("-u"); + try argv.append(symbol); + } + switch (self.base.options.hash_style) { .gnu => try argv.append("--hash-style=gnu"), .sysv => try argv.append("--hash-style=sysv"), diff --git a/src/mingw.zig b/src/mingw.zig index e99a1af8fc6b5a72b5b4693fea629929275916df..b50cc4b00994b102853e3d1f4c7c128f53e95bff 100644 --- a/src/mingw.zig +++ b/src/mingw.zig @@ -93,12 +93,6 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile) !void { "-D_WIN32_WINNT=0x0f00", "-D__MSVCRT_VERSION__=0x700", }); - if (std.mem.eql(u8, dep, "tlssup.c") and comp.bin_file.options.lto) { - // LLD will incorrectly drop the `_tls_index` symbol. Here we work - // around it by not using LTO for this one file. - // https://github.com/ziglang/zig/issues/8531 - try args.append("-fno-lto"); - } c_source_files[i] = .{ .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", "mingw", "crt", dep,