Fix improper reuse of global symbols in MachO
Signed-off-by: Jakub Konka <kubkon@jakubkonka.com>
This commit is contained in:
@@ -93,7 +93,7 @@ pub const Export = struct {
|
||||
/// Byte offset into the file that contains the export directive.
|
||||
src: usize,
|
||||
/// Represents the position of the export, if any, in the output file.
|
||||
link: link.File.Elf.Export,
|
||||
link: link.File.Export,
|
||||
/// The Decl that performs the export. Note that this is *not* the Decl being exported.
|
||||
owner_decl: *Decl,
|
||||
/// The Decl being exported. Note this is *not* the Decl performing the export.
|
||||
@@ -1712,7 +1712,10 @@ fn deleteDeclExports(self: *Module, decl: *Decl) void {
|
||||
}
|
||||
}
|
||||
if (self.comp.bin_file.cast(link.File.Elf)) |elf| {
|
||||
elf.deleteExport(exp.link);
|
||||
elf.deleteExport(exp.link.elf);
|
||||
}
|
||||
if (self.comp.bin_file.cast(link.File.MachO)) |macho| {
|
||||
macho.deleteExport(exp.link.macho);
|
||||
}
|
||||
if (self.failed_exports.remove(exp)) |entry| {
|
||||
entry.value.destroy(self.gpa);
|
||||
@@ -1875,7 +1878,13 @@ pub fn analyzeExport(self: *Module, scope: *Scope, src: usize, borrowed_symbol_n
|
||||
new_export.* = .{
|
||||
.options = .{ .name = symbol_name },
|
||||
.src = src,
|
||||
.link = .{},
|
||||
.link = switch (self.comp.bin_file.tag) {
|
||||
.coff => .{ .coff = {} },
|
||||
.elf => .{ .elf = link.File.Elf.Export{} },
|
||||
.macho => .{ .macho = link.File.MachO.Export{} },
|
||||
.c => .{ .c = {} },
|
||||
.wasm => .{ .wasm = {} },
|
||||
},
|
||||
.owner_decl = owner_decl,
|
||||
.exported_decl = exported_decl,
|
||||
.status = .in_progress,
|
||||
|
||||
@@ -133,6 +133,14 @@ pub const File = struct {
|
||||
wasm: ?Wasm.FnData,
|
||||
};
|
||||
|
||||
pub const Export = union {
|
||||
elf: Elf.Export,
|
||||
coff: void,
|
||||
macho: MachO.Export,
|
||||
c: void,
|
||||
wasm: void,
|
||||
};
|
||||
|
||||
/// For DWARF .debug_info.
|
||||
pub const DbgInfoTypeRelocsTable = std.HashMapUnmanaged(Type, DbgInfoTypeReloc, Type.hash, Type.eql, std.hash_map.DefaultMaxLoadPercentage);
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user