| ... | ... | @@ -159,19 +159,29 @@ last_text_block: ?*TextBlock = null, |
| 159 | 159 | /// prior to calling `generateSymbol`, and then immediately deallocated |
| 160 | 160 | /// rather than sitting in the global scope. |
| 161 | 161 | pie_fixups: std.ArrayListUnmanaged(PieFixup) = .{}, |
| 162 | | |
| 162 | /// A list of all stub (extern decls) fixups required for this run of the linker. |
| 163 | /// Warning, this is currently NOT thread-safe. See the TODO below. |
| 164 | /// TODO Move this list inside `updateDecl` where it should be allocated |
| 165 | /// prior to calling `generateSymbol`, and then immediately deallocated |
| 166 | /// rather than sitting in the global scope. |
| 163 | 167 | stub_fixups: std.ArrayListUnmanaged(StubFixup) = .{}, |
| 164 | 168 | |
| 165 | | pub const StubFixup = struct { |
| 166 | | symbol: u32, |
| 167 | | already_defined: bool, |
| 169 | pub const PieFixup = struct { |
| 170 | /// Target address we wanted to address in absolute terms. |
| 171 | address: u64, |
| 172 | /// Where in the byte stream we should perform the fixup. |
| 168 | 173 | start: usize, |
| 174 | /// The length of the byte stream. For x86_64, this will be |
| 175 | /// variable. For aarch64, it will be fixed at 4 bytes. |
| 169 | 176 | len: usize, |
| 170 | 177 | }; |
| 171 | 178 | |
| 172 | | pub const PieFixup = struct { |
| 173 | | /// Target address we wanted to address in absolute terms. |
| 174 | | address: u64, |
| 179 | pub const StubFixup = struct { |
| 180 | /// Id of extern (lazy) symbol. |
| 181 | symbol: u32, |
| 182 | /// Signals whether the symbol has already been declared before. If so, |
| 183 | /// then there is no need to rewrite the stub entry and related. |
| 184 | already_defined: bool, |
| 175 | 185 | /// Where in the byte stream we should perform the fixup. |
| 176 | 186 | start: usize, |
| 177 | 187 | /// The length of the byte stream. For x86_64, this will be |
| ... | ... | @@ -1030,13 +1040,20 @@ pub fn deinit(self: *MachO) void { |
| 1030 | 1040 | if (self.d_sym) |*ds| { |
| 1031 | 1041 | ds.deinit(self.base.allocator); |
| 1032 | 1042 | } |
| 1043 | for (self.extern_lazy_symbols.items()) |*entry| { |
| 1044 | entry.value.deinit(self.base.allocator); |
| 1045 | } |
| 1046 | self.extern_lazy_symbols.deinit(self.base.allocator); |
| 1047 | for (self.extern_nonlazy_symbols.items()) |*entry| { |
| 1048 | entry.value.deinit(self.base.allocator); |
| 1049 | } |
| 1050 | self.extern_nonlazy_symbols.deinit(self.base.allocator); |
| 1033 | 1051 | self.pie_fixups.deinit(self.base.allocator); |
| 1052 | self.stub_fixups.deinit(self.base.allocator); |
| 1034 | 1053 | self.text_block_free_list.deinit(self.base.allocator); |
| 1035 | 1054 | self.offset_table.deinit(self.base.allocator); |
| 1036 | 1055 | self.offset_table_free_list.deinit(self.base.allocator); |
| 1037 | 1056 | self.string_table.deinit(self.base.allocator); |
| 1038 | | self.extern_lazy_symbols.deinit(self.base.allocator); |
| 1039 | | self.extern_nonlazy_symbols.deinit(self.base.allocator); |
| 1040 | 1057 | self.global_symbols.deinit(self.base.allocator); |
| 1041 | 1058 | self.global_symbol_free_list.deinit(self.base.allocator); |
| 1042 | 1059 | self.local_symbols.deinit(self.base.allocator); |
| ... | ... | @@ -2047,7 +2064,6 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 2047 | 2064 | try self.extern_nonlazy_symbols.putNoClobber(self.base.allocator, name, .{ |
| 2048 | 2065 | .name = name, |
| 2049 | 2066 | .dylib_ordinal = 1, // TODO this is currently hardcoded. |
| 2050 | | .index = index, |
| 2051 | 2067 | .segment = self.data_const_segment_cmd_index.?, |
| 2052 | 2068 | .offset = index * @sizeOf(u64), |
| 2053 | 2069 | }); |
| ... | ... | @@ -2582,12 +2598,12 @@ fn writeAllGlobalAndUndefSymbols(self: *MachO) !void { |
| 2582 | 2598 | } |
| 2583 | 2599 | |
| 2584 | 2600 | fn writeIndirectSymbolTable(self: *MachO) !void { |
| 2585 | | const text_seg = &self.load_commands.items[self.text_segment_cmd_index.?].Segment; |
| 2586 | | const stubs = &text_seg.sections.items[self.stubs_section_index.?]; |
| 2587 | | const dc_seg = &self.load_commands.items[self.data_const_segment_cmd_index.?].Segment; |
| 2588 | | const got = &dc_seg.sections.items[self.data_got_section_index.?]; |
| 2589 | | const data_seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment; |
| 2590 | | const la = &data_seg.sections.items[self.la_symbol_ptr_section_index.?]; |
| 2601 | const text_segment = &self.load_commands.items[self.text_segment_cmd_index.?].Segment; |
| 2602 | const stubs = &text_segment.sections.items[self.stubs_section_index.?]; |
| 2603 | const data_const_seg = &self.load_commands.items[self.data_const_segment_cmd_index.?].Segment; |
| 2604 | const got = &data_const_seg.sections.items[self.data_got_section_index.?]; |
| 2605 | const data_segment = &self.load_commands.items[self.data_segment_cmd_index.?].Segment; |
| 2606 | const la_symbol_ptr = &data_segment.sections.items[self.la_symbol_ptr_section_index.?]; |
| 2591 | 2607 | const dysymtab = &self.load_commands.items[self.dysymtab_cmd_index.?].Dysymtab; |
| 2592 | 2608 | dysymtab.nindirectsyms = 0; |
| 2593 | 2609 | |
| ... | ... | @@ -2595,8 +2611,8 @@ fn writeIndirectSymbolTable(self: *MachO) !void { |
| 2595 | 2611 | var off = dysymtab.indirectsymoff; |
| 2596 | 2612 | |
| 2597 | 2613 | stubs.reserved1 = 0; |
| 2598 | | for (self.extern_lazy_symbols.items()) |entry| { |
| 2599 | | const symtab_idx = @intCast(u32, dysymtab.iundefsym + entry.value.index); |
| 2614 | for (self.extern_lazy_symbols.items()) |_, i| { |
| 2615 | const symtab_idx = @intCast(u32, dysymtab.iundefsym + i); |
| 2600 | 2616 | mem.writeIntLittle(u32, &buf, symtab_idx); |
| 2601 | 2617 | try self.base.file.?.pwriteAll(&buf, off); |
| 2602 | 2618 | off += @sizeOf(u32); |
| ... | ... | @@ -2605,17 +2621,17 @@ fn writeIndirectSymbolTable(self: *MachO) !void { |
| 2605 | 2621 | |
| 2606 | 2622 | const base_id = @intCast(u32, self.extern_lazy_symbols.items().len); |
| 2607 | 2623 | got.reserved1 = base_id; |
| 2608 | | for (self.extern_nonlazy_symbols.items()) |entry| { |
| 2609 | | const symtab_idx = @intCast(u32, dysymtab.iundefsym + entry.value.index + base_id); |
| 2624 | for (self.extern_nonlazy_symbols.items()) |_, i| { |
| 2625 | const symtab_idx = @intCast(u32, dysymtab.iundefsym + i + base_id); |
| 2610 | 2626 | mem.writeIntLittle(u32, &buf, symtab_idx); |
| 2611 | 2627 | try self.base.file.?.pwriteAll(&buf, off); |
| 2612 | 2628 | off += @sizeOf(u32); |
| 2613 | 2629 | dysymtab.nindirectsyms += 1; |
| 2614 | 2630 | } |
| 2615 | 2631 | |
| 2616 | | la.reserved1 = got.reserved1 + @intCast(u32, self.extern_nonlazy_symbols.items().len); |
| 2617 | | for (self.extern_lazy_symbols.items()) |entry| { |
| 2618 | | const symtab_idx = @intCast(u32, dysymtab.iundefsym + entry.value.index); |
| 2632 | la_symbol_ptr.reserved1 = got.reserved1 + @intCast(u32, self.extern_nonlazy_symbols.items().len); |
| 2633 | for (self.extern_lazy_symbols.items()) |_, i| { |
| 2634 | const symtab_idx = @intCast(u32, dysymtab.iundefsym + i); |
| 2619 | 2635 | mem.writeIntLittle(u32, &buf, symtab_idx); |
| 2620 | 2636 | try self.base.file.?.pwriteAll(&buf, off); |
| 2621 | 2637 | off += @sizeOf(u32); |