| ... | @@ -1,6 +1,6 @@ | ... | @@ -1,6 +1,6 @@ |
| 1 | archive: ?Archive = null, | 1 | archive: ?Archive = null, |
| 2 | path: []const u8, | 2 | path: []const u8, |
| 3 | file: std.fs.File, | 3 | file_handle: File.HandleIndex, |
| 4 | mtime: u64, | 4 | mtime: u64, |
| 5 | index: File.Index, | 5 | index: File.Index, |
| 6 | | 6 | |
| ... | @@ -43,7 +43,6 @@ pub fn isObject(path: []const u8) !bool { | ... | @@ -43,7 +43,6 @@ pub fn isObject(path: []const u8) !bool { |
| 43 | } | 43 | } |
| 44 | | 44 | |
| 45 | pub fn deinit(self: *Object, allocator: Allocator) void { | 45 | pub 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 { |
| 73 | | 72 | |
| 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); |
| 76 | | 76 | |
| 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 | } |
| 103 | | 103 | |
| ... | @@ -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 | } |
| 130 | | 130 | |
| 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]; |
| 698 | | 698 | |
| 699 | // TODO: read into buffer directly | 699 | // 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); |
| 702 | | 702 | |
| 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 | }; |
| 801 | | 801 | |
| 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 { |
| 1019 | | 1019 | |
| 1020 | if (debug_info_index == null or debug_abbrev_index == null) return; | 1020 | if (debug_info_index == null or debug_abbrev_index == null) return; |
| 1021 | | 1021 | |
| 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); |
| 1028 | | 1028 | |
| 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 | } |
| 1591 | | 1591 | |
| 1592 | fn getSectionData(self: *const Object, allocator: Allocator, index: u32) ![]u8 { | 1592 | fn 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 | } |
| 1604 | | 1606 | |
| 1605 | pub fn getAtomData(self: *const Object, atom: Atom, buffer: []u8) !void { | 1607 | pub 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 | } |
| 1613 | | 1616 | |
| ... | @@ -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; |
| 1887 | | 1890 | |
| | 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]; |
| 1896 | | 1900 | |
| 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); |
| 1899 | | 1903 | |
| 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; |
| 2049 | | 2053 | |
| | 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]; |
| 2058 | | 2063 | |
| 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); |
| 2061 | | 2066 | |
| 2062 | try out.ensureTotalCapacityPrecise(gpa, relocs.len); | 2067 | try out.ensureTotalCapacityPrecise(gpa, relocs.len); |