authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-07-15 07:41:59+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-07-15 18:49:47+02:00
logf8678c48ff43879d043b626031f7a5c92303fdea
treebc6955440f013026f692a35345f7ab5ac8492653
parentec874a9b2bf24bb37f1e90558153bbf04ac5f22a

zld: reuse string table for symbol names

rather than manage allocs separately per symbol.

4 files changed, 107 insertions(+), 116 deletions(-)

src/link/MachO/Object.zig+25-14
......@@ -389,7 +389,7 @@ const TextBlockParser = struct {
389389 return switch (rreg.linkage) {
390390 .global => true,
391391 .linkage_unit => lreg.linkage == .translation_unit,
392 else => lsym.isTemp(),
392 else => lsym.isTemp(context.zld),
393393 };
394394 }
395395
......@@ -417,7 +417,7 @@ const TextBlockParser = struct {
417417 const sym = self.object.symbols.items[nlist_with_index.index];
418418 if (sym.payload != .regular) {
419419 log.err("expected a regular symbol, found {s}", .{sym.payload});
420 log.err(" when remapping {s}", .{sym.name});
420 log.err(" when remapping {s}", .{self.zld.getString(sym.strx)});
421421 return error.SymbolIsNotRegular;
422422 }
423423 assert(sym.payload.regular.local_sym_index != 0); // This means the symbol has not been properly resolved.
......@@ -463,7 +463,7 @@ const TextBlockParser = struct {
463463 }
464464 }
465465 }
466 if (self.zld.globals.contains(senior_sym.name)) break :blk .global;
466 if (self.zld.globals.contains(self.zld.getString(senior_sym.strx))) break :blk .global;
467467 break :blk .static;
468468 } else null;
469469
......@@ -598,7 +598,11 @@ pub fn parseTextBlocks(self: *Object, zld: *Zld) !void {
598598 sectionName(sect),
599599 });
600600 defer self.allocator.free(name);
601 const symbol = try Symbol.new(self.allocator, name);
601 const symbol = try zld.allocator.create(Symbol);
602 symbol.* = .{
603 .strx = try zld.makeString(name),
604 .payload = .{ .undef = .{} },
605 };
602606 try self.sections_as_symbols.putNoClobber(self.allocator, sect_id, symbol);
603607 break :symbol symbol;
604608 };
......@@ -684,7 +688,7 @@ pub fn parseTextBlocks(self: *Object, zld: *Zld) !void {
684688 const reg = &sym.payload.regular;
685689 if (reg.file) |file| {
686690 if (file != self) {
687 log.debug("deduping definition of {s} in {s}", .{ sym.name, self.name.? });
691 log.debug("deduping definition of {s} in {s}", .{ zld.getString(sym.strx), self.name.? });
688692 block.deinit();
689693 self.allocator.destroy(block);
690694 continue;
......@@ -739,7 +743,11 @@ pub fn parseTextBlocks(self: *Object, zld: *Zld) !void {
739743 sectionName(sect),
740744 });
741745 defer self.allocator.free(name);
742 const symbol = try Symbol.new(self.allocator, name);
746 const symbol = try zld.allocator.create(Symbol);
747 symbol.* = .{
748 .strx = try zld.makeString(name),
749 .payload = .{ .undef = .{} },
750 };
743751 try self.sections_as_symbols.putNoClobber(self.allocator, sect_id, symbol);
744752 break :symbol symbol;
745753 };
......@@ -812,7 +820,7 @@ pub fn parseTextBlocks(self: *Object, zld: *Zld) !void {
812820 }
813821 }
814822 }
815 if (zld.globals.contains(sym.name)) break :blk .global;
823 if (zld.globals.contains(zld.getString(sym.strx))) break :blk .global;
816824 break :blk .static;
817825 } else null;
818826
......@@ -870,7 +878,7 @@ fn parseRelocs(
870878 try parser.parse();
871879}
872880
873pub fn symbolFromReloc(self: *Object, rel: macho.relocation_info) !*Symbol {
881pub fn symbolFromReloc(self: *Object, zld: *Zld, rel: macho.relocation_info) !*Symbol {
874882 const symbol = blk: {
875883 if (rel.r_extern == 1) {
876884 break :blk self.symbols.items[rel.r_symbolnum];
......@@ -888,12 +896,15 @@ pub fn symbolFromReloc(self: *Object, rel: macho.relocation_info) !*Symbol {
888896 sectionName(sect),
889897 });
890898 defer self.allocator.free(name);
891 const symbol = try Symbol.new(self.allocator, name);
892 symbol.payload = .{
893 .regular = .{
894 .linkage = .translation_unit,
895 .address = sect.addr,
896 .file = self,
899 const symbol = try zld.allocator.create(Symbol);
900 symbol.* = .{
901 .strx = try zld.makeString(name),
902 .payload = .{
903 .regular = .{
904 .linkage = .translation_unit,
905 .address = sect.addr,
906 .file = self,
907 },
897908 },
898909 };
899910 try self.sections_as_symbols.putNoClobber(self.allocator, sect_id, symbol);
src/link/MachO/Symbol.zig+10-40
......@@ -11,8 +11,8 @@ const Dylib = @import("Dylib.zig");
1111const Object = @import("Object.zig");
1212const Zld = @import("Zld.zig");
1313
14/// Symbol name. Owned slice.
15name: []const u8,
14/// Offset into the string table.
15strx: u32,
1616
1717/// Index in GOT table for indirection.
1818got_index: ?u32 = null,
......@@ -160,26 +160,11 @@ pub const Undefined = struct {
160160 }
161161};
162162
163/// Create new undefined symbol.
164pub fn new(allocator: *Allocator, name: []const u8) !*Symbol {
165 const new_sym = try allocator.create(Symbol);
166 errdefer allocator.destroy(new_sym);
167
168 new_sym.* = .{
169 .name = try allocator.dupe(u8, name),
170 .payload = .{
171 .undef = .{},
172 },
173 };
174
175 return new_sym;
176}
177
178163pub fn format(self: Symbol, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void {
179164 _ = fmt;
180165 _ = options;
181166 try std.fmt.format(writer, "Symbol {{", .{});
182 try std.fmt.format(writer, ".name = {s}, ", .{self.name});
167 try std.fmt.format(writer, ".strx = {d}, ", .{self.strx});
183168 if (self.got_index) |got_index| {
184169 try std.fmt.format(writer, ".got_index = {}, ", .{got_index});
185170 }
......@@ -190,11 +175,12 @@ pub fn format(self: Symbol, comptime fmt: []const u8, options: std.fmt.FormatOpt
190175 try std.fmt.format(writer, "}}", .{});
191176}
192177
193pub fn isTemp(symbol: Symbol) bool {
178pub fn isTemp(symbol: Symbol, zld: *Zld) bool {
179 const sym_name = zld.getString(symbol.strx);
194180 switch (symbol.payload) {
195181 .regular => |regular| {
196182 if (regular.linkage == .translation_unit) {
197 return mem.startsWith(u8, symbol.name, "l") or mem.startsWith(u8, symbol.name, "L");
183 return mem.startsWith(u8, sym_name, "l") or mem.startsWith(u8, sym_name, "L");
198184 }
199185 },
200186 else => {},
......@@ -202,24 +188,12 @@ pub fn isTemp(symbol: Symbol) bool {
202188 return false;
203189}
204190
205pub fn needsTlvOffset(self: Symbol, zld: *Zld) bool {
206 if (self.payload != .regular) return false;
207
208 const reg = self.payload.regular;
209 const seg = zld.load_command.items[reg.segment_id].Segment;
210 const sect = seg.sections.items[reg.section_id];
211 const sect_type = commands.sectionType(sect);
212
213 return sect_type == macho.S_THREAD_LOCAL_VARIABLES;
214}
215
216191pub fn asNlist(symbol: *Symbol, zld: *Zld) !macho.nlist_64 {
217 const n_strx = try zld.makeString(symbol.name);
218192 const nlist = nlist: {
219193 switch (symbol.payload) {
220194 .regular => |regular| {
221195 var nlist = macho.nlist_64{
222 .n_strx = n_strx,
196 .n_strx = symbol.strx,
223197 .n_type = macho.N_SECT,
224198 .n_sect = regular.sectionId(zld),
225199 .n_desc = 0,
......@@ -239,7 +213,7 @@ pub fn asNlist(symbol: *Symbol, zld: *Zld) !macho.nlist_64 {
239213 .tentative => {
240214 // TODO
241215 break :nlist macho.nlist_64{
242 .n_strx = n_strx,
216 .n_strx = symbol.strx,
243217 .n_type = macho.N_UNDF,
244218 .n_sect = 0,
245219 .n_desc = 0,
......@@ -248,7 +222,7 @@ pub fn asNlist(symbol: *Symbol, zld: *Zld) !macho.nlist_64 {
248222 },
249223 .proxy => |proxy| {
250224 break :nlist macho.nlist_64{
251 .n_strx = n_strx,
225 .n_strx = symbol.strx,
252226 .n_type = macho.N_UNDF | macho.N_EXT,
253227 .n_sect = 0,
254228 .n_desc = (proxy.dylibOrdinal() * macho.N_SYMBOL_RESOLVER) | macho.REFERENCE_FLAG_UNDEFINED_NON_LAZY,
......@@ -258,7 +232,7 @@ pub fn asNlist(symbol: *Symbol, zld: *Zld) !macho.nlist_64 {
258232 .undef => {
259233 // TODO
260234 break :nlist macho.nlist_64{
261 .n_strx = n_strx,
235 .n_strx = symbol.strx,
262236 .n_type = macho.N_UNDF,
263237 .n_sect = 0,
264238 .n_desc = 0,
......@@ -270,10 +244,6 @@ pub fn asNlist(symbol: *Symbol, zld: *Zld) !macho.nlist_64 {
270244 return nlist;
271245}
272246
273pub fn deinit(symbol: *Symbol, allocator: *Allocator) void {
274 allocator.free(symbol.name);
275}
276
277247pub fn isStab(sym: macho.nlist_64) bool {
278248 return (macho.N_STAB & sym.n_type) != 0;
279249}
src/link/MachO/Zld.zig+59-54
......@@ -113,7 +113,6 @@ stub_helper_stubs_start_off: ?u64 = null,
113113blocks: std.AutoHashMapUnmanaged(MatchingSection, *TextBlock) = .{},
114114
115115strtab: std.ArrayListUnmanaged(u8) = .{},
116strtab_cache: std.StringHashMapUnmanaged(u32) = .{},
117116
118117has_dices: bool = false,
119118has_stabs: bool = false,
......@@ -171,7 +170,7 @@ pub const TextBlock = struct {
171170 .n_value = reg.address,
172171 });
173172 nlists.appendAssumeCapacity(.{
174 .n_strx = try zld.makeString(sym.name),
173 .n_strx = sym.strx,
175174 .n_type = macho.N_FUN,
176175 .n_sect = section_id,
177176 .n_desc = 0,
......@@ -194,7 +193,7 @@ pub const TextBlock = struct {
194193 },
195194 .global => {
196195 try nlists.append(.{
197 .n_strx = try zld.makeString(sym.name),
196 .n_strx = sym.strx,
198197 .n_type = macho.N_GSYM,
199198 .n_sect = 0,
200199 .n_desc = 0,
......@@ -203,7 +202,7 @@ pub const TextBlock = struct {
203202 },
204203 .static => {
205204 try nlists.append(.{
206 .n_strx = try zld.makeString(sym.name),
205 .n_strx = sym.strx,
207206 .n_type = macho.N_STSYM,
208207 .n_sect = reg.sectionId(zld),
209208 .n_desc = 0,
......@@ -349,26 +348,20 @@ pub fn deinit(self: *Zld) void {
349348 self.dylibs.deinit(self.allocator);
350349
351350 for (self.imports.items) |sym| {
352 sym.deinit(self.allocator);
353351 self.allocator.destroy(sym);
354352 }
355353 self.imports.deinit(self.allocator);
356354
357355 for (self.locals.items) |sym| {
358 sym.deinit(self.allocator);
359356 self.allocator.destroy(sym);
360357 }
361358 self.locals.deinit(self.allocator);
362359
360 for (self.globals.keys()) |key| {
361 self.allocator.free(key);
362 }
363363 self.globals.deinit(self.allocator);
364364
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);
372365 self.strtab.deinit(self.allocator);
373366
374367 // TODO dealloc all blocks
......@@ -1168,7 +1161,7 @@ fn allocateTextBlocks(self: *Zld) !void {
11681161 sym.payload.regular.address = base_addr;
11691162
11701163 log.debug(" {s}: start=0x{x}, end=0x{x}, size={}, align={}", .{
1171 sym.name,
1164 self.getString(sym.strx),
11721165 base_addr,
11731166 base_addr + block.size,
11741167 block.size,
......@@ -1231,7 +1224,7 @@ fn writeTextBlocks(self: *Zld) !void {
12311224
12321225 const sym = self.locals.items[block.local_sym_index];
12331226 log.debug(" {s}: start=0x{x}, end=0x{x}, size={}, align={}", .{
1234 sym.name,
1227 self.getString(sym.strx),
12351228 aligned_base_off,
12361229 aligned_base_off + block.size,
12371230 block.size,
......@@ -1552,14 +1545,17 @@ fn resolveSymbolsInObject(self: *Zld, object: *Object) !void {
15521545
15531546 if (Symbol.isSect(sym) and !Symbol.isExt(sym)) {
15541547 // Regular symbol local to translation unit
1555 const symbol = try Symbol.new(self.allocator, sym_name);
1556 symbol.payload = .{
1557 .regular = .{
1558 .linkage = .translation_unit,
1559 .address = sym.n_value,
1560 .weak_ref = Symbol.isWeakRef(sym),
1561 .file = object,
1562 .local_sym_index = @intCast(u32, self.locals.items.len),
1548 const symbol = try self.allocator.create(Symbol);
1549 symbol.* = .{
1550 .strx = try self.makeString(sym_name),
1551 .payload = .{
1552 .regular = .{
1553 .linkage = .translation_unit,
1554 .address = sym.n_value,
1555 .weak_ref = Symbol.isWeakRef(sym),
1556 .file = object,
1557 .local_sym_index = @intCast(u32, self.locals.items.len),
1558 },
15631559 },
15641560 };
15651561 try self.locals.append(self.allocator, symbol);
......@@ -1569,9 +1565,13 @@ fn resolveSymbolsInObject(self: *Zld, object: *Object) !void {
15691565
15701566 const symbol = self.globals.get(sym_name) orelse symbol: {
15711567 // Insert new global symbol.
1572 const symbol = try Symbol.new(self.allocator, sym_name);
1573 symbol.payload.undef.file = object;
1574 try self.globals.putNoClobber(self.allocator, symbol.name, symbol);
1568 const symbol = try self.allocator.create(Symbol);
1569 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);
15751575 break :symbol symbol;
15761576 };
15771577
......@@ -1628,7 +1628,8 @@ fn resolveSymbolsInObject(self: *Zld, object: *Object) !void {
16281628fn resolveSymbols(self: *Zld) !void {
16291629 // TODO mimicking insertion of null symbol from incremental linker.
16301630 // 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 = .{} } };
16321633 try self.locals.append(self.allocator, null_sym);
16331634
16341635 // First pass, resolve symbols in provided objects.
......@@ -1639,12 +1640,13 @@ fn resolveSymbols(self: *Zld) !void {
16391640 // Second pass, resolve symbols in static libraries.
16401641 var sym_it = self.globals.iterator();
16411642 while (sym_it.next()) |entry| {
1643 const sym_name = entry.key_ptr.*;
16421644 const symbol = entry.value_ptr.*;
16431645 if (symbol.payload != .undef) continue;
16441646
16451647 for (self.archives.items) |archive| {
16461648 // 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 {
16481650 // No hit.
16491651 continue;
16501652 };
......@@ -1734,21 +1736,27 @@ fn resolveSymbols(self: *Zld) !void {
17341736 // Third pass, resolve symbols in dynamic libraries.
17351737 {
17361738 // 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 };
17381744 const index = @intCast(u32, self.got_entries.items.len);
17391745 symbol.got_index = index;
17401746 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);
17421749 }
17431750
17441751 var referenced = std.AutoHashMap(*Dylib, void).init(self.allocator);
17451752 defer referenced.deinit();
17461753
1747 loop: for (self.globals.values()) |symbol| {
1754 loop: for (self.globals.keys()) |sym_name| {
1755 const symbol = self.globals.get(sym_name).?;
17481756 if (symbol.payload != .undef) continue;
17491757
17501758 for (self.dylibs.items) |dylib| {
1751 if (!dylib.symbols.contains(symbol.name)) continue;
1759 if (!dylib.symbols.contains(sym_name)) continue;
17521760
17531761 try referenced.put(dylib, {});
17541762 const index = @intCast(u32, self.imports.items.len);
......@@ -1798,10 +1806,11 @@ fn resolveSymbols(self: *Zld) !void {
17981806 }
17991807
18001808 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).?;
18021811 if (symbol.payload != .undef) continue;
18031812
1804 log.err("undefined reference to symbol '{s}'", .{symbol.name});
1813 log.err("undefined reference to symbol '{s}'", .{sym_name});
18051814 if (symbol.payload.undef.file) |file| {
18061815 log.err(" | referenced in {s}", .{file.name.?});
18071816 }
......@@ -2344,7 +2353,7 @@ fn writeBindInfoTable(self: *Zld) !void {
23442353 .offset = base_offset + sym.got_index.? * @sizeOf(u64),
23452354 .segment_id = segment_id,
23462355 .dylib_ordinal = proxy.dylibOrdinal(),
2347 .name = sym.name,
2356 .name = self.getString(sym.strx),
23482357 });
23492358 }
23502359 }
......@@ -2372,7 +2381,7 @@ fn writeBindInfoTable(self: *Zld) !void {
23722381 .offset = binding.offset + base_offset,
23732382 .segment_id = match.seg,
23742383 .dylib_ordinal = proxy.dylibOrdinal(),
2375 .name = bind_sym.name,
2384 .name = self.getString(bind_sym.strx),
23762385 });
23772386 }
23782387
......@@ -2395,7 +2404,7 @@ fn writeBindInfoTable(self: *Zld) !void {
23952404 .offset = base_offset,
23962405 .segment_id = segment_id,
23972406 .dylib_ordinal = proxy.dylibOrdinal(),
2398 .name = sym.name,
2407 .name = self.getString(sym.strx),
23992408 });
24002409 }
24012410
......@@ -2435,7 +2444,7 @@ fn writeLazyBindInfoTable(self: *Zld) !void {
24352444 .offset = base_offset + sym.stubs_index.? * @sizeOf(u64),
24362445 .segment_id = segment_id,
24372446 .dylib_ordinal = proxy.dylibOrdinal(),
2438 .name = sym.name,
2447 .name = self.getString(sym.strx),
24392448 });
24402449 }
24412450 }
......@@ -2547,7 +2556,7 @@ fn writeExportInfo(self: *Zld) !void {
25472556 if (sym.payload != .regular) continue;
25482557 const reg = sym.payload.regular;
25492558 if (reg.linkage != .global) continue;
2550 try sorted_globals.append(sym.name);
2559 try sorted_globals.append(self.getString(sym.strx));
25512560 }
25522561
25532562 std.sort.sort([]const u8, sorted_globals.items, {}, Sorter.lessThan);
......@@ -2556,10 +2565,10 @@ fn writeExportInfo(self: *Zld) !void {
25562565 const sym = self.globals.get(sym_name) orelse unreachable;
25572566 const reg = sym.payload.regular;
25582567
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 });
25602569
25612570 try trie.put(.{
2562 .name = sym.name,
2571 .name = sym_name,
25632572 .vmaddr_offset = reg.address - base_address,
25642573 .export_flags = macho.EXPORT_SYMBOL_FLAGS_KIND_REGULAR,
25652574 });
......@@ -2597,7 +2606,7 @@ fn writeSymbolTable(self: *Zld) !void {
25972606
25982607 for (self.locals.items) |symbol, i| {
25992608 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
26012610
26022611 const reg = symbol.payload.regular;
26032612 const nlist = try symbol.asNlist(self);
......@@ -2673,7 +2682,7 @@ fn writeSymbolTable(self: *Zld) !void {
26732682 const nlist = try sym.asNlist(self);
26742683 const id = @intCast(u32, undefs.items.len);
26752684 try undefs.append(nlist);
2676 try undef_dir.putNoClobber(sym.name, id);
2685 try undef_dir.putNoClobber(self.getString(sym.strx), id);
26772686 }
26782687
26792688 const nlocals = locals.items.len;
......@@ -2735,7 +2744,8 @@ fn writeSymbolTable(self: *Zld) !void {
27352744
27362745 stubs.reserved1 = 0;
27372746 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;
27392749 try writer.writeIntLittle(u32, dysymtab.iundefsym + id);
27402750 }
27412751
......@@ -2743,7 +2753,8 @@ fn writeSymbolTable(self: *Zld) !void {
27432753 for (self.got_entries.items) |sym| {
27442754 switch (sym.payload) {
27452755 .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;
27472758 try writer.writeIntLittle(u32, dysymtab.iundefsym + id);
27482759 },
27492760 else => {
......@@ -2754,7 +2765,8 @@ fn writeSymbolTable(self: *Zld) !void {
27542765
27552766 la_symbol_ptr.reserved1 = got.reserved1 + ngot_entries;
27562767 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;
27582770 try writer.writeIntLittle(u32, dysymtab.iundefsym + id);
27592771 }
27602772
......@@ -2940,11 +2952,6 @@ fn writeHeader(self: *Zld) !void {
29402952}
29412953
29422954pub 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
29482955 try self.strtab.ensureUnusedCapacity(self.allocator, string.len + 1);
29492956 const new_off = @intCast(u32, self.strtab.items.len);
29502957
......@@ -2953,12 +2960,10 @@ pub fn makeString(self: *Zld, string: []const u8) !u32 {
29532960 self.strtab.appendSliceAssumeCapacity(string);
29542961 self.strtab.appendAssumeCapacity(0);
29552962
2956 try self.strtab_cache.putNoClobber(self.allocator, try self.allocator.dupe(u8, string), new_off);
2957
29582963 return new_off;
29592964}
29602965
2961pub fn getString(self: *Zld, off: u32) ?[]const u8 {
2966pub fn getString(self: *Zld, off: u32) []const u8 {
29622967 assert(off < self.strtab.items.len);
29632968 return mem.spanZ(@ptrCast([*:0]const u8, self.strtab.items.ptr + off));
29642969}
src/link/MachO/reloc.zig+13-8
......@@ -407,7 +407,7 @@ pub const Relocation = struct {
407407 const dc_seg = zld.load_commands.items[zld.data_const_segment_cmd_index.?].Segment;
408408 const got = dc_seg.sections.items[zld.got_section_index.?];
409409 const got_index = self.target.got_index orelse {
410 log.err("expected GOT entry for symbol '{s}'", .{self.target.name});
410 log.err("expected GOT entry for symbol '{s}'", .{zld.getString(self.target.strx)});
411411 log.err(" this is an internal linker error", .{});
412412 return error.FailedToResolveRelocationTarget;
413413 };
......@@ -446,8 +446,8 @@ pub const Relocation = struct {
446446
447447 break :blk reg.address;
448448 },
449 .proxy => |proxy| {
450 if (mem.eql(u8, self.target.name, "__tlv_bootstrap")) {
449 .proxy => {
450 if (mem.eql(u8, zld.getString(self.target.strx), "__tlv_bootstrap")) {
451451 break :blk 0; // Dynamically bound by dyld.
452452 }
453453
......@@ -460,7 +460,9 @@ pub const Relocation = struct {
460460 break :blk stubs.addr + stubs_index * stubs.reserved2;
461461 },
462462 else => {
463 log.err("failed to resolve symbol '{s}' as a relocation target", .{self.target.name});
463 log.err("failed to resolve symbol '{s}' as a relocation target", .{
464 zld.getString(self.target.strx),
465 });
464466 log.err(" this is an internal linker error", .{});
465467 return error.FailedToResolveRelocationTarget;
466468 },
......@@ -634,7 +636,10 @@ pub const Parser = struct {
634636 out_rel.target.got_index = index;
635637 try self.zld.got_entries.append(self.zld.allocator, out_rel.target);
636638
637 log.debug("adding GOT entry for symbol {s} at index {}", .{ out_rel.target.name, index });
639 log.debug("adding GOT entry for symbol {s} at index {}", .{
640 self.zld.getString(out_rel.target.strx),
641 index,
642 });
638643 } else if (out_rel.payload == .unsigned) {
639644 const sym = out_rel.target;
640645 switch (sym.payload) {
......@@ -697,14 +702,14 @@ pub const Parser = struct {
697702 sym.stubs_index = index;
698703 try self.zld.stubs.append(self.zld.allocator, sym);
699704
700 log.debug("adding stub entry for symbol {s} at index {}", .{ sym.name, index });
705 log.debug("adding stub entry for symbol {s} at index {}", .{ self.zld.getString(sym.strx), index });
701706 }
702707 }
703708 }
704709
705710 fn parseBaseRelInfo(self: *Parser, rel: macho.relocation_info) !Relocation {
706711 const offset = @intCast(u32, @intCast(u64, rel.r_address) - self.base_addr);
707 const target = try self.object.symbolFromReloc(rel);
712 const target = try self.object.symbolFromReloc(self.zld, rel);
708713 return Relocation{
709714 .offset = offset,
710715 .target = target,
......@@ -888,7 +893,7 @@ pub const Parser = struct {
888893 assert(rel.r_pcrel == 0);
889894 assert(self.subtractor == null);
890895
891 self.subtractor = try self.object.symbolFromReloc(rel);
896 self.subtractor = try self.object.symbolFromReloc(self.zld, rel);
892897 }
893898
894899 fn parseLoad(self: *Parser, rel: macho.relocation_info) !Relocation {