| author | |
| committer | |
| log | 30e254fc311875720466d9a2b19d06e5599cd8c1 |
| tree | e0ade21398e53abe485c50d274c9cf8b968c79f8 |
| parent | 5668c8b7babfdc00ace04feceb9bcf8b95681982 |
| signature |
This allows emitting object files for s390x-zos (GOFF) and powerpc(64)-aix
(XCOFF).
Note that GOFF emission in LLVM is still being worked on upstream for LLVM 21;
the resulting object files are useless right now. Also, -fstrip is required, or
LLVM will SIGSEGV during DWARF emission.5 files changed, 264 insertions(+), 6 deletions(-)
CMakeLists.txt+2| ... | @@ -612,6 +612,7 @@ set(ZIG_STAGE2_SOURCES | ... | @@ -612,6 +612,7 @@ set(ZIG_STAGE2_SOURCES |
| 612 | src/link/Elf/relocatable.zig | 612 | src/link/Elf/relocatable.zig |
| 613 | src/link/Elf/relocation.zig | 613 | src/link/Elf/relocation.zig |
| 614 | src/link/Elf/synthetic_sections.zig | 614 | src/link/Elf/synthetic_sections.zig |
| 615 | src/link/Goff.zig | ||
| 615 | src/link/LdScript.zig | 616 | src/link/LdScript.zig |
| 616 | src/link/MachO.zig | 617 | src/link/MachO.zig |
| 617 | src/link/MachO/Archive.zig | 618 | src/link/MachO/Archive.zig |
| ... | @@ -652,6 +653,7 @@ set(ZIG_STAGE2_SOURCES | ... | @@ -652,6 +653,7 @@ set(ZIG_STAGE2_SOURCES |
| 652 | src/link/Wasm/Archive.zig | 653 | src/link/Wasm/Archive.zig |
| 653 | src/link/Wasm/Flush.zig | 654 | src/link/Wasm/Flush.zig |
| 654 | src/link/Wasm/Object.zig | 655 | src/link/Wasm/Object.zig |
| 656 | src/link/Xcoff.zig | ||
| 655 | src/link/aarch64.zig | 657 | src/link/aarch64.zig |
| 656 | src/link/riscv.zig | 658 | src/link/riscv.zig |
| 657 | src/link/table_section.zig | 659 | src/link/table_section.zig |
src/dev.zig+4| ... | @@ -82,6 +82,8 @@ pub const Env = enum { | ... | @@ -82,6 +82,8 @@ pub const Env = enum { |
| 82 | .spirv_linker, | 82 | .spirv_linker, |
| 83 | .plan9_linker, | 83 | .plan9_linker, |
| 84 | .nvptx_linker, | 84 | .nvptx_linker, |
| 85 | .goff_linker, | ||
| 86 | .xcoff_linker, | ||
| 85 | => true, | 87 | => true, |
| 86 | .cc_command, | 88 | .cc_command, |
| 87 | .translate_c_command, | 89 | .translate_c_command, |
| ... | @@ -228,6 +230,8 @@ pub const Feature = enum { | ... | @@ -228,6 +230,8 @@ pub const Feature = enum { |
| 228 | spirv_linker, | 230 | spirv_linker, |
| 229 | plan9_linker, | 231 | plan9_linker, |
| 230 | nvptx_linker, | 232 | nvptx_linker, |
| 233 | goff_linker, | ||
| 234 | xcoff_linker, | ||
| 231 | }; | 235 | }; |
| 232 | 236 | ||
| 233 | /// Makes the code following the call to this function unreachable if `feature` is disabled. | 237 | /// Makes the code following the call to this function unreachable if `feature` is disabled. |
src/link.zig+18-6| ... | @@ -556,9 +556,9 @@ pub const File = struct { | ... | @@ -556,9 +556,9 @@ pub const File = struct { |
| 556 | const comp = base.comp; | 556 | const comp = base.comp; |
| 557 | const gpa = comp.gpa; | 557 | const gpa = comp.gpa; |
| 558 | switch (base.tag) { | 558 | switch (base.tag) { |
| 559 | .coff, .elf, .macho, .plan9, .wasm => { | 559 | .coff, .elf, .macho, .plan9, .wasm, .goff, .xcoff => { |
| 560 | if (base.file != null) return; | 560 | if (base.file != null) return; |
| 561 | dev.checkAny(&.{ .coff_linker, .elf_linker, .macho_linker, .plan9_linker, .wasm_linker }); | 561 | dev.checkAny(&.{ .coff_linker, .elf_linker, .macho_linker, .plan9_linker, .wasm_linker, .goff_linker, .xcoff_linker }); |
| 562 | const emit = base.emit; | 562 | const emit = base.emit; |
| 563 | if (base.child_pid) |pid| { | 563 | if (base.child_pid) |pid| { |
| 564 | if (builtin.os.tag == .windows) { | 564 | if (builtin.os.tag == .windows) { |
| ... | @@ -650,8 +650,8 @@ pub const File = struct { | ... | @@ -650,8 +650,8 @@ pub const File = struct { |
| 650 | } | 650 | } |
| 651 | } | 651 | } |
| 652 | }, | 652 | }, |
| 653 | .coff, .macho, .plan9, .wasm => if (base.file) |f| { | 653 | .coff, .macho, .plan9, .wasm, .goff, .xcoff => if (base.file) |f| { |
| 654 | dev.checkAny(&.{ .coff_linker, .macho_linker, .plan9_linker, .wasm_linker }); | 654 | dev.checkAny(&.{ .coff_linker, .macho_linker, .plan9_linker, .wasm_linker, .goff_linker, .xcoff_linker }); |
| 655 | if (base.zcu_object_sub_path != null) { | 655 | if (base.zcu_object_sub_path != null) { |
| 656 | // The file we have open is not the final file that we want to | 656 | // The file we have open is not the final file that we want to |
| 657 | // make executable, so we don't have to close it. | 657 | // make executable, so we don't have to close it. |
| ... | @@ -767,6 +767,7 @@ pub const File = struct { | ... | @@ -767,6 +767,7 @@ pub const File = struct { |
| 767 | 767 | ||
| 768 | switch (base.tag) { | 768 | switch (base.tag) { |
| 769 | .spirv, .nvptx => {}, | 769 | .spirv, .nvptx => {}, |
| 770 | .goff, .xcoff => {}, | ||
| 770 | inline else => |tag| { | 771 | inline else => |tag| { |
| 771 | dev.check(tag.devFeature()); | 772 | dev.check(tag.devFeature()); |
| 772 | return @as(*tag.Type(), @fieldParentPtr("base", base)).updateLineNumber(pt, ti_id); | 773 | return @as(*tag.Type(), @fieldParentPtr("base", base)).updateLineNumber(pt, ti_id); |
| ... | @@ -902,6 +903,7 @@ pub const File = struct { | ... | @@ -902,6 +903,7 @@ pub const File = struct { |
| 902 | .spirv => unreachable, | 903 | .spirv => unreachable, |
| 903 | .nvptx => unreachable, | 904 | .nvptx => unreachable, |
| 904 | .wasm => unreachable, | 905 | .wasm => unreachable, |
| 906 | .goff, .xcoff => unreachable, | ||
| 905 | inline else => |tag| { | 907 | inline else => |tag| { |
| 906 | dev.check(tag.devFeature()); | 908 | dev.check(tag.devFeature()); |
| 907 | return @as(*tag.Type(), @fieldParentPtr("base", base)).getNavVAddr(pt, nav_index, reloc_info); | 909 | return @as(*tag.Type(), @fieldParentPtr("base", base)).getNavVAddr(pt, nav_index, reloc_info); |
| ... | @@ -921,6 +923,7 @@ pub const File = struct { | ... | @@ -921,6 +923,7 @@ pub const File = struct { |
| 921 | .spirv => unreachable, | 923 | .spirv => unreachable, |
| 922 | .nvptx => unreachable, | 924 | .nvptx => unreachable, |
| 923 | .wasm => unreachable, | 925 | .wasm => unreachable, |
| 926 | .goff, .xcoff => unreachable, | ||
| 924 | inline else => |tag| { | 927 | inline else => |tag| { |
| 925 | dev.check(tag.devFeature()); | 928 | dev.check(tag.devFeature()); |
| 926 | return @as(*tag.Type(), @fieldParentPtr("base", base)).lowerUav(pt, decl_val, decl_align, src_loc); | 929 | return @as(*tag.Type(), @fieldParentPtr("base", base)).lowerUav(pt, decl_val, decl_align, src_loc); |
| ... | @@ -934,6 +937,7 @@ pub const File = struct { | ... | @@ -934,6 +937,7 @@ pub const File = struct { |
| 934 | .spirv => unreachable, | 937 | .spirv => unreachable, |
| 935 | .nvptx => unreachable, | 938 | .nvptx => unreachable, |
| 936 | .wasm => unreachable, | 939 | .wasm => unreachable, |
| 940 | .goff, .xcoff => unreachable, | ||
| 937 | inline else => |tag| { | 941 | inline else => |tag| { |
| 938 | dev.check(tag.devFeature()); | 942 | dev.check(tag.devFeature()); |
| 939 | return @as(*tag.Type(), @fieldParentPtr("base", base)).getUavVAddr(decl_val, reloc_info); | 943 | return @as(*tag.Type(), @fieldParentPtr("base", base)).getUavVAddr(decl_val, reloc_info); |
| ... | @@ -950,6 +954,8 @@ pub const File = struct { | ... | @@ -950,6 +954,8 @@ pub const File = struct { |
| 950 | .plan9, | 954 | .plan9, |
| 951 | .spirv, | 955 | .spirv, |
| 952 | .nvptx, | 956 | .nvptx, |
| 957 | .goff, | ||
| 958 | .xcoff, | ||
| 953 | => {}, | 959 | => {}, |
| 954 | 960 | ||
| 955 | inline else => |tag| { | 961 | inline else => |tag| { |
| ... | @@ -1246,6 +1252,8 @@ pub const File = struct { | ... | @@ -1246,6 +1252,8 @@ pub const File = struct { |
| 1246 | spirv, | 1252 | spirv, |
| 1247 | plan9, | 1253 | plan9, |
| 1248 | nvptx, | 1254 | nvptx, |
| 1255 | goff, | ||
| 1256 | xcoff, | ||
| 1249 | 1257 | ||
| 1250 | pub fn Type(comptime tag: Tag) type { | 1258 | pub fn Type(comptime tag: Tag) type { |
| 1251 | return switch (tag) { | 1259 | return switch (tag) { |
| ... | @@ -1257,6 +1265,8 @@ pub const File = struct { | ... | @@ -1257,6 +1265,8 @@ pub const File = struct { |
| 1257 | .spirv => SpirV, | 1265 | .spirv => SpirV, |
| 1258 | .plan9 => Plan9, | 1266 | .plan9 => Plan9, |
| 1259 | .nvptx => NvPtx, | 1267 | .nvptx => NvPtx, |
| 1268 | .goff => Goff, | ||
| 1269 | .xcoff => Xcoff, | ||
| 1260 | }; | 1270 | }; |
| 1261 | } | 1271 | } |
| 1262 | 1272 | ||
| ... | @@ -1270,8 +1280,8 @@ pub const File = struct { | ... | @@ -1270,8 +1280,8 @@ pub const File = struct { |
| 1270 | .c => .c, | 1280 | .c => .c, |
| 1271 | .spirv => .spirv, | 1281 | .spirv => .spirv, |
| 1272 | .nvptx => .nvptx, | 1282 | .nvptx => .nvptx, |
| 1273 | .goff => @panic("TODO implement goff object format"), | 1283 | .goff => .goff, |
| 1274 | .xcoff => @panic("TODO implement xcoff object format"), | 1284 | .xcoff => .xcoff, |
| 1275 | .hex => @panic("TODO implement hex object format"), | 1285 | .hex => @panic("TODO implement hex object format"), |
| 1276 | .raw => @panic("TODO implement raw object format"), | 1286 | .raw => @panic("TODO implement raw object format"), |
| 1277 | }; | 1287 | }; |
| ... | @@ -1377,6 +1387,8 @@ pub const File = struct { | ... | @@ -1377,6 +1387,8 @@ pub const File = struct { |
| 1377 | pub const SpirV = @import("link/SpirV.zig"); | 1387 | pub const SpirV = @import("link/SpirV.zig"); |
| 1378 | pub const Wasm = @import("link/Wasm.zig"); | 1388 | pub const Wasm = @import("link/Wasm.zig"); |
| 1379 | pub const NvPtx = @import("link/NvPtx.zig"); | 1389 | pub const NvPtx = @import("link/NvPtx.zig"); |
| 1390 | pub const Goff = @import("link/Goff.zig"); | ||
| 1391 | pub const Xcoff = @import("link/Xcoff.zig"); | ||
| 1380 | pub const Dwarf = @import("link/Dwarf.zig"); | 1392 | pub const Dwarf = @import("link/Dwarf.zig"); |
| 1381 | }; | 1393 | }; |
| 1382 | 1394 |
src/link/Goff.zig created+120| ... | @@ -0,0 +1,120 @@ | ||
| 1 | //! Stub linker support for GOFF based on LLVM. | ||
| 2 | |||
| 3 | const Goff = @This(); | ||
| 4 | |||
| 5 | const std = @import("std"); | ||
| 6 | const builtin = @import("builtin"); | ||
| 7 | |||
| 8 | const Allocator = std.mem.Allocator; | ||
| 9 | const assert = std.debug.assert; | ||
| 10 | const log = std.log.scoped(.link); | ||
| 11 | const Path = std.Build.Cache.Path; | ||
| 12 | |||
| 13 | const Zcu = @import("../Zcu.zig"); | ||
| 14 | const InternPool = @import("../InternPool.zig"); | ||
| 15 | const Compilation = @import("../Compilation.zig"); | ||
| 16 | const link = @import("../link.zig"); | ||
| 17 | const trace = @import("../tracy.zig").trace; | ||
| 18 | const build_options = @import("build_options"); | ||
| 19 | const Air = @import("../Air.zig"); | ||
| 20 | const Liveness = @import("../Liveness.zig"); | ||
| 21 | const LlvmObject = @import("../codegen/llvm.zig").Object; | ||
| 22 | |||
| 23 | base: link.File, | ||
| 24 | llvm_object: LlvmObject.Ptr, | ||
| 25 | |||
| 26 | pub fn createEmpty( | ||
| 27 | arena: Allocator, | ||
| 28 | comp: *Compilation, | ||
| 29 | emit: Path, | ||
| 30 | options: link.File.OpenOptions, | ||
| 31 | ) !*Goff { | ||
| 32 | const target = comp.root_mod.resolved_target.result; | ||
| 33 | const use_lld = build_options.have_llvm and comp.config.use_lld; | ||
| 34 | const use_llvm = comp.config.use_llvm; | ||
| 35 | |||
| 36 | assert(use_llvm); // Caught by Compilation.Config.resolve. | ||
| 37 | assert(!use_lld); // Caught by Compilation.Config.resolve. | ||
| 38 | assert(target.os.tag == .zos); // Caught by Compilation.Config.resolve. | ||
| 39 | |||
| 40 | const llvm_object = try LlvmObject.create(arena, comp); | ||
| 41 | const goff = try arena.create(Goff); | ||
| 42 | goff.* = .{ | ||
| 43 | .base = .{ | ||
| 44 | .tag = .goff, | ||
| 45 | .comp = comp, | ||
| 46 | .emit = emit, | ||
| 47 | .zcu_object_sub_path = emit.sub_path, | ||
| 48 | .gc_sections = options.gc_sections orelse false, | ||
| 49 | .print_gc_sections = options.print_gc_sections, | ||
| 50 | .stack_size = options.stack_size orelse 0, | ||
| 51 | .allow_shlib_undefined = options.allow_shlib_undefined orelse false, | ||
| 52 | .file = null, | ||
| 53 | .disable_lld_caching = options.disable_lld_caching, | ||
| 54 | .build_id = options.build_id, | ||
| 55 | }, | ||
| 56 | .llvm_object = llvm_object, | ||
| 57 | }; | ||
| 58 | |||
| 59 | return goff; | ||
| 60 | } | ||
| 61 | |||
| 62 | pub fn open( | ||
| 63 | arena: Allocator, | ||
| 64 | comp: *Compilation, | ||
| 65 | emit: Path, | ||
| 66 | options: link.File.OpenOptions, | ||
| 67 | ) !*Goff { | ||
| 68 | const target = comp.root_mod.resolved_target.result; | ||
| 69 | assert(target.ofmt == .goff); | ||
| 70 | return createEmpty(arena, comp, emit, options); | ||
| 71 | } | ||
| 72 | |||
| 73 | pub fn deinit(self: *Goff) void { | ||
| 74 | self.llvm_object.deinit(); | ||
| 75 | } | ||
| 76 | |||
| 77 | pub fn updateFunc( | ||
| 78 | self: *Goff, | ||
| 79 | pt: Zcu.PerThread, | ||
| 80 | func_index: InternPool.Index, | ||
| 81 | air: Air, | ||
| 82 | liveness: Liveness, | ||
| 83 | ) link.File.UpdateNavError!void { | ||
| 84 | if (build_options.skip_non_native and builtin.object_format != .goff) | ||
| 85 | @panic("Attempted to compile for object format that was disabled by build configuration"); | ||
| 86 | |||
| 87 | try self.llvm_object.updateFunc(pt, func_index, air, liveness); | ||
| 88 | } | ||
| 89 | |||
| 90 | pub fn updateNav(self: *Goff, pt: Zcu.PerThread, nav: InternPool.Nav.Index) link.File.UpdateNavError!void { | ||
| 91 | if (build_options.skip_non_native and builtin.object_format != .goff) | ||
| 92 | @panic("Attempted to compile for object format that was disabled by build configuration"); | ||
| 93 | |||
| 94 | return self.llvm_object.updateNav(pt, nav); | ||
| 95 | } | ||
| 96 | |||
| 97 | pub fn updateExports( | ||
| 98 | self: *Goff, | ||
| 99 | pt: Zcu.PerThread, | ||
| 100 | exported: Zcu.Exported, | ||
| 101 | export_indices: []const Zcu.Export.Index, | ||
| 102 | ) !void { | ||
| 103 | if (build_options.skip_non_native and builtin.object_format != .goff) | ||
| 104 | @panic("Attempted to compile for object format that was disabled by build configuration"); | ||
| 105 | |||
| 106 | return self.llvm_object.updateExports(pt, exported, export_indices); | ||
| 107 | } | ||
| 108 | |||
| 109 | pub fn flush(self: *Goff, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void { | ||
| 110 | return self.flushModule(arena, tid, prog_node); | ||
| 111 | } | ||
| 112 | |||
| 113 | pub fn flushModule(self: *Goff, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void { | ||
| 114 | if (build_options.skip_non_native and builtin.object_format != .goff) | ||
| 115 | @panic("Attempted to compile for object format that was disabled by build configuration"); | ||
| 116 | |||
| 117 | _ = tid; | ||
| 118 | |||
| 119 | try self.base.emitLlvmObject(arena, self.llvm_object, prog_node); | ||
| 120 | } | ||
src/link/Xcoff.zig created+120| ... | @@ -0,0 +1,120 @@ | ||
| 1 | //! Stub linker support for GOFF based on LLVM. | ||
| 2 | |||
| 3 | const Xcoff = @This(); | ||
| 4 | |||
| 5 | const std = @import("std"); | ||
| 6 | const builtin = @import("builtin"); | ||
| 7 | |||
| 8 | const Allocator = std.mem.Allocator; | ||
| 9 | const assert = std.debug.assert; | ||
| 10 | const log = std.log.scoped(.link); | ||
| 11 | const Path = std.Build.Cache.Path; | ||
| 12 | |||
| 13 | const Zcu = @import("../Zcu.zig"); | ||
| 14 | const InternPool = @import("../InternPool.zig"); | ||
| 15 | const Compilation = @import("../Compilation.zig"); | ||
| 16 | const link = @import("../link.zig"); | ||
| 17 | const trace = @import("../tracy.zig").trace; | ||
| 18 | const build_options = @import("build_options"); | ||
| 19 | const Air = @import("../Air.zig"); | ||
| 20 | const Liveness = @import("../Liveness.zig"); | ||
| 21 | const LlvmObject = @import("../codegen/llvm.zig").Object; | ||
| 22 | |||
| 23 | base: link.File, | ||
| 24 | llvm_object: LlvmObject.Ptr, | ||
| 25 | |||
| 26 | pub fn createEmpty( | ||
| 27 | arena: Allocator, | ||
| 28 | comp: *Compilation, | ||
| 29 | emit: Path, | ||
| 30 | options: link.File.OpenOptions, | ||
| 31 | ) !*Xcoff { | ||
| 32 | const target = comp.root_mod.resolved_target.result; | ||
| 33 | const use_lld = build_options.have_llvm and comp.config.use_lld; | ||
| 34 | const use_llvm = comp.config.use_llvm; | ||
| 35 | |||
| 36 | assert(use_llvm); // Caught by Compilation.Config.resolve. | ||
| 37 | assert(!use_lld); // Caught by Compilation.Config.resolve. | ||
| 38 | assert(target.os.tag == .aix); // Caught by Compilation.Config.resolve. | ||
| 39 | |||
| 40 | const llvm_object = try LlvmObject.create(arena, comp); | ||
| 41 | const xcoff = try arena.create(Xcoff); | ||
| 42 | xcoff.* = .{ | ||
| 43 | .base = .{ | ||
| 44 | .tag = .xcoff, | ||
| 45 | .comp = comp, | ||
| 46 | .emit = emit, | ||
| 47 | .zcu_object_sub_path = emit.sub_path, | ||
| 48 | .gc_sections = options.gc_sections orelse false, | ||
| 49 | .print_gc_sections = options.print_gc_sections, | ||
| 50 | .stack_size = options.stack_size orelse 0, | ||
| 51 | .allow_shlib_undefined = options.allow_shlib_undefined orelse false, | ||
| 52 | .file = null, | ||
| 53 | .disable_lld_caching = options.disable_lld_caching, | ||
| 54 | .build_id = options.build_id, | ||
| 55 | }, | ||
| 56 | .llvm_object = llvm_object, | ||
| 57 | }; | ||
| 58 | |||
| 59 | return xcoff; | ||
| 60 | } | ||
| 61 | |||
| 62 | pub fn open( | ||
| 63 | arena: Allocator, | ||
| 64 | comp: *Compilation, | ||
| 65 | emit: Path, | ||
| 66 | options: link.File.OpenOptions, | ||
| 67 | ) !*Xcoff { | ||
| 68 | const target = comp.root_mod.resolved_target.result; | ||
| 69 | assert(target.ofmt == .xcoff); | ||
| 70 | return createEmpty(arena, comp, emit, options); | ||
| 71 | } | ||
| 72 | |||
| 73 | pub fn deinit(self: *Xcoff) void { | ||
| 74 | self.llvm_object.deinit(); | ||
| 75 | } | ||
| 76 | |||
| 77 | pub fn updateFunc( | ||
| 78 | self: *Xcoff, | ||
| 79 | pt: Zcu.PerThread, | ||
| 80 | func_index: InternPool.Index, | ||
| 81 | air: Air, | ||
| 82 | liveness: Liveness, | ||
| 83 | ) link.File.UpdateNavError!void { | ||
| 84 | if (build_options.skip_non_native and builtin.object_format != .xcoff) | ||
| 85 | @panic("Attempted to compile for object format that was disabled by build configuration"); | ||
| 86 | |||
| 87 | try self.llvm_object.updateFunc(pt, func_index, air, liveness); | ||
| 88 | } | ||
| 89 | |||
| 90 | pub fn updateNav(self: *Xcoff, pt: Zcu.PerThread, nav: InternPool.Nav.Index) link.File.UpdateNavError!void { | ||
| 91 | if (build_options.skip_non_native and builtin.object_format != .xcoff) | ||
| 92 | @panic("Attempted to compile for object format that was disabled by build configuration"); | ||
| 93 | |||
| 94 | return self.llvm_object.updateNav(pt, nav); | ||
| 95 | } | ||
| 96 | |||
| 97 | pub fn updateExports( | ||
| 98 | self: *Xcoff, | ||
| 99 | pt: Zcu.PerThread, | ||
| 100 | exported: Zcu.Exported, | ||
| 101 | export_indices: []const Zcu.Export.Index, | ||
| 102 | ) !void { | ||
| 103 | if (build_options.skip_non_native and builtin.object_format != .xcoff) | ||
| 104 | @panic("Attempted to compile for object format that was disabled by build configuration"); | ||
| 105 | |||
| 106 | return self.llvm_object.updateExports(pt, exported, export_indices); | ||
| 107 | } | ||
| 108 | |||
| 109 | pub fn flush(self: *Xcoff, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void { | ||
| 110 | return self.flushModule(arena, tid, prog_node); | ||
| 111 | } | ||
| 112 | |||
| 113 | pub fn flushModule(self: *Xcoff, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void { | ||
| 114 | if (build_options.skip_non_native and builtin.object_format != .xcoff) | ||
| 115 | @panic("Attempted to compile for object format that was disabled by build configuration"); | ||
| 116 | |||
| 117 | _ = tid; | ||
| 118 | |||
| 119 | try self.base.emitLlvmObject(arena, self.llvm_object, prog_node); | ||
| 120 | } | ||