From 06224c23b7ac3b4e31c6f63898da4107cbe918a8 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Sun, 21 Jan 2024 21:12:15 +0100 Subject: [PATCH] macho: fix 32bit compilation issues --- src/link/MachO.zig | 47 ++++++++++++++++++----------- src/link/MachO/Atom.zig | 2 +- src/link/MachO/DwarfInfo.zig | 23 ++++++++------ src/link/MachO/Dylib.zig | 4 +-- src/link/MachO/Object.zig | 46 +++++++++++++++------------- src/link/MachO/UnwindInfo.zig | 6 ++-- src/link/MachO/ZigObject.zig | 3 +- src/link/MachO/dyld_info/Rebase.zig | 2 +- src/link/MachO/dyld_info/bind.zig | 2 +- src/link/MachO/file.zig | 2 +- src/link/MachO/hasher.zig | 14 ++++++--- src/link/MachO/relocatable.zig | 16 ++++++---- 12 files changed, 98 insertions(+), 69 deletions(-) diff --git a/src/link/MachO.zig b/src/link/MachO.zig index e561b64cf2..00e6b7f235 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -2557,7 +2557,8 @@ fn writeAtoms(self: *MachO) !void { if (atoms.items.len == 0) continue; if (header.isZerofill()) continue; - const buffer = try gpa.alloc(u8, header.size); + const size = math.cast(usize, header.size) orelse return error.Overflow; + const buffer = try gpa.alloc(u8, size); defer gpa.free(buffer); const padding_byte: u8 = if (header.isCode() and cpu_arch == .x86_64) 0xcc else 0; @memset(buffer, padding_byte); @@ -2565,14 +2566,15 @@ fn writeAtoms(self: *MachO) !void { for (atoms.items) |atom_index| { const atom = self.getAtom(atom_index).?; assert(atom.flags.alive); - const off = atom.value - header.addr; + const off = math.cast(usize, atom.value - header.addr) orelse return error.Overflow; const data = switch (atom.getFile(self)) { - .object => |x| x.getAtomData(atom.*), + .object => |x| try x.getAtomData(atom.*), .zig_object => |x| try x.getAtomDataAlloc(self, arena.allocator(), atom.*), else => unreachable, }; - @memcpy(buffer[off..][0..atom.size], data); - atom.resolveRelocs(self, buffer[off..][0..atom.size]) catch |err| switch (err) { + const atom_size = math.cast(usize, atom.size) orelse return error.Overflow; + @memcpy(buffer[off..][0..atom_size], data); + atom.resolveRelocs(self, buffer[off..][0..atom_size]) catch |err| switch (err) { error.ResolveFailed => has_resolve_error = true, else => |e| return e, }; @@ -2602,7 +2604,8 @@ fn writeUnwindInfo(self: *MachO) !void { if (self.eh_frame_sect_index) |index| { const header = self.sections.items(.header)[index]; - const buffer = try gpa.alloc(u8, header.size); + const size = math.cast(usize, header.size) orelse return error.Overflow; + const buffer = try gpa.alloc(u8, size); defer gpa.free(buffer); eh_frame.write(self, buffer); try self.base.file.?.pwriteAll(buffer, header.offset); @@ -2610,7 +2613,8 @@ fn writeUnwindInfo(self: *MachO) !void { if (self.unwind_info_sect_index) |index| { const header = self.sections.items(.header)[index]; - const buffer = try gpa.alloc(u8, header.size); + const size = math.cast(usize, header.size) orelse return error.Overflow; + const buffer = try gpa.alloc(u8, size); defer gpa.free(buffer); try self.unwind_info.write(self, buffer); try self.base.file.?.pwriteAll(buffer, header.offset); @@ -2637,7 +2641,8 @@ fn writeSyntheticSections(self: *MachO) !void { if (self.got_sect_index) |sect_id| { const header = self.sections.items(.header)[sect_id]; - var buffer = try std.ArrayList(u8).initCapacity(gpa, header.size); + const size = math.cast(usize, header.size) orelse return error.Overflow; + var buffer = try std.ArrayList(u8).initCapacity(gpa, size); defer buffer.deinit(); try self.got.write(self, buffer.writer()); assert(buffer.items.len == header.size); @@ -2646,7 +2651,8 @@ fn writeSyntheticSections(self: *MachO) !void { if (self.stubs_sect_index) |sect_id| { const header = self.sections.items(.header)[sect_id]; - var buffer = try std.ArrayList(u8).initCapacity(gpa, header.size); + const size = math.cast(usize, header.size) orelse return error.Overflow; + var buffer = try std.ArrayList(u8).initCapacity(gpa, size); defer buffer.deinit(); try self.stubs.write(self, buffer.writer()); assert(buffer.items.len == header.size); @@ -2655,7 +2661,8 @@ fn writeSyntheticSections(self: *MachO) !void { if (self.stubs_helper_sect_index) |sect_id| { const header = self.sections.items(.header)[sect_id]; - var buffer = try std.ArrayList(u8).initCapacity(gpa, header.size); + const size = math.cast(usize, header.size) orelse return error.Overflow; + var buffer = try std.ArrayList(u8).initCapacity(gpa, size); defer buffer.deinit(); try self.stubs_helper.write(self, buffer.writer()); assert(buffer.items.len == header.size); @@ -2664,7 +2671,8 @@ fn writeSyntheticSections(self: *MachO) !void { if (self.la_symbol_ptr_sect_index) |sect_id| { const header = self.sections.items(.header)[sect_id]; - var buffer = try std.ArrayList(u8).initCapacity(gpa, header.size); + const size = math.cast(usize, header.size) orelse return error.Overflow; + var buffer = try std.ArrayList(u8).initCapacity(gpa, size); defer buffer.deinit(); try self.la_symbol_ptr.write(self, buffer.writer()); assert(buffer.items.len == header.size); @@ -2673,7 +2681,8 @@ fn writeSyntheticSections(self: *MachO) !void { if (self.tlv_ptr_sect_index) |sect_id| { const header = self.sections.items(.header)[sect_id]; - var buffer = try std.ArrayList(u8).initCapacity(gpa, header.size); + const size = math.cast(usize, header.size) orelse return error.Overflow; + var buffer = try std.ArrayList(u8).initCapacity(gpa, size); defer buffer.deinit(); try self.tlv_ptr.write(self, buffer.writer()); assert(buffer.items.len == header.size); @@ -2682,7 +2691,8 @@ fn writeSyntheticSections(self: *MachO) !void { if (self.objc_stubs_sect_index) |sect_id| { const header = self.sections.items(.header)[sect_id]; - var buffer = try std.ArrayList(u8).initCapacity(gpa, header.size); + const size = math.cast(usize, header.size) orelse return error.Overflow; + var buffer = try std.ArrayList(u8).initCapacity(gpa, size); defer buffer.deinit(); try self.objc_stubs.write(self, buffer.writer()); assert(buffer.items.len == header.size); @@ -2876,10 +2886,10 @@ pub fn writeSymtab(self: *MachO, off: u32) !u32 { zo.writeSymtab(self); } for (self.objects.items) |index| { - self.getFile(index).?.writeSymtab(self); + try self.getFile(index).?.writeSymtab(self); } for (self.dylibs.items) |index| { - self.getFile(index).?.writeSymtab(self); + try self.getFile(index).?.writeSymtab(self); } if (self.getInternalObject()) |internal| { internal.writeSymtab(self); @@ -2916,7 +2926,7 @@ pub fn writeStrtab(self: *MachO, off: u32) !u32 { return off + cmd.strsize; } -fn writeLoadCommands(self: *MachO) !struct { usize, usize, usize } { +fn writeLoadCommands(self: *MachO) !struct { usize, usize, u64 } { const gpa = self.base.comp.gpa; const needed_size = load_commands.calcLoadCommandsSize(self, false); const buffer = try gpa.alloc(u8, needed_size); @@ -3075,7 +3085,7 @@ fn writeHeader(self: *MachO, ncmds: usize, sizeofcmds: usize) !void { try self.base.file.?.pwriteAll(mem.asBytes(&header), 0); } -fn writeUuid(self: *MachO, uuid_cmd_offset: usize, has_codesig: bool) !void { +fn writeUuid(self: *MachO, uuid_cmd_offset: u64, has_codesig: bool) !void { const file_size = if (!has_codesig) blk: { const seg = self.getLinkeditSegment(); break :blk seg.fileoff + seg.filesize; @@ -3273,7 +3283,8 @@ fn copyRangeAllZeroOut(self: *MachO, old_offset: u64, new_offset: u64, size: u64 const file = self.base.file.?; const amt = try file.copyRangeAll(old_offset, file, new_offset, size); if (amt != size) return error.InputOutput; - const zeroes = try gpa.alloc(u8, size); + const size_u = math.cast(usize, size) orelse return error.Overflow; + const zeroes = try gpa.alloc(u8, size_u); defer gpa.free(zeroes); @memset(zeroes, 0); try file.pwriteAll(zeroes, old_offset); diff --git a/src/link/MachO/Atom.zig b/src/link/MachO/Atom.zig index c8564c95d8..5f6671c493 100644 --- a/src/link/MachO/Atom.zig +++ b/src/link/MachO/Atom.zig @@ -579,7 +579,7 @@ fn resolveRelocInner( writer: anytype, ) ResolveError!void { const cpu_arch = macho_file.getTarget().cpu.arch; - const rel_offset = rel.offset - self.off; + const rel_offset = math.cast(usize, rel.offset - self.off) orelse return error.Overflow; const seg_id = macho_file.sections.items(.segment_id)[self.out_n_sect]; const seg = macho_file.segments.items[seg_id]; const P = @as(i64, @intCast(self.value)) + @as(i64, @intCast(rel_offset)); diff --git a/src/link/MachO/DwarfInfo.zig b/src/link/MachO/DwarfInfo.zig index 8b32faa567..036738225d 100644 --- a/src/link/MachO/DwarfInfo.zig +++ b/src/link/MachO/DwarfInfo.zig @@ -20,7 +20,7 @@ pub fn deinit(dw: *DwarfInfo, allocator: Allocator) void { dw.compile_units.deinit(allocator); } -fn getString(dw: DwarfInfo, off: u64) [:0]const u8 { +fn getString(dw: DwarfInfo, off: usize) [:0]const u8 { assert(off < dw.debug_str.len); return mem.sliceTo(@as([*:0]const u8, @ptrCast(dw.debug_str.ptr + off)), 0); } @@ -144,9 +144,9 @@ fn parseDie( try cu.diePtr(die).values.ensureTotalCapacityPrecise(allocator, decl.attrs.values().len); for (decl.attrs.values()) |attr| { - const start = creader.bytes_read; + const start = std.math.cast(usize, creader.bytes_read) orelse return error.Overflow; try advanceByFormSize(cu, attr.form, creader); - const end = creader.bytes_read; + const end = std.math.cast(usize, creader.bytes_read) orelse return error.Overflow; cu.diePtr(die).values.appendAssumeCapacity(data[start..end]); } @@ -184,14 +184,16 @@ fn advanceByFormSize(cu: *CompileUnit, form: Form, creader: anytype) !void { dwarf.FORM.block => try leb.readULEB128(u64, reader), else => unreachable, }; - for (0..len) |_| { + var i: u64 = 0; + while (i < len) : (i += 1) { _ = try reader.readByte(); } }, dwarf.FORM.exprloc => { const len = try leb.readULEB128(u64, reader); - for (0..len) |_| { + var i: u64 = 0; + while (i < len) : (i += 1) { _ = try reader.readByte(); } }, @@ -292,7 +294,7 @@ pub const CompileUnitHeader = struct { pub const CompileUnit = struct { header: CompileUnitHeader, - pos: usize, + pos: u64, dies: std.ArrayListUnmanaged(Die) = .{}, children: std.ArrayListUnmanaged(Die.Index) = .{}, @@ -314,14 +316,14 @@ pub const CompileUnit = struct { return &cu.dies.items[index]; } - pub fn getCompileDir(cu: CompileUnit, ctx: DwarfInfo) ?[:0]const u8 { + pub fn getCompileDir(cu: CompileUnit, ctx: DwarfInfo) error{Overflow}!?[:0]const u8 { assert(cu.dies.items.len > 0); const die = cu.dies.items[0]; const res = die.find(dwarf.AT.comp_dir, cu, ctx) orelse return null; return res.getString(cu.header.format, ctx); } - pub fn getSourceFile(cu: CompileUnit, ctx: DwarfInfo) ?[:0]const u8 { + pub fn getSourceFile(cu: CompileUnit, ctx: DwarfInfo) error{Overflow}!?[:0]const u8 { assert(cu.dies.items.len > 0); const die = cu.dies.items[0]; const res = die.find(dwarf.AT.name, cu, ctx) orelse return null; @@ -370,7 +372,7 @@ pub const DieValue = struct { }; } - pub fn getString(value: DieValue, format: Format, ctx: DwarfInfo) ?[:0]const u8 { + pub fn getString(value: DieValue, format: Format, ctx: DwarfInfo) error{Overflow}!?[:0]const u8 { switch (value.attr.form) { dwarf.FORM.string => { return mem.sliceTo(@as([*:0]const u8, @ptrCast(value.bytes.ptr)), 0); @@ -380,7 +382,8 @@ pub const DieValue = struct { .dwarf64 => mem.readInt(u64, value.bytes[0..8], .little), .dwarf32 => mem.readInt(u32, value.bytes[0..4], .little), }; - return ctx.getString(off); + const off_u = std.math.cast(usize, off) orelse return error.Overflow; + return ctx.getString(off_u); }, else => return null, } diff --git a/src/link/MachO/Dylib.zig b/src/link/MachO/Dylib.zig index 0f4ee09e78..363ec2e3f9 100644 --- a/src/link/MachO/Dylib.zig +++ b/src/link/MachO/Dylib.zig @@ -139,7 +139,7 @@ const TrieIterator = struct { var creader = std.io.countingReader(stream.reader()); const reader = creader.reader(); const value = try std.leb.readULEB128(u64, reader); - it.pos += creader.bytes_read; + it.pos += math.cast(usize, creader.bytes_read) orelse return error.Overflow; return value; } @@ -212,7 +212,7 @@ fn parseTrieNode( const off = try it.readULEB128(); const prefix_label = try std.fmt.allocPrint(arena, "{s}{s}", .{ prefix, label }); const curr = it.pos; - it.pos = off; + it.pos = math.cast(usize, off) orelse return error.Overflow; try self.parseTrieNode(it, allocator, arena, prefix_label); it.pos = curr; } diff --git a/src/link/MachO/Object.zig b/src/link/MachO/Object.zig index 367b7bc8fa..3d1984e43f 100644 --- a/src/link/MachO/Object.zig +++ b/src/link/MachO/Object.zig @@ -632,7 +632,7 @@ fn initEhFrameRecords(self: *Object, sect_id: u8, macho_file: *MachO) !void { const sect = slice.items(.header)[sect_id]; const relocs = slice.items(.relocs)[sect_id]; - const data = self.getSectionData(sect_id); + const data = try self.getSectionData(sect_id); try self.eh_frame_data.ensureTotalCapacityPrecise(gpa, data.len); self.eh_frame_data.appendSliceAssumeCapacity(data); @@ -733,7 +733,7 @@ fn initUnwindRecords(self: *Object, sect_id: u8, macho_file: *MachO) !void { }; const gpa = macho_file.base.comp.gpa; - const data = self.getSectionData(sect_id); + const data = try self.getSectionData(sect_id); const nrecs = @divExact(data.len, @sizeOf(macho.compact_unwind_entry)); const recs = @as([*]align(1) const macho.compact_unwind_entry, @ptrCast(data.ptr))[0..nrecs]; const sym_lookup = SymbolLookup{ .ctx = self }; @@ -974,9 +974,9 @@ fn initDwarfInfo(self: *Object, macho_file: *MachO) !void { if (debug_info_index == null or debug_abbrev_index == null) return; var dwarf_info = DwarfInfo{ - .debug_info = self.getSectionData(@intCast(debug_info_index.?)), - .debug_abbrev = self.getSectionData(@intCast(debug_abbrev_index.?)), - .debug_str = if (debug_str_index) |index| self.getSectionData(@intCast(index)) else "", + .debug_info = try self.getSectionData(@intCast(debug_info_index.?)), + .debug_abbrev = try self.getSectionData(@intCast(debug_abbrev_index.?)), + .debug_str = if (debug_str_index) |index| try self.getSectionData(@intCast(index)) else "", }; dwarf_info.init(gpa) catch { try macho_file.reportParseError2(self.index, "invalid __DWARF info found", .{}); @@ -1203,15 +1203,15 @@ pub fn calcSymtabSize(self: *Object, macho_file: *MachO) !void { } if (macho_file.base.comp.config.debug_format != .strip and self.hasDebugInfo()) - self.calcStabsSize(macho_file); + try self.calcStabsSize(macho_file); } -pub fn calcStabsSize(self: *Object, macho_file: *MachO) void { +pub fn calcStabsSize(self: *Object, macho_file: *MachO) error{Overflow}!void { if (self.dwarf_info) |dw| { // TODO handle multiple CUs const cu = dw.compile_units.items[0]; - const comp_dir = cu.getCompileDir(dw) orelse return; - const tu_name = cu.getSourceFile(dw) orelse return; + const comp_dir = try cu.getCompileDir(dw) orelse return; + const tu_name = try cu.getSourceFile(dw) orelse return; self.output_symtab_ctx.nstabs += 4; // N_SO, N_SO, N_OSO, N_SO self.output_symtab_ctx.strsize += @as(u32, @intCast(comp_dir.len + 1)); // comp_dir @@ -1266,7 +1266,7 @@ pub fn calcStabsSize(self: *Object, macho_file: *MachO) void { } } -pub fn writeSymtab(self: Object, macho_file: *MachO) void { +pub fn writeSymtab(self: Object, macho_file: *MachO) error{Overflow}!void { const tracy = trace(@src()); defer tracy.end(); @@ -1284,10 +1284,10 @@ pub fn writeSymtab(self: Object, macho_file: *MachO) void { } if (macho_file.base.comp.config.debug_format != .strip and self.hasDebugInfo()) - self.writeStabs(macho_file); + try self.writeStabs(macho_file); } -pub fn writeStabs(self: *const Object, macho_file: *MachO) void { +pub fn writeStabs(self: *const Object, macho_file: *MachO) error{Overflow}!void { const writeFuncStab = struct { inline fn writeFuncStab( n_strx: u32, @@ -1333,8 +1333,8 @@ pub fn writeStabs(self: *const Object, macho_file: *MachO) void { if (self.dwarf_info) |dw| { // TODO handle multiple CUs const cu = dw.compile_units.items[0]; - const comp_dir = cu.getCompileDir(dw) orelse return; - const tu_name = cu.getSourceFile(dw) orelse return; + const comp_dir = try cu.getCompileDir(dw) orelse return; + const tu_name = try cu.getSourceFile(dw) orelse return; // Open scope // N_SO comp_dir @@ -1540,16 +1540,20 @@ fn getLoadCommand(self: Object, lc: macho.LC) ?LoadCommandIterator.LoadCommand { } else return null; } -pub fn getSectionData(self: *const Object, index: u32) []const u8 { +pub fn getSectionData(self: *const Object, index: u32) error{Overflow}![]const u8 { const slice = self.sections.slice(); assert(index < slice.items(.header).len); const sect = slice.items(.header)[index]; - return self.data[sect.offset..][0..sect.size]; + const off = math.cast(usize, sect.offset) orelse return error.Overflow; + const size = math.cast(usize, sect.size) orelse return error.Overflow; + return self.data[off..][0..size]; } -pub fn getAtomData(self: *const Object, atom: Atom) []const u8 { - const data = self.getSectionData(atom.n_sect); - return data[atom.off..][0..atom.size]; +pub fn getAtomData(self: *const Object, atom: Atom) error{Overflow}![]const u8 { + const data = try self.getSectionData(atom.n_sect); + const off = math.cast(usize, atom.off) orelse return error.Overflow; + const size = math.cast(usize, atom.size) orelse return error.Overflow; + return data[off..][0..size]; } pub fn getAtomRelocs(self: *const Object, atom: Atom) []const Relocation { @@ -1821,7 +1825,7 @@ const x86_64 = struct { [*]align(1) const macho.relocation_info, @ptrCast(self.data.ptr + sect.reloff), )[0..sect.nreloc]; - const code = self.getSectionData(@intCast(n_sect)); + const code = try self.getSectionData(@intCast(n_sect)); try out.ensureTotalCapacityPrecise(gpa, relocs.len); @@ -1977,7 +1981,7 @@ const aarch64 = struct { [*]align(1) const macho.relocation_info, @ptrCast(self.data.ptr + sect.reloff), )[0..sect.nreloc]; - const code = self.getSectionData(@intCast(n_sect)); + const code = try self.getSectionData(@intCast(n_sect)); try out.ensureTotalCapacityPrecise(gpa, relocs.len); diff --git a/src/link/MachO/UnwindInfo.zig b/src/link/MachO/UnwindInfo.zig index ed70b1c083..8f62cc2f88 100644 --- a/src/link/MachO/UnwindInfo.zig +++ b/src/link/MachO/UnwindInfo.zig @@ -333,13 +333,15 @@ pub fn write(info: UnwindInfo, macho_file: *MachO, buffer: []u8) !void { try page.write(info, macho_file, writer); const nwritten = cwriter.bytes_written - start; if (nwritten < second_level_page_bytes) { - try writer.writeByteNTimes(0, second_level_page_bytes - nwritten); + 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) { - @memset(buffer[cwriter.bytes_written..], 0); + const off = math.cast(usize, cwriter.bytes_written) orelse return error.Overflow; + @memset(buffer[off..], 0); } } diff --git a/src/link/MachO/ZigObject.zig b/src/link/MachO/ZigObject.zig index 5c1fc9971f..6f55a077b5 100644 --- a/src/link/MachO/ZigObject.zig +++ b/src/link/MachO/ZigObject.zig @@ -154,7 +154,8 @@ pub fn getAtomDataAlloc( return data; }, macho.S_THREAD_LOCAL_VARIABLES => { - const data = try allocator.alloc(u8, atom.size); + const size = std.math.cast(usize, atom.size) orelse return error.Overflow; + const data = try allocator.alloc(u8, size); @memset(data, 0); return data; }, diff --git a/src/link/MachO/dyld_info/Rebase.zig b/src/link/MachO/dyld_info/Rebase.zig index 5209dcd9f4..776d144754 100644 --- a/src/link/MachO/dyld_info/Rebase.zig +++ b/src/link/MachO/dyld_info/Rebase.zig @@ -181,7 +181,7 @@ fn rebaseTimesSkip(count: usize, skip: u64, writer: anytype) !void { fn addAddr(addr: u64, writer: anytype) !void { log.debug(">>> add: {x}", .{addr}); - if (std.mem.isAligned(addr, @sizeOf(u64))) { + if (std.mem.isAlignedGeneric(u64, addr, @sizeOf(u64))) { const imm = @divExact(addr, @sizeOf(u64)); if (imm <= 0xf) { try writer.writeByte(macho.REBASE_OPCODE_ADD_ADDR_IMM_SCALED | @as(u4, @truncate(imm))); diff --git a/src/link/MachO/dyld_info/bind.zig b/src/link/MachO/dyld_info/bind.zig index bb746b05e3..7c0d2ab692 100644 --- a/src/link/MachO/dyld_info/bind.zig +++ b/src/link/MachO/dyld_info/bind.zig @@ -448,7 +448,7 @@ fn doBind(writer: anytype) !void { fn doBindAddAddr(addr: u64, writer: anytype) !void { log.debug(">>> bind with add: {x}", .{addr}); - if (std.mem.isAligned(addr, @sizeOf(u64))) { + if (std.mem.isAlignedGeneric(u64, addr, @sizeOf(u64))) { const imm = @divExact(addr, @sizeOf(u64)); if (imm <= 0xf) { try writer.writeByte( diff --git a/src/link/MachO/file.zig b/src/link/MachO/file.zig index 7033f58761..67b2b9106e 100644 --- a/src/link/MachO/file.zig +++ b/src/link/MachO/file.zig @@ -90,7 +90,7 @@ pub const File = union(enum) { }; } - pub fn writeSymtab(file: File, macho_file: *MachO) void { + pub fn writeSymtab(file: File, macho_file: *MachO) !void { return switch (file) { inline else => |x| x.writeSymtab(macho_file), }; diff --git a/src/link/MachO/hasher.zig b/src/link/MachO/hasher.zig index 57c8acd35e..aff4696c08 100644 --- a/src/link/MachO/hasher.zig +++ b/src/link/MachO/hasher.zig @@ -14,9 +14,13 @@ pub fn ParallelHasher(comptime Hasher: type) type { var wg: WaitGroup = .{}; - const file_size = opts.max_file_size orelse try file.getEndPos(); + const file_size = blk: { + const file_size = opts.max_file_size orelse try file.getEndPos(); + break :blk std.math.cast(usize, file_size) orelse return error.Overflow; + }; + const chunk_size = std.math.cast(usize, opts.chunk_size) orelse return error.Overflow; - const buffer = try self.allocator.alloc(u8, opts.chunk_size * out.len); + const buffer = try self.allocator.alloc(u8, chunk_size * out.len); defer self.allocator.free(buffer); const results = try self.allocator.alloc(fs.File.PReadError!usize, out.len); @@ -27,11 +31,11 @@ pub fn ParallelHasher(comptime Hasher: type) type { defer wg.wait(); for (out, results, 0..) |*out_buf, *result, i| { - const fstart = i * opts.chunk_size; - const fsize = if (fstart + opts.chunk_size > file_size) + const fstart = i * chunk_size; + const fsize = if (fstart + chunk_size > file_size) file_size - fstart else - opts.chunk_size; + chunk_size; wg.start(); try self.thread_pool.spawn(worker, .{ file, diff --git a/src/link/MachO/relocatable.zig b/src/link/MachO/relocatable.zig index 8b47d8eeb5..ecd1d6220b 100644 --- a/src/link/MachO/relocatable.zig +++ b/src/link/MachO/relocatable.zig @@ -262,7 +262,8 @@ fn writeAtoms(macho_file: *MachO) !void { if (atoms.items.len == 0) continue; if (header.isZerofill()) continue; - const code = try gpa.alloc(u8, header.size); + const size = math.cast(usize, header.size) orelse return error.Overflow; + const code = try gpa.alloc(u8, size); defer gpa.free(code); const padding_byte: u8 = if (header.isCode() and cpu_arch == .x86_64) 0xcc else 0; @memset(code, padding_byte); @@ -273,9 +274,11 @@ fn writeAtoms(macho_file: *MachO) !void { for (atoms.items) |atom_index| { const atom = macho_file.getAtom(atom_index).?; assert(atom.flags.alive); - const off = atom.value - header.addr; - @memcpy(code[off..][0..atom.size], atom.getFile(macho_file).object.getAtomData(atom.*)); - try atom.writeRelocs(macho_file, code[off..][0..atom.size], &relocs); + const off = math.cast(usize, atom.value - header.addr) orelse return error.Overflow; + const atom_size = math.cast(usize, atom.size) orelse return error.Overflow; + const atom_data = try atom.getFile(macho_file).object.getAtomData(atom.*); + @memcpy(code[off..][0..atom_size], atom_data); + try atom.writeRelocs(macho_file, code[off..][0..atom_size], &relocs); } assert(relocs.items.len == header.nreloc); @@ -293,7 +296,7 @@ fn writeCompactUnwind(macho_file: *MachO) !void { const gpa = macho_file.base.comp.gpa; const header = macho_file.sections.items(.header)[sect_index]; - const nrecs = @divExact(header.size, @sizeOf(macho.compact_unwind_entry)); + const nrecs = math.cast(usize, @divExact(header.size, @sizeOf(macho.compact_unwind_entry))) orelse return error.Overflow; var entries = try std.ArrayList(macho.compact_unwind_entry).initCapacity(gpa, nrecs); defer entries.deinit(); @@ -379,8 +382,9 @@ fn writeEhFrame(macho_file: *MachO) !void { const sect_index = macho_file.eh_frame_sect_index orelse return; const gpa = macho_file.base.comp.gpa; const header = macho_file.sections.items(.header)[sect_index]; + const size = math.cast(usize, header.size) orelse return error.Overflow; - const code = try gpa.alloc(u8, header.size); + const code = try gpa.alloc(u8, size); defer gpa.free(code); var relocs = try std.ArrayList(macho.relocation_info).initCapacity(gpa, header.nreloc);