| ... | ... | @@ -330,16 +330,6 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 330 | 330 | try wasm.addFunction(.__wasm_init_memory, &.{}, &.{}); |
| 331 | 331 | } |
| 332 | 332 | |
| 333 | | // When we have TLS GOT entries and shared memory is enabled, |
| 334 | | // we must perform runtime relocations or else we don't create the function. |
| 335 | | if (shared_memory) { |
| 336 | | // This logic that checks `any_tls_relocs` is missing the part where it |
| 337 | | // also notices threadlocal globals from Zcu code. |
| 338 | | if (wasm.any_tls_relocs) try wasm.addFunction(.__wasm_apply_global_tls_relocs, &.{}, &.{}); |
| 339 | | try wasm.addFunction(.__wasm_init_tls, &.{.i32}, &.{}); |
| 340 | | try wasm.globals.put(gpa, .__tls_base, {}); |
| 341 | | } |
| 342 | | |
| 343 | 333 | try wasm.tables.ensureUnusedCapacity(gpa, 1); |
| 344 | 334 | |
| 345 | 335 | if (f.indirect_function_table.entries.len > 0) { |
| ... | ... | @@ -446,17 +436,25 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 446 | 436 | const want_new_segment = b: { |
| 447 | 437 | if (is_obj) break :b false; |
| 448 | 438 | switch (seen_tls) { |
| 449 | | .before => if (category == .tls) { |
| 450 | | virtual_addrs.tls_base = if (shared_memory) 0 else @intCast(start_addr); |
| 451 | | virtual_addrs.tls_align = alignment; |
| 452 | | seen_tls = .during; |
| 453 | | break :b f.data_segment_groups.items.len > 0; |
| 439 | .before => switch (category) { |
| 440 | .tls => { |
| 441 | virtual_addrs.tls_base = if (shared_memory) 0 else @intCast(start_addr); |
| 442 | virtual_addrs.tls_align = alignment; |
| 443 | seen_tls = .during; |
| 444 | break :b f.data_segment_groups.items.len > 0; |
| 445 | }, |
| 446 | else => {}, |
| 454 | 447 | }, |
| 455 | | .during => if (category != .tls) { |
| 456 | | virtual_addrs.tls_size = @intCast(start_addr - virtual_addrs.tls_base.?); |
| 457 | | virtual_addrs.tls_align = virtual_addrs.tls_align.maxStrict(alignment); |
| 458 | | seen_tls = .after; |
| 459 | | break :b true; |
| 448 | .during => switch (category) { |
| 449 | .tls => { |
| 450 | virtual_addrs.tls_align = virtual_addrs.tls_align.maxStrict(alignment); |
| 451 | virtual_addrs.tls_size = @intCast(memory_ptr - virtual_addrs.tls_base.?); |
| 452 | break :b false; |
| 453 | }, |
| 454 | else => { |
| 455 | seen_tls = .after; |
| 456 | break :b true; |
| 457 | }, |
| 460 | 458 | }, |
| 461 | 459 | .after => {}, |
| 462 | 460 | } |
| ... | ... | @@ -480,6 +478,9 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 480 | 478 | .first_segment = first_segment, |
| 481 | 479 | .end_addr = @intCast(memory_ptr), |
| 482 | 480 | }); |
| 481 | if (category == .tls and seen_tls == .during) { |
| 482 | virtual_addrs.tls_size = @intCast(memory_ptr - virtual_addrs.tls_base.?); |
| 483 | } |
| 483 | 484 | } |
| 484 | 485 | |
| 485 | 486 | if (shared_memory and wasm.any_passive_inits) { |
| ... | ... | @@ -537,6 +538,19 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 537 | 538 | } |
| 538 | 539 | f.memory_layout_finished = true; |
| 539 | 540 | |
| 541 | // When we have TLS GOT entries and shared memory is enabled, we must |
| 542 | // perform runtime relocations or else we don't create the function. |
| 543 | if (shared_memory and virtual_addrs.tls_base != null) { |
| 544 | // This logic that checks `any_tls_relocs` is missing the part where it |
| 545 | // also notices threadlocal globals from Zcu code. |
| 546 | if (wasm.any_tls_relocs) try wasm.addFunction(.__wasm_apply_global_tls_relocs, &.{}, &.{}); |
| 547 | try wasm.addFunction(.__wasm_init_tls, &.{.i32}, &.{}); |
| 548 | try wasm.globals.ensureUnusedCapacity(gpa, 3); |
| 549 | wasm.globals.putAssumeCapacity(.__tls_base, {}); |
| 550 | wasm.globals.putAssumeCapacity(.__tls_size, {}); |
| 551 | wasm.globals.putAssumeCapacity(.__tls_align, {}); |
| 552 | } |
| 553 | |
| 540 | 554 | var section_index: u32 = 0; |
| 541 | 555 | // Index of the code section. Used to tell relocation table where the section lives. |
| 542 | 556 | var code_section_index: ?u32 = null; |
| ... | ... | @@ -986,9 +1000,8 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 986 | 1000 | } |
| 987 | 1001 | segment_offset += @intCast(binary_bytes.items.len - code_start); |
| 988 | 1002 | } |
| 989 | | assert(group_index == f.data_segment_groups.items.len); |
| 990 | 1003 | |
| 991 | | replaceVecSectionHeader(binary_bytes, header_offset, .data, group_index); |
| 1004 | replaceVecSectionHeader(binary_bytes, header_offset, .data, @intCast(f.data_segment_groups.items.len)); |
| 992 | 1005 | data_section_index = section_index; |
| 993 | 1006 | section_index += 1; |
| 994 | 1007 | } |
| ... | ... | @@ -1128,7 +1141,7 @@ fn emitNameSection( |
| 1128 | 1141 | try leb.writeUleb128(binary_bytes.writer(gpa), total_data_segments); |
| 1129 | 1142 | |
| 1130 | 1143 | for (data_segment_groups, 0..) |group, i| { |
| 1131 | | const name = group.first_segment.name(wasm); |
| 1144 | const name, _ = splitSegmentName(group.first_segment.name(wasm)); |
| 1132 | 1145 | try leb.writeUleb128(binary_bytes.writer(gpa), @as(u32, @intCast(i))); |
| 1133 | 1146 | try leb.writeUleb128(binary_bytes.writer(gpa), @as(u32, @intCast(name.len))); |
| 1134 | 1147 | try binary_bytes.appendSlice(gpa, name); |
| ... | ... | @@ -1680,8 +1693,8 @@ fn applyRelocs(code: []u8, code_offset: u32, relocs: Wasm.ObjectRelocation.Itera |
| 1680 | 1693 | .memory_addr_rel_sleb64 => @panic("TODO implement relocation memory_addr_rel_sleb64"), |
| 1681 | 1694 | .memory_addr_sleb => reloc_sleb_addr(sliced_code, .fromObjectData(wasm, pointee.data, addend.*)), |
| 1682 | 1695 | .memory_addr_sleb64 => reloc_sleb64_addr(sliced_code, .fromObjectData(wasm, pointee.data, addend.*)), |
| 1683 | | .memory_addr_tls_sleb => @panic("TODO implement relocation memory_addr_tls_sleb"), |
| 1684 | | .memory_addr_tls_sleb64 => @panic("TODO implement relocation memory_addr_tls_sleb64"), |
| 1696 | .memory_addr_tls_sleb => reloc_sleb_addr(sliced_code, .fromObjectData(wasm, pointee.data, addend.*)), |
| 1697 | .memory_addr_tls_sleb64 => reloc_sleb64_addr(sliced_code, .fromObjectData(wasm, pointee.data, addend.*)), |
| 1685 | 1698 | |
| 1686 | 1699 | .memory_addr_import_i32 => reloc_u32_addr(sliced_code, .fromSymbolName(wasm, pointee.symbol_name, addend.*)), |
| 1687 | 1700 | .memory_addr_import_i64 => reloc_u64_addr(sliced_code, .fromSymbolName(wasm, pointee.symbol_name, addend.*)), |