From e25015bdce1e6ff4ab594a34fc7d1f0cd296dc25 Mon Sep 17 00:00:00 2001 From: "Marcel W. Wysocki" Date: Sun, 15 Feb 2026 23:47:07 +0800 Subject: [PATCH] cc: add --wrap=, --nmagic, --fatal-warnings, and -m linker args Needed for linking the Linux kernel. --- src/Compilation.zig | 4 ++++ src/link.zig | 2 ++ src/link/Lld.zig | 12 ++++++++++++ src/main.zig | 17 ++++++++++++++++- 4 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src/Compilation.zig b/src/Compilation.zig index c79afb0923996fb4c41afb1d42fe80809149d130..09a52629200253620e34890507178530d6bef6dc 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -1485,6 +1485,8 @@ pub const CreateOptions = struct { linker_print_gc_sections: bool = false, linker_print_icf_sections: bool = false, linker_print_map: bool = false, + linker_nmagic: bool = false, + linker_fatal_warnings: bool = false, llvm_opt_bisect_limit: i32 = -1, build_id: ?std.zig.BuildId = null, disable_c_depfile: bool = false, @@ -2188,6 +2190,8 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic, .print_gc_sections = options.linker_print_gc_sections, .print_icf_sections = options.linker_print_icf_sections, .print_map = options.linker_print_map, + .nmagic = options.linker_nmagic, + .fatal_warnings = options.linker_fatal_warnings, .tsaware = options.linker_tsaware, .nxcompat = options.linker_nxcompat, .dynamicbase = options.linker_dynamicbase, diff --git a/src/link.zig b/src/link.zig index 04f642e4f988ba9147a04152f407cb1a5a47a315..2917b6b7e59618f2adfde27b273d5b4cd19d0f92 100644 --- a/src/link.zig +++ b/src/link.zig @@ -466,6 +466,8 @@ pub const File = struct { print_gc_sections: bool, print_icf_sections: bool, print_map: bool, + nmagic: bool, + fatal_warnings: bool, /// Use a wrapper function for symbol. Any undefined reference to symbol /// will be resolved to __wrap_symbol. Any undefined reference to diff --git a/src/link/Lld.zig b/src/link/Lld.zig index 894e21785c1ff5c5a969a12acff6538c8a752e12..1ac882f2d95cfed859cafc44d6096eaa05c008a8 100644 --- a/src/link/Lld.zig +++ b/src/link/Lld.zig @@ -80,6 +80,8 @@ pub const Elf = struct { sort_section: ?SortSection, print_icf_sections: bool, print_map: bool, + nmagic: bool, + fatal_warnings: bool, emit_relocs: bool, z_nodelete: bool, z_notext: bool, @@ -135,6 +137,8 @@ pub const Elf = struct { .sort_section = options.sort_section, .print_icf_sections = options.print_icf_sections, .print_map = options.print_map, + .nmagic = options.nmagic, + .fatal_warnings = options.fatal_warnings, .emit_relocs = options.emit_relocs, .z_nodelete = options.z_nodelete, .z_notext = options.z_notext, @@ -947,6 +951,14 @@ fn elfLink(lld: *Lld, arena: Allocator) !void { try argv.append("--print-map"); } + if (elf.nmagic) { + try argv.append("--nmagic"); + } + + if (elf.fatal_warnings) { + try argv.append("--fatal-warnings"); + } + if (comp.link_eh_frame_hdr) { try argv.append("--eh-frame-hdr"); } diff --git a/src/main.zig b/src/main.zig index c577bf1079e218b0ae2a2ca281f89001f1d4e52f..f57371bf05e6ddd60185e0d2ad7a6e300ae70fb4 100644 --- a/src/main.zig +++ b/src/main.zig @@ -991,6 +991,8 @@ fn buildOutputType( var linker_print_gc_sections: bool = false; var linker_print_icf_sections: bool = false; var linker_print_map: bool = false; + var linker_nmagic: bool = false; + var linker_fatal_warnings: bool = false; var llvm_opt_bisect_limit: c_int = -1; var linker_z_nocopyreloc = false; var linker_z_nodelete = false; @@ -2676,6 +2678,15 @@ fn buildOutputType( linker_print_icf_sections = true; } else if (mem.eql(u8, arg, "--print-map")) { linker_print_map = true; + } else if (mem.eql(u8, arg, "-n") or mem.eql(u8, arg, "--nmagic")) { + linker_nmagic = true; + } else if (mem.eql(u8, arg, "--fatal-warnings")) { + linker_fatal_warnings = true; + } else if (mem.eql(u8, arg, "--no-fatal-warnings")) { + linker_fatal_warnings = false; + } else if (mem.eql(u8, arg, "-m")) { + _ = linker_args_it.nextOrFatal(); + warn("-m option is ignored; emulation is derived from target", .{}); } else if (mem.eql(u8, arg, "--sort-section")) { const arg1 = linker_args_it.nextOrFatal(); linker_sort_section = stringToEnum(link.File.Lld.Elf.SortSection, arg1) orelse { @@ -2948,9 +2959,11 @@ fn buildOutputType( hash_style = stringToEnum(link.File.Lld.Elf.HashStyle, next_arg) orelse { fatal("expected [sysv|gnu|both] after --hash-style, found {q}", .{next_arg}); }; - } else if (mem.eql(u8, arg, "-wrap")) { + } else if (mem.eql(u8, arg, "-wrap") or mem.eql(u8, arg, "--wrap")) { const next_arg = linker_args_it.nextOrFatal(); try symbol_wrap_set.put(arena, next_arg, {}); + } else if (mem.cutPrefix(u8, arg, "--wrap=")) |symbol| { + try symbol_wrap_set.put(arena, symbol, {}); } else if (mem.startsWith(u8, arg, "/subsystem:")) { var split_it = mem.splitBackwardsScalar(u8, arg, ':'); subsystem = try parseSubsystem(split_it.first()); @@ -3666,6 +3679,8 @@ fn buildOutputType( .linker_print_gc_sections = linker_print_gc_sections, .linker_print_icf_sections = linker_print_icf_sections, .linker_print_map = linker_print_map, + .linker_nmagic = linker_nmagic, + .linker_fatal_warnings = linker_fatal_warnings, .llvm_opt_bisect_limit = llvm_opt_bisect_limit, .linker_global_base = linker_global_base, .linker_export_symbol_names = linker_export_symbol_names.items, -- 2.54.0