aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJakub Konka <kubkon@jakubkonka.com>2022-02-23 18:44:16 +0100
committerJakub Konka <kubkon@jakubkonka.com>2022-02-23 19:10:44 +0100
commit2ca809c32a69c286568814043019e444c1c85ff2 (patch)
tree1de0a2c7b2c080e880bc6b2f8ddc43b49ab34bf3 /src
parent897a5a4735d5e72c53529a9a3f3a815943568214 (diff)
downloadzig-2ca809c32a69c286568814043019e444c1c85ff2.tar.gz
zig-2ca809c32a69c286568814043019e444c1c85ff2.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/link/MachO.zig56
1 files changed, 27 insertions, 29 deletions
diff --git a/src/link/MachO.zig b/src/link/MachO.zig
index 7bb8490e6f..00019879ad 100644
--- a/src/link/MachO.zig
+++ b/src/link/MachO.zig
@@ -3763,9 +3763,12 @@ pub fn lowerUnnamedConst(self: *MachO, typed_value: TypedValue, decl: *Module.De
}
const unnamed_consts = gop.value_ptr;
+ const decl_name = try decl.getFullyQualifiedName(self.base.allocator);
+ defer self.base.allocator.free(decl_name);
+
const name_str_index = blk: {
const index = unnamed_consts.items.len;
- const name = try std.fmt.allocPrint(self.base.allocator, "__unnamed_{s}_{d}", .{ decl.name, index });
+ const name = try std.fmt.allocPrint(self.base.allocator, "__unnamed_{s}_{d}", .{ decl_name, index });
defer self.base.allocator.free(name);
break :blk try self.makeString(name);
};
@@ -4057,14 +4060,17 @@ fn placeDecl(self: *MachO, decl: *Module.Decl, code_len: usize) !*macho.nlist_64
decl_ptr.* = try self.getMatchingSectionAtom(&decl.link.macho, decl.ty, decl.val);
}
const match = decl_ptr.*.?;
+ const sym_name = try decl.getFullyQualifiedName(self.base.allocator);
+ defer self.base.allocator.free(sym_name);
if (decl.link.macho.size != 0) {
const capacity = decl.link.macho.capacity(self.*);
const need_realloc = code_len > capacity or !mem.isAlignedGeneric(u64, symbol.n_value, required_alignment);
+
if (need_realloc) {
const vaddr = try self.growAtom(&decl.link.macho, code_len, required_alignment, match);
- log.debug("growing {s} and moving from 0x{x} to 0x{x}", .{ decl.name, symbol.n_value, vaddr });
+ log.debug("growing {s} and moving from 0x{x} to 0x{x}", .{ sym_name, symbol.n_value, vaddr });
if (vaddr != symbol.n_value) {
log.debug(" (writing new GOT entry)", .{});
@@ -4090,25 +4096,15 @@ fn placeDecl(self: *MachO, decl: *Module.Decl, code_len: usize) !*macho.nlist_64
decl.link.macho.size = code_len;
decl.link.macho.dirty = true;
- const new_name = try std.fmt.allocPrint(self.base.allocator, "_{s}", .{
- mem.sliceTo(decl.name, 0),
- });
- defer self.base.allocator.free(new_name);
-
- symbol.n_strx = try self.makeString(new_name);
+ symbol.n_strx = try self.makeString(sym_name);
symbol.n_type = macho.N_SECT;
symbol.n_sect = @intCast(u8, self.text_section_index.?) + 1;
symbol.n_desc = 0;
} else {
- const decl_name = try std.fmt.allocPrint(self.base.allocator, "_{s}", .{
- mem.sliceTo(decl.name, 0),
- });
- defer self.base.allocator.free(decl_name);
-
- const name_str_index = try self.makeString(decl_name);
+ const name_str_index = try self.makeString(sym_name);
const addr = try self.allocateAtom(&decl.link.macho, code_len, required_alignment, match);
- log.debug("allocated atom for {s} at 0x{x}", .{ decl_name, addr });
+ log.debug("allocated atom for {s} at 0x{x}", .{ sym_name, addr });
errdefer self.freeAtom(&decl.link.macho, match, false);
@@ -6691,17 +6687,17 @@ fn snapshotState(self: *MachO) !void {
fn logSymtab(self: MachO) void {
log.debug("locals:", .{});
for (self.locals.items) |sym, id| {
- log.debug(" {d}: {s}: {}", .{ id, self.getString(sym.n_strx), sym });
+ log.debug(" {d}: {s}: @{x} in {d}", .{ id, self.getString(sym.n_strx), sym.n_value, sym.n_sect });
}
log.debug("globals:", .{});
for (self.globals.items) |sym, id| {
- log.debug(" {d}: {s}: {}", .{ id, self.getString(sym.n_strx), sym });
+ log.debug(" {d}: {s}: @{x} in {d}", .{ id, self.getString(sym.n_strx), sym.n_value, sym.n_sect });
}
log.debug("undefs:", .{});
for (self.undefs.items) |sym, id| {
- log.debug(" {d}: {s}: {}", .{ id, self.getString(sym.n_strx), sym });
+ log.debug(" {d}: {s}: in {d}", .{ id, self.getString(sym.n_strx), sym.n_desc });
}
{
@@ -6716,26 +6712,28 @@ fn logSymtab(self: MachO) void {
for (self.got_entries_table.values()) |value| {
const key = self.got_entries.items[value].target;
const atom = self.got_entries.items[value].atom;
+ const n_value = self.locals.items[atom.local_sym_index].n_value;
switch (key) {
- .local => {
- const sym = self.locals.items[atom.local_sym_index];
- log.debug(" {} => {s}", .{ key, self.getString(sym.n_strx) });
- },
- .global => |n_strx| log.debug(" {} => {s}", .{ key, self.getString(n_strx) }),
+ .local => |ndx| log.debug(" {d}: @{x}", .{ ndx, n_value }),
+ .global => |n_strx| log.debug(" {s}: @{x}", .{ self.getString(n_strx), n_value }),
}
}
log.debug("__thread_ptrs entries:", .{});
- for (self.tlv_ptr_entries_table.keys()) |key| {
- switch (key) {
- .local => unreachable,
- .global => |n_strx| log.debug(" {} => {s}", .{ key, self.getString(n_strx) }),
- }
+ for (self.tlv_ptr_entries_table.values()) |value| {
+ const key = self.tlv_ptr_entries.items[value].target;
+ const atom = self.tlv_ptr_entries.items[value].atom;
+ const n_value = self.locals.items[atom.local_sym_index].n_value;
+ assert(key == .global);
+ log.debug(" {s}: @{x}", .{ self.getString(key.global), n_value });
}
log.debug("stubs:", .{});
for (self.stubs_table.keys()) |key| {
- log.debug(" {} => {s}", .{ key, self.getString(key) });
+ const value = self.stubs_table.get(key).?;
+ const atom = self.stubs.items[value];
+ const sym = self.locals.items[atom.local_sym_index];
+ log.debug(" {s}: @{x}", .{ self.getString(key), sym.n_value });
}
}