mirror of
https://github.com/ziglang/zig.git
synced 2026-02-13 12:59:04 +00:00
macho: add simple error reporting for misc errors
This commit is contained in:
parent
7b282dffe6
commit
05c9d6c00b
@ -2609,6 +2609,9 @@ pub fn totalErrorCount(self: *Compilation) u32 {
|
||||
}
|
||||
total += @intFromBool(self.link_error_flags.missing_libc);
|
||||
|
||||
// Misc linker errors
|
||||
total += self.bin_file.miscErrors().len;
|
||||
|
||||
// Compile log errors only count if there are no other errors.
|
||||
if (total == 0) {
|
||||
if (self.bin_file.options.module) |module| {
|
||||
@ -2759,6 +2762,19 @@ pub fn getAllErrorsAlloc(self: *Compilation) !ErrorBundle {
|
||||
}));
|
||||
}
|
||||
|
||||
for (self.bin_file.miscErrors()) |link_err| {
|
||||
try bundle.addRootErrorMessage(.{
|
||||
.msg = try bundle.addString(link_err.msg),
|
||||
.notes_len = @intCast(link_err.notes.len),
|
||||
});
|
||||
const notes_start = try bundle.reserveNotes(@intCast(link_err.notes.len));
|
||||
for (link_err.notes, 0..) |note, i| {
|
||||
bundle.extra.items[notes_start + i] = @intFromEnum(try bundle.addErrorMessage(.{
|
||||
.msg = try bundle.addString(note.msg),
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
if (self.bin_file.options.module) |module| {
|
||||
if (bundle.root_list.items.len == 0 and module.compile_log_decls.count() != 0) {
|
||||
const keys = module.compile_log_decls.keys();
|
||||
|
||||
20
src/link.zig
20
src/link.zig
@ -866,6 +866,13 @@ pub const File = struct {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn miscErrors(base: *File) []const ErrorMsg {
|
||||
switch (base.tag) {
|
||||
.macho => return @fieldParentPtr(MachO, "base", base).misc_errors.items,
|
||||
else => return &.{},
|
||||
}
|
||||
}
|
||||
|
||||
pub const UpdateDeclExportsError = error{
|
||||
OutOfMemory,
|
||||
AnalysisFail,
|
||||
@ -1129,6 +1136,19 @@ pub const File = struct {
|
||||
missing_libc: bool = false,
|
||||
};
|
||||
|
||||
pub const ErrorMsg = struct {
|
||||
msg: []const u8,
|
||||
notes: []ErrorMsg = &.{},
|
||||
|
||||
pub fn deinit(self: *ErrorMsg, gpa: Allocator) void {
|
||||
for (self.notes) |*note| {
|
||||
note.deinit(gpa);
|
||||
}
|
||||
gpa.free(self.notes);
|
||||
gpa.free(self.msg);
|
||||
}
|
||||
};
|
||||
|
||||
pub const LazySymbol = struct {
|
||||
pub const Kind = enum { code, const_data };
|
||||
|
||||
|
||||
@ -52,8 +52,8 @@ const Value = @import("../value.zig").Value;
|
||||
|
||||
pub const DebugSymbols = @import("MachO/DebugSymbols.zig");
|
||||
|
||||
const Bind = @import("MachO/dyld_info/bind.zig").Bind(*const MachO, MachO.SymbolWithLoc);
|
||||
const LazyBind = @import("MachO/dyld_info/bind.zig").LazyBind(*const MachO, MachO.SymbolWithLoc);
|
||||
const Bind = @import("MachO/dyld_info/bind.zig").Bind(*const MachO, SymbolWithLoc);
|
||||
const LazyBind = @import("MachO/dyld_info/bind.zig").LazyBind(*const MachO, SymbolWithLoc);
|
||||
const Rebase = @import("MachO/dyld_info/Rebase.zig");
|
||||
|
||||
pub const base_tag: File.Tag = File.Tag.macho;
|
||||
@ -154,6 +154,7 @@ got_table: TableSection(SymbolWithLoc) = .{},
|
||||
stub_table: TableSection(SymbolWithLoc) = .{},
|
||||
|
||||
error_flags: File.ErrorFlags = File.ErrorFlags{},
|
||||
misc_errors: std.ArrayListUnmanaged(File.ErrorMsg) = .{},
|
||||
|
||||
segment_table_dirty: bool = false,
|
||||
got_table_count_dirty: bool = false,
|
||||
@ -295,6 +296,12 @@ pub const SymbolWithLoc = extern struct {
|
||||
}
|
||||
};
|
||||
|
||||
pub const SymbolResolver = struct {
|
||||
arena: Allocator,
|
||||
table: std.StringHashMap(u32),
|
||||
unresolved: std.AutoArrayHashMap(u32, void),
|
||||
};
|
||||
|
||||
const HotUpdateState = struct {
|
||||
mach_task: ?std.os.darwin.MachTask = null,
|
||||
};
|
||||
@ -1856,6 +1863,11 @@ pub fn deinit(self: *MachO) void {
|
||||
bindings.deinit(gpa);
|
||||
}
|
||||
self.bindings.deinit(gpa);
|
||||
|
||||
for (self.misc_errors.items) |*err| {
|
||||
err.deinit(gpa);
|
||||
}
|
||||
self.misc_errors.deinit(gpa);
|
||||
}
|
||||
|
||||
fn freeAtom(self: *MachO, atom_index: Atom.Index) void {
|
||||
@ -4021,6 +4033,38 @@ pub inline fn getPageSize(cpu_arch: std.Target.Cpu.Arch) u16 {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn reportUndefined(self: *MachO, ctx: anytype, resolver: *const SymbolResolver) !void {
|
||||
const count = resolver.unresolved.count();
|
||||
if (count == 0) return;
|
||||
|
||||
const gpa = self.base.allocator;
|
||||
|
||||
try self.misc_errors.ensureUnusedCapacity(gpa, count);
|
||||
|
||||
for (resolver.unresolved.keys()) |global_index| {
|
||||
const global = ctx.globals.items[global_index];
|
||||
const sym_name = ctx.getSymbolName(global);
|
||||
|
||||
const nnotes: usize = if (global.getFile() == null) @as(usize, 0) else 1;
|
||||
var notes = try std.ArrayList(File.ErrorMsg).initCapacity(gpa, nnotes);
|
||||
defer notes.deinit();
|
||||
|
||||
if (global.getFile()) |file| {
|
||||
const note = try std.fmt.allocPrint(gpa, "referenced in {s}", .{ctx.objects.items[file].name});
|
||||
notes.appendAssumeCapacity(.{ .msg = note });
|
||||
}
|
||||
|
||||
var err_msg = File.ErrorMsg{
|
||||
.msg = try std.fmt.allocPrint(gpa, "undefined reference to symbol {s}", .{sym_name}),
|
||||
};
|
||||
err_msg.notes = try notes.toOwnedSlice();
|
||||
|
||||
self.misc_errors.appendAssumeCapacity(err_msg);
|
||||
}
|
||||
|
||||
return error.FlushFailure;
|
||||
}
|
||||
|
||||
/// Binary search
|
||||
pub fn bsearch(comptime T: type, haystack: []align(1) const T, predicate: anytype) usize {
|
||||
if (!@hasDecl(@TypeOf(predicate), "predicate"))
|
||||
|
||||
@ -13,7 +13,7 @@ const AtomIndex = @import("zld.zig").AtomIndex;
|
||||
const Atom = @import("ZldAtom.zig");
|
||||
const MachO = @import("../MachO.zig");
|
||||
const SymbolWithLoc = MachO.SymbolWithLoc;
|
||||
const SymbolResolver = @import("zld.zig").SymbolResolver;
|
||||
const SymbolResolver = MachO.SymbolResolver;
|
||||
const UnwindInfo = @import("UnwindInfo.zig");
|
||||
const Zld = @import("zld.zig").Zld;
|
||||
|
||||
|
||||
@ -33,6 +33,7 @@ const LibStub = @import("../tapi.zig").LibStub;
|
||||
const Object = @import("Object.zig");
|
||||
const StringTable = @import("../strtab.zig").StringTable;
|
||||
const SymbolWithLoc = MachO.SymbolWithLoc;
|
||||
const SymbolResolver = MachO.SymbolResolver;
|
||||
const Trie = @import("Trie.zig");
|
||||
const UnwindInfo = @import("UnwindInfo.zig");
|
||||
|
||||
@ -788,7 +789,6 @@ pub const Zld = struct {
|
||||
const global_index = resolver.unresolved.keys()[next_sym];
|
||||
const global = self.globals.items[global_index];
|
||||
const sym = self.getSymbolPtr(global);
|
||||
const sym_name = self.getSymbolName(global);
|
||||
|
||||
if (sym.discarded()) {
|
||||
sym.* = .{
|
||||
@ -811,11 +811,6 @@ pub const Zld = struct {
|
||||
continue;
|
||||
}
|
||||
|
||||
log.err("undefined reference to symbol '{s}'", .{sym_name});
|
||||
if (global.getFile()) |file| {
|
||||
log.err(" first referenced in '{s}'", .{self.objects.items[file].name});
|
||||
}
|
||||
|
||||
next_sym += 1;
|
||||
}
|
||||
}
|
||||
@ -3022,12 +3017,6 @@ const IndirectPointer = struct {
|
||||
}
|
||||
};
|
||||
|
||||
pub const SymbolResolver = struct {
|
||||
arena: Allocator,
|
||||
table: std.StringHashMap(u32),
|
||||
unresolved: std.AutoArrayHashMap(u32, void),
|
||||
};
|
||||
|
||||
pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progress.Node) link.File.FlushError!void {
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
@ -3419,10 +3408,7 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr
|
||||
.unresolved = std.AutoArrayHashMap(u32, void).init(arena),
|
||||
};
|
||||
try zld.resolveSymbols(&resolver);
|
||||
|
||||
if (resolver.unresolved.count() > 0) {
|
||||
return error.UndefinedSymbolReference;
|
||||
}
|
||||
try macho_file.reportUndefined(&zld, &resolver);
|
||||
|
||||
if (options.output_mode == .Exe) {
|
||||
const entry_name = options.entry orelse load_commands.default_entry_point;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user