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...@@ -89,12 +89,13 @@ pub fn unpack(self: *Archive, macho_file: *MachO, path: Path, handle_index: File
89pub fn writeHeader(89pub fn writeHeader(
90 object_name: []const u8,90 object_name: []const u8,
91 object_size: usize,91 object_size: usize,
92 format: Format,
93 writer: *Writer,92 writer: *Writer,
94) !void {93) !void {
95 var hdr: ar_hdr = .{};94 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;
98 const total_object_size = object_size + object_name_len;99 const total_object_size = object_size + object_name_len;
99100
100 {101 {
...@@ -193,7 +194,7 @@ pub const ArSymtab = struct {...@@ -193,7 +194,7 @@ pub const ArSymtab = struct {
193 pub fn write(ar: ArSymtab, format: Format, macho_file: *MachO, writer: *Writer) !void {194 pub fn write(ar: ArSymtab, format: Format, macho_file: *MachO, writer: *Writer) !void {
194 const ptr_width = ptrWidth(format);195 const ptr_width = ptrWidth(format);
195 // Header196 // Header
196 try writeHeader(SYMDEF, ar.size(format), format, writer);197 try writeHeader(SYMDEF, ar.size(format), writer);
197 // Symtab size198 // Symtab size
198 try writeInt(format, ar.entries.items.len * 2 * ptr_width, writer);199 try writeInt(format, ar.entries.items.len * 2 * ptr_width, writer);
199 // Symtab entries200 // Symtab entries
src/link/MachO/Object.zig+2-2
...@@ -1805,11 +1805,11 @@ pub fn updateArSize(self: *Object, macho_file: *MachO) !void {...@@ -1805,11 +1805,11 @@ pub fn updateArSize(self: *Object, macho_file: *MachO) !void {
1805 };1805 };
1806}1806}
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 {
1809 // Header1809 // Header
1810 const size = try macho_file.cast(usize, self.output_ar_state.size);1810 const size = try macho_file.cast(usize, self.output_ar_state.size);
1811 const basename = std.fs.path.basename(self.path);1811 const basename = std.fs.path.basename(self.path);
1812 try Archive.writeHeader(basename, size, ar_format, writer);1812 try Archive.writeHeader(basename, size, writer);
1813 // Data1813 // Data
1814 const file = macho_file.getFileHandle(self.file_handle);1814 const file = macho_file.getFileHandle(self.file_handle);
1815 // TODO try using copyRangeAll1815 // TODO try using copyRangeAll
src/link/MachO/ZigObject.zig+2-2
...@@ -322,10 +322,10 @@ pub fn updateArSize(self: *ZigObject) void {...@@ -322,10 +322,10 @@ pub fn updateArSize(self: *ZigObject) void {
322 self.output_ar_state.size = self.data.items.len;322 self.output_ar_state.size = self.data.items.len;
323}323}
324324
325pub fn writeAr(self: ZigObject, ar_format: Archive.Format, writer: anytype) !void {325pub fn writeAr(self: ZigObject, writer: anytype) !void {
326 // Header326 // Header
327 const size = std.math.cast(usize, self.output_ar_state.size) orelse return error.Overflow;327 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);
329 // Data329 // Data
330 try writer.writeAll(self.data.items);330 try writer.writeAll(self.data.items);
331}331}
src/link/MachO/file.zig+3-3
...@@ -322,11 +322,11 @@ pub const File = union(enum) {...@@ -322,11 +322,11 @@ pub const File = union(enum) {
322 };322 };
323 }323 }
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 {
326 return switch (file) {326 return switch (file) {
327 .dylib, .internal => unreachable,327 .dylib, .internal => unreachable,
328 .zig_object => |x| x.writeAr(ar_format, writer),328 .zig_object => |x| x.writeAr(writer),
329 .object => |x| x.writeAr(ar_format, macho_file, writer),329 .object => |x| x.writeAr(macho_file, writer),
330 };330 };
331 }331 }
332332
src/link/MachO/relocatable.zig+7-5
...@@ -149,7 +149,6 @@ pub fn flushStaticLib(macho_file: *MachO, comp: *Compilation, module_obj_path: ?...@@ -149,7 +149,6 @@ pub fn flushStaticLib(macho_file: *MachO, comp: *Compilation, module_obj_path: ?
149 for (macho_file.objects.items) |index| files.appendAssumeCapacity(index);149 for (macho_file.objects.items) |index| files.appendAssumeCapacity(index);
150150
151 const format: Archive.Format = .p32;151 const format: Archive.Format = .p32;
152 const ptr_width = Archive.ptrWidth(format);
153152
154 // Update ar symtab from parsed objects153 // Update ar symtab from parsed objects
155 var ar_symtab: Archive.ArSymtab = .{};154 var ar_symtab: Archive.ArSymtab = .{};
...@@ -171,7 +170,8 @@ pub fn flushStaticLib(macho_file: *MachO, comp: *Compilation, module_obj_path: ?...@@ -171,7 +170,8 @@ pub fn flushStaticLib(macho_file: *MachO, comp: *Compilation, module_obj_path: ?
171 const total_size: usize = blk: {170 const total_size: usize = blk: {
172 var pos: usize = Archive.SARMAG;171 var pos: usize = Archive.SARMAG;
173 pos += @sizeOf(Archive.ar_hdr);172 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);
175 pos += ar_symtab.size(format);175 pos += ar_symtab.size(format);
176176
177 for (files.items) |index| {177 for (files.items) |index| {
...@@ -182,7 +182,8 @@ pub fn flushStaticLib(macho_file: *MachO, comp: *Compilation, module_obj_path: ?...@@ -182,7 +182,8 @@ pub fn flushStaticLib(macho_file: *MachO, comp: *Compilation, module_obj_path: ?
182 pos = mem.alignForward(usize, pos, 2);182 pos = mem.alignForward(usize, pos, 2);
183 state.file_off = pos;183 state.file_off = pos;
184 pos += @sizeOf(Archive.ar_hdr);184 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);
186 pos += try macho_file.cast(usize, state.size);187 pos += try macho_file.cast(usize, state.size);
187 },188 },
188 .object => |o| {189 .object => |o| {
...@@ -190,7 +191,8 @@ pub fn flushStaticLib(macho_file: *MachO, comp: *Compilation, module_obj_path: ?...@@ -190,7 +191,8 @@ pub fn flushStaticLib(macho_file: *MachO, comp: *Compilation, module_obj_path: ?
190 pos = mem.alignForward(usize, pos, 2);191 pos = mem.alignForward(usize, pos, 2);
191 state.file_off = pos;192 state.file_off = pos;
192 pos += @sizeOf(Archive.ar_hdr);193 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);
194 pos += try macho_file.cast(usize, state.size);196 pos += try macho_file.cast(usize, state.size);
195 },197 },
196 else => unreachable,198 else => unreachable,
...@@ -222,7 +224,7 @@ pub fn flushStaticLib(macho_file: *MachO, comp: *Compilation, module_obj_path: ?...@@ -222,7 +224,7 @@ pub fn flushStaticLib(macho_file: *MachO, comp: *Compilation, module_obj_path: ?
222 if (padding > 0) {224 if (padding > 0) {
223 writer.splatByteAll(0, padding) catch unreachable;225 writer.splatByteAll(0, padding) catch unreachable;
224 }226 }
225 macho_file.getFile(index).?.writeAr(format, macho_file, &writer) catch |err|227 macho_file.getFile(index).?.writeAr(macho_file, &writer) catch |err|
226 return diags.fail("failed to write archive: {t}", .{err});228 return diags.fail("failed to write archive: {t}", .{err});
227 }229 }
228230