| author | |
| committer | |
| log | 788b7f8f115e8510176ca7fbfdc04fb48d69ecb1 |
| tree | 91208c95559c3d9ddb00ea97c6a7a64ca70292c2 |
| parent | 1c4b4fb51604f388bb4355e566aac4ea9fda8960 |
3 files changed, 14 insertions(+), 5 deletions(-)
src/link/Wasm.zig+10-2| ... | @@ -117,7 +117,7 @@ object_memories: std.ArrayListUnmanaged(ObjectMemory) = .empty, | ... | @@ -117,7 +117,7 @@ object_memories: std.ArrayListUnmanaged(ObjectMemory) = .empty, |
| 117 | object_relocations: std.MultiArrayList(ObjectRelocation) = .empty, | 117 | object_relocations: std.MultiArrayList(ObjectRelocation) = .empty, |
| 118 | 118 | ||
| 119 | /// List of initialization functions. These must be called in order of priority | 119 | /// List of initialization functions. These must be called in order of priority |
| 120 | /// by the (synthetic) __wasm_call_ctors function. | 120 | /// by the (synthetic) `__wasm_call_ctors` function. |
| 121 | object_init_funcs: std.ArrayListUnmanaged(InitFunc) = .empty, | 121 | object_init_funcs: std.ArrayListUnmanaged(InitFunc) = .empty, |
| 122 | 122 | ||
| 123 | /// The data section of an object has many segments. Each segment corresponds | 123 | /// 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 | ... | @@ -3308,7 +3308,10 @@ pub fn prelink(wasm: *Wasm, prog_node: std.Progress.Node) link.File.FlushError!v |
| 3308 | } | 3308 | } |
| 3309 | // Also treat init functions as roots. | 3309 | // Also treat init functions as roots. |
| 3310 | for (wasm.object_init_funcs.items) |init_func| { | 3310 | for (wasm.object_init_funcs.items) |init_func| { |
| 3311 | try markFunction(wasm, init_func.function_index); | 3311 | const func = init_func.function_index.ptr(wasm); |
| 3312 | if (func.object_index.ptr(wasm).is_included) { | ||
| 3313 | try markFunction(wasm, init_func.function_index); | ||
| 3314 | } | ||
| 3312 | } | 3315 | } |
| 3313 | wasm.functions_end_prelink = @intCast(wasm.functions.entries.len); | 3316 | wasm.functions_end_prelink = @intCast(wasm.functions.entries.len); |
| 3314 | wasm.function_exports_len = @intCast(wasm.function_exports.items.len); | 3317 | wasm.function_exports_len = @intCast(wasm.function_exports.items.len); |
| ... | @@ -3383,6 +3386,7 @@ fn markFunction(wasm: *Wasm, i: ObjectFunctionIndex) link.File.FlushError!void { | ... | @@ -3383,6 +3386,7 @@ fn markFunction(wasm: *Wasm, i: ObjectFunctionIndex) link.File.FlushError!void { |
| 3383 | const rdynamic = comp.config.rdynamic; | 3386 | const rdynamic = comp.config.rdynamic; |
| 3384 | const is_obj = comp.config.output_mode == .Obj; | 3387 | const is_obj = comp.config.output_mode == .Obj; |
| 3385 | const function = i.ptr(wasm); | 3388 | const function = i.ptr(wasm); |
| 3389 | markObject(wasm, function.object_index); | ||
| 3386 | 3390 | ||
| 3387 | if (!is_obj and function.flags.isExported(rdynamic)) try wasm.function_exports.append(gpa, .{ | 3391 | if (!is_obj and function.flags.isExported(rdynamic)) try wasm.function_exports.append(gpa, .{ |
| 3388 | .name = function.name.unwrap().?, | 3392 | .name = function.name.unwrap().?, |
| ... | @@ -3392,6 +3396,10 @@ fn markFunction(wasm: *Wasm, i: ObjectFunctionIndex) link.File.FlushError!void { | ... | @@ -3392,6 +3396,10 @@ fn markFunction(wasm: *Wasm, i: ObjectFunctionIndex) link.File.FlushError!void { |
| 3392 | try wasm.markRelocations(function.relocations(wasm)); | 3396 | try wasm.markRelocations(function.relocations(wasm)); |
| 3393 | } | 3397 | } |
| 3394 | 3398 | ||
| 3399 | fn markObject(wasm: *Wasm, i: ObjectIndex) void { | ||
| 3400 | i.ptr(wasm).is_included = true; | ||
| 3401 | } | ||
| 3402 | |||
| 3395 | /// Recursively mark alive everything referenced by the global. | 3403 | /// Recursively mark alive everything referenced by the global. |
| 3396 | fn markGlobalImport( | 3404 | fn markGlobalImport( |
| 3397 | wasm: *Wasm, | 3405 | wasm: *Wasm, |
src/link/Wasm/Flush.zig+2-3| ... | @@ -188,8 +188,6 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { | ... | @@ -188,8 +188,6 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 188 | for (wasm.object_indirect_function_set.keys()) |object_function_index| | 188 | for (wasm.object_indirect_function_set.keys()) |object_function_index| |
| 189 | f.indirect_function_table.putAssumeCapacity(.fromObjectFunction(wasm, object_function_index), {}); | 189 | f.indirect_function_table.putAssumeCapacity(.fromObjectFunction(wasm, object_function_index), {}); |
| 190 | 190 | ||
| 191 | // TODO only include init functions for objects with must_link=true or | ||
| 192 | // which have any alive functions inside them. | ||
| 193 | if (wasm.object_init_funcs.items.len > 0) { | 191 | if (wasm.object_init_funcs.items.len > 0) { |
| 194 | // Zig has no constructors so these are only for object file inputs. | 192 | // Zig has no constructors so these are only for object file inputs. |
| 195 | mem.sortUnstable(Wasm.InitFunc, wasm.object_init_funcs.items, {}, Wasm.InitFunc.lessThan); | 193 | mem.sortUnstable(Wasm.InitFunc, wasm.object_init_funcs.items, {}, Wasm.InitFunc.lessThan); |
| ... | @@ -692,7 +690,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { | ... | @@ -692,7 +690,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 692 | } | 690 | } |
| 693 | 691 | ||
| 694 | // When the shared-memory option is enabled, we *must* emit the 'data count' section. | 692 | // When the shared-memory option is enabled, we *must* emit the 'data count' section. |
| 695 | if (f.data_segment_groups.items.len > 0 and shared_memory) { | 693 | { |
| 696 | const header_offset = try reserveVecSectionHeader(gpa, binary_bytes); | 694 | const header_offset = try reserveVecSectionHeader(gpa, binary_bytes); |
| 697 | replaceVecSectionHeader(binary_bytes, header_offset, .data_count, @intCast(f.data_segment_groups.items.len)); | 695 | replaceVecSectionHeader(binary_bytes, header_offset, .data_count, @intCast(f.data_segment_groups.items.len)); |
| 698 | } | 696 | } |
| ... | @@ -1644,6 +1642,7 @@ fn emitCallCtorsFunction(wasm: *const Wasm, binary_bytes: *std.ArrayListUnmanage | ... | @@ -1644,6 +1642,7 @@ fn emitCallCtorsFunction(wasm: *const Wasm, binary_bytes: *std.ArrayListUnmanage |
| 1644 | 1642 | ||
| 1645 | for (wasm.object_init_funcs.items) |init_func| { | 1643 | for (wasm.object_init_funcs.items) |init_func| { |
| 1646 | const func = init_func.function_index.ptr(wasm); | 1644 | const func = init_func.function_index.ptr(wasm); |
| 1645 | if (!func.object_index.ptr(wasm).is_included) continue; | ||
| 1647 | const ty = func.type_index.ptr(wasm); | 1646 | const ty = func.type_index.ptr(wasm); |
| 1648 | const n_returns = ty.returns.slice(wasm).len; | 1647 | const n_returns = ty.returns.slice(wasm).len; |
| 1649 | 1648 |
src/link/Wasm/Object.zig+2| ... | @@ -48,6 +48,7 @@ code_section_index: ?Wasm.ObjectSectionIndex, | ... | @@ -48,6 +48,7 @@ code_section_index: ?Wasm.ObjectSectionIndex, |
| 48 | global_section_index: ?Wasm.ObjectSectionIndex, | 48 | global_section_index: ?Wasm.ObjectSectionIndex, |
| 49 | /// Guaranteed to be non-null when data segments has nonzero length. | 49 | /// Guaranteed to be non-null when data segments has nonzero length. |
| 50 | data_section_index: ?Wasm.ObjectSectionIndex, | 50 | data_section_index: ?Wasm.ObjectSectionIndex, |
| 51 | is_included: bool, | ||
| 51 | 52 | ||
| 52 | pub const RelativeSlice = struct { | 53 | pub const RelativeSlice = struct { |
| 53 | off: u32, | 54 | off: u32, |
| ... | @@ -1414,6 +1415,7 @@ pub fn parse( | ... | @@ -1414,6 +1415,7 @@ pub fn parse( |
| 1414 | .code_section_index = code_section_index, | 1415 | .code_section_index = code_section_index, |
| 1415 | .global_section_index = global_section_index, | 1416 | .global_section_index = global_section_index, |
| 1416 | .data_section_index = data_section_index, | 1417 | .data_section_index = data_section_index, |
| 1418 | .is_included = must_link, | ||
| 1417 | }; | 1419 | }; |
| 1418 | } | 1420 | } |
| 1419 | 1421 |