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...@@ -3763,9 +3763,12 @@ pub fn lowerUnnamedConst(self: *MachO, typed_value: TypedValue, decl: *Module.De
3763 }3763 }
3764 const unnamed_consts = gop.value_ptr;3764 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
3766 const name_str_index = blk: {3769 const name_str_index = blk: {
3767 const index = unnamed_consts.items.len;3770 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 });
3769 defer self.base.allocator.free(name);3772 defer self.base.allocator.free(name);
3770 break :blk try self.makeString(name);3773 break :blk try self.makeString(name);
3771 };3774 };
...@@ -4057,14 +4060,17 @@ fn placeDecl(self: *MachO, decl: *Module.Decl, code_len: usize) !*macho.nlist_64...@@ -4057,14 +4060,17 @@ fn placeDecl(self: *MachO, decl: *Module.Decl, code_len: usize) !*macho.nlist_64
4057 decl_ptr.* = try self.getMatchingSectionAtom(&decl.link.macho, decl.ty, decl.val);4060 decl_ptr.* = try self.getMatchingSectionAtom(&decl.link.macho, decl.ty, decl.val);
4058 }4061 }
4059 const match = decl_ptr.*.?;4062 const match = decl_ptr.*.?;
4063 const sym_name = try decl.getFullyQualifiedName(self.base.allocator);
4064 defer self.base.allocator.free(sym_name);
40604065
4061 if (decl.link.macho.size != 0) {4066 if (decl.link.macho.size != 0) {
4062 const capacity = decl.link.macho.capacity(self.*);4067 const capacity = decl.link.macho.capacity(self.*);
4063 const need_realloc = code_len > capacity or !mem.isAlignedGeneric(u64, symbol.n_value, required_alignment);4068 const need_realloc = code_len > capacity or !mem.isAlignedGeneric(u64, symbol.n_value, required_alignment);
4069
4064 if (need_realloc) {4070 if (need_realloc) {
4065 const vaddr = try self.growAtom(&decl.link.macho, code_len, required_alignment, match);4071 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
4069 if (vaddr != symbol.n_value) {4075 if (vaddr != symbol.n_value) {
4070 log.debug(" (writing new GOT entry)", .{});4076 log.debug(" (writing new GOT entry)", .{});
...@@ -4090,25 +4096,15 @@ fn placeDecl(self: *MachO, decl: *Module.Decl, code_len: usize) !*macho.nlist_64...@@ -4090,25 +4096,15 @@ fn placeDecl(self: *MachO, decl: *Module.Decl, code_len: usize) !*macho.nlist_64
4090 decl.link.macho.size = code_len;4096 decl.link.macho.size = code_len;
4091 decl.link.macho.dirty = true;4097 decl.link.macho.dirty = true;
40924098
4093 const new_name = try std.fmt.allocPrint(self.base.allocator, "_{s}", .{4099 symbol.n_strx = try self.makeString(sym_name);
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_type = macho.N_SECT;4100 symbol.n_type = macho.N_SECT;
4100 symbol.n_sect = @intCast(u8, self.text_section_index.?) + 1;4101 symbol.n_sect = @intCast(u8, self.text_section_index.?) + 1;
4101 symbol.n_desc = 0;4102 symbol.n_desc = 0;
4102 } else {4103 } else {
4103 const decl_name = try std.fmt.allocPrint(self.base.allocator, "_{s}", .{4104 const name_str_index = try self.makeString(sym_name);
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);
4109 const addr = try self.allocateAtom(&decl.link.macho, code_len, required_alignment, match);4105 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
4113 errdefer self.freeAtom(&decl.link.macho, match, false);4109 errdefer self.freeAtom(&decl.link.macho, match, false);
41144110
...@@ -6691,17 +6687,17 @@ fn snapshotState(self: *MachO) !void {...@@ -6691,17 +6687,17 @@ fn snapshotState(self: *MachO) !void {
6691fn logSymtab(self: MachO) void {6687fn logSymtab(self: MachO) void {
6692 log.debug("locals:", .{});6688 log.debug("locals:", .{});
6693 for (self.locals.items) |sym, id| {6689 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 });
6695 }6691 }
66966692
6697 log.debug("globals:", .{});6693 log.debug("globals:", .{});
6698 for (self.globals.items) |sym, id| {6694 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 });
6700 }6696 }
67016697
6702 log.debug("undefs:", .{});6698 log.debug("undefs:", .{});
6703 for (self.undefs.items) |sym, id| {6699 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 });
6705 }6701 }
67066702
6707 {6703 {
...@@ -6716,26 +6712,28 @@ fn logSymtab(self: MachO) void {...@@ -6716,26 +6712,28 @@ fn logSymtab(self: MachO) void {
6716 for (self.got_entries_table.values()) |value| {6712 for (self.got_entries_table.values()) |value| {
6717 const key = self.got_entries.items[value].target;6713 const key = self.got_entries.items[value].target;
6718 const atom = self.got_entries.items[value].atom;6714 const atom = self.got_entries.items[value].atom;
6715 const n_value = self.locals.items[atom.local_sym_index].n_value;
6719 switch (key) {6716 switch (key) {
6720 .local => {6717 .local => |ndx| log.debug(" {d}: @{x}", .{ ndx, n_value }),
6721 const sym = self.locals.items[atom.local_sym_index];6718 .global => |n_strx| log.debug(" {s}: @{x}", .{ self.getString(n_strx), n_value }),
6722 log.debug(" {} => {s}", .{ key, self.getString(sym.n_strx) });
6723 },
6724 .global => |n_strx| log.debug(" {} => {s}", .{ key, self.getString(n_strx) }),
6725 }6719 }
6726 }6720 }
67276721
6728 log.debug("__thread_ptrs entries:", .{});6722 log.debug("__thread_ptrs entries:", .{});
6729 for (self.tlv_ptr_entries_table.keys()) |key| {6723 for (self.tlv_ptr_entries_table.values()) |value| {
6730 switch (key) {6724 const key = self.tlv_ptr_entries.items[value].target;
6731 .local => unreachable,6725 const atom = self.tlv_ptr_entries.items[value].atom;
6732 .global => |n_strx| log.debug(" {} => {s}", .{ key, self.getString(n_strx) }),6726 const n_value = self.locals.items[atom.local_sym_index].n_value;
6733 }6727 assert(key == .global);
6728 log.debug(" {s}: @{x}", .{ self.getString(key.global), n_value });
6734 }6729 }
67356730
6736 log.debug("stubs:", .{});6731 log.debug("stubs:", .{});
6737 for (self.stubs_table.keys()) |key| {6732 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 });
6739 }6737 }
6740}6738}
67416739