authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-02-23 18:44:16+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-02-23 19:10:44+01:00
log2ca809c32a69c286568814043019e444c1c85ff2
tree1de0a2c7b2c080e880bc6b2f8ddc43b49ab34bf3
parent897a5a4735d5e72c53529a9a3f3a815943568214

macho: ensure we save the fully qualified name for any local symbol

Otherwise, we risk collisions in the global symbol table. This is also an opportunity to generalise and rewrite the symbol table abstraction. Also, improve the logs for the symbol table.

1 files changed, 27 insertions(+), 29 deletions(-)

src/link/MachO.zig+27-29
......@@ -3763,9 +3763,12 @@ pub fn lowerUnnamedConst(self: *MachO, typed_value: TypedValue, decl: *Module.De
37633763 }
37643764 const unnamed_consts = gop.value_ptr;
37653765
3766 const decl_name = try decl.getFullyQualifiedName(self.base.allocator);
3767 defer self.base.allocator.free(decl_name);
3768
37663769 const name_str_index = blk: {
37673770 const index = unnamed_consts.items.len;
3768 const name = try std.fmt.allocPrint(self.base.allocator, "__unnamed_{s}_{d}", .{ decl.name, index });
3771 const name = try std.fmt.allocPrint(self.base.allocator, "__unnamed_{s}_{d}", .{ decl_name, index });
37693772 defer self.base.allocator.free(name);
37703773 break :blk try self.makeString(name);
37713774 };
......@@ -4057,14 +4060,17 @@ fn placeDecl(self: *MachO, decl: *Module.Decl, code_len: usize) !*macho.nlist_64
40574060 decl_ptr.* = try self.getMatchingSectionAtom(&decl.link.macho, decl.ty, decl.val);
40584061 }
40594062 const match = decl_ptr.*.?;
4063 const sym_name = try decl.getFullyQualifiedName(self.base.allocator);
4064 defer self.base.allocator.free(sym_name);
40604065
40614066 if (decl.link.macho.size != 0) {
40624067 const capacity = decl.link.macho.capacity(self.*);
40634068 const need_realloc = code_len > capacity or !mem.isAlignedGeneric(u64, symbol.n_value, required_alignment);
4069
40644070 if (need_realloc) {
40654071 const vaddr = try self.growAtom(&decl.link.macho, code_len, required_alignment, match);
40664072
4067 log.debug("growing {s} and moving from 0x{x} to 0x{x}", .{ decl.name, symbol.n_value, vaddr });
4073 log.debug("growing {s} and moving from 0x{x} to 0x{x}", .{ sym_name, symbol.n_value, vaddr });
40684074
40694075 if (vaddr != symbol.n_value) {
40704076 log.debug(" (writing new GOT entry)", .{});
......@@ -4090,25 +4096,15 @@ fn placeDecl(self: *MachO, decl: *Module.Decl, code_len: usize) !*macho.nlist_64
40904096 decl.link.macho.size = code_len;
40914097 decl.link.macho.dirty = true;
40924098
4093 const new_name = try std.fmt.allocPrint(self.base.allocator, "_{s}", .{
4094 mem.sliceTo(decl.name, 0),
4095 });
4096 defer self.base.allocator.free(new_name);
4097
4098 symbol.n_strx = try self.makeString(new_name);
4099 symbol.n_strx = try self.makeString(sym_name);
40994100 symbol.n_type = macho.N_SECT;
41004101 symbol.n_sect = @intCast(u8, self.text_section_index.?) + 1;
41014102 symbol.n_desc = 0;
41024103 } else {
4103 const decl_name = try std.fmt.allocPrint(self.base.allocator, "_{s}", .{
4104 mem.sliceTo(decl.name, 0),
4105 });
4106 defer self.base.allocator.free(decl_name);
4107
4108 const name_str_index = try self.makeString(decl_name);
4104 const name_str_index = try self.makeString(sym_name);
41094105 const addr = try self.allocateAtom(&decl.link.macho, code_len, required_alignment, match);
41104106
4111 log.debug("allocated atom for {s} at 0x{x}", .{ decl_name, addr });
4107 log.debug("allocated atom for {s} at 0x{x}", .{ sym_name, addr });
41124108
41134109 errdefer self.freeAtom(&decl.link.macho, match, false);
41144110
......@@ -6691,17 +6687,17 @@ fn snapshotState(self: *MachO) !void {
66916687fn logSymtab(self: MachO) void {
66926688 log.debug("locals:", .{});
66936689 for (self.locals.items) |sym, id| {
6694 log.debug(" {d}: {s}: {}", .{ id, self.getString(sym.n_strx), sym });
6690 log.debug(" {d}: {s}: @{x} in {d}", .{ id, self.getString(sym.n_strx), sym.n_value, sym.n_sect });
66956691 }
66966692
66976693 log.debug("globals:", .{});
66986694 for (self.globals.items) |sym, id| {
6699 log.debug(" {d}: {s}: {}", .{ id, self.getString(sym.n_strx), sym });
6695 log.debug(" {d}: {s}: @{x} in {d}", .{ id, self.getString(sym.n_strx), sym.n_value, sym.n_sect });
67006696 }
67016697
67026698 log.debug("undefs:", .{});
67036699 for (self.undefs.items) |sym, id| {
6704 log.debug(" {d}: {s}: {}", .{ id, self.getString(sym.n_strx), sym });
6700 log.debug(" {d}: {s}: in {d}", .{ id, self.getString(sym.n_strx), sym.n_desc });
67056701 }
67066702
67076703 {
......@@ -6716,26 +6712,28 @@ fn logSymtab(self: MachO) void {
67166712 for (self.got_entries_table.values()) |value| {
67176713 const key = self.got_entries.items[value].target;
67186714 const atom = self.got_entries.items[value].atom;
6715 const n_value = self.locals.items[atom.local_sym_index].n_value;
67196716 switch (key) {
6720 .local => {
6721 const sym = self.locals.items[atom.local_sym_index];
6722 log.debug(" {} => {s}", .{ key, self.getString(sym.n_strx) });
6723 },
6724 .global => |n_strx| log.debug(" {} => {s}", .{ key, self.getString(n_strx) }),
6717 .local => |ndx| log.debug(" {d}: @{x}", .{ ndx, n_value }),
6718 .global => |n_strx| log.debug(" {s}: @{x}", .{ self.getString(n_strx), n_value }),
67256719 }
67266720 }
67276721
67286722 log.debug("__thread_ptrs entries:", .{});
6729 for (self.tlv_ptr_entries_table.keys()) |key| {
6730 switch (key) {
6731 .local => unreachable,
6732 .global => |n_strx| log.debug(" {} => {s}", .{ key, self.getString(n_strx) }),
6733 }
6723 for (self.tlv_ptr_entries_table.values()) |value| {
6724 const key = self.tlv_ptr_entries.items[value].target;
6725 const atom = self.tlv_ptr_entries.items[value].atom;
6726 const n_value = self.locals.items[atom.local_sym_index].n_value;
6727 assert(key == .global);
6728 log.debug(" {s}: @{x}", .{ self.getString(key.global), n_value });
67346729 }
67356730
67366731 log.debug("stubs:", .{});
67376732 for (self.stubs_table.keys()) |key| {
6738 log.debug(" {} => {s}", .{ key, self.getString(key) });
6733 const value = self.stubs_table.get(key).?;
6734 const atom = self.stubs.items[value];
6735 const sym = self.locals.items[atom.local_sym_index];
6736 log.debug(" {s}: @{x}", .{ self.getString(key), sym.n_value });
67396737 }
67406738}
67416739