authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-02-06 11:17:00+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-02-06 17:38:50+01:00
logdb6addf31ac6566fc219b6dbe971c5dd96d14edc
treea155c868836b59570f7430d8a1b6de94c4ecaf00
parent7bd8b35a3dfe61e59ffea39d464e84fbcdead29a

macho: store open file descriptors in a global array


5 files changed, 68 insertions(+), 36 deletions(-)

src/link/MachO.zig+28-6
...@@ -10,6 +10,10 @@ d_sym: ?DebugSymbols = null,...@@ -10,6 +10,10 @@ d_sym: ?DebugSymbols = null,
10/// Index of each input file also encodes the priority or precedence of one input file10/// Index of each input file also encodes the priority or precedence of one input file
11/// over another.11/// over another.
12files: std.MultiArrayList(File.Entry) = .{},12files: std.MultiArrayList(File.Entry) = .{},
13/// Long-lived list of all file descriptors.
14/// We store them globally rather than per actual File so that we can re-use
15/// one file handle per every object file within an archive.
16file_handles: std.ArrayListUnmanaged(File.Handle) = .{},
13zig_object: ?File.Index = null,17zig_object: ?File.Index = null,
14internal_object: ?File.Index = null,18internal_object: ?File.Index = null,
15objects: std.ArrayListUnmanaged(File.Index) = .{},19objects: std.ArrayListUnmanaged(File.Index) = .{},
...@@ -315,6 +319,11 @@ pub fn deinit(self: *MachO) void {...@@ -315,6 +319,11 @@ pub fn deinit(self: *MachO) void {
315 d_sym.deinit();319 d_sym.deinit();
316 }320 }
317321
322 for (self.file_handles.items) |handle| {
323 handle.close();
324 }
325 self.file_handles.deinit(gpa);
326
318 for (self.files.items(.tags), self.files.items(.data)) |tag, *data| switch (tag) {327 for (self.files.items(.tags), self.files.items(.data)) |tag, *data| switch (tag) {
319 .null => {},328 .null => {},
320 .zig_object => data.zig_object.deinit(gpa),329 .zig_object => data.zig_object.deinit(gpa),
...@@ -394,8 +403,6 @@ pub fn flushModule(self: *MachO, arena: Allocator, prog_node: *std.Progress.Node...@@ -394,8 +403,6 @@ pub fn flushModule(self: *MachO, arena: Allocator, prog_node: *std.Progress.Node
394 sub_prog_node.activate();403 sub_prog_node.activate();
395 defer sub_prog_node.end();404 defer sub_prog_node.end();
396405
397 const target = comp.root_mod.resolved_target.result;
398 _ = target;
399 const directory = self.base.emit.directory;406 const directory = self.base.emit.directory;
400 const full_out_path = try directory.join(arena, &[_][]const u8{self.base.emit.sub_path});407 const full_out_path = try directory.join(arena, &[_][]const u8{self.base.emit.sub_path});
401 const module_obj_path: ?[]const u8 = if (self.base.zcu_object_sub_path) |path| blk: {408 const module_obj_path: ?[]const u8 = if (self.base.zcu_object_sub_path) |path| blk: {
...@@ -985,6 +992,8 @@ fn parseObject(self: *MachO, path: []const u8) ParseError!void {...@@ -985,6 +992,8 @@ fn parseObject(self: *MachO, path: []const u8) ParseError!void {
985992
986 const gpa = self.base.comp.gpa;993 const gpa = self.base.comp.gpa;
987 const file = try std.fs.cwd().openFile(path, .{});994 const file = try std.fs.cwd().openFile(path, .{});
995 errdefer file.close();
996 const handle = try self.addFileHandle(file);
988 const mtime: u64 = mtime: {997 const mtime: u64 = mtime: {
989 const stat = file.stat() catch break :mtime 0;998 const stat = file.stat() catch break :mtime 0;
990 break :mtime @as(u64, @intCast(@divFloor(stat.mtime, 1_000_000_000)));999 break :mtime @as(u64, @intCast(@divFloor(stat.mtime, 1_000_000_000)));
...@@ -992,7 +1001,7 @@ fn parseObject(self: *MachO, path: []const u8) ParseError!void {...@@ -992,7 +1001,7 @@ fn parseObject(self: *MachO, path: []const u8) ParseError!void {
992 const index = @as(File.Index, @intCast(try self.files.addOne(gpa)));1001 const index = @as(File.Index, @intCast(try self.files.addOne(gpa)));
993 self.files.set(index, .{ .object = .{1002 self.files.set(index, .{ .object = .{
994 .path = try gpa.dupe(u8, path),1003 .path = try gpa.dupe(u8, path),
995 .file = file,1004 .file_handle = handle,
996 .mtime = mtime,1005 .mtime = mtime,
997 .index = index,1006 .index = index,
998 } });1007 } });
...@@ -1020,11 +1029,12 @@ fn parseArchive(self: *MachO, lib: SystemLib, must_link: bool, fat_arch: ?fat.Ar...@@ -1020,11 +1029,12 @@ fn parseArchive(self: *MachO, lib: SystemLib, must_link: bool, fat_arch: ?fat.Ar
1020 const gpa = self.base.comp.gpa;1029 const gpa = self.base.comp.gpa;
10211030
1022 const file = try std.fs.cwd().openFile(lib.path, .{});1031 const file = try std.fs.cwd().openFile(lib.path, .{});
1023 defer file.close();1032 errdefer file.close();
1033 const handle = try self.addFileHandle(file);
10241034
1025 var archive = Archive{};1035 var archive = Archive{};
1026 defer archive.deinit(gpa);1036 defer archive.deinit(gpa);
1027 try archive.parse(self, lib.path, file, fat_arch);1037 try archive.parse(self, lib.path, handle, fat_arch);
10281038
1029 var has_parse_error = false;1039 var has_parse_error = false;
1030 for (archive.objects.items) |extracted| {1040 for (archive.objects.items) |extracted| {
...@@ -3796,6 +3806,19 @@ pub fn getInternalObject(self: *MachO) ?*InternalObject {...@@ -3796,6 +3806,19 @@ pub fn getInternalObject(self: *MachO) ?*InternalObject {
3796 return self.getFile(index).?.internal;3806 return self.getFile(index).?.internal;
3797}3807}
37983808
3809pub fn addFileHandle(self: *MachO, file: std.fs.File) !File.HandleIndex {
3810 const gpa = self.base.comp.gpa;
3811 const index: File.HandleIndex = @intCast(self.file_handles.items.len);
3812 const fh = try self.file_handles.addOne(gpa);
3813 fh.* = file;
3814 return index;
3815}
3816
3817pub fn getFileHandle(self: MachO, index: File.HandleIndex) File.Handle {
3818 assert(index < self.file_handles.items.len);
3819 return self.file_handles.items[index];
3820}
3821
3799pub fn addAtom(self: *MachO) error{OutOfMemory}!Atom.Index {3822pub fn addAtom(self: *MachO) error{OutOfMemory}!Atom.Index {
3800 const index = @as(Atom.Index, @intCast(self.atoms.items.len));3823 const index = @as(Atom.Index, @intCast(self.atoms.items.len));
3801 const atom = try self.atoms.addOne(self.base.comp.gpa);3824 const atom = try self.atoms.addOne(self.base.comp.gpa);
...@@ -4616,7 +4639,6 @@ const Cache = std.Build.Cache;...@@ -4616,7 +4639,6 @@ const Cache = std.Build.Cache;
4616const CodeSignature = @import("MachO/CodeSignature.zig");4639const CodeSignature = @import("MachO/CodeSignature.zig");
4617const Compilation = @import("../Compilation.zig");4640const Compilation = @import("../Compilation.zig");
4618pub const DebugSymbols = @import("MachO/DebugSymbols.zig");4641pub const DebugSymbols = @import("MachO/DebugSymbols.zig");
4619const Dwarf = File.Dwarf;
4620const DwarfInfo = @import("MachO/DwarfInfo.zig");4642const DwarfInfo = @import("MachO/DwarfInfo.zig");
4621const Dylib = @import("MachO/Dylib.zig");4643const Dylib = @import("MachO/Dylib.zig");
4622const ExportTrieSection = synthetic.ExportTrieSection;4644const ExportTrieSection = synthetic.ExportTrieSection;
src/link/MachO/Archive.zig+9-7
...@@ -73,24 +73,25 @@ pub fn deinit(self: *Archive, allocator: Allocator) void {...@@ -73,24 +73,25 @@ pub fn deinit(self: *Archive, allocator: Allocator) void {
73 self.objects.deinit(allocator);73 self.objects.deinit(allocator);
74}74}
7575
76pub fn parse(self: *Archive, macho_file: *MachO, path: []const u8, file: std.fs.File, fat_arch: ?fat.Arch) !void {76pub fn parse(self: *Archive, macho_file: *MachO, path: []const u8, handle_index: File.HandleIndex, fat_arch: ?fat.Arch) !void {
77 const gpa = macho_file.base.comp.gpa;77 const gpa = macho_file.base.comp.gpa;
7878
79 var arena = std.heap.ArenaAllocator.init(gpa);79 var arena = std.heap.ArenaAllocator.init(gpa);
80 defer arena.deinit();80 defer arena.deinit();
8181
82 const handle = macho_file.getFileHandle(handle_index);
82 const offset = if (fat_arch) |ar| ar.offset else 0;83 const offset = if (fat_arch) |ar| ar.offset else 0;
83 const size = if (fat_arch) |ar| ar.size else (try file.stat()).size;84 const size = if (fat_arch) |ar| ar.size else (try handle.stat()).size;
84 try file.seekTo(offset);85 try handle.seekTo(offset);
8586
86 const reader = file.reader();87 const reader = handle.reader();
87 _ = try reader.readBytesNoEof(Archive.SARMAG);88 _ = try reader.readBytesNoEof(Archive.SARMAG);
8889
89 var pos: usize = Archive.SARMAG;90 var pos: usize = Archive.SARMAG;
90 while (true) {91 while (true) {
91 if (pos >= size) break;92 if (pos >= size) break;
92 if (!mem.isAligned(pos, 2)) {93 if (!mem.isAligned(pos, 2)) {
93 try file.seekBy(1);94 try handle.seekBy(1);
94 pos += 1;95 pos += 1;
95 }96 }
9697
...@@ -118,7 +119,7 @@ pub fn parse(self: *Archive, macho_file: *MachO, path: []const u8, file: std.fs....@@ -118,7 +119,7 @@ pub fn parse(self: *Archive, macho_file: *MachO, path: []const u8, file: std.fs.
118 unreachable;119 unreachable;
119 };120 };
120 defer {121 defer {
121 _ = file.seekBy(hdr_size) catch {};122 _ = handle.seekBy(hdr_size) catch {};
122 pos += hdr_size;123 pos += hdr_size;
123 }124 }
124125
...@@ -130,7 +131,7 @@ pub fn parse(self: *Archive, macho_file: *MachO, path: []const u8, file: std.fs....@@ -130,7 +131,7 @@ pub fn parse(self: *Archive, macho_file: *MachO, path: []const u8, file: std.fs.
130 .offset = offset + pos,131 .offset = offset + pos,
131 },132 },
132 .path = try gpa.dupe(u8, name),133 .path = try gpa.dupe(u8, name),
133 .file = try std.fs.cwd().openFile(path, .{}),134 .file_handle = handle_index,
134 .index = undefined,135 .index = undefined,
135 .alive = false,136 .alive = false,
136 .mtime = hdr.date() catch 0,137 .mtime = hdr.date() catch 0,
...@@ -150,5 +151,6 @@ const std = @import("std");...@@ -150,5 +151,6 @@ const std = @import("std");
150151
151const Allocator = mem.Allocator;152const Allocator = mem.Allocator;
152const Archive = @This();153const Archive = @This();
154const File = @import("file.zig").File;
153const MachO = @import("../MachO.zig");155const MachO = @import("../MachO.zig");
154const Object = @import("Object.zig");156const Object = @import("Object.zig");
src/link/MachO/Atom.zig+1-1
...@@ -58,7 +58,7 @@ pub fn getData(self: Atom, macho_file: *MachO, buffer: []u8) !void {...@@ -58,7 +58,7 @@ pub fn getData(self: Atom, macho_file: *MachO, buffer: []u8) !void {
58 assert(buffer.len == self.size);58 assert(buffer.len == self.size);
59 switch (self.getFile(macho_file)) {59 switch (self.getFile(macho_file)) {
60 .internal => |x| try x.getAtomData(self, buffer),60 .internal => |x| try x.getAtomData(self, buffer),
61 .object => |x| try x.getAtomData(self, buffer),61 .object => |x| try x.getAtomData(macho_file, self, buffer),
62 .zig_object => |x| try x.getAtomData(macho_file, self, buffer),62 .zig_object => |x| try x.getAtomData(macho_file, self, buffer),
63 else => unreachable,63 else => unreachable,
64 }64 }
src/link/MachO/Object.zig+27-22
...@@ -1,6 +1,6 @@...@@ -1,6 +1,6 @@
1archive: ?Archive = null,1archive: ?Archive = null,
2path: []const u8,2path: []const u8,
3file: std.fs.File,3file_handle: File.HandleIndex,
4mtime: u64,4mtime: u64,
5index: File.Index,5index: File.Index,
66
...@@ -43,7 +43,6 @@ pub fn isObject(path: []const u8) !bool {...@@ -43,7 +43,6 @@ pub fn isObject(path: []const u8) !bool {
43}43}
4444
45pub fn deinit(self: *Object, allocator: Allocator) void {45pub fn deinit(self: *Object, allocator: Allocator) void {
46 self.file.close();
47 if (self.archive) |*ar| allocator.free(ar.path);46 if (self.archive) |*ar| allocator.free(ar.path);
48 allocator.free(self.path);47 allocator.free(self.path);
49 for (self.sections.items(.relocs), self.sections.items(.subsections)) |*relocs, *sub| {48 for (self.sections.items(.relocs), self.sections.items(.subsections)) |*relocs, *sub| {
...@@ -73,10 +72,11 @@ pub fn parse(self: *Object, macho_file: *MachO) !void {...@@ -73,10 +72,11 @@ pub fn parse(self: *Object, macho_file: *MachO) !void {
7372
74 const gpa = macho_file.base.comp.gpa;73 const gpa = macho_file.base.comp.gpa;
75 const offset = if (self.archive) |ar| ar.offset else 0;74 const offset = if (self.archive) |ar| ar.offset else 0;
75 const handle = macho_file.getFileHandle(self.file_handle);
7676
77 var header_buffer: [@sizeOf(macho.mach_header_64)]u8 = undefined;77 var header_buffer: [@sizeOf(macho.mach_header_64)]u8 = undefined;
78 {78 {
79 const amt = try self.file.preadAll(&header_buffer, offset);79 const amt = try handle.preadAll(&header_buffer, offset);
80 if (amt != @sizeOf(macho.mach_header_64)) return error.InputOutput;80 if (amt != @sizeOf(macho.mach_header_64)) return error.InputOutput;
81 }81 }
82 self.header = @as(*align(1) const macho.mach_header_64, @ptrCast(&header_buffer)).*;82 self.header = @as(*align(1) const macho.mach_header_64, @ptrCast(&header_buffer)).*;
...@@ -97,7 +97,7 @@ pub fn parse(self: *Object, macho_file: *MachO) !void {...@@ -97,7 +97,7 @@ pub fn parse(self: *Object, macho_file: *MachO) !void {
97 const lc_buffer = try gpa.alloc(u8, self.header.?.sizeofcmds);97 const lc_buffer = try gpa.alloc(u8, self.header.?.sizeofcmds);
98 defer gpa.free(lc_buffer);98 defer gpa.free(lc_buffer);
99 {99 {
100 const amt = try self.file.preadAll(lc_buffer, offset + @sizeOf(macho.mach_header_64));100 const amt = try handle.preadAll(lc_buffer, offset + @sizeOf(macho.mach_header_64));
101 if (amt != self.header.?.sizeofcmds) return error.InputOutput;101 if (amt != self.header.?.sizeofcmds) return error.InputOutput;
102 }102 }
103103
...@@ -124,14 +124,14 @@ pub fn parse(self: *Object, macho_file: *MachO) !void {...@@ -124,14 +124,14 @@ pub fn parse(self: *Object, macho_file: *MachO) !void {
124 const cmd = lc.cast(macho.symtab_command).?;124 const cmd = lc.cast(macho.symtab_command).?;
125 try self.strtab.resize(gpa, cmd.strsize);125 try self.strtab.resize(gpa, cmd.strsize);
126 {126 {
127 const amt = try self.file.preadAll(self.strtab.items, cmd.stroff + offset);127 const amt = try handle.preadAll(self.strtab.items, cmd.stroff + offset);
128 if (amt != self.strtab.items.len) return error.InputOutput;128 if (amt != self.strtab.items.len) return error.InputOutput;
129 }129 }
130130
131 const symtab_buffer = try gpa.alloc(u8, cmd.nsyms * @sizeOf(macho.nlist_64));131 const symtab_buffer = try gpa.alloc(u8, cmd.nsyms * @sizeOf(macho.nlist_64));
132 defer gpa.free(symtab_buffer);132 defer gpa.free(symtab_buffer);
133 {133 {
134 const amt = try self.file.preadAll(symtab_buffer, cmd.symoff + offset);134 const amt = try handle.preadAll(symtab_buffer, cmd.symoff + offset);
135 if (amt != symtab_buffer.len) return error.InputOutput;135 if (amt != symtab_buffer.len) return error.InputOutput;
136 }136 }
137 const symtab = @as([*]align(1) const macho.nlist_64, @ptrCast(symtab_buffer.ptr))[0..cmd.nsyms];137 const symtab = @as([*]align(1) const macho.nlist_64, @ptrCast(symtab_buffer.ptr))[0..cmd.nsyms];
...@@ -149,7 +149,7 @@ pub fn parse(self: *Object, macho_file: *MachO) !void {...@@ -149,7 +149,7 @@ pub fn parse(self: *Object, macho_file: *MachO) !void {
149 const buffer = try gpa.alloc(u8, cmd.datasize);149 const buffer = try gpa.alloc(u8, cmd.datasize);
150 defer gpa.free(buffer);150 defer gpa.free(buffer);
151 {151 {
152 const amt = try self.file.preadAll(buffer, offset + cmd.dataoff);152 const amt = try handle.preadAll(buffer, offset + cmd.dataoff);
153 if (amt != buffer.len) return error.InputOutput;153 if (amt != buffer.len) return error.InputOutput;
154 }154 }
155 const ndice = @divExact(cmd.datasize, @sizeOf(macho.data_in_code_entry));155 const ndice = @divExact(cmd.datasize, @sizeOf(macho.data_in_code_entry));
...@@ -697,7 +697,7 @@ fn initEhFrameRecords(self: *Object, sect_id: u8, macho_file: *MachO) !void {...@@ -697,7 +697,7 @@ fn initEhFrameRecords(self: *Object, sect_id: u8, macho_file: *MachO) !void {
697 const relocs = slice.items(.relocs)[sect_id];697 const relocs = slice.items(.relocs)[sect_id];
698698
699 // TODO: read into buffer directly699 // TODO: read into buffer directly
700 const data = try self.getSectionData(gpa, sect_id);700 const data = try self.getSectionData(sect_id, macho_file);
701 defer gpa.free(data);701 defer gpa.free(data);
702702
703 try self.eh_frame_data.ensureTotalCapacityPrecise(gpa, data.len);703 try self.eh_frame_data.ensureTotalCapacityPrecise(gpa, data.len);
...@@ -800,7 +800,7 @@ fn initUnwindRecords(self: *Object, sect_id: u8, macho_file: *MachO) !void {...@@ -800,7 +800,7 @@ fn initUnwindRecords(self: *Object, sect_id: u8, macho_file: *MachO) !void {
800 };800 };
801801
802 const gpa = macho_file.base.comp.gpa;802 const gpa = macho_file.base.comp.gpa;
803 const data = try self.getSectionData(gpa, sect_id);803 const data = try self.getSectionData(sect_id, macho_file);
804 defer gpa.free(data);804 defer gpa.free(data);
805 const nrecs = @divExact(data.len, @sizeOf(macho.compact_unwind_entry));805 const nrecs = @divExact(data.len, @sizeOf(macho.compact_unwind_entry));
806 const recs = @as([*]align(1) const macho.compact_unwind_entry, @ptrCast(data.ptr))[0..nrecs];806 const recs = @as([*]align(1) const macho.compact_unwind_entry, @ptrCast(data.ptr))[0..nrecs];
...@@ -1019,11 +1019,11 @@ fn initDwarfInfo(self: *Object, macho_file: *MachO) !void {...@@ -1019,11 +1019,11 @@ fn initDwarfInfo(self: *Object, macho_file: *MachO) !void {
10191019
1020 if (debug_info_index == null or debug_abbrev_index == null) return;1020 if (debug_info_index == null or debug_abbrev_index == null) return;
10211021
1022 const debug_info = try self.getSectionData(gpa, @intCast(debug_info_index.?));1022 const debug_info = try self.getSectionData(@intCast(debug_info_index.?), macho_file);
1023 defer gpa.free(debug_info);1023 defer gpa.free(debug_info);
1024 const debug_abbrev = try self.getSectionData(gpa, @intCast(debug_abbrev_index.?));1024 const debug_abbrev = try self.getSectionData(@intCast(debug_abbrev_index.?), macho_file);
1025 defer gpa.free(debug_abbrev);1025 defer gpa.free(debug_abbrev);
1026 const debug_str = if (debug_str_index) |index| try self.getSectionData(gpa, @intCast(index)) else &[0]u8{};1026 const debug_str = if (debug_str_index) |index| try self.getSectionData(@intCast(index), macho_file) else &[0]u8{};
1027 defer gpa.free(debug_str);1027 defer gpa.free(debug_str);
10281028
1029 var dwarf_info = DwarfInfo{};1029 var dwarf_info = DwarfInfo{};
...@@ -1589,25 +1589,28 @@ pub fn writeStabs(self: *const Object, macho_file: *MachO, ctx: anytype) error{O...@@ -1589,25 +1589,28 @@ pub fn writeStabs(self: *const Object, macho_file: *MachO, ctx: anytype) error{O
1589 }1589 }
1590}1590}
15911591
1592fn getSectionData(self: *const Object, allocator: Allocator, index: u32) ![]u8 {1592fn getSectionData(self: *const Object, index: u32, macho_file: *MachO) ![]u8 {
1593 const gpa = macho_file.base.comp.gpa;
1593 const slice = self.sections.slice();1594 const slice = self.sections.slice();
1594 assert(index < slice.items(.header).len);1595 assert(index < slice.items(.header).len);
1595 const sect = slice.items(.header)[index];1596 const sect = slice.items(.header)[index];
1597 const handle = macho_file.getFileHandle(self.file_handle);
1596 const offset = if (self.archive) |ar| ar.offset else 0;1598 const offset = if (self.archive) |ar| ar.offset else 0;
1597 const size = math.cast(usize, sect.size) orelse return error.Overflow;1599 const size = math.cast(usize, sect.size) orelse return error.Overflow;
1598 const buffer = try allocator.alloc(u8, size);1600 const buffer = try gpa.alloc(u8, size);
1599 errdefer allocator.free(buffer);1601 errdefer gpa.free(buffer);
1600 const amt = try self.file.preadAll(buffer, sect.offset + offset);1602 const amt = try handle.preadAll(buffer, sect.offset + offset);
1601 if (amt != buffer.len) return error.InputOutput;1603 if (amt != buffer.len) return error.InputOutput;
1602 return buffer;1604 return buffer;
1603}1605}
16041606
1605pub fn getAtomData(self: *const Object, atom: Atom, buffer: []u8) !void {1607pub fn getAtomData(self: *const Object, macho_file: *MachO, atom: Atom, buffer: []u8) !void {
1606 assert(buffer.len == atom.size);1608 assert(buffer.len == atom.size);
1607 const slice = self.sections.slice();1609 const slice = self.sections.slice();
1610 const handle = macho_file.getFileHandle(self.file_handle);
1608 const offset = if (self.archive) |ar| ar.offset else 0;1611 const offset = if (self.archive) |ar| ar.offset else 0;
1609 const sect = slice.items(.header)[atom.n_sect];1612 const sect = slice.items(.header)[atom.n_sect];
1610 const amt = try self.file.preadAll(buffer, sect.offset + offset + atom.off);1613 const amt = try handle.preadAll(buffer, sect.offset + offset + atom.off);
1611 if (amt != buffer.len) return error.InputOutput;1614 if (amt != buffer.len) return error.InputOutput;
1612}1615}
16131616
...@@ -1885,16 +1888,17 @@ const x86_64 = struct {...@@ -1885,16 +1888,17 @@ const x86_64 = struct {
1885 ) !void {1888 ) !void {
1886 const gpa = macho_file.base.comp.gpa;1889 const gpa = macho_file.base.comp.gpa;
18871890
1891 const handle = macho_file.getFileHandle(self.file_handle);
1888 const offset = if (self.archive) |ar| ar.offset else 0;1892 const offset = if (self.archive) |ar| ar.offset else 0;
1889 const relocs_buffer = try gpa.alloc(u8, sect.nreloc * @sizeOf(macho.relocation_info));1893 const relocs_buffer = try gpa.alloc(u8, sect.nreloc * @sizeOf(macho.relocation_info));
1890 defer gpa.free(relocs_buffer);1894 defer gpa.free(relocs_buffer);
1891 {1895 {
1892 const amt = try self.file.preadAll(relocs_buffer, sect.reloff + offset);1896 const amt = try handle.preadAll(relocs_buffer, sect.reloff + offset);
1893 if (amt != relocs_buffer.len) return error.InputOutput;1897 if (amt != relocs_buffer.len) return error.InputOutput;
1894 }1898 }
1895 const relocs = @as([*]align(1) const macho.relocation_info, @ptrCast(relocs_buffer.ptr))[0..sect.nreloc];1899 const relocs = @as([*]align(1) const macho.relocation_info, @ptrCast(relocs_buffer.ptr))[0..sect.nreloc];
18961900
1897 const code = try self.getSectionData(gpa, @intCast(n_sect));1901 const code = try self.getSectionData(@intCast(n_sect), macho_file);
1898 defer gpa.free(code);1902 defer gpa.free(code);
18991903
1900 try out.ensureTotalCapacityPrecise(gpa, relocs.len);1904 try out.ensureTotalCapacityPrecise(gpa, relocs.len);
...@@ -2047,16 +2051,17 @@ const aarch64 = struct {...@@ -2047,16 +2051,17 @@ const aarch64 = struct {
2047 ) !void {2051 ) !void {
2048 const gpa = macho_file.base.comp.gpa;2052 const gpa = macho_file.base.comp.gpa;
20492053
2054 const handle = macho_file.getFileHandle(self.file_handle);
2050 const offset = if (self.archive) |ar| ar.offset else 0;2055 const offset = if (self.archive) |ar| ar.offset else 0;
2051 const relocs_buffer = try gpa.alloc(u8, sect.nreloc * @sizeOf(macho.relocation_info));2056 const relocs_buffer = try gpa.alloc(u8, sect.nreloc * @sizeOf(macho.relocation_info));
2052 defer gpa.free(relocs_buffer);2057 defer gpa.free(relocs_buffer);
2053 {2058 {
2054 const amt = try self.file.preadAll(relocs_buffer, sect.reloff + offset);2059 const amt = try handle.preadAll(relocs_buffer, sect.reloff + offset);
2055 if (amt != relocs_buffer.len) return error.InputOutput;2060 if (amt != relocs_buffer.len) return error.InputOutput;
2056 }2061 }
2057 const relocs = @as([*]align(1) const macho.relocation_info, @ptrCast(relocs_buffer.ptr))[0..sect.nreloc];2062 const relocs = @as([*]align(1) const macho.relocation_info, @ptrCast(relocs_buffer.ptr))[0..sect.nreloc];
20582063
2059 const code = try self.getSectionData(gpa, @intCast(n_sect));2064 const code = try self.getSectionData(@intCast(n_sect), macho_file);
2060 defer gpa.free(code);2065 defer gpa.free(code);
20612066
2062 try out.ensureTotalCapacityPrecise(gpa, relocs.len);2067 try out.ensureTotalCapacityPrecise(gpa, relocs.len);
src/link/MachO/file.zig+3
...@@ -105,6 +105,9 @@ pub const File = union(enum) {...@@ -105,6 +105,9 @@ pub const File = union(enum) {
105 object: Object,105 object: Object,
106 dylib: Dylib,106 dylib: Dylib,
107 };107 };
108
109 pub const Handle = std.fs.File;
110 pub const HandleIndex = Index;
108};111};
109112
110const macho = std.macho;113const macho = std.macho;