| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | archive: ?Archive = null, |
| 2 | 2 | path: []const u8, |
| 3 | | file: std.fs.File, |
| 3 | file_handle: File.HandleIndex, |
| 4 | 4 | mtime: u64, |
| 5 | 5 | index: File.Index, |
| 6 | 6 | |
| ... | ... | @@ -43,7 +43,6 @@ pub fn isObject(path: []const u8) !bool { |
| 43 | 43 | } |
| 44 | 44 | |
| 45 | 45 | pub fn deinit(self: *Object, allocator: Allocator) void { |
| 46 | | self.file.close(); |
| 47 | 46 | if (self.archive) |*ar| allocator.free(ar.path); |
| 48 | 47 | allocator.free(self.path); |
| 49 | 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 | 72 | |
| 74 | 73 | const gpa = macho_file.base.comp.gpa; |
| 75 | 74 | const offset = if (self.archive) |ar| ar.offset else 0; |
| 75 | const handle = macho_file.getFileHandle(self.file_handle); |
| 76 | 76 | |
| 77 | 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 | 80 | if (amt != @sizeOf(macho.mach_header_64)) return error.InputOutput; |
| 81 | 81 | } |
| 82 | 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 | 97 | const lc_buffer = try gpa.alloc(u8, self.header.?.sizeofcmds); |
| 98 | 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 | 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 | 124 | const cmd = lc.cast(macho.symtab_command).?; |
| 125 | 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 | 128 | if (amt != self.strtab.items.len) return error.InputOutput; |
| 129 | 129 | } |
| 130 | 130 | |
| 131 | 131 | const symtab_buffer = try gpa.alloc(u8, cmd.nsyms * @sizeOf(macho.nlist_64)); |
| 132 | 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 | 135 | if (amt != symtab_buffer.len) return error.InputOutput; |
| 136 | 136 | } |
| 137 | 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 | 149 | const buffer = try gpa.alloc(u8, cmd.datasize); |
| 150 | 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 | 153 | if (amt != buffer.len) return error.InputOutput; |
| 154 | 154 | } |
| 155 | 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 | 697 | const relocs = slice.items(.relocs)[sect_id]; |
| 698 | 698 | |
| 699 | 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 | 701 | defer gpa.free(data); |
| 702 | 702 | |
| 703 | 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 | 800 | }; |
| 801 | 801 | |
| 802 | 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 | 804 | defer gpa.free(data); |
| 805 | 805 | const nrecs = @divExact(data.len, @sizeOf(macho.compact_unwind_entry)); |
| 806 | 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 | 1019 | |
| 1020 | 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 | 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 | 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 | 1027 | defer gpa.free(debug_str); |
| 1028 | 1028 | |
| 1029 | 1029 | var dwarf_info = DwarfInfo{}; |
| ... | ... | @@ -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 | 1594 | const slice = self.sections.slice(); |
| 1594 | 1595 | assert(index < slice.items(.header).len); |
| 1595 | 1596 | const sect = slice.items(.header)[index]; |
| 1597 | const handle = macho_file.getFileHandle(self.file_handle); |
| 1596 | 1598 | const offset = if (self.archive) |ar| ar.offset else 0; |
| 1597 | 1599 | const size = math.cast(usize, sect.size) orelse return error.Overflow; |
| 1598 | | const buffer = try allocator.alloc(u8, size); |
| 1599 | | errdefer allocator.free(buffer); |
| 1600 | | const amt = try self.file.preadAll(buffer, sect.offset + offset); |
| 1600 | const buffer = try gpa.alloc(u8, size); |
| 1601 | errdefer gpa.free(buffer); |
| 1602 | const amt = try handle.preadAll(buffer, sect.offset + offset); |
| 1601 | 1603 | if (amt != buffer.len) return error.InputOutput; |
| 1602 | 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 | 1608 | assert(buffer.len == atom.size); |
| 1607 | 1609 | const slice = self.sections.slice(); |
| 1610 | const handle = macho_file.getFileHandle(self.file_handle); |
| 1608 | 1611 | const offset = if (self.archive) |ar| ar.offset else 0; |
| 1609 | 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 | 1614 | if (amt != buffer.len) return error.InputOutput; |
| 1612 | 1615 | } |
| 1613 | 1616 | |
| ... | ... | @@ -1885,16 +1888,17 @@ const x86_64 = struct { |
| 1885 | 1888 | ) !void { |
| 1886 | 1889 | const gpa = macho_file.base.comp.gpa; |
| 1887 | 1890 | |
| 1891 | const handle = macho_file.getFileHandle(self.file_handle); |
| 1888 | 1892 | const offset = if (self.archive) |ar| ar.offset else 0; |
| 1889 | 1893 | const relocs_buffer = try gpa.alloc(u8, sect.nreloc * @sizeOf(macho.relocation_info)); |
| 1890 | 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 | 1897 | if (amt != relocs_buffer.len) return error.InputOutput; |
| 1894 | 1898 | } |
| 1895 | 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 | 1902 | defer gpa.free(code); |
| 1899 | 1903 | |
| 1900 | 1904 | try out.ensureTotalCapacityPrecise(gpa, relocs.len); |
| ... | ... | @@ -2047,16 +2051,17 @@ const aarch64 = struct { |
| 2047 | 2051 | ) !void { |
| 2048 | 2052 | const gpa = macho_file.base.comp.gpa; |
| 2049 | 2053 | |
| 2054 | const handle = macho_file.getFileHandle(self.file_handle); |
| 2050 | 2055 | const offset = if (self.archive) |ar| ar.offset else 0; |
| 2051 | 2056 | const relocs_buffer = try gpa.alloc(u8, sect.nreloc * @sizeOf(macho.relocation_info)); |
| 2052 | 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 | 2060 | if (amt != relocs_buffer.len) return error.InputOutput; |
| 2056 | 2061 | } |
| 2057 | 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 | 2065 | defer gpa.free(code); |
| 2061 | 2066 | |
| 2062 | 2067 | try out.ensureTotalCapacityPrecise(gpa, relocs.len); |