Skip to content

Commit f0ec70e

Browse files
committed
macho: do not write null symbols into undef symbols section
Also, skip creating stub entries for resolved globally defined regular symbols.
1 parent 83a6681 commit f0ec70e

File tree

2 files changed

+27
-8
lines changed

2 files changed

+27
-8
lines changed

src/link/MachO.zig

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -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,21 +5540,21 @@ 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
}
55355550
}
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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -571,6 +571,10 @@ fn addGotEntry(target: Relocation.Target, context: RelocContext) !void {
571571
fn 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| {

0 commit comments

Comments
 (0)