Skip to content

x86_64: linking libc panics with TODO unhandled compression scheme #24954

@neoto

Description

@neoto

Zig Version

0.16.0-dev.9+8248597a2

Steps to Reproduce and Observed Behavior

me@gekai ~> uname -rom
6.15.6-321.current x86_64 GNU/Linux
me@gekai ~> cat /etc/os-release
NAME="Solus"
VERSION="4.7"
ID="solus"
VERSION_CODENAME=endurance
VERSION_ID="4.7"
PRETTY_NAME="Solus 4.7 Endurance"
// main.zig
pub fn main() void {}
// build.zig
const std = @import("std");

pub fn build(b: *std.Build) void {
    const target = b.standardTargetOptions(.{});
    const optimize = b.standardOptimizeOption(.{});

    const exe = b.addExecutable(.{
        .name = "test",
        .root_module = b.createModule(.{
            .root_source_file = b.path("src/main.zig"),
            .target = target,
            .optimize = optimize,
            .link_libc = true,
        }),
        // .use_llvm = true, // works when using LLVM
    });

    b.installArtifact(exe);
}
me@gekai ~/N/d/p/z/test> zig build
install
└─ install test
   └─ compile exe test Debug native failure
error: thread 165492 panic: TODO unhandled compression scheme
Unable to dump stack trace: debug info stripped

Expected Behavior

Build succeeds without any issues.

Notes:

  • using LLVM instead of the x86_64 backend works fine
  • in an attempt to debug this, I went down the rabbit hole of compiling LLVM and Zig from scratch because Solus has an older version of the LLVM toolchain, but that, funnily enough, also failed at the linking step. Interestingly, this didn't happen when using CachyOS (?)
  • I discovered that chdr.ch_type here equals ZSTD in my case
  • applying the following diff (adapted from the ZLIB one) resolves the issue
--- a/src/link/Elf/Object.zig
+++ b/src/link/Elf/Object.zig
@@ -1207,6 +1207,17 @@ pub fn codeDecompressAlloc(self: *Object, elf_file: *Elf, atom_index: Atom.Index
                 _ = try zlib_stream.reader.streamRemaining(&aw.writer);
                 return aw.toOwnedSlice();
             },
+            .ZSTD => {
+                var reader: std.Io.Reader = .fixed(data[@sizeOf(elf.Elf64_Chdr)..]);
+                var stream: std.compress.zstd.Decompress = .init(&reader, &.{}, .{});
+                const size = std.math.cast(usize, chdr.ch_size) orelse return error.Overflow;
+                var aw: std.Io.Writer.Allocating = .init(gpa);
+                defer aw.deinit();
+                try aw.ensureUnusedCapacity(size);
+                _ = try stream.reader.streamRemaining(&aw.writer);
+
+                return aw.toOwnedSlice();
+            },
             else => @panic("TODO unhandled compression scheme"),
         }
     }

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugObserved behavior contradicts documented or intended behavior

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions