Commit d6f43a1eac

Jakub Konka <kubkon@jakubkonka.com>
2021-11-26 10:46:40
bpf: do not invoke lld when linking eBPF relocatables
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. Co-authored-by: Matthew Knight <mattnite@protonmail.com>
1 parent a96b6ad
Changed files (3)
lib
src
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();
     }
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.
src/link.zig
@@ -532,9 +532,6 @@ pub const File = struct {
             return;
         }
 
-        if (base.options.output_mode == .Obj)
-            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);