diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/Module.zig | 15 | ||||
| -rw-r--r-- | src/link.zig | 8 | ||||
| -rw-r--r-- | src/link/Elf.zig | 4 | ||||
| -rw-r--r-- | src/link/MachO.zig | 24 |
4 files changed, 42 insertions, 9 deletions
diff --git a/src/Module.zig b/src/Module.zig index 75b6afffcd..0c2a38be28 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -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, diff --git a/src/link.zig b/src/link.zig index 139977b3e2..99bca45fbe 100644 --- a/src/link.zig +++ b/src/link.zig @@ -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); 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 { |
