diff options
| author | Jakub Konka <kubkon@jakubkonka.com> | 2022-02-23 18:44:16 +0100 |
|---|---|---|
| committer | Jakub Konka <kubkon@jakubkonka.com> | 2022-02-23 19:10:44 +0100 |
| commit | 2ca809c32a69c286568814043019e444c1c85ff2 (patch) | |
| tree | 1de0a2c7b2c080e880bc6b2f8ddc43b49ab34bf3 /src | |
| parent | 897a5a4735d5e72c53529a9a3f3a815943568214 (diff) | |
| download | zig-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.zig | 56 |
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 }); } } |
