authorgravatar for preeternal@noreply.codeberg.orgPreeternal <preeternal@noreply.codeberg.org> 2026-07-14 19:14:13+02:00
committergravatar for paul.verigo@gmail.comPavel Verigo <paul.verigo@gmail.com> 2026-07-14 19:14:13+02:00
log64dfaa568db04aedb72ac9070484a7e3bd987e24
tree80708e92460bd69e9fabe36d44d4f8be707a1f99
parent80d06578ac66bce3aa0a21e9610cdb782b9a0593

fix(MachO): align 64-bit archive member contents (#35984)

refs: https://codeberg.org/ziglang/zig/issues/35280 Co-authored-by: Pavel Verigo <paul.verigo@gmail.com> Reviewed-on: https://codeberg.org/ziglang/zig/pulls/35984

5 files changed, 18 insertions(+), 15 deletions(-)

src/link/MachO/Archive.zig+4-3
......@@ -89,12 +89,13 @@ pub fn unpack(self: *Archive, macho_file: *MachO, path: Path, handle_index: File
8989pub fn writeHeader(
9090 object_name: []const u8,
9191 object_size: usize,
92 format: Format,
9392 writer: *Writer,
9493) !void {
9594 var hdr: ar_hdr = .{};
9695
97 const object_name_len = mem.alignForward(usize, object_name.len + 1, ptrWidth(format));
96 const object_name_start = writer.end + @sizeOf(ar_hdr);
97 const object_start = mem.alignForward(usize, object_name_start + object_name.len + 1, 8);
98 const object_name_len = object_start - object_name_start;
9899 const total_object_size = object_size + object_name_len;
99100
100101 {
......@@ -193,7 +194,7 @@ pub const ArSymtab = struct {
193194 pub fn write(ar: ArSymtab, format: Format, macho_file: *MachO, writer: *Writer) !void {
194195 const ptr_width = ptrWidth(format);
195196 // Header
196 try writeHeader(SYMDEF, ar.size(format), format, writer);
197 try writeHeader(SYMDEF, ar.size(format), writer);
197198 // Symtab size
198199 try writeInt(format, ar.entries.items.len * 2 * ptr_width, writer);
199200 // Symtab entries
src/link/MachO/Object.zig+2-2
......@@ -1805,11 +1805,11 @@ pub fn updateArSize(self: *Object, macho_file: *MachO) !void {
18051805 };
18061806}
18071807
1808pub fn writeAr(self: Object, ar_format: Archive.Format, macho_file: *MachO, writer: *Writer) !void {
1808pub fn writeAr(self: Object, macho_file: *MachO, writer: *Writer) !void {
18091809 // Header
18101810 const size = try macho_file.cast(usize, self.output_ar_state.size);
18111811 const basename = std.fs.path.basename(self.path);
1812 try Archive.writeHeader(basename, size, ar_format, writer);
1812 try Archive.writeHeader(basename, size, writer);
18131813 // Data
18141814 const file = macho_file.getFileHandle(self.file_handle);
18151815 // TODO try using copyRangeAll
src/link/MachO/ZigObject.zig+2-2
......@@ -322,10 +322,10 @@ pub fn updateArSize(self: *ZigObject) void {
322322 self.output_ar_state.size = self.data.items.len;
323323}
324324
325pub fn writeAr(self: ZigObject, ar_format: Archive.Format, writer: anytype) !void {
325pub fn writeAr(self: ZigObject, writer: anytype) !void {
326326 // Header
327327 const size = std.math.cast(usize, self.output_ar_state.size) orelse return error.Overflow;
328 try Archive.writeHeader(self.basename, size, ar_format, writer);
328 try Archive.writeHeader(self.basename, size, writer);
329329 // Data
330330 try writer.writeAll(self.data.items);
331331}
src/link/MachO/file.zig+3-3
......@@ -322,11 +322,11 @@ pub const File = union(enum) {
322322 };
323323 }
324324
325 pub fn writeAr(file: File, ar_format: Archive.Format, macho_file: *MachO, writer: anytype) !void {
325 pub fn writeAr(file: File, macho_file: *MachO, writer: anytype) !void {
326326 return switch (file) {
327327 .dylib, .internal => unreachable,
328 .zig_object => |x| x.writeAr(ar_format, writer),
329 .object => |x| x.writeAr(ar_format, macho_file, writer),
328 .zig_object => |x| x.writeAr(writer),
329 .object => |x| x.writeAr(macho_file, writer),
330330 };
331331 }
332332
src/link/MachO/relocatable.zig+7-5
......@@ -149,7 +149,6 @@ pub fn flushStaticLib(macho_file: *MachO, comp: *Compilation, module_obj_path: ?
149149 for (macho_file.objects.items) |index| files.appendAssumeCapacity(index);
150150
151151 const format: Archive.Format = .p32;
152 const ptr_width = Archive.ptrWidth(format);
153152
154153 // Update ar symtab from parsed objects
155154 var ar_symtab: Archive.ArSymtab = .{};
......@@ -171,7 +170,8 @@ pub fn flushStaticLib(macho_file: *MachO, comp: *Compilation, module_obj_path: ?
171170 const total_size: usize = blk: {
172171 var pos: usize = Archive.SARMAG;
173172 pos += @sizeOf(Archive.ar_hdr);
174 pos += mem.alignForward(usize, Archive.SYMDEF.len + 1, ptr_width);
173 pos += Archive.SYMDEF.len + 1;
174 pos = mem.alignForward(usize, pos, 8);
175175 pos += ar_symtab.size(format);
176176
177177 for (files.items) |index| {
......@@ -182,7 +182,8 @@ pub fn flushStaticLib(macho_file: *MachO, comp: *Compilation, module_obj_path: ?
182182 pos = mem.alignForward(usize, pos, 2);
183183 state.file_off = pos;
184184 pos += @sizeOf(Archive.ar_hdr);
185 pos += mem.alignForward(usize, zo.basename.len + 1, ptr_width);
185 pos += zo.basename.len + 1;
186 pos = mem.alignForward(usize, pos, 8);
186187 pos += try macho_file.cast(usize, state.size);
187188 },
188189 .object => |o| {
......@@ -190,7 +191,8 @@ pub fn flushStaticLib(macho_file: *MachO, comp: *Compilation, module_obj_path: ?
190191 pos = mem.alignForward(usize, pos, 2);
191192 state.file_off = pos;
192193 pos += @sizeOf(Archive.ar_hdr);
193 pos += mem.alignForward(usize, std.fs.path.basename(o.path).len + 1, ptr_width);
194 pos += std.fs.path.basename(o.path).len + 1;
195 pos = mem.alignForward(usize, pos, 8);
194196 pos += try macho_file.cast(usize, state.size);
195197 },
196198 else => unreachable,
......@@ -222,7 +224,7 @@ pub fn flushStaticLib(macho_file: *MachO, comp: *Compilation, module_obj_path: ?
222224 if (padding > 0) {
223225 writer.splatByteAll(0, padding) catch unreachable;
224226 }
225 macho_file.getFile(index).?.writeAr(format, macho_file, &writer) catch |err|
227 macho_file.getFile(index).?.writeAr(macho_file, &writer) catch |err|
226228 return diags.fail("failed to write archive: {t}", .{err});
227229 }
228230