authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-12-08 12:42:03+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-12-08 16:58:29+01:00
logf0ec70edd1ab632ab25d48f7b27a444d9ac444bd
treeca0c95bcdb725265f1278654af0ed360010430dc
parent83a668195526df745362b1174bfd643a0cdfb128

macho: do not write null symbols into undef symbols section

Also, skip creating stub entries for resolved globally defined regular symbols.

2 files changed, 27 insertions(+), 8 deletions(-)

src/link/MachO.zig+23-8
......@@ -5400,6 +5400,21 @@ fn writeSymbolTable(self: *MachO) !void {
54005400 try locals.append(sym);
54015401 }
54025402
5403 // TODO How do we handle null global symbols in incremental context?
5404 var undefs = std.ArrayList(macho.nlist_64).init(self.base.allocator);
5405 defer undefs.deinit();
5406 var undefs_table = std.AutoHashMap(u32, u32).init(self.base.allocator);
5407 defer undefs_table.deinit();
5408 try undefs.ensureTotalCapacity(self.undefs.items.len);
5409 try undefs_table.ensureTotalCapacity(@intCast(u32, self.undefs.items.len));
5410
5411 for (self.undefs.items) |sym, i| {
5412 if (sym.n_strx == 0) continue;
5413 const new_index = @intCast(u32, undefs.items.len);
5414 undefs.appendAssumeCapacity(sym);
5415 undefs_table.putAssumeCapacityNoClobber(@intCast(u32, i), new_index);
5416 }
5417
54035418 if (self.has_stabs) {
54045419 for (self.objects.items) |object| {
54055420 if (object.debug_info == null) continue;
......@@ -5456,7 +5471,7 @@ fn writeSymbolTable(self: *MachO) !void {
54565471
54575472 const nlocals = locals.items.len;
54585473 const nexports = self.globals.items.len;
5459 const nundefs = self.undefs.items.len;
5474 const nundefs = undefs.items.len;
54605475
54615476 const locals_off = symtab.symoff;
54625477 const locals_size = nlocals * @sizeOf(macho.nlist_64);
......@@ -5471,7 +5486,7 @@ fn writeSymbolTable(self: *MachO) !void {
54715486 const undefs_off = exports_off + exports_size;
54725487 const undefs_size = nundefs * @sizeOf(macho.nlist_64);
54735488 log.debug("writing undefined symbols from 0x{x} to 0x{x}", .{ undefs_off, undefs_size + undefs_off });
5474 try self.base.file.?.pwriteAll(mem.sliceAsBytes(self.undefs.items), undefs_off);
5489 try self.base.file.?.pwriteAll(mem.sliceAsBytes(undefs.items), undefs_off);
54755490
54765491 symtab.nsyms = @intCast(u32, nlocals + nexports + nundefs);
54775492 seg.inner.filesize += locals_size + exports_size + undefs_size;
......@@ -5513,10 +5528,10 @@ fn writeSymbolTable(self: *MachO) !void {
55135528
55145529 stubs.reserved1 = 0;
55155530 for (self.stubs_map.keys()) |key| {
5516 const resolv = self.symbol_resolver.get(key) orelse continue;
5531 const resolv = self.symbol_resolver.get(key).?;
55175532 switch (resolv.where) {
55185533 .global => try writer.writeIntLittle(u32, macho.INDIRECT_SYMBOL_LOCAL),
5519 .undef => try writer.writeIntLittle(u32, dysymtab.iundefsym + resolv.where_index),
5534 .undef => try writer.writeIntLittle(u32, dysymtab.iundefsym + undefs_table.get(resolv.where_index).?),
55205535 }
55215536 }
55225537
......@@ -5525,10 +5540,10 @@ fn writeSymbolTable(self: *MachO) !void {
55255540 switch (key) {
55265541 .local => try writer.writeIntLittle(u32, macho.INDIRECT_SYMBOL_LOCAL),
55275542 .global => |n_strx| {
5528 const resolv = self.symbol_resolver.get(n_strx) orelse continue;
5543 const resolv = self.symbol_resolver.get(n_strx).?;
55295544 switch (resolv.where) {
55305545 .global => try writer.writeIntLittle(u32, macho.INDIRECT_SYMBOL_LOCAL),
5531 .undef => try writer.writeIntLittle(u32, dysymtab.iundefsym + resolv.where_index),
5546 .undef => try writer.writeIntLittle(u32, dysymtab.iundefsym + undefs_table.get(resolv.where_index).?),
55325547 }
55335548 },
55345549 }
......@@ -5536,10 +5551,10 @@ fn writeSymbolTable(self: *MachO) !void {
55365551
55375552 la_symbol_ptr.reserved1 = got.reserved1 + ngot_entries;
55385553 for (self.stubs_map.keys()) |key| {
5539 const resolv = self.symbol_resolver.get(key) orelse continue;
5554 const resolv = self.symbol_resolver.get(key).?;
55405555 switch (resolv.where) {
55415556 .global => try writer.writeIntLittle(u32, macho.INDIRECT_SYMBOL_LOCAL),
5542 .undef => try writer.writeIntLittle(u32, dysymtab.iundefsym + resolv.where_index),
5557 .undef => try writer.writeIntLittle(u32, dysymtab.iundefsym + undefs_table.get(resolv.where_index).?),
55435558 }
55445559 }
55455560
src/link/MachO/Atom.zig+4
......@@ -571,6 +571,10 @@ fn addGotEntry(target: Relocation.Target, context: RelocContext) !void {
571571fn addStub(target: Relocation.Target, context: RelocContext) !void {
572572 if (target != .global) return;
573573 if (context.macho_file.stubs_map.contains(target.global)) return;
574 // If the symbol has been resolved as defined globally elsewhere (in a different translation unit),
575 // then skip creating stub entry.
576 // TODO Is this the correct for the incremental?
577 if (context.macho_file.symbol_resolver.get(target.global).?.where == .global) return;
574578
575579 const value_ptr = blk: {
576580 if (context.macho_file.stubs_map_free_list.popOrNull()) |i| {