From 06879041acfe73e62f549a412d9f012a190113a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Wed, 4 Feb 2026 00:00:06 +0100 Subject: [PATCH] link.Lld: disable parallel linking on NetBSD host To work around NetBSD 10.1 malloc bugs. --- src/link/Lld.zig | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/link/Lld.zig b/src/link/Lld.zig index fa94e534593a81c853c85911bf7054af03b65eab..5c7ba84623bde145063b4ff87b08434840ec43d9 100644 --- a/src/link/Lld.zig +++ b/src/link/Lld.zig @@ -356,6 +356,16 @@ fn linkAsArchive(lld: *Lld, arena: Allocator) !void { if (bad) return error.UnableToWriteArchive; } +fn addCommonArgs(argv: *std.array_list.Managed([]const u8), coff: bool) !void { + if (builtin.os.tag == .netbsd) { + // NetBSD 10.1's `malloc` appears to have some nasty bugs that occur + // when doing parallel linking in LLD, manifesting as input and/or + // output section memory randomly being unmapped. So just don't do + // parallel linking for now. + try argv.append(if (coff) "-threads:1" else "--threads=1"); + } +} + fn coffLink(lld: *Lld, arena: Allocator) !void { const comp = lld.base.comp; const gpa = comp.gpa; @@ -418,6 +428,7 @@ fn coffLink(lld: *Lld, arena: Allocator) !void { // it calls exit() and does not reset all global data between invocations. const linker_command = "lld-link"; try argv.appendSlice(&[_][]const u8{ comp.self_exe_path.?, linker_command }); + try addCommonArgs(&argv, true); if (target.isMinGW()) { try argv.append("-lldmingw"); @@ -836,6 +847,8 @@ fn elfLink(lld: *Lld, arena: Allocator) !void { // it calls exit() and does not reset all global data between invocations. const linker_command = "ld.lld"; try argv.appendSlice(&[_][]const u8{ comp.self_exe_path.?, linker_command }); + try addCommonArgs(&argv, false); + if (is_obj) { try argv.append("-r"); } @@ -1401,6 +1414,8 @@ fn wasmLink(lld: *Lld, arena: Allocator) !void { // it calls exit() and does not reset all global data between invocations. const linker_command = "wasm-ld"; try argv.appendSlice(&[_][]const u8{ comp.self_exe_path.?, linker_command }); + try addCommonArgs(&argv, false); + try argv.append("--error-limit=0"); if (comp.config.lto != .none) { @@ -1724,6 +1739,7 @@ fn spawnLld(comp: *Compilation, arena: Allocator, argv: []const []const u8) !voi if (stderr.len > 0) log.warn("unexpected LLD stderr:\n{s}", .{stderr}); } +const builtin = @import("builtin"); const std = @import("std"); const Io = std.Io; const Allocator = std.mem.Allocator; -- 2.54.0