diff options
| author | Jakub Konka <kubkon@jakubkonka.com> | 2022-07-16 10:53:47 +0200 |
|---|---|---|
| committer | Jakub Konka <kubkon@jakubkonka.com> | 2022-07-22 16:58:21 +0200 |
| commit | 41b91442f4af293d4cbbabbe9e451bd31c5c5679 (patch) | |
| tree | 97cf00b1e93bd90847f33ce905db1d5e87fd5e9d /src/link | |
| parent | 4658d857de9198e825f13c136b2342d630e19e62 (diff) | |
| download | zig-41b91442f4af293d4cbbabbe9e451bd31c5c5679.tar.gz zig-41b91442f4af293d4cbbabbe9e451bd31c5c5679.zip | |
macho: improve logs for dyld info
Diffstat (limited to 'src/link')
| -rw-r--r-- | src/link/MachO.zig | 69 | ||||
| -rw-r--r-- | src/link/MachO/Atom.zig | 6 |
2 files changed, 54 insertions, 21 deletions
diff --git a/src/link/MachO.zig b/src/link/MachO.zig index b441aaefc1..d4fbd14287 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -153,6 +153,13 @@ rustc_section_size: u64 = 0, locals: std.ArrayListUnmanaged(macho.nlist_64) = .{}, globals: std.StringArrayHashMapUnmanaged(SymbolWithLoc) = .{}, +// FIXME Jakub +// TODO storing index into globals might be dangerous if we delete a global +// while not having everything resolved. Actually, perhaps `unresolved` +// should not be stored at the global scope? Is this possible? +// Otherwise, audit if this can be a problem. +// An alternative, which I still need to investigate for perf reasons is to +// store all global names in an adapted with context strtab. unresolved: std.AutoArrayHashMapUnmanaged(u32, bool) = .{}, locals_free_list: std.ArrayListUnmanaged(u32) = .{}, @@ -2449,9 +2456,9 @@ pub fn createGotAtom(self: *MachO, target: SymbolWithLoc) !*Atom { const target_sym = self.getSymbol(target); if (target_sym.undf()) { - const global_index = @intCast(u32, self.globals.getIndex(self.getSymbolName(target)).?); + const global = self.globals.get(self.getSymbolName(target)).?; try atom.bindings.append(gpa, .{ - .global_index = global_index, + .target = global, .offset = 0, }); } else { @@ -2483,9 +2490,10 @@ pub fn createTlvPtrAtom(self: *MachO, target: SymbolWithLoc) !*Atom { const atom = try MachO.createEmptyAtom(gpa, sym_index, @sizeOf(u64), 3); const target_sym = self.getSymbol(target); assert(target_sym.undf()); - const global_index = @intCast(u32, self.globals.getIndex(self.getSymbolName(target)).?); + + const global = self.globals.get(self.getSymbolName(target)).?; try atom.bindings.append(gpa, .{ - .global_index = global_index, + .target = global, .offset = 0, }); @@ -2739,7 +2747,6 @@ pub fn createStubHelperAtom(self: *MachO) !*Atom { pub fn createLazyPointerAtom(self: *MachO, stub_sym_index: u32, target: SymbolWithLoc) !*Atom { const gpa = self.base.allocator; const sym_index = @intCast(u32, self.locals.items.len); - const global_index = @intCast(u32, self.globals.getIndex(self.getSymbolName(target)).?); try self.locals.append(gpa, .{ .n_strx = 0, .n_type = macho.N_SECT, @@ -2762,8 +2769,10 @@ pub fn createLazyPointerAtom(self: *MachO, stub_sym_index: u32, target: SymbolWi }, }); try atom.rebases.append(gpa, 0); + + const global = self.globals.get(self.getSymbolName(target)).?; try atom.lazy_bindings.append(gpa, .{ - .global_index = global_index, + .target = global, .offset = 0, }); @@ -4149,6 +4158,7 @@ pub fn deleteExport(self: *MachO, exp: Export) void { const sym = self.getSymbolPtr(sym_loc); const sym_name = self.getSymbolName(sym_loc); log.debug("deleting export '{s}'", .{sym_name}); + assert(sym.sect() and sym.ext()); sym.* = .{ .n_strx = 0, .n_type = 0, @@ -5307,7 +5317,9 @@ pub fn getGlobalSymbol(self: *MachO, name: []const u8) !u32 { defer if (gop.found_existing) gpa.free(sym_name); if (gop.found_existing) { - return @intCast(u32, self.globals.getIndex(sym_name).?); + // TODO audit this: can we ever reference anything from outside the Zig module? + assert(gop.value_ptr.file == null); + return gop.value_ptr.sym_index; } const sym_index = @intCast(u32, self.locals.items.len); @@ -5324,7 +5336,7 @@ pub fn getGlobalSymbol(self: *MachO, name: []const u8) !u32 { }; try self.unresolved.putNoClobber(gpa, global_index, true); - return global_index; + return sym_index; } fn getSegmentAllocBase(self: MachO, indices: []const ?u16) struct { vmaddr: u64, fileoff: u64 } { @@ -5690,6 +5702,8 @@ fn updateSectionOrdinals(self: *MachO) !void { } } + // FIXME Jakub + // TODO no need for duping work here; simply walk the atom graph for (self.locals.items) |*sym| { if (sym.undf()) continue; if (sym.n_sect == 0) continue; @@ -5735,11 +5749,12 @@ fn writeDyldInfoData(self: *MachO) !void { log.debug("dyld info for {s},{s}", .{ sect.segName(), sect.sectName() }); while (true) { - log.debug(" ATOM %{d}", .{atom.sym_index}); + log.debug(" ATOM(%{d}, '{s}')", .{ atom.sym_index, atom.getName(self) }); const sym = atom.getSymbol(self); const base_offset = sym.n_value - seg.inner.vmaddr; for (atom.rebases.items) |offset| { + log.debug(" | rebase at {x}", .{base_offset + offset}); try rebase_pointers.append(.{ .offset = base_offset + offset, .segment_id = match.seg, @@ -5747,33 +5762,53 @@ fn writeDyldInfoData(self: *MachO) !void { } for (atom.bindings.items) |binding| { - const global = self.globals.values()[binding.global_index]; - const bind_sym = self.getSymbol(global); + const bind_sym = self.getSymbol(binding.target); + const bind_sym_name = self.getSymbolName(binding.target); + const dylib_ordinal = @divTrunc( + @bitCast(i16, bind_sym.n_desc), + macho.N_SYMBOL_RESOLVER, + ); var flags: u4 = 0; + log.debug(" | bind at {x}, import('{s}') in dylib({d})", .{ + binding.offset + base_offset, + bind_sym_name, + dylib_ordinal, + }); if (bind_sym.weakRef()) { + log.debug(" | marking as weak ref ", .{}); flags |= @truncate(u4, macho.BIND_SYMBOL_FLAGS_WEAK_IMPORT); } try bind_pointers.append(.{ .offset = binding.offset + base_offset, .segment_id = match.seg, - .dylib_ordinal = @divTrunc(@bitCast(i16, bind_sym.n_desc), macho.N_SYMBOL_RESOLVER), - .name = self.getSymbolName(global), + .dylib_ordinal = dylib_ordinal, + .name = bind_sym_name, .bind_flags = flags, }); } for (atom.lazy_bindings.items) |binding| { - const global = self.globals.values()[binding.global_index]; - const bind_sym = self.getSymbol(global); + const bind_sym = self.getSymbol(binding.target); + const bind_sym_name = self.getSymbolName(binding.target); + const dylib_ordinal = @divTrunc( + @bitCast(i16, bind_sym.n_desc), + macho.N_SYMBOL_RESOLVER, + ); var flags: u4 = 0; + log.debug(" | lazy bind at {x} import('{s}') ord({d})", .{ + binding.offset + base_offset, + bind_sym_name, + dylib_ordinal, + }); if (bind_sym.weakRef()) { + log.debug(" | marking as weak ref ", .{}); flags |= @truncate(u4, macho.BIND_SYMBOL_FLAGS_WEAK_IMPORT); } try lazy_bind_pointers.append(.{ .offset = binding.offset + base_offset, .segment_id = match.seg, - .dylib_ordinal = @divTrunc(@bitCast(i16, bind_sym.n_desc), macho.N_SYMBOL_RESOLVER), - .name = self.getSymbolName(global), + .dylib_ordinal = dylib_ordinal, + .name = bind_sym_name, .bind_flags = flags, }); } diff --git a/src/link/MachO/Atom.zig b/src/link/MachO/Atom.zig index ecf2f10149..e5a940bdda 100644 --- a/src/link/MachO/Atom.zig +++ b/src/link/MachO/Atom.zig @@ -71,7 +71,7 @@ dbg_info_atom: Dwarf.Atom, dirty: bool = true, pub const Binding = struct { - global_index: u32, + target: SymbolWithLoc, offset: u64, }; @@ -536,10 +536,8 @@ fn addPtrBindingOrRebase( const gpa = context.macho_file.base.allocator; const sym = context.macho_file.getSymbol(target); if (sym.undf()) { - const sym_name = context.macho_file.getSymbolName(target); - const global_index = @intCast(u32, context.macho_file.globals.getIndex(sym_name).?); try self.bindings.append(gpa, .{ - .global_index = global_index, + .target = target, .offset = @intCast(u32, rel.r_address - context.base_offset), }); } else { |
