diff --git a/src/link/Elf.zig b/src/link/Elf.zig index 319e6e4517..bf7bfaeb43 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -1493,6 +1493,7 @@ fn resolveSymbols(self: *Elf) error{Overflow}!void { /// This routine will prune unneeded objects extracted from archives and /// unneeded shared objects. fn markLive(self: *Elf) void { + if (self.zig_module_index) |index| self.file(index).?.markLive(self); for (self.objects.items) |index| { const file_ptr = self.file(index).?; if (file_ptr.isAlive()) file_ptr.markLive(self); diff --git a/src/link/Elf/ZigModule.zig b/src/link/Elf/ZigModule.zig index 746266a5b4..091c72fad9 100644 --- a/src/link/Elf/ZigModule.zig +++ b/src/link/Elf/ZigModule.zig @@ -155,6 +155,22 @@ pub fn resetGlobals(self: *ZigModule, elf_file: *Elf) void { } } +pub fn markLive(self: *ZigModule, elf_file: *Elf) void { + for (self.globals(), 0..) |index, i| { + const esym = self.global_esyms.items[i]; + if (esym.st_bind() == elf.STB_WEAK) continue; + + const global = elf_file.symbol(index); + const file = global.file(elf_file) orelse continue; + const should_keep = esym.st_shndx == elf.SHN_UNDEF or + (esym.st_shndx == elf.SHN_COMMON and global.elfSym(elf_file).st_shndx != elf.SHN_COMMON); + if (should_keep and !file.isAlive()) { + file.setAlive(); + file.markLive(elf_file); + } + } +} + pub fn updateSymtabSize(self: *ZigModule, elf_file: *Elf) void { for (self.locals()) |local_index| { const local = elf_file.symbol(local_index); diff --git a/src/link/Elf/file.zig b/src/link/Elf/file.zig index 3b9790dffa..e1235140d2 100644 --- a/src/link/Elf/file.zig +++ b/src/link/Elf/file.zig @@ -84,7 +84,7 @@ pub const File = union(enum) { pub fn markLive(file: File, elf_file: *Elf) void { switch (file) { - .zig_module, .linker_defined => unreachable, + .linker_defined => unreachable, inline else => |x| x.markLive(elf_file), } }