From 116ea1bf2c7b3dd722beb1b4cf8d6e7e9755294f Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Sun, 28 Mar 2021 11:07:30 +0200 Subject: [PATCH] zld: assume remaining undefs are from libSystem --- src/link/MachO/Zld.zig | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/src/link/MachO/Zld.zig b/src/link/MachO/Zld.zig index b75cdb18cc..b10125881f 100644 --- a/src/link/MachO/Zld.zig +++ b/src/link/MachO/Zld.zig @@ -75,6 +75,7 @@ bss_section_index: ?u16 = null, globals: std.StringArrayHashMapUnmanaged(Symbol) = .{}, undefs: std.StringArrayHashMapUnmanaged(Symbol) = .{}, +externs: std.StringArrayHashMapUnmanaged(Symbol) = .{}, strtab: std.ArrayListUnmanaged(u8) = .{}, // locals: std.StringArrayHashMapUnmanaged(std.ArrayListUnmanaged(Symbol)) = .{}, @@ -223,6 +224,11 @@ pub fn deinit(self: *Zld) void { self.allocator.free(entry.key); } self.undefs.deinit(self.allocator); + + for (self.externs.items()) |*entry| { + self.allocator.free(entry.key); + } + self.externs.deinit(self.allocator); } pub fn closeFiles(self: Zld) void { @@ -1215,7 +1221,11 @@ fn resolveSymbolsInObject(self: *Zld, object_id: u16) !void { .file = object_id, .index = @intCast(u32, sym_id), }); - _ = self.undefs.swapRemove(sym_name); + + if (self.undefs.swapRemove(sym_name)) |undef| { + self.allocator.free(undef.key); + } + continue; }; @@ -1252,6 +1262,7 @@ fn resolveSymbols(self: *Zld) !void { try self.resolveSymbolsInObject(@intCast(u16, object_id)); } + // Second pass, resolve symbols in static libraries. var next: usize = 0; while (true) { var archive = &self.archives.items[next]; @@ -1285,6 +1296,26 @@ fn resolveSymbols(self: *Zld) !void { archive = &self.archives.items[next]; } } + + // Third pass, resolve symbols in dynamic libraries. + // TODO Implement libSystem as a hard-coded library, or ship with + // a libSystem.B.tbd definition file? + while (self.undefs.items().len > 0) { + const entry = self.undefs.pop(); + try self.externs.putNoClobber(self.allocator, entry.key, .{ + .inner = entry.value.inner, + .file = 0, + }); + } + + // If there are any undefs left, flag an error. + if (self.undefs.items().len > 0) { + for (self.undefs.items()) |entry| { + log.err("undefined reference to symbol '{s}'", .{entry.key}); + } + + return error.UndefinedSymbolReference; + } } fn doRelocs(self: *Zld) !void { @@ -3203,6 +3234,11 @@ fn printSymtab(self: Zld) void { log.warn(" | {s} => {any}", .{ entry.key, entry.value }); } + log.warn("externs", .{}); + for (self.externs.items()) |entry| { + log.warn(" | {s} => {any}", .{ entry.key, entry.value }); + } + log.warn("undefs", .{}); for (self.undefs.items()) |entry| { log.warn(" | {s} => {any}", .{ entry.key, entry.value });