aboutsummaryrefslogtreecommitdiff
path: root/src/link
diff options
context:
space:
mode:
authorJakub Konka <kubkon@jakubkonka.com>2020-10-07 20:32:02 +0200
committerJakub Konka <kubkon@jakubkonka.com>2020-10-07 20:34:40 +0200
commitb5b25d38a8fa4e66e54ff1279c1becee877793f6 (patch)
tree38aeff3d774dc291e75dcdd869c1eb3b2653b804 /src/link
parentbdab4f53c1fa614fcd89468f305184fa36520039 (diff)
downloadzig-b5b25d38a8fa4e66e54ff1279c1becee877793f6.tar.gz
zig-b5b25d38a8fa4e66e54ff1279c1becee877793f6.zip
Fix improper reuse of global symbols in MachO
Signed-off-by: Jakub Konka <kubkon@jakubkonka.com>
Diffstat (limited to 'src/link')
-rw-r--r--src/link/Elf.zig4
-rw-r--r--src/link/MachO.zig24
2 files changed, 22 insertions, 6 deletions
diff --git a/src/link/Elf.zig b/src/link/Elf.zig
index c62bb29f78..a316a9c19e 100644
--- a/src/link/Elf.zig
+++ b/src/link/Elf.zig
@@ -2588,7 +2588,7 @@ pub fn updateDeclExports(
},
};
const stt_bits: u8 = @truncate(u4, decl_sym.st_info);
- if (exp.link.sym_index) |i| {
+ if (exp.link.elf.sym_index) |i| {
const sym = &self.global_symbols.items[i];
sym.* = .{
.st_name = try self.updateString(sym.st_name, exp.options.name),
@@ -2613,7 +2613,7 @@ pub fn updateDeclExports(
.st_size = decl_sym.st_size,
};
- exp.link.sym_index = @intCast(u32, i);
+ exp.link.elf.sym_index = @intCast(u32, i);
}
}
}
diff --git a/src/link/MachO.zig b/src/link/MachO.zig
index afc54f8f7b..486620804b 100644
--- a/src/link/MachO.zig
+++ b/src/link/MachO.zig
@@ -115,6 +115,9 @@ local_symbols: std.ArrayListUnmanaged(macho.nlist_64) = .{},
global_symbols: std.ArrayListUnmanaged(macho.nlist_64) = .{},
/// Table of all undefined symbols
undef_symbols: std.ArrayListUnmanaged(macho.nlist_64) = .{},
+
+global_symbol_free_list: std.ArrayListUnmanaged(u32) = .{},
+
dyld_stub_binder_index: ?u16 = null,
/// Table of symbol names aka the string table.
@@ -178,6 +181,10 @@ pub const TextBlock = struct {
};
};
+pub const Export = struct {
+ sym_index: ?u32 = null,
+};
+
pub const SrcFn = struct {
pub const empty = SrcFn{};
};
@@ -713,6 +720,7 @@ pub fn deinit(self: *MachO) void {
self.string_table.deinit(self.base.allocator);
self.undef_symbols.deinit(self.base.allocator);
self.global_symbols.deinit(self.base.allocator);
+ self.global_symbol_free_list.deinit(self.base.allocator);
self.local_symbols.deinit(self.base.allocator);
self.sections.deinit(self.base.allocator);
self.load_commands.deinit(self.base.allocator);
@@ -837,7 +845,7 @@ pub fn updateDeclExports(
},
};
const n_type = decl_sym.n_type | macho.N_EXT;
- if (exp.link.sym_index) |i| {
+ if (exp.link.macho.sym_index) |i| {
const sym = &self.global_symbols.items[i];
sym.* = .{
.n_strx = try self.updateString(sym.n_strx, exp.options.name),
@@ -848,8 +856,10 @@ pub fn updateDeclExports(
};
} else {
const name_str_index = try self.makeString(exp.options.name);
- _ = self.global_symbols.addOneAssumeCapacity();
- const i = self.global_symbols.items.len - 1;
+ const i = if (self.global_symbol_free_list.popOrNull()) |i| i else blk: {
+ _ = self.global_symbols.addOneAssumeCapacity();
+ break :blk self.global_symbols.items.len - 1;
+ };
self.global_symbols.items[i] = .{
.n_strx = name_str_index,
.n_type = n_type,
@@ -858,11 +868,17 @@ pub fn updateDeclExports(
.n_value = decl_sym.n_value,
};
- exp.link.sym_index = @intCast(u32, i);
+ exp.link.macho.sym_index = @intCast(u32, i);
}
}
}
+pub fn deleteExport(self: *MachO, exp: Export) void {
+ const sym_index = exp.sym_index orelse return;
+ self.global_symbol_free_list.append(self.base.allocator, sym_index) catch {};
+ self.global_symbols.items[sym_index].n_type = 0;
+}
+
pub fn freeDecl(self: *MachO, decl: *Module.Decl) void {}
pub fn getDeclVAddr(self: *MachO, decl: *const Module.Decl) u64 {