| ... | @@ -509,6 +509,14 @@ pub fn flushModule(self: *MachO, arena: Allocator, prog_node: *std.Progress.Node | ... | @@ -509,6 +509,14 @@ pub fn flushModule(self: *MachO, arena: Allocator, prog_node: *std.Progress.Node |
| 509 | try dead_strip.gcAtoms(self); | 509 | try dead_strip.gcAtoms(self); |
| 510 | } | 510 | } |
| 511 | | 511 | |
| | 512 | self.checkDuplicates() catch |err| switch (err) { |
| | 513 | error.HasDuplicates => return error.FlushFailure, |
| | 514 | else => |e| { |
| | 515 | try self.reportUnexpectedError("unexpected error while checking for duplicate symbol definitions", .{}); |
| | 516 | return e; |
| | 517 | }, |
| | 518 | }; |
| | 519 | |
| 512 | self.markImportsAndExports(); | 520 | self.markImportsAndExports(); |
| 513 | self.deadStripDylibs(); | 521 | self.deadStripDylibs(); |
| 514 | | 522 | |
| ... | @@ -1414,6 +1422,24 @@ fn claimUnresolved(self: *MachO) error{OutOfMemory}!void { | ... | @@ -1414,6 +1422,24 @@ fn claimUnresolved(self: *MachO) error{OutOfMemory}!void { |
| 1414 | } | 1422 | } |
| 1415 | } | 1423 | } |
| 1416 | | 1424 | |
| | 1425 | fn checkDuplicates(self: *MachO) !void { |
| | 1426 | const gpa = self.base.comp.gpa; |
| | 1427 | |
| | 1428 | var dupes = std.AutoArrayHashMap(Symbol.Index, std.ArrayListUnmanaged(File.Index)).init(gpa); |
| | 1429 | defer { |
| | 1430 | for (dupes.values()) |*list| { |
| | 1431 | list.deinit(gpa); |
| | 1432 | } |
| | 1433 | dupes.deinit(); |
| | 1434 | } |
| | 1435 | |
| | 1436 | for (self.objects.items) |index| { |
| | 1437 | try self.getFile(index).?.object.checkDuplicates(&dupes, self); |
| | 1438 | } |
| | 1439 | |
| | 1440 | try self.reportDuplicates(dupes); |
| | 1441 | } |
| | 1442 | |
| 1417 | fn markImportsAndExports(self: *MachO) void { | 1443 | fn markImportsAndExports(self: *MachO) void { |
| 1418 | for (self.objects.items) |index| { | 1444 | for (self.objects.items) |index| { |
| 1419 | for (self.getFile(index).?.getSymbols()) |sym_index| { | 1445 | for (self.getFile(index).?.getSymbols()) |sym_index| { |
| ... | @@ -3468,68 +3494,38 @@ fn reportUnexpectedError(self: *MachO, comptime format: []const u8, args: anytyp | ... | @@ -3468,68 +3494,38 @@ fn reportUnexpectedError(self: *MachO, comptime format: []const u8, args: anytyp |
| 3468 | try err.addNote(self, "please report this as a linker bug on https://github.com/ziglang/zig/issues/new/choose", .{}); | 3494 | try err.addNote(self, "please report this as a linker bug on https://github.com/ziglang/zig/issues/new/choose", .{}); |
| 3469 | } | 3495 | } |
| 3470 | | 3496 | |
| 3471 | // fn reportSymbolCollision( | 3497 | fn reportDuplicates(self: *MachO, dupes: anytype) error{ HasDuplicates, OutOfMemory }!void { |
| 3472 | // self: *MachO, | 3498 | const tracy = trace(@src()); |
| 3473 | // first: SymbolWithLoc, | 3499 | defer tracy.end(); |
| 3474 | // other: SymbolWithLoc, | 3500 | |
| 3475 | // ) error{OutOfMemory}!void { | 3501 | const max_notes = 4; |
| 3476 | // const comp = self.base.comp; | | |
| 3477 | // const gpa = comp.gpa; | | |
| 3478 | // try comp.link_errors.ensureUnusedCapacity(gpa, 1); | | |
| 3479 | | 3502 | |
| 3480 | // var notes = try std.ArrayList(File.ErrorMsg).initCapacity(gpa, 2); | 3503 | var has_dupes = false; |
| 3481 | // defer notes.deinit(); | 3504 | var it = dupes.iterator(); |
| | 3505 | while (it.next()) |entry| { |
| | 3506 | const sym = self.getSymbol(entry.key_ptr.*); |
| | 3507 | const notes = entry.value_ptr.*; |
| | 3508 | const nnotes = @min(notes.items.len, max_notes) + @intFromBool(notes.items.len > max_notes); |
| 3482 | | 3509 | |
| 3483 | // if (first.getFile()) |file| { | 3510 | var err = try self.addErrorWithNotes(nnotes); |
| 3484 | // const note = try std.fmt.allocPrint(gpa, "first definition in {s}", .{ | 3511 | try err.addMsg(self, "duplicate symbol definition: {s}", .{sym.getName(self)}); |
| 3485 | // self.objects.items[file].name, | 3512 | |
| 3486 | // }); | 3513 | var inote: usize = 0; |
| 3487 | // notes.appendAssumeCapacity(.{ .msg = note }); | 3514 | while (inote < @min(notes.items.len, max_notes)) : (inote += 1) { |
| 3488 | // } | 3515 | const file = self.getFile(notes.items[inote]).?; |
| 3489 | // if (other.getFile()) |file| { | 3516 | try err.addNote(self, "defined by {}", .{file.fmtPath()}); |
| 3490 | // const note = try std.fmt.allocPrint(gpa, "next definition in {s}", .{ | 3517 | } |
| 3491 | // self.objects.items[file].name, | | |
| 3492 | // }); | | |
| 3493 | // notes.appendAssumeCapacity(.{ .msg = note }); | | |
| 3494 | // } | | |
| 3495 | | 3518 | |
| 3496 | // var err_msg = File.ErrorMsg{ .msg = try std.fmt.allocPrint(gpa, "symbol {s} defined multiple times", .{ | 3519 | if (notes.items.len > max_notes) { |
| 3497 | // self.getSymbolName(first), | 3520 | const remaining = notes.items.len - max_notes; |
| 3498 | // }) }; | 3521 | try err.addNote(self, "defined {d} more times", .{remaining}); |
| 3499 | // err_msg.notes = try notes.toOwnedSlice(); | 3522 | } |
| 3500 | | 3523 | |
| 3501 | // comp.link_errors.appendAssumeCapacity(err_msg); | 3524 | has_dupes = true; |
| 3502 | // } | 3525 | } |
| 3503 | | 3526 | |
| 3504 | // fn reportUnhandledSymbolType(self: *MachO, sym_with_loc: SymbolWithLoc) error{OutOfMemory}!void { | 3527 | if (has_dupes) return error.HasDuplicates; |
| 3505 | // const comp = self.base.comp; | 3528 | } |
| 3506 | // const gpa = comp.gpa; | | |
| 3507 | // try comp.link_errors.ensureUnusedCapacity(gpa, 1); | | |
| 3508 | | | |
| 3509 | // const notes = try gpa.alloc(File.ErrorMsg, 1); | | |
| 3510 | // errdefer gpa.free(notes); | | |
| 3511 | | | |
| 3512 | // const file = sym_with_loc.getFile().?; | | |
| 3513 | // notes[0] = .{ .msg = try std.fmt.allocPrint(gpa, "defined in {s}", .{self.objects.items[file].name}) }; | | |
| 3514 | | | |
| 3515 | // const sym = self.getSymbol(sym_with_loc); | | |
| 3516 | // const sym_type = if (sym.stab()) | | |
| 3517 | // "stab" | | |
| 3518 | // else if (sym.indr()) | | |
| 3519 | // "indirect" | | |
| 3520 | // else if (sym.abs()) | | |
| 3521 | // "absolute" | | |
| 3522 | // else | | |
| 3523 | // unreachable; | | |
| 3524 | | | |
| 3525 | // comp.link_errors.appendAssumeCapacity(.{ | | |
| 3526 | // .msg = try std.fmt.allocPrint(gpa, "unhandled symbol type: '{s}' has type {s}", .{ | | |
| 3527 | // self.getSymbolName(sym_with_loc), | | |
| 3528 | // sym_type, | | |
| 3529 | // }), | | |
| 3530 | // .notes = notes, | | |
| 3531 | // }); | | |
| 3532 | // } | | |
| 3533 | | 3529 | |
| 3534 | pub fn getDebugSymbols(self: *MachO) ?*DebugSymbols { | 3530 | pub fn getDebugSymbols(self: *MachO) ?*DebugSymbols { |
| 3535 | if (self.d_sym) |*ds| { | 3531 | if (self.d_sym) |*ds| { |