| ... | ... | @@ -16,6 +16,7 @@ const link = @import("../link.zig"); |
| 16 | 16 | const build_options = @import("build_options"); |
| 17 | 17 | const Cache = @import("../Cache.zig"); |
| 18 | 18 | const mingw = @import("../mingw.zig"); |
| 19 | const llvm_backend = @import("../llvm_backend.zig"); |
| 19 | 20 | |
| 20 | 21 | const allocation_padding = 4 / 3; |
| 21 | 22 | const minimum_text_block_size = 64 * allocation_padding; |
| ... | ... | @@ -32,6 +33,9 @@ pub const base_tag: link.File.Tag = .coff; |
| 32 | 33 | |
| 33 | 34 | const msdos_stub = @embedFile("msdos-stub.bin"); |
| 34 | 35 | |
| 36 | /// If this is not null, an object file is created by LLVM and linked with LLD afterwards. |
| 37 | llvm_ir_module: ?*llvm_backend.LLVMIRModule = null, |
| 38 | |
| 35 | 39 | base: link.File, |
| 36 | 40 | ptr_width: PtrWidth, |
| 37 | 41 | error_flags: link.File.ErrorFlags = .{}, |
| ... | ... | @@ -121,8 +125,13 @@ pub const SrcFn = void; |
| 121 | 125 | pub fn openPath(allocator: *Allocator, sub_path: []const u8, options: link.Options) !*Coff { |
| 122 | 126 | assert(options.object_format == .coff); |
| 123 | 127 | |
| 124 | | if (options.use_llvm) return error.LLVM_BackendIsTODO_ForCoff; // TODO |
| 125 | | if (options.use_lld) return error.LLD_LinkingIsTODO_ForCoff; // TODO |
| 128 | if (options.use_llvm) { |
| 129 | const self = try createEmpty(allocator, options); |
| 130 | errdefer self.base.destroy(); |
| 131 | |
| 132 | self.llvm_ir_module = try llvm_backend.LLVMIRModule.create(allocator, sub_path, options); |
| 133 | return self; |
| 134 | } |
| 126 | 135 | |
| 127 | 136 | const file = try options.emit.?.directory.handle.createFile(sub_path, .{ |
| 128 | 137 | .truncate = false, |
| ... | ... | @@ -648,6 +657,11 @@ pub fn updateDecl(self: *Coff, module: *Module, decl: *Module.Decl) !void { |
| 648 | 657 | const tracy = trace(@src()); |
| 649 | 658 | defer tracy.end(); |
| 650 | 659 | |
| 660 | if (self.llvm_ir_module) |llvm_ir_module| { |
| 661 | try llvm_ir_module.updateDecl(module, decl); |
| 662 | return; |
| 663 | } |
| 664 | |
| 651 | 665 | var code_buffer = std.ArrayList(u8).init(self.base.allocator); |
| 652 | 666 | defer code_buffer.deinit(); |
| 653 | 667 | |
| ... | ... | @@ -704,6 +718,8 @@ pub fn freeDecl(self: *Coff, decl: *Module.Decl) void { |
| 704 | 718 | } |
| 705 | 719 | |
| 706 | 720 | pub fn updateDeclExports(self: *Coff, module: *Module, decl: *const Module.Decl, exports: []const *Module.Export) !void { |
| 721 | if (self.llvm_ir_module) |_| return; |
| 722 | |
| 707 | 723 | for (exports) |exp| { |
| 708 | 724 | if (exp.options.section) |section_name| { |
| 709 | 725 | if (!mem.eql(u8, section_name, ".text")) { |
| ... | ... | @@ -744,6 +760,11 @@ pub fn flushModule(self: *Coff, comp: *Compilation) !void { |
| 744 | 760 | const tracy = trace(@src()); |
| 745 | 761 | defer tracy.end(); |
| 746 | 762 | |
| 763 | if (self.llvm_ir_module) |llvm_ir_module| { |
| 764 | try llvm_ir_module.flushModule(comp); |
| 765 | return; |
| 766 | } |
| 767 | |
| 747 | 768 | if (self.text_section_size_dirty) { |
| 748 | 769 | // Write the new raw size in the .text header |
| 749 | 770 | var buf: [4]u8 = undefined; |
| ... | ... | @@ -1124,8 +1145,9 @@ fn linkWithLLD(self: *Coff, comp: *Compilation) !void { |
| 1124 | 1145 | try argv.append(comp.libunwind_static_lib.?.full_object_path); |
| 1125 | 1146 | } |
| 1126 | 1147 | |
| 1148 | // TODO: remove when stage2 can build compiler_rt.zig, c.zig and ssp.zig |
| 1127 | 1149 | // compiler-rt, libc and libssp |
| 1128 | | if (is_exe_or_dyn_lib and !self.base.options.skip_linker_dependencies) { |
| 1150 | if (is_exe_or_dyn_lib and !self.base.options.skip_linker_dependencies and build_options.is_stage1) { |
| 1129 | 1151 | if (!self.base.options.link_libc) { |
| 1130 | 1152 | try argv.append(comp.libc_static_lib.?.full_object_path); |
| 1131 | 1153 | } |
| ... | ... | @@ -1235,6 +1257,7 @@ pub fn updateDeclLineNumber(self: *Coff, module: *Module, decl: *Module.Decl) !v |
| 1235 | 1257 | } |
| 1236 | 1258 | |
| 1237 | 1259 | pub fn deinit(self: *Coff) void { |
| 1260 | if (self.llvm_ir_module) |ir_module| ir_module.deinit(self.base.allocator); |
| 1238 | 1261 | self.text_block_free_list.deinit(self.base.allocator); |
| 1239 | 1262 | self.offset_table.deinit(self.base.allocator); |
| 1240 | 1263 | self.offset_table_free_list.deinit(self.base.allocator); |