From 0ae2ea671b867e5ecd0bc779405c175f33316559 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Thu, 8 Sep 2022 14:29:51 +0200 Subject: wasm: temporarily save curr file pointer before pwriting on Win This is a temporary workaround to an unclear platform-dependence behavior we have in libstd for `std.fs.File` abstraction. See https://github.com/ziglang/zig/issues/12783 for more information. --- lib/std/fs/file.zig | 16 ++++++++++++++++ src/link/Wasm.zig | 16 ++++++++++++++-- test/link.zig | 14 +++++++------- 3 files changed, 37 insertions(+), 9 deletions(-) diff --git a/lib/std/fs/file.zig b/lib/std/fs/file.zig index 5de746150b..3792e1c1f2 100644 --- a/lib/std/fs/file.zig +++ b/lib/std/fs/file.zig @@ -990,6 +990,8 @@ pub const File = struct { return index; } + /// On Windows, this function currently does alter the file pointer. + /// https://github.com/ziglang/zig/issues/12783 pub fn pread(self: File, buffer: []u8, offset: u64) PReadError!usize { if (is_windows) { return windows.ReadFile(self.handle, buffer, offset, self.intended_io_mode); @@ -1004,6 +1006,8 @@ pub const File = struct { /// Returns the number of bytes read. If the number read is smaller than `buffer.len`, it /// means the file reached the end. Reaching the end of a file is not an error condition. + /// On Windows, this function currently does alter the file pointer. + /// https://github.com/ziglang/zig/issues/12783 pub fn preadAll(self: File, buffer: []u8, offset: u64) PReadError!usize { var index: usize = 0; while (index != buffer.len) { @@ -1058,6 +1062,8 @@ pub const File = struct { } /// See https://github.com/ziglang/zig/issues/7699 + /// On Windows, this function currently does alter the file pointer. + /// https://github.com/ziglang/zig/issues/12783 pub fn preadv(self: File, iovecs: []const os.iovec, offset: u64) PReadError!usize { if (is_windows) { // TODO improve this to use ReadFileScatter @@ -1079,6 +1085,8 @@ pub const File = struct { /// The `iovecs` parameter is mutable because this function needs to mutate the fields in /// order to handle partial reads from the underlying OS layer. /// See https://github.com/ziglang/zig/issues/7699 + /// On Windows, this function currently does alter the file pointer. + /// https://github.com/ziglang/zig/issues/12783 pub fn preadvAll(self: File, iovecs: []os.iovec, offset: u64) PReadError!usize { if (iovecs.len == 0) return 0; @@ -1122,6 +1130,8 @@ pub const File = struct { } } + /// On Windows, this function currently does alter the file pointer. + /// https://github.com/ziglang/zig/issues/12783 pub fn pwrite(self: File, bytes: []const u8, offset: u64) PWriteError!usize { if (is_windows) { return windows.WriteFile(self.handle, bytes, offset, self.intended_io_mode); @@ -1134,6 +1144,8 @@ pub const File = struct { } } + /// On Windows, this function currently does alter the file pointer. + /// https://github.com/ziglang/zig/issues/12783 pub fn pwriteAll(self: File, bytes: []const u8, offset: u64) PWriteError!void { var index: usize = 0; while (index < bytes.len) { @@ -1179,6 +1191,8 @@ pub const File = struct { } /// See https://github.com/ziglang/zig/issues/7699 + /// On Windows, this function currently does alter the file pointer. + /// https://github.com/ziglang/zig/issues/12783 pub fn pwritev(self: File, iovecs: []os.iovec_const, offset: u64) PWriteError!usize { if (is_windows) { // TODO improve this to use WriteFileScatter @@ -1197,6 +1211,8 @@ pub const File = struct { /// The `iovecs` parameter is mutable because this function needs to mutate the fields in /// order to handle partial writes from the underlying OS layer. /// See https://github.com/ziglang/zig/issues/7699 + /// On Windows, this function currently does alter the file pointer. + /// https://github.com/ziglang/zig/issues/12783 pub fn pwritevAll(self: File, iovecs: []os.iovec_const, offset: u64) PWriteError!void { if (iovecs.len == 0) return; diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig index 8c73336e9f..f0f50049b8 100644 --- a/src/link/Wasm.zig +++ b/src/link/Wasm.zig @@ -3055,14 +3055,26 @@ fn writeVecSectionHeader(file: fs.File, offset: u64, section: wasm.Section, size buf[0] = @enumToInt(section); leb.writeUnsignedFixed(5, buf[1..6], size); leb.writeUnsignedFixed(5, buf[6..], items); - try file.pwriteAll(&buf, offset); + + if (builtin.target.os.tag == .windows) { + // https://github.com/ziglang/zig/issues/12783 + const curr_pos = try file.getPos(); + try file.pwriteAll(&buf, offset); + try file.seekTo(curr_pos); + } else try file.pwriteAll(&buf, offset); } fn writeCustomSectionHeader(file: fs.File, offset: u64, size: u32) !void { var buf: [1 + 5]u8 = undefined; buf[0] = 0; // 0 = 'custom' section leb.writeUnsignedFixed(5, buf[1..6], size); - try file.pwriteAll(&buf, offset); + + if (builtin.target.os.tag == .windows) { + // https://github.com/ziglang/zig/issues/12783 + const curr_pos = try file.getPos(); + try file.pwriteAll(&buf, offset); + try file.seekTo(curr_pos); + } else try file.pwriteAll(&buf, offset); } fn emitLinkSection(self: *Wasm, file: fs.File, arena: Allocator, symbol_table: *std.AutoArrayHashMap(SymbolLoc, u32)) !void { diff --git a/test/link.zig b/test/link.zig index b68353122c..d1dcbbc292 100644 --- a/test/link.zig +++ b/test/link.zig @@ -28,35 +28,35 @@ pub fn addCases(cases: *tests.StandaloneContext) void { } fn addWasmCases(cases: *tests.StandaloneContext) void { - cases.addBuildFile("test/link/wasm/bss/build.zig", .{ + cases.addBuildFile("test/link/wasm/archive/build.zig", .{ .build_modes = true, .requires_stage2 = true, }); - cases.addBuildFile("test/link/wasm/segments/build.zig", .{ + cases.addBuildFile("test/link/wasm/bss/build.zig", .{ .build_modes = true, .requires_stage2 = true, }); - cases.addBuildFile("test/link/wasm/stack_pointer/build.zig", .{ + cases.addBuildFile("test/link/wasm/extern/build.zig", .{ .build_modes = true, .requires_stage2 = true, + .use_emulation = true, }); - cases.addBuildFile("test/link/wasm/type/build.zig", .{ + cases.addBuildFile("test/link/wasm/segments/build.zig", .{ .build_modes = true, .requires_stage2 = true, }); - cases.addBuildFile("test/link/wasm/archive/build.zig", .{ + cases.addBuildFile("test/link/wasm/stack_pointer/build.zig", .{ .build_modes = true, .requires_stage2 = true, }); - cases.addBuildFile("test/link/wasm/extern/build.zig", .{ + cases.addBuildFile("test/link/wasm/type/build.zig", .{ .build_modes = true, .requires_stage2 = true, - .use_emulation = true, }); } -- cgit v1.2.3