| ... | ... | @@ -162,7 +162,10 @@ strtab: std.ArrayListUnmanaged(u8) = .{}, |
| 162 | 162 | strtab_dir: std.HashMapUnmanaged(u32, void, StringIndexContext, std.hash_map.default_max_load_percentage) = .{}, |
| 163 | 163 | |
| 164 | 164 | got_entries_map: std.AutoArrayHashMapUnmanaged(Atom.Relocation.Target, *Atom) = .{}, |
| 165 | got_entries_map_free_list: std.ArrayListUnmanaged(u32) = .{}, |
| 166 | |
| 165 | 167 | stubs_map: std.AutoArrayHashMapUnmanaged(u32, *Atom) = .{}, |
| 168 | stubs_map_free_list: std.ArrayListUnmanaged(u32) = .{}, |
| 166 | 169 | |
| 167 | 170 | error_flags: File.ErrorFlags = File.ErrorFlags{}, |
| 168 | 171 | |
| ... | ... | @@ -175,6 +178,7 @@ has_stabs: bool = false, |
| 175 | 178 | /// TODO once we add opening a prelinked output binary from file, this will become |
| 176 | 179 | /// obsolete as we will carry on where we left off. |
| 177 | 180 | cold_start: bool = false, |
| 181 | invalidate_relocs: bool = false, |
| 178 | 182 | |
| 179 | 183 | section_ordinals: std.AutoArrayHashMapUnmanaged(MatchingSection, void) = .{}, |
| 180 | 184 | |
| ... | ... | @@ -610,9 +614,24 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void { |
| 610 | 614 | sym.n_desc = 0; |
| 611 | 615 | }, |
| 612 | 616 | } |
| 617 | if (self.got_entries_map.getIndex(.{ .global = entry.key })) |i| { |
| 618 | self.got_entries_map_free_list.append( |
| 619 | self.base.allocator, |
| 620 | @intCast(u32, i), |
| 621 | ) catch {}; |
| 622 | self.got_entries_map.keys()[i] = .{ .local = 0 }; |
| 623 | } |
| 624 | if (self.stubs_map.getIndex(entry.key)) |i| { |
| 625 | self.stubs_map_free_list.append(self.base.allocator, @intCast(u32, i)) catch {}; |
| 626 | self.stubs_map.keys()[i] = 0; |
| 627 | } |
| 613 | 628 | } |
| 614 | 629 | } |
| 615 | 630 | } |
| 631 | // Invalidate all relocs |
| 632 | // TODO we only need to invalidate the backlinks to the relinked atoms from |
| 633 | // the relocatable object files. |
| 634 | self.invalidate_relocs = true; |
| 616 | 635 | |
| 617 | 636 | // Positional arguments to the linker such as object files and static archives. |
| 618 | 637 | var positionals = std.ArrayList([]const u8).init(arena); |
| ... | ... | @@ -889,6 +908,19 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void { |
| 889 | 908 | } |
| 890 | 909 | } |
| 891 | 910 | |
| 911 | log.debug("GOT entries:", .{}); |
| 912 | for (self.got_entries_map.keys()) |key| { |
| 913 | switch (key) { |
| 914 | .local => |sym_index| log.debug(" {} => {d}", .{ key, sym_index }), |
| 915 | .global => |n_strx| log.debug(" {} => {s}", .{ key, self.getString(n_strx) }), |
| 916 | } |
| 917 | } |
| 918 | |
| 919 | log.debug("stubs:", .{}); |
| 920 | for (self.stubs_map.keys()) |key| { |
| 921 | log.debug(" {} => {s}", .{ key, self.getString(key) }); |
| 922 | } |
| 923 | |
| 892 | 924 | try self.writeAtoms(); |
| 893 | 925 | |
| 894 | 926 | if (self.bss_section_index) |idx| { |
| ... | ... | @@ -1838,7 +1870,7 @@ fn writeAtoms(self: *MachO) !void { |
| 1838 | 1870 | } |
| 1839 | 1871 | |
| 1840 | 1872 | while (true) { |
| 1841 | | if (atom.dirty) { |
| 1873 | if (atom.dirty or self.invalidate_relocs) { |
| 1842 | 1874 | const atom_sym = self.locals.items[atom.local_sym_index]; |
| 1843 | 1875 | const padding_size: u64 = if (atom.next) |next| blk: { |
| 1844 | 1876 | const next_sym = self.locals.items[next.local_sym_index]; |
| ... | ... | @@ -2907,7 +2939,9 @@ pub fn deinit(self: *MachO) void { |
| 2907 | 2939 | |
| 2908 | 2940 | self.section_ordinals.deinit(self.base.allocator); |
| 2909 | 2941 | self.got_entries_map.deinit(self.base.allocator); |
| 2942 | self.got_entries_map_free_list.deinit(self.base.allocator); |
| 2910 | 2943 | self.stubs_map.deinit(self.base.allocator); |
| 2944 | self.stubs_map_free_list.deinit(self.base.allocator); |
| 2911 | 2945 | self.strtab_dir.deinit(self.base.allocator); |
| 2912 | 2946 | self.strtab.deinit(self.base.allocator); |
| 2913 | 2947 | self.undefs.deinit(self.base.allocator); |
| ... | ... | @@ -3091,8 +3125,22 @@ pub fn allocateDeclIndexes(self: *MachO, decl: *Module.Decl) !void { |
| 3091 | 3125 | |
| 3092 | 3126 | // TODO try popping from free list first before allocating a new GOT atom. |
| 3093 | 3127 | const target = Atom.Relocation.Target{ .local = decl.link.macho.local_sym_index }; |
| 3094 | | const got_atom = try self.createGotAtom(target); |
| 3095 | | try self.got_entries_map.put(self.base.allocator, target, got_atom); |
| 3128 | const value_ptr = blk: { |
| 3129 | if (self.got_entries_map_free_list.popOrNull()) |i| { |
| 3130 | log.debug("reusing GOT entry index {d} for {s}", .{ i, decl.name }); |
| 3131 | self.got_entries_map.keys()[i] = target; |
| 3132 | const value_ptr = self.got_entries_map.getPtr(target).?; |
| 3133 | break :blk value_ptr; |
| 3134 | } else { |
| 3135 | const res = try self.got_entries_map.getOrPut(self.base.allocator, target); |
| 3136 | log.debug("creating new GOT entry at index {d} for {s}", .{ |
| 3137 | self.got_entries_map.getIndex(target).?, |
| 3138 | decl.name, |
| 3139 | }); |
| 3140 | break :blk res.value_ptr; |
| 3141 | } |
| 3142 | }; |
| 3143 | value_ptr.* = try self.createGotAtom(target); |
| 3096 | 3144 | } |
| 3097 | 3145 | |
| 3098 | 3146 | pub fn updateFunc(self: *MachO, module: *Module, func: *Module.Fn, air: Air, liveness: Liveness) !void { |
| ... | ... | @@ -3516,7 +3564,9 @@ pub fn freeDecl(self: *MachO, decl: *Module.Decl) void { |
| 3516 | 3564 | if (decl.link.macho.local_sym_index != 0) { |
| 3517 | 3565 | self.locals_free_list.append(self.base.allocator, decl.link.macho.local_sym_index) catch {}; |
| 3518 | 3566 | |
| 3519 | | // TODO free GOT atom here. |
| 3567 | // Try freeing GOT atom |
| 3568 | const got_index = self.got_entries_map.getIndex(.{ .local = decl.link.macho.local_sym_index }).?; |
| 3569 | self.got_entries_map_free_list.append(self.base.allocator, @intCast(u32, got_index)) catch {}; |
| 3520 | 3570 | |
| 3521 | 3571 | self.locals.items[decl.link.macho.local_sym_index].n_type = 0; |
| 3522 | 3572 | decl.link.macho.local_sym_index = 0; |
| ... | ... | @@ -4907,7 +4957,7 @@ fn writeSymbolTable(self: *MachO) !void { |
| 4907 | 4957 | |
| 4908 | 4958 | stubs.reserved1 = 0; |
| 4909 | 4959 | for (self.stubs_map.keys()) |key| { |
| 4910 | | const resolv = self.symbol_resolver.get(key).?; |
| 4960 | const resolv = self.symbol_resolver.get(key) orelse continue; |
| 4911 | 4961 | switch (resolv.where) { |
| 4912 | 4962 | .global => try writer.writeIntLittle(u32, macho.INDIRECT_SYMBOL_LOCAL), |
| 4913 | 4963 | .undef => try writer.writeIntLittle(u32, dysymtab.iundefsym + resolv.where_index), |
| ... | ... | @@ -4919,7 +4969,7 @@ fn writeSymbolTable(self: *MachO) !void { |
| 4919 | 4969 | switch (key) { |
| 4920 | 4970 | .local => try writer.writeIntLittle(u32, macho.INDIRECT_SYMBOL_LOCAL), |
| 4921 | 4971 | .global => |n_strx| { |
| 4922 | | const resolv = self.symbol_resolver.get(n_strx).?; |
| 4972 | const resolv = self.symbol_resolver.get(n_strx) orelse continue; |
| 4923 | 4973 | switch (resolv.where) { |
| 4924 | 4974 | .global => try writer.writeIntLittle(u32, macho.INDIRECT_SYMBOL_LOCAL), |
| 4925 | 4975 | .undef => try writer.writeIntLittle(u32, dysymtab.iundefsym + resolv.where_index), |
| ... | ... | @@ -4930,7 +4980,7 @@ fn writeSymbolTable(self: *MachO) !void { |
| 4930 | 4980 | |
| 4931 | 4981 | la_symbol_ptr.reserved1 = got.reserved1 + ngot_entries; |
| 4932 | 4982 | for (self.stubs_map.keys()) |key| { |
| 4933 | | const resolv = self.symbol_resolver.get(key).?; |
| 4983 | const resolv = self.symbol_resolver.get(key) orelse continue; |
| 4934 | 4984 | switch (resolv.where) { |
| 4935 | 4985 | .global => try writer.writeIntLittle(u32, macho.INDIRECT_SYMBOL_LOCAL), |
| 4936 | 4986 | .undef => try writer.writeIntLittle(u32, dysymtab.iundefsym + resolv.where_index), |
| ... | ... | @@ -5346,7 +5396,7 @@ fn snapshotState(self: *MachO) !void { |
| 5346 | 5396 | }; |
| 5347 | 5397 | |
| 5348 | 5398 | if (is_via_got) { |
| 5349 | | const got_atom = self.got_entries_map.get(rel.target).?; |
| 5399 | const got_atom = self.got_entries_map.get(rel.target) orelse break :blk 0; |
| 5350 | 5400 | break :blk self.locals.items[got_atom.local_sym_index].n_value; |
| 5351 | 5401 | } |
| 5352 | 5402 | |