authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-06-10 11:03:14+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-06-10 11:03:14+02:00
log03cda80a634d82e02e641fe04fa2abda4455966a
tree43593edce0f5c9d4e76725908eccc0efaa8653c3
parent66ff56c58f3ef71f5cc3b8392632b3ec8abec43f

zld: handle aliasing of tentative into regular global


2 files changed, 36 insertions(+), 6 deletions(-)

src/link/MachO/Object.zig+4-6
......@@ -351,15 +351,15 @@ pub fn parseSymbols(self: *Object) !void {
351351 const sym_name = mem.spanZ(@ptrCast([*:0]const u8, strtab.ptr + sym.n_strx));
352352
353353 if (Symbol.isStab(sym)) {
354 log.err("stab {s} in {s}", .{ sym_name, self.name.? });
354 log.err("unhandled symbol type: stab {s} in {s}", .{ sym_name, self.name.? });
355355 return error.UnhandledSymbolType;
356356 }
357357 if (Symbol.isIndr(sym)) {
358 log.err("indirect symbol {s} in {s}", .{ sym_name, self.name.? });
358 log.err("unhandled symbol type: indirect {s} in {s}", .{ sym_name, self.name.? });
359359 return error.UnhandledSymbolType;
360360 }
361361 if (Symbol.isAbs(sym)) {
362 log.err("absolute symbol {s} in {s}", .{ sym_name, self.name.? });
362 log.err("unhandled symbol type: absolute {s} in {s}", .{ sym_name, self.name.? });
363363 return error.UnhandledSymbolType;
364364 }
365365
......@@ -399,9 +399,7 @@ pub fn parseSymbols(self: *Object) !void {
399399 .alignment = (sym.n_desc >> 8) & 0x0f,
400400 .file = self,
401401 };
402
403 log.err("Common symbol {s} in {s}: {}", .{ sym_name, self.name.?, tentative });
404 return error.UnhandledSymbolType;
402 break :symbol &tentative.base;
405403 }
406404
407405 const undef = try self.allocator.create(Symbol.Unresolved);
src/link/MachO/Zld.zig+32
......@@ -84,6 +84,11 @@ common_section_index: ?u16 = null,
8484globals: std.StringArrayHashMapUnmanaged(*Symbol) = .{},
8585imports: std.StringArrayHashMapUnmanaged(*Symbol) = .{},
8686unresolved: std.StringArrayHashMapUnmanaged(*Symbol) = .{},
87tentatives: std.StringArrayHashMapUnmanaged(*Symbol) = .{},
88
89// /// Offset into __DATA,__common section.
90// /// Set if the linker found tentative definitions in any of the objects.
91// tentative_defs_offset: u32 = 0,
8792
8893strtab: std.ArrayListUnmanaged(u8) = .{},
8994strtab_dir: std.StringHashMapUnmanaged(u32) = .{},
......@@ -144,6 +149,7 @@ pub fn deinit(self: *Zld) void {
144149 }
145150 self.dylibs.deinit(self.allocator);
146151
152 self.tentatives.deinit(self.allocator);
147153 self.globals.deinit(self.allocator);
148154 self.imports.deinit(self.allocator);
149155 self.unresolved.deinit(self.allocator);
......@@ -1379,6 +1385,10 @@ fn resolveSymbolsInObject(self: *Zld, object: *Object) !void {
13791385 if (sym.cast(Symbol.Regular)) |reg| {
13801386 if (reg.linkage == .translation_unit) continue; // Symbol local to TU.
13811387
1388 if (self.tentatives.fetchSwapRemove(sym.name)) |kv| {
1389 // Create link to the global.
1390 kv.value.alias = sym;
1391 }
13821392 if (self.unresolved.fetchSwapRemove(sym.name)) |kv| {
13831393 // Create link to the global.
13841394 kv.value.alias = sym;
......@@ -1412,11 +1422,33 @@ fn resolveSymbolsInObject(self: *Zld, object: *Object) !void {
14121422
14131423 g_sym.alias = sym;
14141424 sym_ptr.* = sym;
1425 } else if (sym.cast(Symbol.Tentative)) |tent| {
1426 if (self.globals.get(sym.name)) |g_sym| {
1427 sym.alias = g_sym;
1428 continue;
1429 }
1430
1431 if (self.unresolved.fetchSwapRemove(sym.name)) |kv| {
1432 kv.value.alias = sym;
1433 }
1434
1435 const t_sym = self.tentatives.get(sym.name) orelse {
1436 // Put new tentative definition symbol into symbol table.
1437 try self.tentatives.putNoClobber(self.allocator, sym.name, sym);
1438 continue;
1439 };
1440
1441 // TODO compare by size and pick the largest.
1442 return error.TODOResolveTentatives;
14151443 } else if (sym.cast(Symbol.Unresolved)) |und| {
14161444 if (self.globals.get(sym.name)) |g_sym| {
14171445 sym.alias = g_sym;
14181446 continue;
14191447 }
1448 if (self.tentatives.get(sym.name)) |t_sym| {
1449 sym.alias = t_sym;
1450 continue;
1451 }
14201452 if (self.unresolved.get(sym.name)) |u_sym| {
14211453 sym.alias = u_sym;
14221454 continue;