From 1edcea9ec80d9ca6fd9700ef605cfa9c3722817b Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 24 Dec 2023 19:48:01 -0700 Subject: [PATCH] link.Wasm: fix relationship between createEmpty/open --- src/link/Wasm.zig | 108 +++++++++++++++++++++++----------------------- 1 file changed, 55 insertions(+), 53 deletions(-) diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig index cf41110307..edc4ada405 100644 --- a/src/link/Wasm.zig +++ b/src/link/Wasm.zig @@ -377,6 +377,17 @@ pub fn open( comp: *Compilation, emit: Compilation.Emit, options: link.File.OpenOptions, +) !*Wasm { + // TODO: restore saved linker state, don't truncate the file, and + // participate in incremental compilation. + return createEmpty(arena, comp, emit, options); +} + +pub fn createEmpty( + arena: Allocator, + comp: *Compilation, + emit: Compilation.Emit, + options: link.File.OpenOptions, ) !*Wasm { const gpa = comp.gpa; const target = comp.root_mod.resolved_target.result; @@ -387,7 +398,46 @@ pub fn open( const output_mode = comp.config.output_mode; const shared_memory = comp.config.shared_memory; - const wasm = try createEmpty(arena, comp, emit, options); + // If using LLD to link, this code should produce an object file so that it + // can be passed to LLD. + // If using LLVM to generate the object file for the zig compilation unit, + // we need a place to put the object file so that it can be subsequently + // handled. + const zcu_object_sub_path = if (!use_lld and !use_llvm) + null + else + try std.fmt.allocPrint(arena, "{s}.o", .{emit.sub_path}); + + const wasm = try arena.create(Wasm); + wasm.* = .{ + .base = .{ + .tag = .wasm, + .comp = comp, + .emit = emit, + .zcu_object_sub_path = zcu_object_sub_path, + .gc_sections = options.gc_sections orelse (output_mode != .Obj), + .print_gc_sections = options.print_gc_sections, + .stack_size = options.stack_size orelse std.wasm.page_size * 16, // 1MB + .allow_shlib_undefined = options.allow_shlib_undefined orelse false, + .file = null, + .disable_lld_caching = options.disable_lld_caching, + .build_id = options.build_id, + .rpath_list = options.rpath_list, + .force_undefined_symbols = options.force_undefined_symbols, + }, + .name = undefined, + .import_table = options.import_table, + .export_table = options.export_table, + .import_symbols = options.import_symbols, + .export_symbol_names = options.export_symbol_names, + .global_base = options.global_base, + .initial_memory = options.initial_memory, + .max_memory = options.max_memory, + .wasi_emulated_libs = options.wasi_emulated_libs, + }; + if (use_llvm and comp.config.have_zcu) { + wasm.llvm_object = try LlvmObject.create(arena, comp); + } errdefer wasm.base.destroy(); if (use_lld and use_llvm) { @@ -395,17 +445,11 @@ pub fn open( return wasm; } - const sub_path = if (!use_lld) emit.sub_path else p: { - // Open a temporary object file, not the final output file because we - // want to link with LLD. - const o_file_path = try std.fmt.allocPrint(arena, "{s}{s}", .{ - emit.sub_path, target.ofmt.fileExt(target.cpu.arch), - }); - wasm.base.zcu_object_sub_path = o_file_path; - break :p o_file_path; - }; + // What path should this Wasm linker code output to? + // If using LLD to link, this code should produce an object file so that it + // can be passed to LLD. + const sub_path = if (use_lld) zcu_object_sub_path.? else emit.sub_path; - // TODO: read the file and keep valid parts instead of truncating const file = try emit.directory.handle.createFile(sub_path, .{ .truncate = true, .read = true, @@ -532,48 +576,6 @@ pub fn open( return wasm; } -pub fn createEmpty( - arena: Allocator, - comp: *Compilation, - emit: Compilation.Emit, - options: link.File.OpenOptions, -) !*Wasm { - const use_llvm = comp.config.use_llvm; - const output_mode = comp.config.output_mode; - - const wasm = try arena.create(Wasm); - wasm.* = .{ - .base = .{ - .tag = .wasm, - .comp = comp, - .emit = emit, - .gc_sections = options.gc_sections orelse (output_mode != .Obj), - .print_gc_sections = options.print_gc_sections, - .stack_size = options.stack_size orelse std.wasm.page_size * 16, // 1MB - .allow_shlib_undefined = options.allow_shlib_undefined orelse false, - .file = null, - .disable_lld_caching = options.disable_lld_caching, - .build_id = options.build_id, - .rpath_list = options.rpath_list, - .force_undefined_symbols = options.force_undefined_symbols, - }, - .name = undefined, - .import_table = options.import_table, - .export_table = options.export_table, - .import_symbols = options.import_symbols, - .export_symbol_names = options.export_symbol_names, - .global_base = options.global_base, - .initial_memory = options.initial_memory, - .max_memory = options.max_memory, - .wasi_emulated_libs = options.wasi_emulated_libs, - }; - - if (use_llvm) { - wasm.llvm_object = try LlvmObject.create(arena, comp); - } - return wasm; -} - /// For a given name, creates a new global synthetic symbol. /// Leaves index undefined and the default flags (0). fn createSyntheticSymbol(wasm: *Wasm, name: []const u8, tag: Symbol.Tag) !SymbolLoc {