zld: assume remaining undefs are from libSystem

This commit is contained in:
Jakub Konka 2021-03-28 11:07:30 +02:00
parent b0105029ca
commit 116ea1bf2c

View File

@ -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 });