diff --git a/src/link/MachO.zig b/src/link/MachO.zig index 7dfafef8eb..69dcf7aba1 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -2250,7 +2250,7 @@ fn initSegments(self: *MachO) !void { } fn allocateSections(self: *MachO) !void { - const headerpad = load_commands.calcMinHeaderPadSize(self); + const headerpad = try load_commands.calcMinHeaderPadSize(self); var vmaddr: u64 = if (self.pagezero_seg_index) |index| self.segments.items[index].vmaddr + self.segments.items[index].vmsize else @@ -2904,13 +2904,12 @@ pub fn writeStrtab(self: *MachO, off: u32) !u32 { fn writeLoadCommands(self: *MachO) !struct { usize, usize, u64 } { const gpa = self.base.comp.gpa; - const needed_size = load_commands.calcLoadCommandsSize(self, false); + const needed_size = try load_commands.calcLoadCommandsSize(self, false); const buffer = try gpa.alloc(u8, needed_size); defer gpa.free(buffer); var stream = std.io.fixedBufferStream(buffer); - var cwriter = std.io.countingWriter(stream.writer()); - const writer = cwriter.writer(); + const writer = stream.writer(); var ncmds: usize = 0; @@ -2974,7 +2973,7 @@ fn writeLoadCommands(self: *MachO) !struct { usize, usize, u64 } { ncmds += 1; } - const uuid_cmd_offset = @sizeOf(macho.mach_header_64) + cwriter.bytes_written; + const uuid_cmd_offset = @sizeOf(macho.mach_header_64) + stream.pos; try writer.writeStruct(self.uuid_cmd); ncmds += 1; @@ -3002,7 +3001,7 @@ fn writeLoadCommands(self: *MachO) !struct { usize, usize, u64 } { ncmds += 1; } - assert(cwriter.bytes_written == needed_size); + assert(stream.pos == needed_size); try self.base.file.?.pwriteAll(buffer, @sizeOf(macho.mach_header_64)); diff --git a/src/link/MachO/DebugSymbols.zig b/src/link/MachO/DebugSymbols.zig index 959a88b4da..3f0e84d6a2 100644 --- a/src/link/MachO/DebugSymbols.zig +++ b/src/link/MachO/DebugSymbols.zig @@ -269,8 +269,7 @@ fn writeLoadCommands(self: *DebugSymbols, macho_file: *MachO) !struct { usize, u defer gpa.free(buffer); var stream = std.io.fixedBufferStream(buffer); - var cwriter = std.io.countingWriter(stream.writer()); - const writer = cwriter.writer(); + const writer = stream.writer(); var ncmds: usize = 0; @@ -314,7 +313,7 @@ fn writeLoadCommands(self: *DebugSymbols, macho_file: *MachO) !struct { usize, u try writer.writeStruct(self.symtab_cmd); ncmds += 1; - assert(cwriter.bytes_written == needed_size); + assert(stream.pos == needed_size); try self.file.pwriteAll(buffer, @sizeOf(macho.mach_header_64)); diff --git a/src/link/MachO/UnwindInfo.zig b/src/link/MachO/UnwindInfo.zig index e16e03b09a..44bb9bfab1 100644 --- a/src/link/MachO/UnwindInfo.zig +++ b/src/link/MachO/UnwindInfo.zig @@ -271,8 +271,7 @@ pub fn write(info: UnwindInfo, macho_file: *MachO, buffer: []u8) !void { const header = macho_file.sections.items(.header)[macho_file.unwind_info_sect_index.?]; var stream = std.io.fixedBufferStream(buffer); - var cwriter = std.io.countingWriter(stream.writer()); - const writer = cwriter.writer(); + const writer = stream.writer(); const common_encodings_offset: u32 = @sizeOf(macho.unwind_info_section_header); const common_encodings_count: u32 = info.common_encodings_count; @@ -329,20 +328,16 @@ pub fn write(info: UnwindInfo, macho_file: *MachO, buffer: []u8) !void { } for (info.pages.items) |page| { - const start = cwriter.bytes_written; + const start = stream.pos; try page.write(info, macho_file, writer); - const nwritten = cwriter.bytes_written - start; + const nwritten = stream.pos - start; if (nwritten < second_level_page_bytes) { const padding = math.cast(usize, second_level_page_bytes - nwritten) orelse return error.Overflow; try writer.writeByteNTimes(0, padding); } } - const padding = buffer.len - cwriter.bytes_written; - if (padding > 0) { - const off = math.cast(usize, cwriter.bytes_written) orelse return error.Overflow; - @memset(buffer[off..], 0); - } + @memset(buffer[stream.pos..], 0); } fn getOrPutPersonalityFunction(info: *UnwindInfo, sym_index: Symbol.Index) error{TooManyPersonalities}!u2 { diff --git a/src/link/MachO/dyld_info/bind.zig b/src/link/MachO/dyld_info/bind.zig index 7c0d2ab692..3ee55fe0fb 100644 --- a/src/link/MachO/dyld_info/bind.zig +++ b/src/link/MachO/dyld_info/bind.zig @@ -40,7 +40,7 @@ pub const Bind = struct { } pub fn size(self: Self) u64 { - return @as(u64, @intCast(self.buffer.items.len)); + return @intCast(self.buffer.items.len); } pub fn finalize(self: *Self, gpa: Allocator, ctx: *MachO) !void { @@ -124,7 +124,7 @@ pub const Bind = struct { switch (state) { .start => { if (current.offset < offset) { - try addAddr(@as(u64, @bitCast(@as(i64, @intCast(current.offset)) - @as(i64, @intCast(offset)))), writer); + try addAddr(@bitCast(@as(i64, @intCast(current.offset)) - @as(i64, @intCast(offset))), writer); offset = offset - (offset - current.offset); } else if (current.offset > offset) { const delta = current.offset - offset; @@ -195,7 +195,7 @@ pub const WeakBind = struct { } pub fn size(self: Self) u64 { - return @as(u64, @intCast(self.buffer.items.len)); + return @intCast(self.buffer.items.len); } pub fn finalize(self: *Self, gpa: Allocator, ctx: *MachO) !void { @@ -286,7 +286,7 @@ pub const WeakBind = struct { } else if (current.offset > offset) { const delta = current.offset - offset; state = .bind_times_skip; - skip = @as(u64, @intCast(delta)); + skip = @intCast(delta); offset += skip; } else unreachable; i -= 1; @@ -341,23 +341,20 @@ pub const LazyBind = struct { } pub fn size(self: Self) u64 { - return @as(u64, @intCast(self.buffer.items.len)); + return @intCast(self.buffer.items.len); } pub fn finalize(self: *Self, gpa: Allocator, ctx: *MachO) !void { - if (self.entries.items.len == 0) return; - try self.offsets.ensureTotalCapacityPrecise(gpa, self.entries.items.len); - var cwriter = std.io.countingWriter(self.buffer.writer(gpa)); - const writer = cwriter.writer(); + const writer = self.buffer.writer(gpa); log.debug("lazy bind opcodes", .{}); var addend: i64 = 0; for (self.entries.items) |entry| { - self.offsets.appendAssumeCapacity(@as(u32, @intCast(cwriter.bytes_written))); + self.offsets.appendAssumeCapacity(@intCast(self.buffer.items.len)); const sym = ctx.getSymbol(entry.target); const name = sym.getName(ctx); @@ -388,7 +385,6 @@ pub const LazyBind = struct { } pub fn write(self: Self, writer: anytype) !void { - if (self.size() == 0) return; try writer.writeAll(self.buffer.items); } }; diff --git a/src/link/MachO/load_commands.zig b/src/link/MachO/load_commands.zig index cf8dca92e0..778fdd74c7 100644 --- a/src/link/MachO/load_commands.zig +++ b/src/link/MachO/load_commands.zig @@ -17,7 +17,7 @@ fn calcInstallNameLen(cmd_size: u64, name: []const u8, assume_max_path_len: bool return mem.alignForward(u64, cmd_size + name_len, @alignOf(u64)); } -pub fn calcLoadCommandsSize(macho_file: *MachO, assume_max_path_len: bool) u32 { +pub fn calcLoadCommandsSize(macho_file: *MachO, assume_max_path_len: bool) !u32 { var sizeofcmds: u64 = 0; // LC_SEGMENT_64 @@ -48,15 +48,16 @@ pub fn calcLoadCommandsSize(macho_file: *MachO, assume_max_path_len: bool) u32 { } // LC_ID_DYLIB if (macho_file.base.isDynLib()) { - sizeofcmds += blk: { - const emit = macho_file.base.emit; - const install_name = macho_file.install_name orelse emit.sub_path; - break :blk calcInstallNameLen( - @sizeOf(macho.dylib_command), - install_name, - assume_max_path_len, - ); - }; + const gpa = macho_file.base.comp.gpa; + const emit = macho_file.base.emit; + const install_name = macho_file.install_name orelse + try emit.directory.join(gpa, &.{emit.sub_path}); + defer if (macho_file.install_name == null) gpa.free(install_name); + sizeofcmds += calcInstallNameLen( + @sizeOf(macho.dylib_command), + install_name, + assume_max_path_len, + ); } // LC_RPATH { @@ -148,12 +149,12 @@ pub fn calcLoadCommandsSizeObject(macho_file: *MachO) u32 { return @as(u32, @intCast(sizeofcmds)); } -pub fn calcMinHeaderPadSize(macho_file: *MachO) u32 { - var padding: u32 = calcLoadCommandsSize(macho_file, false) + (macho_file.headerpad_size orelse 0); +pub fn calcMinHeaderPadSize(macho_file: *MachO) !u32 { + var padding: u32 = (try calcLoadCommandsSize(macho_file, false)) + (macho_file.headerpad_size orelse 0); log.debug("minimum requested headerpad size 0x{x}", .{padding + @sizeOf(macho.mach_header_64)}); if (macho_file.headerpad_max_install_names) { - const min_headerpad_size: u32 = calcLoadCommandsSize(macho_file, true); + const min_headerpad_size: u32 = try calcLoadCommandsSize(macho_file, true); log.debug("headerpad_max_install_names minimum headerpad size 0x{x}", .{ min_headerpad_size + @sizeOf(macho.mach_header_64), }); diff --git a/src/link/MachO/relocatable.zig b/src/link/MachO/relocatable.zig index 9408a32d6d..b0eced27eb 100644 --- a/src/link/MachO/relocatable.zig +++ b/src/link/MachO/relocatable.zig @@ -748,8 +748,7 @@ fn writeLoadCommands(macho_file: *MachO) !struct { usize, usize } { defer gpa.free(buffer); var stream = std.io.fixedBufferStream(buffer); - var cwriter = std.io.countingWriter(stream.writer()); - const writer = cwriter.writer(); + const writer = stream.writer(); var ncmds: usize = 0; @@ -779,7 +778,7 @@ fn writeLoadCommands(macho_file: *MachO) !struct { usize, usize } { ncmds += 1; } - assert(cwriter.bytes_written == needed_size); + assert(stream.pos == needed_size); try macho_file.base.file.?.pwriteAll(buffer, @sizeOf(macho.mach_header_64));