diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2025-01-09 20:55:39 -0800 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2025-01-15 15:11:36 -0800 |
| commit | 788b7f8f115e8510176ca7fbfdc04fb48d69ecb1 (patch) | |
| tree | 91208c95559c3d9ddb00ea97c6a7a64ca70292c2 | |
| parent | 1c4b4fb51604f388bb4355e566aac4ea9fda8960 (diff) | |
| download | zig-788b7f8f115e8510176ca7fbfdc04fb48d69ecb1.tar.gz zig-788b7f8f115e8510176ca7fbfdc04fb48d69ecb1.zip | |
wasm linker: don't call init functions unless object included
| -rw-r--r-- | src/link/Wasm.zig | 12 | ||||
| -rw-r--r-- | src/link/Wasm/Flush.zig | 5 | ||||
| -rw-r--r-- | src/link/Wasm/Object.zig | 2 |
3 files changed, 14 insertions, 5 deletions
diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig index 277d092cba..5dd51c2f12 100644 --- a/src/link/Wasm.zig +++ b/src/link/Wasm.zig @@ -117,7 +117,7 @@ object_memories: std.ArrayListUnmanaged(ObjectMemory) = .empty, object_relocations: std.MultiArrayList(ObjectRelocation) = .empty, /// List of initialization functions. These must be called in order of priority -/// by the (synthetic) __wasm_call_ctors function. +/// by the (synthetic) `__wasm_call_ctors` function. object_init_funcs: std.ArrayListUnmanaged(InitFunc) = .empty, /// The data section of an object has many segments. Each segment corresponds @@ -3308,7 +3308,10 @@ pub fn prelink(wasm: *Wasm, prog_node: std.Progress.Node) link.File.FlushError!v } // Also treat init functions as roots. for (wasm.object_init_funcs.items) |init_func| { - try markFunction(wasm, init_func.function_index); + const func = init_func.function_index.ptr(wasm); + if (func.object_index.ptr(wasm).is_included) { + try markFunction(wasm, init_func.function_index); + } } wasm.functions_end_prelink = @intCast(wasm.functions.entries.len); wasm.function_exports_len = @intCast(wasm.function_exports.items.len); @@ -3383,6 +3386,7 @@ fn markFunction(wasm: *Wasm, i: ObjectFunctionIndex) link.File.FlushError!void { const rdynamic = comp.config.rdynamic; const is_obj = comp.config.output_mode == .Obj; const function = i.ptr(wasm); + markObject(wasm, function.object_index); if (!is_obj and function.flags.isExported(rdynamic)) try wasm.function_exports.append(gpa, .{ .name = function.name.unwrap().?, @@ -3392,6 +3396,10 @@ fn markFunction(wasm: *Wasm, i: ObjectFunctionIndex) link.File.FlushError!void { try wasm.markRelocations(function.relocations(wasm)); } +fn markObject(wasm: *Wasm, i: ObjectIndex) void { + i.ptr(wasm).is_included = true; +} + /// Recursively mark alive everything referenced by the global. fn markGlobalImport( wasm: *Wasm, diff --git a/src/link/Wasm/Flush.zig b/src/link/Wasm/Flush.zig index d53a508f9b..390f024642 100644 --- a/src/link/Wasm/Flush.zig +++ b/src/link/Wasm/Flush.zig @@ -188,8 +188,6 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { for (wasm.object_indirect_function_set.keys()) |object_function_index| f.indirect_function_table.putAssumeCapacity(.fromObjectFunction(wasm, object_function_index), {}); - // TODO only include init functions for objects with must_link=true or - // which have any alive functions inside them. if (wasm.object_init_funcs.items.len > 0) { // Zig has no constructors so these are only for object file inputs. mem.sortUnstable(Wasm.InitFunc, wasm.object_init_funcs.items, {}, Wasm.InitFunc.lessThan); @@ -692,7 +690,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { } // When the shared-memory option is enabled, we *must* emit the 'data count' section. - if (f.data_segment_groups.items.len > 0 and shared_memory) { + { const header_offset = try reserveVecSectionHeader(gpa, binary_bytes); replaceVecSectionHeader(binary_bytes, header_offset, .data_count, @intCast(f.data_segment_groups.items.len)); } @@ -1644,6 +1642,7 @@ fn emitCallCtorsFunction(wasm: *const Wasm, binary_bytes: *std.ArrayListUnmanage for (wasm.object_init_funcs.items) |init_func| { const func = init_func.function_index.ptr(wasm); + if (!func.object_index.ptr(wasm).is_included) continue; const ty = func.type_index.ptr(wasm); const n_returns = ty.returns.slice(wasm).len; diff --git a/src/link/Wasm/Object.zig b/src/link/Wasm/Object.zig index 91354c3d03..ecd2630d32 100644 --- a/src/link/Wasm/Object.zig +++ b/src/link/Wasm/Object.zig @@ -48,6 +48,7 @@ code_section_index: ?Wasm.ObjectSectionIndex, global_section_index: ?Wasm.ObjectSectionIndex, /// Guaranteed to be non-null when data segments has nonzero length. data_section_index: ?Wasm.ObjectSectionIndex, +is_included: bool, pub const RelativeSlice = struct { off: u32, @@ -1414,6 +1415,7 @@ pub fn parse( .code_section_index = code_section_index, .global_section_index = global_section_index, .data_section_index = data_section_index, + .is_included = must_link, }; } |
