diff --git a/lib/std/target.zig b/lib/std/target.zig index 3113159995..8a7fb923de 100644 --- a/lib/std/target.zig +++ b/lib/std/target.zig @@ -895,6 +895,13 @@ pub const Target = struct { }; } + pub fn isBpf(arch: Arch) bool { + return switch (arch) { + .bpfel, .bpfeb => true, + else => false, + }; + } + pub fn parseCpuModel(arch: Arch, cpu_name: []const u8) !*const Cpu.Model { for (arch.allCpuModels()) |cpu| { if (mem.eql(u8, cpu_name, cpu.name)) { @@ -1421,6 +1428,10 @@ pub const Target = struct { return self.os.tag.isBSD(); } + pub fn isBpfFreestanding(self: Target) bool { + return self.cpu.arch.isBpf() and self.os.tag == .freestanding; + } + pub fn isGnuLibC_os_tag_abi(os_tag: Os.Tag, abi: Abi) bool { return os_tag == .linux and abi.isGnu(); } diff --git a/src/link.zig b/src/link.zig index f4c51c735f..38b91c9e39 100644 --- a/src/link.zig +++ b/src/link.zig @@ -531,6 +531,7 @@ pub const File = struct { try fs.cwd().copyFile(cached_pp_file_path, fs.cwd(), full_out_path, .{}); return; } + const use_lld = build_options.have_llvm and base.options.use_lld; if (use_lld and base.options.output_mode == .Lib and base.options.link_mode == .Static) { return base.linkAsArchive(comp); diff --git a/src/link/Elf.zig b/src/link/Elf.zig index 646a568684..e96d776d2a 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -1381,7 +1381,11 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { } const full_out_path = try directory.join(arena, &[_][]const u8{self.base.options.emit.?.sub_path}); - if (self.base.options.output_mode == .Obj and self.base.options.lto) { + + // Due to a deficiency in LLD, we need to special-case BPF to a simple file copy when generating + // relocatables. Normally, we would expect `lld -r` to work. However, because LLD wants to resolve + // BPF relocations which it shouldn't, it fails before even generating the relocatable. + if (self.base.options.output_mode == .Obj and (self.base.options.lto or target.isBpfFreestanding())) { // In this case we must do a simple file copy // here. TODO: think carefully about how we can avoid this redundant operation when doing // build-obj. See also the corresponding TODO in linkAsArchive.