| ... | @@ -113,7 +113,6 @@ stub_helper_stubs_start_off: ?u64 = null, | ... | @@ -113,7 +113,6 @@ stub_helper_stubs_start_off: ?u64 = null, |
| 113 | blocks: std.AutoHashMapUnmanaged(MatchingSection, *TextBlock) = .{}, | 113 | blocks: std.AutoHashMapUnmanaged(MatchingSection, *TextBlock) = .{}, |
| 114 | | 114 | |
| 115 | strtab: std.ArrayListUnmanaged(u8) = .{}, | 115 | strtab: std.ArrayListUnmanaged(u8) = .{}, |
| 116 | strtab_cache: std.StringHashMapUnmanaged(u32) = .{}, | | |
| 117 | | 116 | |
| 118 | has_dices: bool = false, | 117 | has_dices: bool = false, |
| 119 | has_stabs: bool = false, | 118 | has_stabs: bool = false, |
| ... | @@ -171,7 +170,7 @@ pub const TextBlock = struct { | ... | @@ -171,7 +170,7 @@ pub const TextBlock = struct { |
| 171 | .n_value = reg.address, | 170 | .n_value = reg.address, |
| 172 | }); | 171 | }); |
| 173 | nlists.appendAssumeCapacity(.{ | 172 | nlists.appendAssumeCapacity(.{ |
| 174 | .n_strx = try zld.makeString(sym.name), | 173 | .n_strx = sym.strx, |
| 175 | .n_type = macho.N_FUN, | 174 | .n_type = macho.N_FUN, |
| 176 | .n_sect = section_id, | 175 | .n_sect = section_id, |
| 177 | .n_desc = 0, | 176 | .n_desc = 0, |
| ... | @@ -194,7 +193,7 @@ pub const TextBlock = struct { | ... | @@ -194,7 +193,7 @@ pub const TextBlock = struct { |
| 194 | }, | 193 | }, |
| 195 | .global => { | 194 | .global => { |
| 196 | try nlists.append(.{ | 195 | try nlists.append(.{ |
| 197 | .n_strx = try zld.makeString(sym.name), | 196 | .n_strx = sym.strx, |
| 198 | .n_type = macho.N_GSYM, | 197 | .n_type = macho.N_GSYM, |
| 199 | .n_sect = 0, | 198 | .n_sect = 0, |
| 200 | .n_desc = 0, | 199 | .n_desc = 0, |
| ... | @@ -203,7 +202,7 @@ pub const TextBlock = struct { | ... | @@ -203,7 +202,7 @@ pub const TextBlock = struct { |
| 203 | }, | 202 | }, |
| 204 | .static => { | 203 | .static => { |
| 205 | try nlists.append(.{ | 204 | try nlists.append(.{ |
| 206 | .n_strx = try zld.makeString(sym.name), | 205 | .n_strx = sym.strx, |
| 207 | .n_type = macho.N_STSYM, | 206 | .n_type = macho.N_STSYM, |
| 208 | .n_sect = reg.sectionId(zld), | 207 | .n_sect = reg.sectionId(zld), |
| 209 | .n_desc = 0, | 208 | .n_desc = 0, |
| ... | @@ -349,26 +348,20 @@ pub fn deinit(self: *Zld) void { | ... | @@ -349,26 +348,20 @@ pub fn deinit(self: *Zld) void { |
| 349 | self.dylibs.deinit(self.allocator); | 348 | self.dylibs.deinit(self.allocator); |
| 350 | | 349 | |
| 351 | for (self.imports.items) |sym| { | 350 | for (self.imports.items) |sym| { |
| 352 | sym.deinit(self.allocator); | | |
| 353 | self.allocator.destroy(sym); | 351 | self.allocator.destroy(sym); |
| 354 | } | 352 | } |
| 355 | self.imports.deinit(self.allocator); | 353 | self.imports.deinit(self.allocator); |
| 356 | | 354 | |
| 357 | for (self.locals.items) |sym| { | 355 | for (self.locals.items) |sym| { |
| 358 | sym.deinit(self.allocator); | | |
| 359 | self.allocator.destroy(sym); | 356 | self.allocator.destroy(sym); |
| 360 | } | 357 | } |
| 361 | self.locals.deinit(self.allocator); | 358 | self.locals.deinit(self.allocator); |
| 362 | | 359 | |
| | 360 | for (self.globals.keys()) |key| { |
| | 361 | self.allocator.free(key); |
| | 362 | } |
| 363 | self.globals.deinit(self.allocator); | 363 | self.globals.deinit(self.allocator); |
| 364 | | 364 | |
| 365 | { | | |
| 366 | var it = self.strtab_cache.keyIterator(); | | |
| 367 | while (it.next()) |key| { | | |
| 368 | self.allocator.free(key.*); | | |
| 369 | } | | |
| 370 | } | | |
| 371 | self.strtab_cache.deinit(self.allocator); | | |
| 372 | self.strtab.deinit(self.allocator); | 365 | self.strtab.deinit(self.allocator); |
| 373 | | 366 | |
| 374 | // TODO dealloc all blocks | 367 | // TODO dealloc all blocks |
| ... | @@ -1168,7 +1161,7 @@ fn allocateTextBlocks(self: *Zld) !void { | ... | @@ -1168,7 +1161,7 @@ fn allocateTextBlocks(self: *Zld) !void { |
| 1168 | sym.payload.regular.address = base_addr; | 1161 | sym.payload.regular.address = base_addr; |
| 1169 | | 1162 | |
| 1170 | log.debug(" {s}: start=0x{x}, end=0x{x}, size={}, align={}", .{ | 1163 | log.debug(" {s}: start=0x{x}, end=0x{x}, size={}, align={}", .{ |
| 1171 | sym.name, | 1164 | self.getString(sym.strx), |
| 1172 | base_addr, | 1165 | base_addr, |
| 1173 | base_addr + block.size, | 1166 | base_addr + block.size, |
| 1174 | block.size, | 1167 | block.size, |
| ... | @@ -1231,7 +1224,7 @@ fn writeTextBlocks(self: *Zld) !void { | ... | @@ -1231,7 +1224,7 @@ fn writeTextBlocks(self: *Zld) !void { |
| 1231 | | 1224 | |
| 1232 | const sym = self.locals.items[block.local_sym_index]; | 1225 | const sym = self.locals.items[block.local_sym_index]; |
| 1233 | log.debug(" {s}: start=0x{x}, end=0x{x}, size={}, align={}", .{ | 1226 | log.debug(" {s}: start=0x{x}, end=0x{x}, size={}, align={}", .{ |
| 1234 | sym.name, | 1227 | self.getString(sym.strx), |
| 1235 | aligned_base_off, | 1228 | aligned_base_off, |
| 1236 | aligned_base_off + block.size, | 1229 | aligned_base_off + block.size, |
| 1237 | block.size, | 1230 | block.size, |
| ... | @@ -1552,14 +1545,17 @@ fn resolveSymbolsInObject(self: *Zld, object: *Object) !void { | ... | @@ -1552,14 +1545,17 @@ fn resolveSymbolsInObject(self: *Zld, object: *Object) !void { |
| 1552 | | 1545 | |
| 1553 | if (Symbol.isSect(sym) and !Symbol.isExt(sym)) { | 1546 | if (Symbol.isSect(sym) and !Symbol.isExt(sym)) { |
| 1554 | // Regular symbol local to translation unit | 1547 | // Regular symbol local to translation unit |
| 1555 | const symbol = try Symbol.new(self.allocator, sym_name); | 1548 | const symbol = try self.allocator.create(Symbol); |
| 1556 | symbol.payload = .{ | 1549 | symbol.* = .{ |
| 1557 | .regular = .{ | 1550 | .strx = try self.makeString(sym_name), |
| 1558 | .linkage = .translation_unit, | 1551 | .payload = .{ |
| 1559 | .address = sym.n_value, | 1552 | .regular = .{ |
| 1560 | .weak_ref = Symbol.isWeakRef(sym), | 1553 | .linkage = .translation_unit, |
| 1561 | .file = object, | 1554 | .address = sym.n_value, |
| 1562 | .local_sym_index = @intCast(u32, self.locals.items.len), | 1555 | .weak_ref = Symbol.isWeakRef(sym), |
| | 1556 | .file = object, |
| | 1557 | .local_sym_index = @intCast(u32, self.locals.items.len), |
| | 1558 | }, |
| 1563 | }, | 1559 | }, |
| 1564 | }; | 1560 | }; |
| 1565 | try self.locals.append(self.allocator, symbol); | 1561 | try self.locals.append(self.allocator, symbol); |
| ... | @@ -1569,9 +1565,13 @@ fn resolveSymbolsInObject(self: *Zld, object: *Object) !void { | ... | @@ -1569,9 +1565,13 @@ fn resolveSymbolsInObject(self: *Zld, object: *Object) !void { |
| 1569 | | 1565 | |
| 1570 | const symbol = self.globals.get(sym_name) orelse symbol: { | 1566 | const symbol = self.globals.get(sym_name) orelse symbol: { |
| 1571 | // Insert new global symbol. | 1567 | // Insert new global symbol. |
| 1572 | const symbol = try Symbol.new(self.allocator, sym_name); | 1568 | const symbol = try self.allocator.create(Symbol); |
| 1573 | symbol.payload.undef.file = object; | 1569 | symbol.* = .{ |
| 1574 | try self.globals.putNoClobber(self.allocator, symbol.name, symbol); | 1570 | .strx = try self.makeString(sym_name), |
| | 1571 | .payload = .{ .undef = .{ .file = object } }, |
| | 1572 | }; |
| | 1573 | const alloc_name = try self.allocator.dupe(u8, sym_name); |
| | 1574 | try self.globals.putNoClobber(self.allocator, alloc_name, symbol); |
| 1575 | break :symbol symbol; | 1575 | break :symbol symbol; |
| 1576 | }; | 1576 | }; |
| 1577 | | 1577 | |
| ... | @@ -1628,7 +1628,8 @@ fn resolveSymbolsInObject(self: *Zld, object: *Object) !void { | ... | @@ -1628,7 +1628,8 @@ fn resolveSymbolsInObject(self: *Zld, object: *Object) !void { |
| 1628 | fn resolveSymbols(self: *Zld) !void { | 1628 | fn resolveSymbols(self: *Zld) !void { |
| 1629 | // TODO mimicking insertion of null symbol from incremental linker. | 1629 | // TODO mimicking insertion of null symbol from incremental linker. |
| 1630 | // This will need to moved. | 1630 | // This will need to moved. |
| 1631 | const null_sym = try Symbol.new(self.allocator, ""); | 1631 | const null_sym = try self.allocator.create(Symbol); |
| | 1632 | null_sym.* = .{ .strx = 0, .payload = .{ .undef = .{} } }; |
| 1632 | try self.locals.append(self.allocator, null_sym); | 1633 | try self.locals.append(self.allocator, null_sym); |
| 1633 | | 1634 | |
| 1634 | // First pass, resolve symbols in provided objects. | 1635 | // First pass, resolve symbols in provided objects. |
| ... | @@ -1639,12 +1640,13 @@ fn resolveSymbols(self: *Zld) !void { | ... | @@ -1639,12 +1640,13 @@ fn resolveSymbols(self: *Zld) !void { |
| 1639 | // Second pass, resolve symbols in static libraries. | 1640 | // Second pass, resolve symbols in static libraries. |
| 1640 | var sym_it = self.globals.iterator(); | 1641 | var sym_it = self.globals.iterator(); |
| 1641 | while (sym_it.next()) |entry| { | 1642 | while (sym_it.next()) |entry| { |
| | 1643 | const sym_name = entry.key_ptr.*; |
| 1642 | const symbol = entry.value_ptr.*; | 1644 | const symbol = entry.value_ptr.*; |
| 1643 | if (symbol.payload != .undef) continue; | 1645 | if (symbol.payload != .undef) continue; |
| 1644 | | 1646 | |
| 1645 | for (self.archives.items) |archive| { | 1647 | for (self.archives.items) |archive| { |
| 1646 | // Check if the entry exists in a static archive. | 1648 | // Check if the entry exists in a static archive. |
| 1647 | const offsets = archive.toc.get(symbol.name) orelse { | 1649 | const offsets = archive.toc.get(sym_name) orelse { |
| 1648 | // No hit. | 1650 | // No hit. |
| 1649 | continue; | 1651 | continue; |
| 1650 | }; | 1652 | }; |
| ... | @@ -1734,21 +1736,27 @@ fn resolveSymbols(self: *Zld) !void { | ... | @@ -1734,21 +1736,27 @@ fn resolveSymbols(self: *Zld) !void { |
| 1734 | // Third pass, resolve symbols in dynamic libraries. | 1736 | // Third pass, resolve symbols in dynamic libraries. |
| 1735 | { | 1737 | { |
| 1736 | // Put dyld_stub_binder as an undefined special symbol. | 1738 | // Put dyld_stub_binder as an undefined special symbol. |
| 1737 | const symbol = try Symbol.new(self.allocator, "dyld_stub_binder"); | 1739 | const symbol = try self.allocator.create(Symbol); |
| | 1740 | symbol.* = .{ |
| | 1741 | .strx = try self.makeString("dyld_stub_binder"), |
| | 1742 | .payload = .{ .undef = .{} }, |
| | 1743 | }; |
| 1738 | const index = @intCast(u32, self.got_entries.items.len); | 1744 | const index = @intCast(u32, self.got_entries.items.len); |
| 1739 | symbol.got_index = index; | 1745 | symbol.got_index = index; |
| 1740 | try self.got_entries.append(self.allocator, symbol); | 1746 | try self.got_entries.append(self.allocator, symbol); |
| 1741 | try self.globals.putNoClobber(self.allocator, symbol.name, symbol); | 1747 | const alloc_name = try self.allocator.dupe(u8, "dyld_stub_binder"); |
| | 1748 | try self.globals.putNoClobber(self.allocator, alloc_name, symbol); |
| 1742 | } | 1749 | } |
| 1743 | | 1750 | |
| 1744 | var referenced = std.AutoHashMap(*Dylib, void).init(self.allocator); | 1751 | var referenced = std.AutoHashMap(*Dylib, void).init(self.allocator); |
| 1745 | defer referenced.deinit(); | 1752 | defer referenced.deinit(); |
| 1746 | | 1753 | |
| 1747 | loop: for (self.globals.values()) |symbol| { | 1754 | loop: for (self.globals.keys()) |sym_name| { |
| | 1755 | const symbol = self.globals.get(sym_name).?; |
| 1748 | if (symbol.payload != .undef) continue; | 1756 | if (symbol.payload != .undef) continue; |
| 1749 | | 1757 | |
| 1750 | for (self.dylibs.items) |dylib| { | 1758 | for (self.dylibs.items) |dylib| { |
| 1751 | if (!dylib.symbols.contains(symbol.name)) continue; | 1759 | if (!dylib.symbols.contains(sym_name)) continue; |
| 1752 | | 1760 | |
| 1753 | try referenced.put(dylib, {}); | 1761 | try referenced.put(dylib, {}); |
| 1754 | const index = @intCast(u32, self.imports.items.len); | 1762 | const index = @intCast(u32, self.imports.items.len); |
| ... | @@ -1798,10 +1806,11 @@ fn resolveSymbols(self: *Zld) !void { | ... | @@ -1798,10 +1806,11 @@ fn resolveSymbols(self: *Zld) !void { |
| 1798 | } | 1806 | } |
| 1799 | | 1807 | |
| 1800 | var has_undefined = false; | 1808 | var has_undefined = false; |
| 1801 | for (self.globals.values()) |symbol| { | 1809 | for (self.globals.keys()) |sym_name| { |
| | 1810 | const symbol = self.globals.get(sym_name).?; |
| 1802 | if (symbol.payload != .undef) continue; | 1811 | if (symbol.payload != .undef) continue; |
| 1803 | | 1812 | |
| 1804 | log.err("undefined reference to symbol '{s}'", .{symbol.name}); | 1813 | log.err("undefined reference to symbol '{s}'", .{sym_name}); |
| 1805 | if (symbol.payload.undef.file) |file| { | 1814 | if (symbol.payload.undef.file) |file| { |
| 1806 | log.err(" | referenced in {s}", .{file.name.?}); | 1815 | log.err(" | referenced in {s}", .{file.name.?}); |
| 1807 | } | 1816 | } |
| ... | @@ -2344,7 +2353,7 @@ fn writeBindInfoTable(self: *Zld) !void { | ... | @@ -2344,7 +2353,7 @@ fn writeBindInfoTable(self: *Zld) !void { |
| 2344 | .offset = base_offset + sym.got_index.? * @sizeOf(u64), | 2353 | .offset = base_offset + sym.got_index.? * @sizeOf(u64), |
| 2345 | .segment_id = segment_id, | 2354 | .segment_id = segment_id, |
| 2346 | .dylib_ordinal = proxy.dylibOrdinal(), | 2355 | .dylib_ordinal = proxy.dylibOrdinal(), |
| 2347 | .name = sym.name, | 2356 | .name = self.getString(sym.strx), |
| 2348 | }); | 2357 | }); |
| 2349 | } | 2358 | } |
| 2350 | } | 2359 | } |
| ... | @@ -2372,7 +2381,7 @@ fn writeBindInfoTable(self: *Zld) !void { | ... | @@ -2372,7 +2381,7 @@ fn writeBindInfoTable(self: *Zld) !void { |
| 2372 | .offset = binding.offset + base_offset, | 2381 | .offset = binding.offset + base_offset, |
| 2373 | .segment_id = match.seg, | 2382 | .segment_id = match.seg, |
| 2374 | .dylib_ordinal = proxy.dylibOrdinal(), | 2383 | .dylib_ordinal = proxy.dylibOrdinal(), |
| 2375 | .name = bind_sym.name, | 2384 | .name = self.getString(bind_sym.strx), |
| 2376 | }); | 2385 | }); |
| 2377 | } | 2386 | } |
| 2378 | | 2387 | |
| ... | @@ -2395,7 +2404,7 @@ fn writeBindInfoTable(self: *Zld) !void { | ... | @@ -2395,7 +2404,7 @@ fn writeBindInfoTable(self: *Zld) !void { |
| 2395 | .offset = base_offset, | 2404 | .offset = base_offset, |
| 2396 | .segment_id = segment_id, | 2405 | .segment_id = segment_id, |
| 2397 | .dylib_ordinal = proxy.dylibOrdinal(), | 2406 | .dylib_ordinal = proxy.dylibOrdinal(), |
| 2398 | .name = sym.name, | 2407 | .name = self.getString(sym.strx), |
| 2399 | }); | 2408 | }); |
| 2400 | } | 2409 | } |
| 2401 | | 2410 | |
| ... | @@ -2435,7 +2444,7 @@ fn writeLazyBindInfoTable(self: *Zld) !void { | ... | @@ -2435,7 +2444,7 @@ fn writeLazyBindInfoTable(self: *Zld) !void { |
| 2435 | .offset = base_offset + sym.stubs_index.? * @sizeOf(u64), | 2444 | .offset = base_offset + sym.stubs_index.? * @sizeOf(u64), |
| 2436 | .segment_id = segment_id, | 2445 | .segment_id = segment_id, |
| 2437 | .dylib_ordinal = proxy.dylibOrdinal(), | 2446 | .dylib_ordinal = proxy.dylibOrdinal(), |
| 2438 | .name = sym.name, | 2447 | .name = self.getString(sym.strx), |
| 2439 | }); | 2448 | }); |
| 2440 | } | 2449 | } |
| 2441 | } | 2450 | } |
| ... | @@ -2547,7 +2556,7 @@ fn writeExportInfo(self: *Zld) !void { | ... | @@ -2547,7 +2556,7 @@ fn writeExportInfo(self: *Zld) !void { |
| 2547 | if (sym.payload != .regular) continue; | 2556 | if (sym.payload != .regular) continue; |
| 2548 | const reg = sym.payload.regular; | 2557 | const reg = sym.payload.regular; |
| 2549 | if (reg.linkage != .global) continue; | 2558 | if (reg.linkage != .global) continue; |
| 2550 | try sorted_globals.append(sym.name); | 2559 | try sorted_globals.append(self.getString(sym.strx)); |
| 2551 | } | 2560 | } |
| 2552 | | 2561 | |
| 2553 | std.sort.sort([]const u8, sorted_globals.items, {}, Sorter.lessThan); | 2562 | std.sort.sort([]const u8, sorted_globals.items, {}, Sorter.lessThan); |
| ... | @@ -2556,10 +2565,10 @@ fn writeExportInfo(self: *Zld) !void { | ... | @@ -2556,10 +2565,10 @@ fn writeExportInfo(self: *Zld) !void { |
| 2556 | const sym = self.globals.get(sym_name) orelse unreachable; | 2565 | const sym = self.globals.get(sym_name) orelse unreachable; |
| 2557 | const reg = sym.payload.regular; | 2566 | const reg = sym.payload.regular; |
| 2558 | | 2567 | |
| 2559 | log.debug(" | putting '{s}' defined at 0x{x}", .{ sym.name, reg.address }); | 2568 | log.debug(" | putting '{s}' defined at 0x{x}", .{ sym_name, reg.address }); |
| 2560 | | 2569 | |
| 2561 | try trie.put(.{ | 2570 | try trie.put(.{ |
| 2562 | .name = sym.name, | 2571 | .name = sym_name, |
| 2563 | .vmaddr_offset = reg.address - base_address, | 2572 | .vmaddr_offset = reg.address - base_address, |
| 2564 | .export_flags = macho.EXPORT_SYMBOL_FLAGS_KIND_REGULAR, | 2573 | .export_flags = macho.EXPORT_SYMBOL_FLAGS_KIND_REGULAR, |
| 2565 | }); | 2574 | }); |
| ... | @@ -2597,7 +2606,7 @@ fn writeSymbolTable(self: *Zld) !void { | ... | @@ -2597,7 +2606,7 @@ fn writeSymbolTable(self: *Zld) !void { |
| 2597 | | 2606 | |
| 2598 | for (self.locals.items) |symbol, i| { | 2607 | for (self.locals.items) |symbol, i| { |
| 2599 | if (i == 0) continue; // skip null symbol | 2608 | if (i == 0) continue; // skip null symbol |
| 2600 | if (symbol.isTemp()) continue; // TODO when merging codepaths, this should go into freelist | 2609 | if (symbol.isTemp(self)) continue; // TODO when merging codepaths, this should go into freelist |
| 2601 | | 2610 | |
| 2602 | const reg = symbol.payload.regular; | 2611 | const reg = symbol.payload.regular; |
| 2603 | const nlist = try symbol.asNlist(self); | 2612 | const nlist = try symbol.asNlist(self); |
| ... | @@ -2673,7 +2682,7 @@ fn writeSymbolTable(self: *Zld) !void { | ... | @@ -2673,7 +2682,7 @@ fn writeSymbolTable(self: *Zld) !void { |
| 2673 | const nlist = try sym.asNlist(self); | 2682 | const nlist = try sym.asNlist(self); |
| 2674 | const id = @intCast(u32, undefs.items.len); | 2683 | const id = @intCast(u32, undefs.items.len); |
| 2675 | try undefs.append(nlist); | 2684 | try undefs.append(nlist); |
| 2676 | try undef_dir.putNoClobber(sym.name, id); | 2685 | try undef_dir.putNoClobber(self.getString(sym.strx), id); |
| 2677 | } | 2686 | } |
| 2678 | | 2687 | |
| 2679 | const nlocals = locals.items.len; | 2688 | const nlocals = locals.items.len; |
| ... | @@ -2735,7 +2744,8 @@ fn writeSymbolTable(self: *Zld) !void { | ... | @@ -2735,7 +2744,8 @@ fn writeSymbolTable(self: *Zld) !void { |
| 2735 | | 2744 | |
| 2736 | stubs.reserved1 = 0; | 2745 | stubs.reserved1 = 0; |
| 2737 | for (self.stubs.items) |sym| { | 2746 | for (self.stubs.items) |sym| { |
| 2738 | const id = undef_dir.get(sym.name) orelse unreachable; | 2747 | const sym_name = self.getString(sym.strx); |
| | 2748 | const id = undef_dir.get(sym_name) orelse unreachable; |
| 2739 | try writer.writeIntLittle(u32, dysymtab.iundefsym + id); | 2749 | try writer.writeIntLittle(u32, dysymtab.iundefsym + id); |
| 2740 | } | 2750 | } |
| 2741 | | 2751 | |
| ... | @@ -2743,7 +2753,8 @@ fn writeSymbolTable(self: *Zld) !void { | ... | @@ -2743,7 +2753,8 @@ fn writeSymbolTable(self: *Zld) !void { |
| 2743 | for (self.got_entries.items) |sym| { | 2753 | for (self.got_entries.items) |sym| { |
| 2744 | switch (sym.payload) { | 2754 | switch (sym.payload) { |
| 2745 | .proxy => { | 2755 | .proxy => { |
| 2746 | const id = undef_dir.get(sym.name) orelse unreachable; | 2756 | const sym_name = self.getString(sym.strx); |
| | 2757 | const id = undef_dir.get(sym_name) orelse unreachable; |
| 2747 | try writer.writeIntLittle(u32, dysymtab.iundefsym + id); | 2758 | try writer.writeIntLittle(u32, dysymtab.iundefsym + id); |
| 2748 | }, | 2759 | }, |
| 2749 | else => { | 2760 | else => { |
| ... | @@ -2754,7 +2765,8 @@ fn writeSymbolTable(self: *Zld) !void { | ... | @@ -2754,7 +2765,8 @@ fn writeSymbolTable(self: *Zld) !void { |
| 2754 | | 2765 | |
| 2755 | la_symbol_ptr.reserved1 = got.reserved1 + ngot_entries; | 2766 | la_symbol_ptr.reserved1 = got.reserved1 + ngot_entries; |
| 2756 | for (self.stubs.items) |sym| { | 2767 | for (self.stubs.items) |sym| { |
| 2757 | const id = undef_dir.get(sym.name) orelse unreachable; | 2768 | const sym_name = self.getString(sym.strx); |
| | 2769 | const id = undef_dir.get(sym_name) orelse unreachable; |
| 2758 | try writer.writeIntLittle(u32, dysymtab.iundefsym + id); | 2770 | try writer.writeIntLittle(u32, dysymtab.iundefsym + id); |
| 2759 | } | 2771 | } |
| 2760 | | 2772 | |
| ... | @@ -2940,11 +2952,6 @@ fn writeHeader(self: *Zld) !void { | ... | @@ -2940,11 +2952,6 @@ fn writeHeader(self: *Zld) !void { |
| 2940 | } | 2952 | } |
| 2941 | | 2953 | |
| 2942 | pub fn makeString(self: *Zld, string: []const u8) !u32 { | 2954 | pub fn makeString(self: *Zld, string: []const u8) !u32 { |
| 2943 | if (self.strtab_cache.get(string)) |off| { | | |
| 2944 | log.debug("reusing string '{s}' at offset 0x{x}", .{ string, off }); | | |
| 2945 | return off; | | |
| 2946 | } | | |
| 2947 | | | |
| 2948 | try self.strtab.ensureUnusedCapacity(self.allocator, string.len + 1); | 2955 | try self.strtab.ensureUnusedCapacity(self.allocator, string.len + 1); |
| 2949 | const new_off = @intCast(u32, self.strtab.items.len); | 2956 | const new_off = @intCast(u32, self.strtab.items.len); |
| 2950 | | 2957 | |
| ... | @@ -2953,12 +2960,10 @@ pub fn makeString(self: *Zld, string: []const u8) !u32 { | ... | @@ -2953,12 +2960,10 @@ pub fn makeString(self: *Zld, string: []const u8) !u32 { |
| 2953 | self.strtab.appendSliceAssumeCapacity(string); | 2960 | self.strtab.appendSliceAssumeCapacity(string); |
| 2954 | self.strtab.appendAssumeCapacity(0); | 2961 | self.strtab.appendAssumeCapacity(0); |
| 2955 | | 2962 | |
| 2956 | try self.strtab_cache.putNoClobber(self.allocator, try self.allocator.dupe(u8, string), new_off); | | |
| 2957 | | | |
| 2958 | return new_off; | 2963 | return new_off; |
| 2959 | } | 2964 | } |
| 2960 | | 2965 | |
| 2961 | pub fn getString(self: *Zld, off: u32) ?[]const u8 { | 2966 | pub fn getString(self: *Zld, off: u32) []const u8 { |
| 2962 | assert(off < self.strtab.items.len); | 2967 | assert(off < self.strtab.items.len); |
| 2963 | return mem.spanZ(@ptrCast([*:0]const u8, self.strtab.items.ptr + off)); | 2968 | return mem.spanZ(@ptrCast([*:0]const u8, self.strtab.items.ptr + off)); |
| 2964 | } | 2969 | } |