| ... | @@ -155,9 +155,7 @@ strtab: std.ArrayListUnmanaged(u8) = .{}, | ... | @@ -155,9 +155,7 @@ strtab: std.ArrayListUnmanaged(u8) = .{}, |
| 155 | strtab_dir: std.HashMapUnmanaged(u32, u32, StringIndexContext, std.hash_map.default_max_load_percentage) = .{}, | 155 | strtab_dir: std.HashMapUnmanaged(u32, u32, StringIndexContext, std.hash_map.default_max_load_percentage) = .{}, |
| 156 | | 156 | |
| 157 | got_entries_map: std.AutoArrayHashMapUnmanaged(GotIndirectionKey, *TextBlock) = .{}, | 157 | got_entries_map: std.AutoArrayHashMapUnmanaged(GotIndirectionKey, *TextBlock) = .{}, |
| 158 | | 158 | stubs_map: std.AutoArrayHashMapUnmanaged(u32, *TextBlock) = .{}, |
| 159 | stubs: std.ArrayListUnmanaged(u32) = .{}, | | |
| 160 | stubs_map: std.AutoHashMapUnmanaged(u32, u32) = .{}, | | |
| 161 | | 159 | |
| 162 | error_flags: File.ErrorFlags = File.ErrorFlags{}, | 160 | error_flags: File.ErrorFlags = File.ErrorFlags{}, |
| 163 | | 161 | |
| ... | @@ -783,27 +781,6 @@ pub fn flush(self: *MachO, comp: *Compilation) !void { | ... | @@ -783,27 +781,6 @@ pub fn flush(self: *MachO, comp: *Compilation) !void { |
| 783 | | 781 | |
| 784 | try self.parseTextBlocks(); | 782 | try self.parseTextBlocks(); |
| 785 | try self.sortSections(); | 783 | try self.sortSections(); |
| 786 | | | |
| 787 | for (self.stubs.items) |_| { | | |
| 788 | const stub_helper_atom = try self.createStubHelperAtom(); | | |
| 789 | try self.allocateAtomStage1(stub_helper_atom, .{ | | |
| 790 | .seg = self.text_segment_cmd_index.?, | | |
| 791 | .sect = self.stub_helper_section_index.?, | | |
| 792 | }); | | |
| 793 | | | |
| 794 | const laptr_atom = try self.createLazyPointerAtom(stub_helper_atom.local_sym_index); | | |
| 795 | try self.allocateAtomStage1(laptr_atom, .{ | | |
| 796 | .seg = self.data_segment_cmd_index.?, | | |
| 797 | .sect = self.la_symbol_ptr_section_index.?, | | |
| 798 | }); | | |
| 799 | | | |
| 800 | const stub_atom = try self.createStubAtom(laptr_atom.local_sym_index); | | |
| 801 | try self.allocateAtomStage1(stub_atom, .{ | | |
| 802 | .seg = self.text_segment_cmd_index.?, | | |
| 803 | .sect = self.stubs_section_index.?, | | |
| 804 | }); | | |
| 805 | } | | |
| 806 | | | |
| 807 | try self.allocateTextSegment(); | 784 | try self.allocateTextSegment(); |
| 808 | try self.allocateDataConstSegment(); | 785 | try self.allocateDataConstSegment(); |
| 809 | try self.allocateDataSegment(); | 786 | try self.allocateDataSegment(); |
| ... | @@ -2159,7 +2136,7 @@ fn createStubHelperPreambleAtom(self: *MachO) !*TextBlock { | ... | @@ -2159,7 +2136,7 @@ fn createStubHelperPreambleAtom(self: *MachO) !*TextBlock { |
| 2159 | return atom; | 2136 | return atom; |
| 2160 | } | 2137 | } |
| 2161 | | 2138 | |
| 2162 | fn createStubHelperAtom(self: *MachO) !*TextBlock { | 2139 | pub fn createStubHelperAtom(self: *MachO) !*TextBlock { |
| 2163 | const arch = self.base.options.target.cpu.arch; | 2140 | const arch = self.base.options.target.cpu.arch; |
| 2164 | const stub_size: u4 = switch (arch) { | 2141 | const stub_size: u4 = switch (arch) { |
| 2165 | .x86_64 => 10, | 2142 | .x86_64 => 10, |
| ... | @@ -2225,7 +2202,7 @@ fn createStubHelperAtom(self: *MachO) !*TextBlock { | ... | @@ -2225,7 +2202,7 @@ fn createStubHelperAtom(self: *MachO) !*TextBlock { |
| 2225 | return atom; | 2202 | return atom; |
| 2226 | } | 2203 | } |
| 2227 | | 2204 | |
| 2228 | fn createLazyPointerAtom(self: *MachO, stub_sym_index: u32) !*TextBlock { | 2205 | pub fn createLazyPointerAtom(self: *MachO, stub_sym_index: u32, lazy_binding_sym_index: u32) !*TextBlock { |
| 2229 | const local_sym_index = @intCast(u32, self.locals.items.len); | 2206 | const local_sym_index = @intCast(u32, self.locals.items.len); |
| 2230 | try self.locals.append(self.base.allocator, .{ | 2207 | try self.locals.append(self.base.allocator, .{ |
| 2231 | .n_strx = try self.makeString("lazy_ptr"), | 2208 | .n_strx = try self.makeString("lazy_ptr"), |
| ... | @@ -2248,11 +2225,15 @@ fn createLazyPointerAtom(self: *MachO, stub_sym_index: u32) !*TextBlock { | ... | @@ -2248,11 +2225,15 @@ fn createLazyPointerAtom(self: *MachO, stub_sym_index: u32) !*TextBlock { |
| 2248 | }, | 2225 | }, |
| 2249 | }); | 2226 | }); |
| 2250 | try atom.rebases.append(self.base.allocator, 0); | 2227 | try atom.rebases.append(self.base.allocator, 0); |
| | 2228 | try atom.lazy_bindings.append(self.base.allocator, .{ |
| | 2229 | .local_sym_index = lazy_binding_sym_index, |
| | 2230 | .offset = 0, |
| | 2231 | }); |
| 2251 | self.lazy_binding_info_dirty = true; | 2232 | self.lazy_binding_info_dirty = true; |
| 2252 | return atom; | 2233 | return atom; |
| 2253 | } | 2234 | } |
| 2254 | | 2235 | |
| 2255 | fn createStubAtom(self: *MachO, laptr_sym_index: u32) !*TextBlock { | 2236 | pub fn createStubAtom(self: *MachO, laptr_sym_index: u32) !*TextBlock { |
| 2256 | const arch = self.base.options.target.cpu.arch; | 2237 | const arch = self.base.options.target.cpu.arch; |
| 2257 | const alignment: u2 = switch (arch) { | 2238 | const alignment: u2 = switch (arch) { |
| 2258 | .x86_64 => 0, | 2239 | .x86_64 => 0, |
| ... | @@ -2661,7 +2642,10 @@ fn resolveSymbols(self: *MachO) !void { | ... | @@ -2661,7 +2642,10 @@ fn resolveSymbols(self: *MachO) !void { |
| 2661 | break :blk atom; | 2642 | break :blk atom; |
| 2662 | }; | 2643 | }; |
| 2663 | const laptr_atom = blk: { | 2644 | const laptr_atom = blk: { |
| 2664 | const atom = try self.createLazyPointerAtom(stub_helper_atom.local_sym_index); | 2645 | const atom = try self.createLazyPointerAtom( |
| | 2646 | stub_helper_atom.local_sym_index, |
| | 2647 | resolv.where_index, |
| | 2648 | ); |
| 2665 | const match = MatchingSection{ | 2649 | const match = MatchingSection{ |
| 2666 | .seg = self.data_segment_cmd_index.?, | 2650 | .seg = self.data_segment_cmd_index.?, |
| 2667 | .sect = self.la_symbol_ptr_section_index.?, | 2651 | .sect = self.la_symbol_ptr_section_index.?, |
| ... | @@ -2990,8 +2974,6 @@ fn writeRebaseInfoTableZld(self: *MachO) !void { | ... | @@ -2990,8 +2974,6 @@ fn writeRebaseInfoTableZld(self: *MachO) !void { |
| 2990 | } | 2974 | } |
| 2991 | } | 2975 | } |
| 2992 | | 2976 | |
| 2993 | std.sort.sort(bind.Pointer, pointers.items, {}, bind.pointerCmp); | | |
| 2994 | | | |
| 2995 | const size = try bind.rebaseInfoSize(pointers.items); | 2977 | const size = try bind.rebaseInfoSize(pointers.items); |
| 2996 | var buffer = try self.base.allocator.alloc(u8, @intCast(usize, size)); | 2978 | var buffer = try self.base.allocator.alloc(u8, @intCast(usize, size)); |
| 2997 | defer self.base.allocator.free(buffer); | 2979 | defer self.base.allocator.free(buffer); |
| ... | @@ -3067,22 +3049,29 @@ fn writeLazyBindInfoTableZld(self: *MachO) !void { | ... | @@ -3067,22 +3049,29 @@ fn writeLazyBindInfoTableZld(self: *MachO) !void { |
| 3067 | var pointers = std.ArrayList(bind.Pointer).init(self.base.allocator); | 3049 | var pointers = std.ArrayList(bind.Pointer).init(self.base.allocator); |
| 3068 | defer pointers.deinit(); | 3050 | defer pointers.deinit(); |
| 3069 | | 3051 | |
| 3070 | if (self.la_symbol_ptr_section_index) |idx| { | 3052 | if (self.la_symbol_ptr_section_index) |sect| blk: { |
| | 3053 | var atom = self.blocks.get(.{ |
| | 3054 | .seg = self.data_segment_cmd_index.?, |
| | 3055 | .sect = sect, |
| | 3056 | }) orelse break :blk; |
| 3071 | const seg = self.load_commands.items[self.data_segment_cmd_index.?].Segment; | 3057 | const seg = self.load_commands.items[self.data_segment_cmd_index.?].Segment; |
| 3072 | const sect = seg.sections.items[idx]; | 3058 | |
| 3073 | const base_offset = sect.addr - seg.inner.vmaddr; | 3059 | while (true) { |
| 3074 | const segment_id = @intCast(u16, self.data_segment_cmd_index.?); | 3060 | const sym = self.locals.items[atom.local_sym_index]; |
| 3075 | | 3061 | const base_offset = sym.n_value - seg.inner.vmaddr; |
| 3076 | try pointers.ensureUnusedCapacity(self.stubs.items.len); | 3062 | |
| 3077 | | 3063 | for (atom.lazy_bindings.items) |binding| { |
| 3078 | for (self.stubs.items) |import_id, i| { | 3064 | const bind_sym = self.undefs.items[binding.local_sym_index]; |
| 3079 | const sym = self.undefs.items[import_id]; | 3065 | try pointers.append(.{ |
| 3080 | pointers.appendAssumeCapacity(.{ | 3066 | .offset = binding.offset + base_offset, |
| 3081 | .offset = base_offset + i * @sizeOf(u64), | 3067 | .segment_id = self.data_segment_cmd_index.?, |
| 3082 | .segment_id = segment_id, | 3068 | .dylib_ordinal = @divExact(bind_sym.n_desc, macho.N_SYMBOL_RESOLVER), |
| 3083 | .dylib_ordinal = @divExact(sym.n_desc, macho.N_SYMBOL_RESOLVER), | 3069 | .name = self.getString(bind_sym.n_strx), |
| 3084 | .name = self.getString(sym.n_strx), | 3070 | }); |
| 3085 | }); | 3071 | } |
| | 3072 | if (atom.prev) |prev| { |
| | 3073 | atom = prev; |
| | 3074 | } else break; |
| 3086 | } | 3075 | } |
| 3087 | } | 3076 | } |
| 3088 | | 3077 | |
| ... | @@ -3245,7 +3234,7 @@ fn writeSymbolTable(self: *MachO) !void { | ... | @@ -3245,7 +3234,7 @@ fn writeSymbolTable(self: *MachO) !void { |
| 3245 | const data_segment = &self.load_commands.items[self.data_segment_cmd_index.?].Segment; | 3234 | const data_segment = &self.load_commands.items[self.data_segment_cmd_index.?].Segment; |
| 3246 | const la_symbol_ptr = &data_segment.sections.items[self.la_symbol_ptr_section_index.?]; | 3235 | const la_symbol_ptr = &data_segment.sections.items[self.la_symbol_ptr_section_index.?]; |
| 3247 | | 3236 | |
| 3248 | const nstubs = @intCast(u32, self.stubs.items.len); | 3237 | const nstubs = @intCast(u32, self.stubs_map.keys().len); |
| 3249 | const ngot_entries = @intCast(u32, self.got_entries_map.keys().len); | 3238 | const ngot_entries = @intCast(u32, self.got_entries_map.keys().len); |
| 3250 | | 3239 | |
| 3251 | dysymtab.indirectsymoff = @intCast(u32, seg.inner.fileoff + seg.inner.filesize); | 3240 | dysymtab.indirectsymoff = @intCast(u32, seg.inner.fileoff + seg.inner.filesize); |
| ... | @@ -3266,8 +3255,8 @@ fn writeSymbolTable(self: *MachO) !void { | ... | @@ -3266,8 +3255,8 @@ fn writeSymbolTable(self: *MachO) !void { |
| 3266 | var writer = stream.writer(); | 3255 | var writer = stream.writer(); |
| 3267 | | 3256 | |
| 3268 | stubs.reserved1 = 0; | 3257 | stubs.reserved1 = 0; |
| 3269 | for (self.stubs.items) |id| { | 3258 | for (self.stubs_map.keys()) |key| { |
| 3270 | try writer.writeIntLittle(u32, dysymtab.iundefsym + id); | 3259 | try writer.writeIntLittle(u32, dysymtab.iundefsym + key); |
| 3271 | } | 3260 | } |
| 3272 | | 3261 | |
| 3273 | got.reserved1 = nstubs; | 3262 | got.reserved1 = nstubs; |
| ... | @@ -3283,8 +3272,8 @@ fn writeSymbolTable(self: *MachO) !void { | ... | @@ -3283,8 +3272,8 @@ fn writeSymbolTable(self: *MachO) !void { |
| 3283 | } | 3272 | } |
| 3284 | | 3273 | |
| 3285 | la_symbol_ptr.reserved1 = got.reserved1 + ngot_entries; | 3274 | la_symbol_ptr.reserved1 = got.reserved1 + ngot_entries; |
| 3286 | for (self.stubs.items) |id| { | 3275 | for (self.stubs_map.keys()) |key| { |
| 3287 | try writer.writeIntLittle(u32, dysymtab.iundefsym + id); | 3276 | try writer.writeIntLittle(u32, dysymtab.iundefsym + key); |
| 3288 | } | 3277 | } |
| 3289 | | 3278 | |
| 3290 | try self.base.file.?.pwriteAll(buf, dysymtab.indirectsymoff); | 3279 | try self.base.file.?.pwriteAll(buf, dysymtab.indirectsymoff); |
| ... | @@ -3301,7 +3290,6 @@ pub fn deinit(self: *MachO) void { | ... | @@ -3301,7 +3290,6 @@ pub fn deinit(self: *MachO) void { |
| 3301 | | 3290 | |
| 3302 | self.section_ordinals.deinit(self.base.allocator); | 3291 | self.section_ordinals.deinit(self.base.allocator); |
| 3303 | self.got_entries_map.deinit(self.base.allocator); | 3292 | self.got_entries_map.deinit(self.base.allocator); |
| 3304 | self.stubs.deinit(self.base.allocator); | | |
| 3305 | self.stubs_map.deinit(self.base.allocator); | 3293 | self.stubs_map.deinit(self.base.allocator); |
| 3306 | self.strtab_dir.deinit(self.base.allocator); | 3294 | self.strtab_dir.deinit(self.base.allocator); |
| 3307 | self.strtab.deinit(self.base.allocator); | 3295 | self.strtab.deinit(self.base.allocator); |
| ... | @@ -4557,10 +4545,6 @@ pub fn addExternFn(self: *MachO, name: []const u8) !u32 { | ... | @@ -4557,10 +4545,6 @@ pub fn addExternFn(self: *MachO, name: []const u8) !u32 { |
| 4557 | }); | 4545 | }); |
| 4558 | try self.unresolved.putNoClobber(self.base.allocator, sym_index, .stub); | 4546 | try self.unresolved.putNoClobber(self.base.allocator, sym_index, .stub); |
| 4559 | | 4547 | |
| 4560 | const stubs_index = @intCast(u32, self.stubs.items.len); | | |
| 4561 | try self.stubs.append(self.base.allocator, sym_index); | | |
| 4562 | try self.stubs_map.putNoClobber(self.base.allocator, sym_index, stubs_index); | | |
| 4563 | | | |
| 4564 | return sym_index; | 4548 | return sym_index; |
| 4565 | } | 4549 | } |
| 4566 | | 4550 | |
| ... | @@ -4803,7 +4787,7 @@ fn writeIndirectSymbolTable(self: *MachO) !void { | ... | @@ -4803,7 +4787,7 @@ fn writeIndirectSymbolTable(self: *MachO) !void { |
| 4803 | const la_symbol_ptr = &data_segment.sections.items[self.la_symbol_ptr_section_index.?]; | 4787 | const la_symbol_ptr = &data_segment.sections.items[self.la_symbol_ptr_section_index.?]; |
| 4804 | const dysymtab = &self.load_commands.items[self.dysymtab_cmd_index.?].Dysymtab; | 4788 | const dysymtab = &self.load_commands.items[self.dysymtab_cmd_index.?].Dysymtab; |
| 4805 | | 4789 | |
| 4806 | const nstubs = @intCast(u32, self.stubs.items.len); | 4790 | const nstubs = @intCast(u32, self.stubs_map.keys().len); |
| 4807 | const ngot_entries = @intCast(u32, self.got_entries_map.keys().len); | 4791 | const ngot_entries = @intCast(u32, self.got_entries_map.keys().len); |
| 4808 | const allocated_size = self.allocatedSizeLinkedit(dysymtab.indirectsymoff); | 4792 | const allocated_size = self.allocatedSizeLinkedit(dysymtab.indirectsymoff); |
| 4809 | const nindirectsyms = nstubs * 2 + ngot_entries; | 4793 | const nindirectsyms = nstubs * 2 + ngot_entries; |
| ... | @@ -4825,8 +4809,8 @@ fn writeIndirectSymbolTable(self: *MachO) !void { | ... | @@ -4825,8 +4809,8 @@ fn writeIndirectSymbolTable(self: *MachO) !void { |
| 4825 | var writer = stream.writer(); | 4809 | var writer = stream.writer(); |
| 4826 | | 4810 | |
| 4827 | stubs.reserved1 = 0; | 4811 | stubs.reserved1 = 0; |
| 4828 | for (self.stubs.items) |id| { | 4812 | for (self.stubs_map.keys()) |key| { |
| 4829 | try writer.writeIntLittle(u32, dysymtab.iundefsym + id); | 4813 | try writer.writeIntLittle(u32, dysymtab.iundefsym + key); |
| 4830 | } | 4814 | } |
| 4831 | | 4815 | |
| 4832 | got.reserved1 = nstubs; | 4816 | got.reserved1 = nstubs; |
| ... | @@ -4842,8 +4826,8 @@ fn writeIndirectSymbolTable(self: *MachO) !void { | ... | @@ -4842,8 +4826,8 @@ fn writeIndirectSymbolTable(self: *MachO) !void { |
| 4842 | } | 4826 | } |
| 4843 | | 4827 | |
| 4844 | la_symbol_ptr.reserved1 = got.reserved1 + ngot_entries; | 4828 | la_symbol_ptr.reserved1 = got.reserved1 + ngot_entries; |
| 4845 | for (self.stubs.items) |id| { | 4829 | for (self.stubs_map.keys()) |key| { |
| 4846 | try writer.writeIntLittle(u32, dysymtab.iundefsym + id); | 4830 | try writer.writeIntLittle(u32, dysymtab.iundefsym + key); |
| 4847 | } | 4831 | } |
| 4848 | | 4832 | |
| 4849 | try self.base.file.?.pwriteAll(buf, dysymtab.indirectsymoff); | 4833 | try self.base.file.?.pwriteAll(buf, dysymtab.indirectsymoff); |
| ... | @@ -5050,8 +5034,6 @@ fn writeRebaseInfoTable(self: *MachO) !void { | ... | @@ -5050,8 +5034,6 @@ fn writeRebaseInfoTable(self: *MachO) !void { |
| 5050 | } | 5034 | } |
| 5051 | } | 5035 | } |
| 5052 | | 5036 | |
| 5053 | std.sort.sort(bind.Pointer, pointers.items, {}, bind.pointerCmp); | | |
| 5054 | | | |
| 5055 | const size = try bind.rebaseInfoSize(pointers.items); | 5037 | const size = try bind.rebaseInfoSize(pointers.items); |
| 5056 | var buffer = try self.base.allocator.alloc(u8, @intCast(usize, size)); | 5038 | var buffer = try self.base.allocator.alloc(u8, @intCast(usize, size)); |
| 5057 | defer self.base.allocator.free(buffer); | 5039 | defer self.base.allocator.free(buffer); |
| ... | @@ -5151,22 +5133,29 @@ fn writeLazyBindInfoTable(self: *MachO) !void { | ... | @@ -5151,22 +5133,29 @@ fn writeLazyBindInfoTable(self: *MachO) !void { |
| 5151 | var pointers = std.ArrayList(bind.Pointer).init(self.base.allocator); | 5133 | var pointers = std.ArrayList(bind.Pointer).init(self.base.allocator); |
| 5152 | defer pointers.deinit(); | 5134 | defer pointers.deinit(); |
| 5153 | | 5135 | |
| 5154 | if (self.la_symbol_ptr_section_index) |idx| { | 5136 | if (self.la_symbol_ptr_section_index) |sect| blk: { |
| | 5137 | var atom = self.blocks.get(.{ |
| | 5138 | .seg = self.data_segment_cmd_index.?, |
| | 5139 | .sect = sect, |
| | 5140 | }) orelse break :blk; |
| 5155 | const seg = self.load_commands.items[self.data_segment_cmd_index.?].Segment; | 5141 | const seg = self.load_commands.items[self.data_segment_cmd_index.?].Segment; |
| 5156 | const sect = seg.sections.items[idx]; | 5142 | |
| 5157 | const base_offset = sect.addr - seg.inner.vmaddr; | 5143 | while (true) { |
| 5158 | const segment_id = @intCast(u16, self.data_segment_cmd_index.?); | 5144 | const sym = self.locals.items[atom.local_sym_index]; |
| 5159 | | 5145 | const base_offset = sym.n_value - seg.inner.vmaddr; |
| 5160 | try pointers.ensureUnusedCapacity(self.stubs.items.len); | 5146 | |
| 5161 | | 5147 | for (atom.lazy_bindings.items) |binding| { |
| 5162 | for (self.stubs.items) |import_id, i| { | 5148 | const bind_sym = self.undefs.items[binding.local_sym_index]; |
| 5163 | const sym = self.undefs.items[import_id]; | 5149 | try pointers.append(.{ |
| 5164 | pointers.appendAssumeCapacity(.{ | 5150 | .offset = binding.offset + base_offset, |
| 5165 | .offset = base_offset + i * @sizeOf(u64), | 5151 | .segment_id = self.data_segment_cmd_index.?, |
| 5166 | .segment_id = segment_id, | 5152 | .dylib_ordinal = @divExact(bind_sym.n_desc, macho.N_SYMBOL_RESOLVER), |
| 5167 | .dylib_ordinal = @divExact(sym.n_desc, macho.N_SYMBOL_RESOLVER), | 5153 | .name = self.getString(bind_sym.n_strx), |
| 5168 | .name = self.getString(sym.n_strx), | 5154 | }); |
| 5169 | }); | 5155 | } |
| | 5156 | if (atom.prev) |prev| { |
| | 5157 | atom = prev; |
| | 5158 | } else break; |
| 5170 | } | 5159 | } |
| 5171 | } | 5160 | } |
| 5172 | | 5161 | |
| ... | @@ -5203,6 +5192,15 @@ fn populateLazyBindOffsetsInStubHelper(self: *MachO, buffer: []const u8) !void { | ... | @@ -5203,6 +5192,15 @@ fn populateLazyBindOffsetsInStubHelper(self: *MachO, buffer: []const u8) !void { |
| 5203 | }) orelse return; | 5192 | }) orelse return; |
| 5204 | if (last_atom.local_sym_index == self.stub_preamble_sym_index.?) return; | 5193 | if (last_atom.local_sym_index == self.stub_preamble_sym_index.?) return; |
| 5205 | | 5194 | |
| | 5195 | // Because we insert lazy binding opcodes in reverse order (from last to the first atom), |
| | 5196 | // we need reverse the order of atom traversal here as well. |
| | 5197 | // TODO figure out a less error prone mechanims for this! |
| | 5198 | var atom = last_atom; |
| | 5199 | while (atom.prev) |prev| { |
| | 5200 | atom = prev; |
| | 5201 | } |
| | 5202 | atom = atom.next.?; |
| | 5203 | |
| 5206 | var stream = std.io.fixedBufferStream(buffer); | 5204 | var stream = std.io.fixedBufferStream(buffer); |
| 5207 | var reader = stream.reader(); | 5205 | var reader = stream.reader(); |
| 5208 | var offsets = std.ArrayList(u32).init(self.base.allocator); | 5206 | var offsets = std.ArrayList(u32).init(self.base.allocator); |
| ... | @@ -5255,7 +5253,6 @@ fn populateLazyBindOffsetsInStubHelper(self: *MachO, buffer: []const u8) !void { | ... | @@ -5255,7 +5253,6 @@ fn populateLazyBindOffsetsInStubHelper(self: *MachO, buffer: []const u8) !void { |
| 5255 | else => unreachable, | 5253 | else => unreachable, |
| 5256 | }; | 5254 | }; |
| 5257 | var buf: [@sizeOf(u32)]u8 = undefined; | 5255 | var buf: [@sizeOf(u32)]u8 = undefined; |
| 5258 | var atom = last_atom; | | |
| 5259 | _ = offsets.pop(); | 5256 | _ = offsets.pop(); |
| 5260 | while (offsets.popOrNull()) |bind_offset| { | 5257 | while (offsets.popOrNull()) |bind_offset| { |
| 5261 | const sym = self.locals.items[atom.local_sym_index]; | 5258 | const sym = self.locals.items[atom.local_sym_index]; |
| ... | @@ -5268,8 +5265,8 @@ fn populateLazyBindOffsetsInStubHelper(self: *MachO, buffer: []const u8) !void { | ... | @@ -5268,8 +5265,8 @@ fn populateLazyBindOffsetsInStubHelper(self: *MachO, buffer: []const u8) !void { |
| 5268 | }); | 5265 | }); |
| 5269 | try self.base.file.?.pwriteAll(&buf, file_offset); | 5266 | try self.base.file.?.pwriteAll(&buf, file_offset); |
| 5270 | | 5267 | |
| 5271 | if (atom.prev) |prev| { | 5268 | if (atom.next) |next| { |
| 5272 | atom = prev; | 5269 | atom = next; |
| 5273 | } else break; | 5270 | } else break; |
| 5274 | } | 5271 | } |
| 5275 | } | 5272 | } |