Commit 116ea1bf2c
Changed files (1)
src
link
MachO
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 });