| ... | @@ -120,6 +120,7 @@ stub_helper_stubs_start_off: ?u64 = null, | ... | @@ -120,6 +120,7 @@ stub_helper_stubs_start_off: ?u64 = null, |
| 120 | | 120 | |
| 121 | /// Table of symbol names aka the string table. | 121 | /// Table of symbol names aka the string table. |
| 122 | string_table: std.ArrayListUnmanaged(u8) = .{}, | 122 | string_table: std.ArrayListUnmanaged(u8) = .{}, |
| | 123 | string_table_directory: std.StringHashMapUnmanaged(u32) = .{}, |
| 123 | | 124 | |
| 124 | /// Table of trampolines to the actual symbols in __text section. | 125 | /// Table of trampolines to the actual symbols in __text section. |
| 125 | offset_table: std.ArrayListUnmanaged(u64) = .{}, | 126 | offset_table: std.ArrayListUnmanaged(u64) = .{}, |
| ... | @@ -1023,6 +1024,13 @@ pub fn deinit(self: *MachO) void { | ... | @@ -1023,6 +1024,13 @@ pub fn deinit(self: *MachO) void { |
| 1023 | self.text_block_free_list.deinit(self.base.allocator); | 1024 | self.text_block_free_list.deinit(self.base.allocator); |
| 1024 | self.offset_table.deinit(self.base.allocator); | 1025 | self.offset_table.deinit(self.base.allocator); |
| 1025 | self.offset_table_free_list.deinit(self.base.allocator); | 1026 | self.offset_table_free_list.deinit(self.base.allocator); |
| | 1027 | { |
| | 1028 | var it = self.string_table_directory.iterator(); |
| | 1029 | while (it.next()) |entry| { |
| | 1030 | self.base.allocator.free(entry.key); |
| | 1031 | } |
| | 1032 | } |
| | 1033 | self.string_table_directory.deinit(self.base.allocator); |
| 1026 | self.string_table.deinit(self.base.allocator); | 1034 | self.string_table.deinit(self.base.allocator); |
| 1027 | self.global_symbols.deinit(self.base.allocator); | 1035 | self.global_symbols.deinit(self.base.allocator); |
| 1028 | self.global_symbol_free_list.deinit(self.base.allocator); | 1036 | self.global_symbol_free_list.deinit(self.base.allocator); |
| ... | @@ -2235,14 +2243,26 @@ pub fn makeStaticString(comptime bytes: []const u8) [16]u8 { | ... | @@ -2235,14 +2243,26 @@ pub fn makeStaticString(comptime bytes: []const u8) [16]u8 { |
| 2235 | } | 2243 | } |
| 2236 | | 2244 | |
| 2237 | fn makeString(self: *MachO, bytes: []const u8) !u32 { | 2245 | fn makeString(self: *MachO, bytes: []const u8) !u32 { |
| | 2246 | if (self.string_table_directory.get(bytes)) |offset| { |
| | 2247 | log.debug("reusing '{s}' from string table at offset 0x{x}", .{ bytes, offset }); |
| | 2248 | return offset; |
| | 2249 | } |
| | 2250 | |
| 2238 | try self.string_table.ensureCapacity(self.base.allocator, self.string_table.items.len + bytes.len + 1); | 2251 | try self.string_table.ensureCapacity(self.base.allocator, self.string_table.items.len + bytes.len + 1); |
| 2239 | const offset = @intCast(u32, self.string_table.items.len); | 2252 | const offset = @intCast(u32, self.string_table.items.len); |
| 2240 | log.debug("writing '{s}' into the string table at offset 0x{x}", .{ bytes, offset }); | 2253 | log.debug("writing new string '{s}' into string table at offset 0x{x}", .{ bytes, offset }); |
| 2241 | self.string_table.appendSliceAssumeCapacity(bytes); | 2254 | self.string_table.appendSliceAssumeCapacity(bytes); |
| 2242 | self.string_table.appendAssumeCapacity(0); | 2255 | self.string_table.appendAssumeCapacity(0); |
| | 2256 | try self.string_table_directory.putNoClobber( |
| | 2257 | self.base.allocator, |
| | 2258 | try self.base.allocator.dupe(u8, bytes), |
| | 2259 | offset, |
| | 2260 | ); |
| | 2261 | |
| 2243 | self.string_table_dirty = true; | 2262 | self.string_table_dirty = true; |
| 2244 | if (self.d_sym) |*ds| | 2263 | if (self.d_sym) |*ds| |
| 2245 | ds.string_table_dirty = true; | 2264 | ds.string_table_dirty = true; |
| | 2265 | |
| 2246 | return offset; | 2266 | return offset; |
| 2247 | } | 2267 | } |
| 2248 | | 2268 | |