Commit f4c4ca4b4c

Jakub Konka <kubkon@jakubkonka.com>
2024-09-23 06:56:33
elf: fix condition for skipping symbols if atom is dead
Skipping the symbols too early when resolving would end up in the linker not deduping CIEs fully.
1 parent d83a3f1
Changed files (2)
src/link/Elf/Object.zig
@@ -524,12 +524,6 @@ pub fn resolveSymbols(self: *Object, elf_file: *Elf) !void {
     const first_global = self.first_global orelse return;
     for (self.globals(), first_global..) |_, i| {
         const esym = self.symtab.items[i];
-        if (esym.st_shndx != elf.SHN_ABS and esym.st_shndx != elf.SHN_COMMON and esym.st_shndx != elf.SHN_UNDEF) {
-            const atom_index = self.atoms_indexes.items[esym.st_shndx];
-            const atom_ptr = self.atom(atom_index) orelse continue;
-            if (!atom_ptr.alive) continue;
-        }
-
         const resolv = &self.symbols_resolver.items[i - first_global];
         const gop = try elf_file.resolver.getOrPut(gpa, .{
             .index = @intCast(i),
@@ -541,6 +535,11 @@ pub fn resolveSymbols(self: *Object, elf_file: *Elf) !void {
         resolv.* = gop.index;
 
         if (esym.st_shndx == elf.SHN_UNDEF) continue;
+        if (esym.st_shndx != elf.SHN_ABS and esym.st_shndx != elf.SHN_COMMON) {
+            const atom_index = self.atoms_indexes.items[esym.st_shndx];
+            const atom_ptr = self.atom(atom_index) orelse continue;
+            if (!atom_ptr.alive) continue;
+        }
         if (elf_file.symbol(gop.ref.*) == null) {
             gop.ref.* = .{ .index = @intCast(i), .file = self.index };
             continue;
src/link/Elf/ZigObject.zig
@@ -603,12 +603,6 @@ pub fn resolveSymbols(self: *ZigObject, elf_file: *Elf) !void {
         const global = &self.symbols.items[index];
         const esym = global.elfSym(elf_file);
         const shndx = self.symtab.items(.shndx)[global.esym_index];
-        if (esym.st_shndx != elf.SHN_ABS and esym.st_shndx != elf.SHN_COMMON and esym.st_shndx != elf.SHN_UNDEF) {
-            assert(esym.st_shndx == SHN_ATOM);
-            const atom_ptr = self.atom(shndx) orelse continue;
-            if (!atom_ptr.alive) continue;
-        }
-
         const resolv = &self.symbols_resolver.items[i];
         const gop = try elf_file.resolver.getOrPut(gpa, .{
             .index = @intCast(i | global_symbol_bit),
@@ -620,6 +614,11 @@ pub fn resolveSymbols(self: *ZigObject, elf_file: *Elf) !void {
         resolv.* = gop.index;
 
         if (esym.st_shndx == elf.SHN_UNDEF) continue;
+        if (esym.st_shndx != elf.SHN_ABS and esym.st_shndx != elf.SHN_COMMON) {
+            assert(esym.st_shndx == SHN_ATOM);
+            const atom_ptr = self.atom(shndx) orelse continue;
+            if (!atom_ptr.alive) continue;
+        }
         if (elf_file.symbol(gop.ref.*) == null) {
             gop.ref.* = .{ .index = @intCast(i | global_symbol_bit), .file = self.index };
             continue;