Commit ef9fb428b7

zhylmzr <zhylmzr@gmail.com>
2024-04-24 11:17:47
fix: object size error in archive
1 parent 600b652
Changed files (4)
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,
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();
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,
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);
 }