aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Konka <kubkon@jakubkonka.com>2021-08-03 13:37:48 +0200
committerJakub Konka <kubkon@jakubkonka.com>2021-08-12 10:20:57 +0200
commitda57d6df320cb6bd9ce09bef192f201d59a50b28 (patch)
tree96deedef1ca153086d9326433c1f398937121d0d
parent493822ac3bab344821aad180aae27b629eb920c1 (diff)
downloadzig-da57d6df320cb6bd9ce09bef192f201d59a50b28.tar.gz
zig-da57d6df320cb6bd9ce09bef192f201d59a50b28.zip
macho: simplify symbol management and resolution
instead of globally storing unresolved and tentative defs, store indices to actual symbols in the functions that are responsible for symbol resolution.
-rw-r--r--src/codegen.zig2
-rw-r--r--src/link/MachO.zig263
-rw-r--r--src/link/MachO/TextBlock.zig21
3 files changed, 137 insertions, 149 deletions
diff --git a/src/codegen.zig b/src/codegen.zig
index 38cc27d5bc..d5b106dbe3 100644
--- a/src/codegen.zig
+++ b/src/codegen.zig
@@ -2714,7 +2714,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
// Add relocation to the decl.
try macho_file.active_decl.?.link.macho.relocs.append(self.bin_file.allocator, .{
.offset = offset,
- .where = .import,
+ .where = .undef,
.where_index = where_index,
.payload = .{ .branch = .{
.arch = arch,
diff --git a/src/link/MachO.zig b/src/link/MachO.zig
index 6fbe3bc150..26a581a22a 100644
--- a/src/link/MachO.zig
+++ b/src/link/MachO.zig
@@ -134,9 +134,7 @@ objc_data_section_index: ?u16 = null,
locals: std.ArrayListUnmanaged(macho.nlist_64) = .{},
globals: std.ArrayListUnmanaged(macho.nlist_64) = .{},
-imports: std.ArrayListUnmanaged(macho.nlist_64) = .{},
undefs: std.ArrayListUnmanaged(macho.nlist_64) = .{},
-tentatives: std.ArrayListUnmanaged(macho.nlist_64) = .{},
symbol_resolver: std.AutoHashMapUnmanaged(u32, SymbolWithLoc) = .{},
locals_free_list: std.ArrayListUnmanaged(u32) = .{},
@@ -252,9 +250,7 @@ const SymbolWithLoc = struct {
// Table where the symbol can be found.
where: enum {
global,
- import,
undef,
- tentative,
},
where_index: u32,
local_sym_index: u32 = 0,
@@ -264,22 +260,11 @@ const SymbolWithLoc = struct {
pub const GotIndirectionKey = struct {
where: enum {
local,
- import,
+ undef,
},
where_index: u32,
};
-pub const PIEFixup = struct {
- /// Target VM address of this relocation.
- target_addr: u64,
-
- /// Offset within the byte stream.
- offset: usize,
-
- /// Size of the relocation.
- size: usize,
-};
-
/// When allocating, the ideal_capacity is calculated by
/// actual_capacity + (actual_capacity / ideal_factor)
const ideal_factor = 2;
@@ -960,7 +945,7 @@ fn linkWithZld(self: *MachO, comp: *Compilation) !void {
const resolv = self.symbol_resolver.get(n_strx) orelse unreachable;
const got_index = @intCast(u32, self.got_entries.items.len);
const got_entry = GotIndirectionKey{
- .where = .import,
+ .where = .undef,
.where_index = resolv.where_index,
};
try self.got_entries.append(self.base.allocator, got_entry);
@@ -1991,7 +1976,7 @@ fn writeStubHelperCommon(self: *MachO) !void {
}) orelse unreachable;
const resolv = self.symbol_resolver.get(n_strx) orelse unreachable;
const got_index = self.got_entries_map.get(.{
- .where = .import,
+ .where = .undef,
.where_index = resolv.where_index,
}) orelse unreachable;
const addr = got.addr + got_index * @sizeOf(u64);
@@ -2042,7 +2027,7 @@ fn writeStubHelperCommon(self: *MachO) !void {
}) orelse unreachable;
const resolv = self.symbol_resolver.get(n_strx) orelse unreachable;
const got_index = self.got_entries_map.get(.{
- .where = .import,
+ .where = .undef,
.where_index = resolv.where_index,
}) orelse unreachable;
const this_addr = stub_helper.addr + 3 * @sizeOf(u32);
@@ -2106,7 +2091,12 @@ fn writeStubHelperCommon(self: *MachO) !void {
}
}
-fn resolveSymbolsInObject(self: *MachO, object_id: u16) !void {
+fn resolveSymbolsInObject(
+ self: *MachO,
+ object_id: u16,
+ tentatives: *std.ArrayList(u32),
+ unresolved: *std.ArrayList(u32),
+) !void {
const object = &self.objects.items[object_id];
log.debug("resolving symbols in '{s}'", .{object.name});
@@ -2174,7 +2164,6 @@ fn resolveSymbolsInObject(self: *MachO, object_id: u16) !void {
};
switch (resolv.where) {
- .import => unreachable,
.global => {
const global = &self.globals.items[resolv.where_index];
@@ -2186,8 +2175,16 @@ fn resolveSymbolsInObject(self: *MachO, object_id: u16) !void {
log.err(" next definition in '{s}'", .{object.name});
return error.MultipleSymbolDefinitions;
}
-
if (symbolIsWeakDef(sym) or symbolIsPext(sym)) continue; // Current symbol is weak, so skip it.
+ if (symbolIsTentative(global.*)) {
+ var i: usize = 0;
+ while (i < tentatives.items.len) : (i += 1) {
+ if (tentatives.items[i] == resolv.where_index) {
+ _ = tentatives.swapRemove(i);
+ break;
+ }
+ }
+ }
// Otherwise, update the resolver and the global symbol.
global.n_type = sym.n_type;
@@ -2205,16 +2202,14 @@ fn resolveSymbolsInObject(self: *MachO, object_id: u16) !void {
.n_desc = 0,
.n_value = 0,
};
- },
- .tentative => {
- const tentative = &self.tentatives.items[resolv.where_index];
- tentative.* = .{
- .n_strx = 0,
- .n_type = macho.N_UNDF,
- .n_sect = 0,
- .n_desc = 0,
- .n_value = 0,
- };
+
+ var i: usize = 0;
+ while (i < unresolved.items.len) : (i += 1) {
+ if (unresolved.items[i] == resolv.where_index) {
+ _ = unresolved.swapRemove(i);
+ break;
+ }
+ }
},
}
@@ -2235,8 +2230,8 @@ fn resolveSymbolsInObject(self: *MachO, object_id: u16) !void {
} else if (symbolIsTentative(sym)) {
// Symbol is a tentative definition.
const resolv = self.symbol_resolver.getPtr(n_strx) orelse {
- const tent_sym_index = @intCast(u32, self.tentatives.items.len);
- try self.tentatives.append(self.base.allocator, .{
+ const global_sym_index = @intCast(u32, self.globals.items.len);
+ try self.globals.append(self.base.allocator, .{
.n_strx = try self.makeString(sym_name),
.n_type = sym.n_type,
.n_sect = 0,
@@ -2244,29 +2239,38 @@ fn resolveSymbolsInObject(self: *MachO, object_id: u16) !void {
.n_value = sym.n_value,
});
try self.symbol_resolver.putNoClobber(self.base.allocator, n_strx, .{
- .where = .tentative,
- .where_index = tent_sym_index,
+ .where = .global,
+ .where_index = global_sym_index,
.file = object_id,
});
+ try tentatives.append(global_sym_index);
continue;
};
switch (resolv.where) {
- .import => unreachable,
- .global => {},
+ .global => {
+ const global = &self.globals.items[resolv.where_index];
+ if (!symbolIsTentative(global.*)) continue;
+ if (global.n_value >= sym.n_value) continue;
+
+ global.n_desc = sym.n_desc;
+ global.n_value = sym.n_value;
+ resolv.file = object_id;
+ },
.undef => {
const undef = &self.undefs.items[resolv.where_index];
- const tent_sym_index = @intCast(u32, self.tentatives.items.len);
- try self.tentatives.append(self.base.allocator, .{
+ const global_sym_index = @intCast(u32, self.globals.items.len);
+ try self.globals.append(self.base.allocator, .{
.n_strx = undef.n_strx,
.n_type = sym.n_type,
.n_sect = 0,
.n_desc = sym.n_desc,
.n_value = sym.n_value,
});
+ try tentatives.append(global_sym_index);
resolv.* = .{
- .where = .tentative,
- .where_index = tent_sym_index,
+ .where = .global,
+ .where_index = global_sym_index,
.file = object_id,
};
undef.* = .{
@@ -2276,14 +2280,13 @@ fn resolveSymbolsInObject(self: *MachO, object_id: u16) !void {
.n_desc = 0,
.n_value = 0,
};
- },
- .tentative => {
- const tentative = &self.tentatives.items[resolv.where_index];
- if (tentative.n_value >= sym.n_value) continue;
-
- tentative.n_desc = sym.n_desc;
- tentative.n_value = sym.n_value;
- resolv.file = object_id;
+ var i: usize = 0;
+ while (i < unresolved.items.len) : (i += 1) {
+ if (unresolved.items[i] == resolv.where_index) {
+ _ = unresolved.swapRemove(i);
+ break;
+ }
+ }
},
}
} else {
@@ -2303,24 +2306,27 @@ fn resolveSymbolsInObject(self: *MachO, object_id: u16) !void {
.where_index = undef_sym_index,
.file = object_id,
});
+ try unresolved.append(undef_sym_index);
}
}
}
fn resolveSymbols(self: *MachO) !void {
+ var tentatives = std.ArrayList(u32).init(self.base.allocator);
+ defer tentatives.deinit();
+
+ var unresolved = std.ArrayList(u32).init(self.base.allocator);
+ defer unresolved.deinit();
+
// First pass, resolve symbols in provided objects.
for (self.objects.items) |_, object_id| {
- try self.resolveSymbolsInObject(@intCast(u16, object_id));
+ try self.resolveSymbolsInObject(@intCast(u16, object_id), &tentatives, &unresolved);
}
// Second pass, resolve symbols in static libraries.
var next_sym: usize = 0;
- loop: while (true) : (next_sym += 1) {
- if (next_sym == self.undefs.items.len) break;
-
- const sym = self.undefs.items[next_sym];
- if (symbolIsNull(sym)) continue;
-
+ loop: while (next_sym < unresolved.items.len) {
+ const sym = self.undefs.items[unresolved.items[next_sym]];
const sym_name = self.getString(sym.n_strx);
for (self.archives.items) |archive| {
@@ -2334,17 +2340,18 @@ fn resolveSymbols(self: *MachO) !void {
const object_id = @intCast(u16, self.objects.items.len);
const object = try self.objects.addOne(self.base.allocator);
object.* = try archive.parseObject(self.base.allocator, self.base.options.target, offsets.items[0]);
- try self.resolveSymbolsInObject(object_id);
+ try self.resolveSymbolsInObject(object_id, &tentatives, &unresolved);
continue :loop;
}
+
+ next_sym += 1;
}
// Convert any tentative definition into a regular symbol and allocate
// text blocks for each tentative defintion.
- for (self.tentatives.items) |sym| {
- if (symbolIsNull(sym)) continue;
-
+ while (tentatives.popOrNull()) |index| {
+ const sym = &self.globals.items[index];
const match: MatchingSection = blk: {
if (self.common_section_index == null) {
const data_seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment;
@@ -2366,24 +2373,17 @@ fn resolveSymbols(self: *MachO) !void {
mem.set(u8, code, 0);
const alignment = (sym.n_desc >> 8) & 0x0f;
- const resolv = self.symbol_resolver.getPtr(sym.n_strx) orelse unreachable;
+ sym.n_value = 0;
+ sym.n_desc = 0;
+ sym.n_sect = @intCast(u8, self.section_ordinals.getIndex(match).? + 1);
+ var local_sym = sym.*;
+ local_sym.n_type = macho.N_SECT;
+
const local_sym_index = @intCast(u32, self.locals.items.len);
- var nlist = macho.nlist_64{
- .n_strx = sym.n_strx,
- .n_type = macho.N_SECT,
- .n_sect = @intCast(u8, self.section_ordinals.getIndex(match).? + 1),
- .n_desc = 0,
- .n_value = 0,
- };
- try self.locals.append(self.base.allocator, nlist);
- const global_sym_index = @intCast(u32, self.globals.items.len);
- nlist.n_type |= macho.N_EXT;
- try self.globals.append(self.base.allocator, nlist);
- resolv.* = .{
- .where = .global,
- .where_index = global_sym_index,
- .local_sym_index = local_sym_index,
- };
+ try self.locals.append(self.base.allocator, local_sym);
+
+ const resolv = self.symbol_resolver.getPtr(sym.n_strx) orelse unreachable;
+ resolv.local_sym_index = local_sym_index;
const block = try self.base.allocator.create(TextBlock);
block.* = TextBlock.empty;
@@ -2430,13 +2430,15 @@ fn resolveSymbols(self: *MachO) !void {
.where = .undef,
.where_index = undef_sym_index,
});
+ try unresolved.append(undef_sym_index);
}
- loop: for (self.undefs.items) |sym| {
- if (symbolIsNull(sym)) continue;
-
+ next_sym = 0;
+ loop: while (next_sym < unresolved.items.len) {
+ const sym = self.undefs.items[unresolved.items[next_sym]];
const sym_name = self.getString(sym.n_strx);
- for (self.dylibs.items) |*dylib, id| {
+
+ for (self.dylibs.items) |dylib, id| {
if (!dylib.symbols.contains(sym_name)) continue;
const dylib_id = @intCast(u16, id);
@@ -2447,28 +2449,15 @@ fn resolveSymbols(self: *MachO) !void {
const ordinal = self.referenced_dylibs.getIndex(dylib_id) orelse unreachable;
const resolv = self.symbol_resolver.getPtr(sym.n_strx) orelse unreachable;
const undef = &self.undefs.items[resolv.where_index];
- const import_sym_index = @intCast(u32, self.imports.items.len);
- try self.imports.append(self.base.allocator, .{
- .n_strx = undef.n_strx,
- .n_type = macho.N_UNDF | macho.N_EXT,
- .n_sect = 0,
- .n_desc = @intCast(u16, ordinal + 1) * macho.N_SYMBOL_RESOLVER,
- .n_value = 0,
- });
- resolv.* = .{
- .where = .import,
- .where_index = import_sym_index,
- };
- undef.* = .{
- .n_strx = 0,
- .n_type = macho.N_UNDF,
- .n_sect = 0,
- .n_desc = 0,
- .n_value = 0,
- };
+ undef.n_type |= macho.N_EXT;
+ undef.n_desc = @intCast(u16, ordinal + 1) * macho.N_SYMBOL_RESOLVER;
+
+ _ = unresolved.swapRemove(next_sym);
continue :loop;
}
+
+ next_sym += 1;
}
// Fourth pass, handle synthetic symbols and flag any undefined references.
@@ -2497,6 +2486,14 @@ fn resolveSymbols(self: *MachO) !void {
nlist.n_desc = macho.N_WEAK_DEF;
try self.globals.append(self.base.allocator, nlist);
+ var i: usize = 0;
+ while (i < unresolved.items.len) : (i += 1) {
+ if (unresolved.items[i] == resolv.where_index) {
+ _ = unresolved.swapRemove(i);
+ break;
+ }
+ }
+
undef.* = .{
.n_strx = 0,
.n_type = macho.N_UNDF,
@@ -2529,19 +2526,17 @@ fn resolveSymbols(self: *MachO) !void {
}
}
- var has_undefined = false;
- for (self.undefs.items) |sym| {
- if (symbolIsNull(sym)) continue;
-
+ for (unresolved.items) |index| {
+ const sym = self.undefs.items[index];
const sym_name = self.getString(sym.n_strx);
const resolv = self.symbol_resolver.get(sym.n_strx) orelse unreachable;
log.err("undefined reference to symbol '{s}'", .{sym_name});
log.err(" first referenced in '{s}'", .{self.objects.items[resolv.file].name});
- has_undefined = true;
}
- if (has_undefined) return error.UndefinedSymbolReference;
+ if (unresolved.items.len > 0)
+ return error.UndefinedSymbolReference;
}
fn parseTextBlocks(self: *MachO) !void {
@@ -3006,7 +3001,7 @@ fn writeGotEntries(self: *MachO) !void {
for (self.got_entries.items) |key| {
const address: u64 = switch (key.where) {
.local => self.locals.items[key.where_index].n_value,
- .import => 0,
+ .undef => 0,
};
try writer.writeIntLittle(u64, address);
}
@@ -3075,7 +3070,7 @@ fn writeRebaseInfoTableZld(self: *MachO) !void {
const segment_id = @intCast(u16, self.data_const_segment_cmd_index.?);
for (self.got_entries.items) |entry, i| {
- if (entry.where == .import) continue;
+ if (entry.where == .undef) continue;
try pointers.append(.{
.offset = base_offset + i * @sizeOf(u64),
@@ -3132,7 +3127,7 @@ fn writeBindInfoTableZld(self: *MachO) !void {
for (self.got_entries.items) |entry, i| {
if (entry.where == .local) continue;
- const sym = self.imports.items[entry.where_index];
+ const sym = self.undefs.items[entry.where_index];
try pointers.append(.{
.offset = base_offset + i * @sizeOf(u64),
.segment_id = segment_id,
@@ -3157,7 +3152,7 @@ fn writeBindInfoTableZld(self: *MachO) !void {
const base_offset = sym.n_value - seg.inner.vmaddr;
for (block.bindings.items) |binding| {
- const bind_sym = self.imports.items[binding.local_sym_index];
+ const bind_sym = self.undefs.items[binding.local_sym_index];
try pointers.append(.{
.offset = binding.offset + base_offset,
.segment_id = match.seg,
@@ -3204,7 +3199,7 @@ fn writeLazyBindInfoTableZld(self: *MachO) !void {
try pointers.ensureUnusedCapacity(self.stubs.items.len);
for (self.stubs.items) |import_id, i| {
- const sym = self.imports.items[import_id];
+ const sym = self.undefs.items[import_id];
pointers.appendAssumeCapacity(.{
.offset = base_offset + i * @sizeOf(u64),
.segment_id = segment_id,
@@ -3338,7 +3333,7 @@ fn writeSymbolTable(self: *MachO) !void {
const nlocals = locals.items.len;
const nexports = self.globals.items.len;
- const nundefs = self.imports.items.len;
+ const nundefs = self.undefs.items.len;
const locals_off = symtab.symoff + symtab.nsyms * @sizeOf(macho.nlist_64);
const locals_size = nlocals * @sizeOf(macho.nlist_64);
@@ -3353,7 +3348,7 @@ fn writeSymbolTable(self: *MachO) !void {
const undefs_off = exports_off + exports_size;
const undefs_size = nundefs * @sizeOf(macho.nlist_64);
log.debug("writing undefined symbols from 0x{x} to 0x{x}", .{ undefs_off, undefs_size + undefs_off });
- try self.base.file.?.pwriteAll(mem.sliceAsBytes(self.imports.items), undefs_off);
+ try self.base.file.?.pwriteAll(mem.sliceAsBytes(self.undefs.items), undefs_off);
symtab.nsyms += @intCast(u32, nlocals + nexports + nundefs);
seg.inner.filesize += locals_size + exports_size + undefs_size;
@@ -3401,7 +3396,7 @@ fn writeSymbolTable(self: *MachO) !void {
got.reserved1 = nstubs;
for (self.got_entries.items) |entry| {
switch (entry.where) {
- .import => {
+ .undef => {
try writer.writeIntLittle(u32, dysymtab.iundefsym + entry.where_index);
},
.local => {
@@ -3437,8 +3432,6 @@ pub fn deinit(self: *MachO) void {
self.strtab_dir.deinit(self.base.allocator);
self.strtab.deinit(self.base.allocator);
self.undefs.deinit(self.base.allocator);
- self.tentatives.deinit(self.base.allocator);
- self.imports.deinit(self.base.allocator);
self.globals.deinit(self.base.allocator);
self.globals_free_list.deinit(self.base.allocator);
self.locals.deinit(self.base.allocator);
@@ -4517,9 +4510,9 @@ pub fn populateMissingMetadata(self: *MachO) !void {
if (!self.strtab_dir.containsAdapted(@as([]const u8, "dyld_stub_binder"), StringSliceAdapter{
.strtab = &self.strtab,
})) {
- const import_sym_index = @intCast(u32, self.imports.items.len);
+ const import_sym_index = @intCast(u32, self.undefs.items.len);
const n_strx = try self.makeString("dyld_stub_binder");
- try self.imports.append(self.base.allocator, .{
+ try self.undefs.append(self.base.allocator, .{
.n_strx = n_strx,
.n_type = macho.N_UNDF | macho.N_EXT,
.n_sect = 0,
@@ -4527,11 +4520,11 @@ pub fn populateMissingMetadata(self: *MachO) !void {
.n_value = 0,
});
try self.symbol_resolver.putNoClobber(self.base.allocator, n_strx, .{
- .where = .import,
+ .where = .undef,
.where_index = import_sym_index,
});
const got_key = GotIndirectionKey{
- .where = .import,
+ .where = .undef,
.where_index = import_sym_index,
};
const got_index = @intCast(u32, self.got_entries.items.len);
@@ -4663,9 +4656,9 @@ pub fn addExternFn(self: *MachO, name: []const u8) !u32 {
}
log.debug("adding new extern function '{s}' with dylib ordinal 1", .{sym_name});
- const import_sym_index = @intCast(u32, self.imports.items.len);
+ const import_sym_index = @intCast(u32, self.undefs.items.len);
const n_strx = try self.makeString(sym_name);
- try self.imports.append(self.base.allocator, .{
+ try self.undefs.append(self.base.allocator, .{
.n_strx = n_strx,
.n_type = macho.N_UNDF | macho.N_EXT,
.n_sect = 0,
@@ -4673,7 +4666,7 @@ pub fn addExternFn(self: *MachO, name: []const u8) !u32 {
.n_value = 0,
});
try self.symbol_resolver.putNoClobber(self.base.allocator, n_strx, .{
- .where = .import,
+ .where = .undef,
.where_index = import_sym_index,
});
@@ -4856,7 +4849,7 @@ fn writeGotEntry(self: *MachO, index: usize) !void {
const got_entry = self.got_entries.items[index];
const sym = switch (got_entry.where) {
.local => self.locals.items[got_entry.where_index],
- .import => self.imports.items[got_entry.where_index],
+ .undef => self.undefs.items[got_entry.where_index],
};
log.debug("writing offset table entry [ 0x{x} => 0x{x} ({s}) ]", .{
off,
@@ -5140,7 +5133,7 @@ fn relocateSymbolTable(self: *MachO) !void {
const symtab = &self.load_commands.items[self.symtab_cmd_index.?].Symtab;
const nlocals = self.locals.items.len;
const nglobals = self.globals.items.len;
- const nundefs = self.imports.items.len;
+ const nundefs = self.undefs.items.len;
const nsyms = nlocals + nglobals + nundefs;
if (symtab.nsyms < nsyms) {
@@ -5185,7 +5178,7 @@ fn writeAllGlobalAndUndefSymbols(self: *MachO) !void {
const symtab = &self.load_commands.items[self.symtab_cmd_index.?].Symtab;
const nlocals = self.locals.items.len;
const nglobals = self.globals.items.len;
- const nundefs = self.imports.items.len;
+ const nundefs = self.undefs.items.len;
const locals_off = symtab.symoff;
const locals_size = nlocals * @sizeOf(macho.nlist_64);
@@ -5198,7 +5191,7 @@ fn writeAllGlobalAndUndefSymbols(self: *MachO) !void {
const undefs_off = globals_off + globals_size;
const undefs_size = nundefs * @sizeOf(macho.nlist_64);
log.debug("writing extern symbols from 0x{x} to 0x{x}", .{ undefs_off, undefs_size + undefs_off });
- try self.base.file.?.pwriteAll(mem.sliceAsBytes(self.imports.items), undefs_off);
+ try self.base.file.?.pwriteAll(mem.sliceAsBytes(self.undefs.items), undefs_off);
// Update dynamic symbol table.
const dysymtab = &self.load_commands.items[self.dysymtab_cmd_index.?].Dysymtab;
@@ -5253,7 +5246,7 @@ fn writeIndirectSymbolTable(self: *MachO) !void {
got.reserved1 = nstubs;
for (self.got_entries.items) |entry| {
switch (entry.where) {
- .import => {
+ .undef => {
try writer.writeIntLittle(u32, dysymtab.iundefsym + entry.where_index);
},
.local => {
@@ -5478,7 +5471,7 @@ fn writeRebaseInfoTable(self: *MachO) !void {
const segment_id = @intCast(u16, self.data_const_segment_cmd_index.?);
for (self.got_entries.items) |entry, i| {
- if (entry.where == .import) continue;
+ if (entry.where == .undef) continue;
try pointers.append(.{
.offset = base_offset + i * @sizeOf(u64),
@@ -5547,7 +5540,7 @@ fn writeBindInfoTable(self: *MachO) !void {
for (self.got_entries.items) |entry, i| {
if (entry.where == .local) continue;
- const sym = self.imports.items[entry.where_index];
+ const sym = self.undefs.items[entry.where_index];
try pointers.append(.{
.offset = base_offset + i * @sizeOf(u64),
.segment_id = segment_id,
@@ -5572,7 +5565,7 @@ fn writeBindInfoTable(self: *MachO) !void {
const base_offset = sym.n_value - seg.inner.vmaddr;
for (block.bindings.items) |binding| {
- const bind_sym = self.imports.items[binding.local_sym_index];
+ const bind_sym = self.undefs.items[binding.local_sym_index];
try pointers.append(.{
.offset = binding.offset + base_offset,
.segment_id = match.seg,
@@ -5631,7 +5624,7 @@ fn writeLazyBindInfoTable(self: *MachO) !void {
try pointers.ensureUnusedCapacity(self.stubs.items.len);
for (self.stubs.items) |import_id, i| {
- const sym = self.imports.items[import_id];
+ const sym = self.undefs.items[import_id];
pointers.appendAssumeCapacity(.{
.offset = base_offset + i * @sizeOf(u64),
.segment_id = segment_id,
@@ -5967,10 +5960,6 @@ pub fn symbolIsTentative(sym: macho.nlist_64) bool {
return sym.n_value != 0;
}
-pub fn symbolIsNull(sym: macho.nlist_64) bool {
- return sym.n_value == 0 and sym.n_desc == 0 and sym.n_type == 0 and sym.n_strx == 0 and sym.n_sect == 0;
-}
-
pub fn symbolIsTemp(sym: macho.nlist_64, sym_name: []const u8) bool {
if (!symbolIsSect(sym)) return false;
if (symbolIsExt(sym)) return false;
diff --git a/src/link/MachO/TextBlock.zig b/src/link/MachO/TextBlock.zig
index 55dc2db471..4788487d3b 100644
--- a/src/link/MachO/TextBlock.zig
+++ b/src/link/MachO/TextBlock.zig
@@ -165,7 +165,7 @@ pub const Relocation = struct {
where: enum {
local,
- import,
+ undef,
},
where_index: u32,
@@ -665,11 +665,10 @@ fn initRelocFromObject(rel: macho.relocation_info, context: RelocContext) !Reloc
parsed_rel.where = .local;
parsed_rel.where_index = resolv.local_sym_index;
},
- .import => {
- parsed_rel.where = .import;
+ .undef => {
+ parsed_rel.where = .undef;
parsed_rel.where_index = resolv.where_index;
},
- else => unreachable,
}
}
}
@@ -825,7 +824,7 @@ pub fn parseRelocs(self: *TextBlock, relocs: []macho.relocation_info, context: R
const key = MachO.GotIndirectionKey{
.where = switch (parsed_rel.where) {
.local => .local,
- .import => .import,
+ .undef => .undef,
},
.where_index = parsed_rel.where_index,
};
@@ -836,7 +835,7 @@ pub fn parseRelocs(self: *TextBlock, relocs: []macho.relocation_info, context: R
try context.macho_file.got_entries_map.putNoClobber(context.allocator, key, got_index);
} else if (parsed_rel.payload == .unsigned) {
switch (parsed_rel.where) {
- .import => {
+ .undef => {
try self.bindings.append(context.allocator, .{
.local_sym_index = parsed_rel.where_index,
.offset = parsed_rel.offset,
@@ -886,7 +885,7 @@ pub fn parseRelocs(self: *TextBlock, relocs: []macho.relocation_info, context: R
},
}
} else if (parsed_rel.payload == .branch) blk: {
- if (parsed_rel.where != .import) break :blk;
+ if (parsed_rel.where != .undef) break :blk;
if (context.macho_file.stubs_map.contains(parsed_rel.where_index)) break :blk;
const stubs_index = @intCast(u32, context.macho_file.stubs.items.len);
@@ -1030,7 +1029,7 @@ fn parseSigned(self: TextBlock, rel: macho.relocation_info, out: *Relocation, co
const source_sym = context.macho_file.locals.items[self.local_sym_index];
const target_sym = switch (out.where) {
.local => context.macho_file.locals.items[out.where_index],
- .import => context.macho_file.imports.items[out.where_index],
+ .undef => context.macho_file.undefs.items[out.where_index],
};
addend = @intCast(i64, source_sym.n_value + out.offset + 4) + addend - @intCast(i64, target_sym.n_value);
}
@@ -1088,13 +1087,13 @@ pub fn resolveRelocs(self: *TextBlock, macho_file: *MachO) !void {
const got_index = macho_file.got_entries_map.get(.{
.where = switch (rel.where) {
.local => .local,
- .import => .import,
+ .undef => .undef,
},
.where_index = rel.where_index,
}) orelse {
const sym = switch (rel.where) {
.local => macho_file.locals.items[rel.where_index],
- .import => macho_file.imports.items[rel.where_index],
+ .undef => macho_file.undefs.items[rel.where_index],
};
log.err("expected GOT entry for symbol '{s}'", .{macho_file.getString(sym.n_strx)});
log.err(" this is an internal linker error", .{});
@@ -1137,7 +1136,7 @@ pub fn resolveRelocs(self: *TextBlock, macho_file: *MachO) !void {
break :blk sym.n_value;
},
- .import => {
+ .undef => {
const stubs_index = macho_file.stubs_map.get(rel.where_index) orelse {
// TODO verify in TextBlock that the symbol is indeed dynamically bound.
break :blk 0; // Dynamically bound by dyld.