diff --git a/src/link/Elf/Archive.zig b/src/link/Elf/Archive.zig index 76ab157bab..030ddc13c6 100644 --- a/src/link/Elf/Archive.zig +++ b/src/link/Elf/Archive.zig @@ -64,6 +64,7 @@ pub fn parse(self: *Archive, elf_file: *Elf, path: []const u8, handle_index: Fil .archive = .{ .path = try gpa.dupe(u8, path), .offset = pos, + .size = obj_size, }, .path = try gpa.dupe(u8, name), .file_handle = handle_index, diff --git a/src/link/Elf/Object.zig b/src/link/Elf/Object.zig index 57531916eb..c0e6266bb7 100644 --- a/src/link/Elf/Object.zig +++ b/src/link/Elf/Object.zig @@ -1009,13 +1009,15 @@ pub fn updateArSymtab(self: Object, ar_symtab: *Archive.ArSymtab, elf_file: *Elf } pub fn updateArSize(self: *Object, elf_file: *Elf) !void { - const handle = elf_file.fileHandle(self.file_handle); - const size = (try handle.stat()).size; - self.output_ar_state.size = size; + self.output_ar_state.size = if (self.archive) |ar| ar.size else size: { + const handle = elf_file.fileHandle(self.file_handle); + break :size (try handle.stat()).size; + }; } pub fn writeAr(self: Object, elf_file: *Elf, writer: anytype) !void { const size = std.math.cast(usize, self.output_ar_state.size) orelse return error.Overflow; + const offset: u64 = if (self.archive) |ar| ar.offset else 0; const name = self.path; const hdr = Archive.setArHdr(.{ .name = if (name.len <= Archive.max_member_name_len) @@ -1029,7 +1031,7 @@ pub fn writeAr(self: Object, elf_file: *Elf, writer: anytype) !void { const gpa = elf_file.base.comp.gpa; const data = try gpa.alloc(u8, size); defer gpa.free(data); - const amt = try handle.preadAll(data, 0); + const amt = try handle.preadAll(data, offset); if (amt != size) return error.InputOutput; try writer.writeAll(data); } @@ -1349,6 +1351,7 @@ fn formatPath( const InArchive = struct { path: []const u8, offset: u64, + size: u32, }; const Object = @This(); diff --git a/src/link/MachO/Archive.zig b/src/link/MachO/Archive.zig index 9285d5998b..c1ce582036 100644 --- a/src/link/MachO/Archive.zig +++ b/src/link/MachO/Archive.zig @@ -70,6 +70,7 @@ pub fn parse(self: *Archive, macho_file: *MachO, path: []const u8, handle_index: .archive = .{ .path = try gpa.dupe(u8, path), .offset = pos, + .size = hdr_size, }, .path = try gpa.dupe(u8, name), .file_handle = handle_index, diff --git a/src/link/MachO/Object.zig b/src/link/MachO/Object.zig index fa405fccf0..dcdb50ab0e 100644 --- a/src/link/MachO/Object.zig +++ b/src/link/MachO/Object.zig @@ -34,6 +34,7 @@ output_ar_state: Archive.ArState = .{}, const InArchive = struct { path: []const u8, offset: u64, + size: u32, }; pub fn isObject(path: []const u8) !bool { @@ -1330,14 +1331,16 @@ pub fn updateArSymtab(self: Object, ar_symtab: *Archive.ArSymtab, macho_file: *M } pub fn updateArSize(self: *Object, macho_file: *MachO) !void { - const file = macho_file.getFileHandle(self.file_handle); - const size = (try file.stat()).size; - self.output_ar_state.size = size; + self.output_ar_state.size = if (self.archive) |ar| ar.size else size: { + const file = macho_file.getFileHandle(self.file_handle); + break :size (try file.stat()).size; + }; } pub fn writeAr(self: Object, ar_format: Archive.Format, macho_file: *MachO, writer: anytype) !void { // Header const size = std.math.cast(usize, self.output_ar_state.size) orelse return error.Overflow; + const offset: u64 = if (self.archive) |ar| ar.offset else 0; try Archive.writeHeader(self.path, size, ar_format, writer); // Data const file = macho_file.getFileHandle(self.file_handle); @@ -1345,7 +1348,7 @@ pub fn writeAr(self: Object, ar_format: Archive.Format, macho_file: *MachO, writ const gpa = macho_file.base.comp.gpa; const data = try gpa.alloc(u8, size); defer gpa.free(data); - const amt = try file.preadAll(data, 0); + const amt = try file.preadAll(data, offset); if (amt != size) return error.InputOutput; try writer.writeAll(data); }