Commit 6f3bbd5eaa

Jakub Konka <kubkon@jakubkonka.com>
2023-11-15 19:00:13
elf: we were writing too many symbols in the symtab
1 parent 760ce69
src/link/Elf/file.zig
@@ -128,63 +128,15 @@ pub const File = union(enum) {
     }
 
     pub fn updateSymtabSize(file: File, elf_file: *Elf) !void {
-        const output_symtab_ctx = switch (file) {
-            inline else => |x| &x.output_symtab_ctx,
+        return switch (file) {
+            inline else => |x| x.updateSymtabSize(elf_file),
         };
-        for (file.locals()) |local_index| {
-            const local = elf_file.symbol(local_index);
-            if (local.atom(elf_file)) |atom| if (!atom.flags.alive) continue;
-            const esym = local.elfSym(elf_file);
-            switch (esym.st_type()) {
-                elf.STT_SECTION, elf.STT_NOTYPE => continue,
-                else => {},
-            }
-            local.flags.output_symtab = true;
-            try local.setOutputSymtabIndex(output_symtab_ctx.nlocals, elf_file);
-            output_symtab_ctx.nlocals += 1;
-            output_symtab_ctx.strsize += @as(u32, @intCast(local.name(elf_file).len)) + 1;
-        }
-
-        for (file.globals()) |global_index| {
-            const global = elf_file.symbol(global_index);
-            const file_ptr = global.file(elf_file) orelse continue;
-            if (file_ptr.index() != file.index()) continue;
-            if (global.atom(elf_file)) |atom| if (!atom.flags.alive) continue;
-            global.flags.output_symtab = true;
-            if (global.isLocal(elf_file)) {
-                try global.setOutputSymtabIndex(output_symtab_ctx.nlocals, elf_file);
-                output_symtab_ctx.nlocals += 1;
-            } else {
-                try global.setOutputSymtabIndex(output_symtab_ctx.nglobals, elf_file);
-                output_symtab_ctx.nglobals += 1;
-            }
-            output_symtab_ctx.strsize += @as(u32, @intCast(global.name(elf_file).len)) + 1;
-        }
     }
 
     pub fn writeSymtab(file: File, elf_file: *Elf) void {
-        for (file.locals()) |local_index| {
-            const local = elf_file.symbol(local_index);
-            const idx = local.outputSymtabIndex(elf_file) orelse continue;
-            const out_sym = &elf_file.symtab.items[idx];
-            out_sym.st_name = @intCast(elf_file.strtab.items.len);
-            elf_file.strtab.appendSliceAssumeCapacity(local.name(elf_file));
-            elf_file.strtab.appendAssumeCapacity(0);
-            local.setOutputSym(elf_file, out_sym);
-        }
-
-        for (file.globals()) |global_index| {
-            const global = elf_file.symbol(global_index);
-            const file_ptr = global.file(elf_file) orelse continue;
-            if (file_ptr.index() != file.index()) continue;
-            const idx = global.outputSymtabIndex(elf_file) orelse continue;
-            const st_name = @as(u32, @intCast(elf_file.strtab.items.len));
-            elf_file.strtab.appendSliceAssumeCapacity(global.name(elf_file));
-            elf_file.strtab.appendAssumeCapacity(0);
-            const out_sym = &elf_file.symtab.items[idx];
-            out_sym.st_name = st_name;
-            global.setOutputSym(elf_file, out_sym);
-        }
+        return switch (file) {
+            inline else => |x| x.writeSymtab(elf_file),
+        };
     }
 
     pub fn updateArSymtab(file: File, ar_symtab: *Archive.ArSymtab, elf_file: *Elf) !void {
src/link/Elf/LinkerDefined.zig
@@ -48,10 +48,42 @@ pub fn resolveSymbols(self: *LinkerDefined, elf_file: *Elf) void {
     }
 }
 
-pub fn globals(self: *LinkerDefined) []const Symbol.Index {
+pub fn globals(self: LinkerDefined) []const Symbol.Index {
     return self.symbols.items;
 }
 
+pub fn updateSymtabSize(self: *LinkerDefined, elf_file: *Elf) !void {
+    for (self.globals()) |global_index| {
+        const global = elf_file.symbol(global_index);
+        const file_ptr = global.file(elf_file) orelse continue;
+        if (file_ptr.index() != self.index) continue;
+        global.flags.output_symtab = true;
+        if (global.isLocal(elf_file)) {
+            try global.setOutputSymtabIndex(self.output_symtab_ctx.nlocals, elf_file);
+            self.output_symtab_ctx.nlocals += 1;
+        } else {
+            try global.setOutputSymtabIndex(self.output_symtab_ctx.nglobals, elf_file);
+            self.output_symtab_ctx.nglobals += 1;
+        }
+        self.output_symtab_ctx.strsize += @as(u32, @intCast(global.name(elf_file).len)) + 1;
+    }
+}
+
+pub fn writeSymtab(self: LinkerDefined, elf_file: *Elf) void {
+    for (self.globals()) |global_index| {
+        const global = elf_file.symbol(global_index);
+        const file_ptr = global.file(elf_file) orelse continue;
+        if (file_ptr.index() != self.index) continue;
+        const idx = global.outputSymtabIndex(elf_file) orelse continue;
+        const st_name = @as(u32, @intCast(elf_file.strtab.items.len));
+        elf_file.strtab.appendSliceAssumeCapacity(global.name(elf_file));
+        elf_file.strtab.appendAssumeCapacity(0);
+        const out_sym = &elf_file.symtab.items[idx];
+        out_sym.st_name = st_name;
+        global.setOutputSym(elf_file, out_sym);
+    }
+}
+
 pub fn asFile(self: *LinkerDefined) File {
     return .{ .linker_defined = self };
 }
src/link/Elf/Object.zig
@@ -741,6 +741,63 @@ pub fn writeAr(self: Object, writer: anytype) !void {
     try writer.writeAll(self.data);
 }
 
+pub fn updateSymtabSize(self: *Object, elf_file: *Elf) !void {
+    for (self.locals()) |local_index| {
+        const local = elf_file.symbol(local_index);
+        if (local.atom(elf_file)) |atom| if (!atom.flags.alive) continue;
+        const esym = local.elfSym(elf_file);
+        switch (esym.st_type()) {
+            elf.STT_SECTION, elf.STT_NOTYPE => continue,
+            else => {},
+        }
+        local.flags.output_symtab = true;
+        try local.setOutputSymtabIndex(self.output_symtab_ctx.nlocals, elf_file);
+        self.output_symtab_ctx.nlocals += 1;
+        self.output_symtab_ctx.strsize += @as(u32, @intCast(local.name(elf_file).len)) + 1;
+    }
+
+    for (self.globals()) |global_index| {
+        const global = elf_file.symbol(global_index);
+        const file_ptr = global.file(elf_file) orelse continue;
+        if (file_ptr.index() != self.index) continue;
+        if (global.atom(elf_file)) |atom| if (!atom.flags.alive) continue;
+        global.flags.output_symtab = true;
+        if (global.isLocal(elf_file)) {
+            try global.setOutputSymtabIndex(self.output_symtab_ctx.nlocals, elf_file);
+            self.output_symtab_ctx.nlocals += 1;
+        } else {
+            try global.setOutputSymtabIndex(self.output_symtab_ctx.nglobals, elf_file);
+            self.output_symtab_ctx.nglobals += 1;
+        }
+        self.output_symtab_ctx.strsize += @as(u32, @intCast(global.name(elf_file).len)) + 1;
+    }
+}
+
+pub fn writeSymtab(self: Object, elf_file: *Elf) void {
+    for (self.locals()) |local_index| {
+        const local = elf_file.symbol(local_index);
+        const idx = local.outputSymtabIndex(elf_file) orelse continue;
+        const out_sym = &elf_file.symtab.items[idx];
+        out_sym.st_name = @intCast(elf_file.strtab.items.len);
+        elf_file.strtab.appendSliceAssumeCapacity(local.name(elf_file));
+        elf_file.strtab.appendAssumeCapacity(0);
+        local.setOutputSym(elf_file, out_sym);
+    }
+
+    for (self.globals()) |global_index| {
+        const global = elf_file.symbol(global_index);
+        const file_ptr = global.file(elf_file) orelse continue;
+        if (file_ptr.index() != self.index) continue;
+        const idx = global.outputSymtabIndex(elf_file) orelse continue;
+        const st_name = @as(u32, @intCast(elf_file.strtab.items.len));
+        elf_file.strtab.appendSliceAssumeCapacity(global.name(elf_file));
+        elf_file.strtab.appendAssumeCapacity(0);
+        const out_sym = &elf_file.symtab.items[idx];
+        out_sym.st_name = st_name;
+        global.setOutputSym(elf_file, out_sym);
+    }
+}
+
 pub fn locals(self: Object) []const Symbol.Index {
     if (self.symbols.items.len == 0) return &[0]Symbol.Index{};
     const end = self.first_global orelse self.symbols.items.len;
src/link/Elf/SharedObject.zig
@@ -191,6 +191,34 @@ pub fn globals(self: SharedObject) []const Symbol.Index {
     return self.symbols.items;
 }
 
+pub fn updateSymtabSize(self: *SharedObject, elf_file: *Elf) !void {
+    for (self.globals()) |global_index| {
+        const global = elf_file.symbol(global_index);
+        const file_ptr = global.file(elf_file) orelse continue;
+        if (file_ptr.index() != self.index) continue;
+        if (global.isLocal(elf_file)) continue;
+        global.flags.output_symtab = true;
+        try global.setOutputSymtabIndex(self.output_symtab_ctx.nglobals, elf_file);
+        self.output_symtab_ctx.nglobals += 1;
+        self.output_symtab_ctx.strsize += @as(u32, @intCast(global.name(elf_file).len)) + 1;
+    }
+}
+
+pub fn writeSymtab(self: SharedObject, elf_file: *Elf) void {
+    for (self.globals()) |global_index| {
+        const global = elf_file.symbol(global_index);
+        const file_ptr = global.file(elf_file) orelse continue;
+        if (file_ptr.index() != self.index) continue;
+        const idx = global.outputSymtabIndex(elf_file) orelse continue;
+        const st_name = @as(u32, @intCast(elf_file.strtab.items.len));
+        elf_file.strtab.appendSliceAssumeCapacity(global.name(elf_file));
+        elf_file.strtab.appendAssumeCapacity(0);
+        const out_sym = &elf_file.symtab.items[idx];
+        out_sym.st_name = st_name;
+        global.setOutputSym(elf_file, out_sym);
+    }
+}
+
 pub fn shdrContents(self: SharedObject, index: u16) []const u8 {
     const shdr = self.shdrs.items[index];
     return self.data[shdr.sh_offset..][0..shdr.sh_size];
src/link/Elf/ZigObject.zig
@@ -528,6 +528,63 @@ pub fn globals(self: ZigObject) []const Symbol.Index {
     return self.global_symbols.items;
 }
 
+pub fn updateSymtabSize(self: *ZigObject, elf_file: *Elf) !void {
+    for (self.locals()) |local_index| {
+        const local = elf_file.symbol(local_index);
+        if (local.atom(elf_file)) |atom| if (!atom.flags.alive) continue;
+        const esym = local.elfSym(elf_file);
+        switch (esym.st_type()) {
+            elf.STT_SECTION, elf.STT_NOTYPE => continue,
+            else => {},
+        }
+        local.flags.output_symtab = true;
+        try local.setOutputSymtabIndex(self.output_symtab_ctx.nlocals, elf_file);
+        self.output_symtab_ctx.nlocals += 1;
+        self.output_symtab_ctx.strsize += @as(u32, @intCast(local.name(elf_file).len)) + 1;
+    }
+
+    for (self.globals()) |global_index| {
+        const global = elf_file.symbol(global_index);
+        const file_ptr = global.file(elf_file) orelse continue;
+        if (file_ptr.index() != self.index) continue;
+        if (global.atom(elf_file)) |atom| if (!atom.flags.alive) continue;
+        global.flags.output_symtab = true;
+        if (global.isLocal(elf_file)) {
+            try global.setOutputSymtabIndex(self.output_symtab_ctx.nlocals, elf_file);
+            self.output_symtab_ctx.nlocals += 1;
+        } else {
+            try global.setOutputSymtabIndex(self.output_symtab_ctx.nglobals, elf_file);
+            self.output_symtab_ctx.nglobals += 1;
+        }
+        self.output_symtab_ctx.strsize += @as(u32, @intCast(global.name(elf_file).len)) + 1;
+    }
+}
+
+pub fn writeSymtab(self: ZigObject, elf_file: *Elf) void {
+    for (self.locals()) |local_index| {
+        const local = elf_file.symbol(local_index);
+        const idx = local.outputSymtabIndex(elf_file) orelse continue;
+        const out_sym = &elf_file.symtab.items[idx];
+        out_sym.st_name = @intCast(elf_file.strtab.items.len);
+        elf_file.strtab.appendSliceAssumeCapacity(local.name(elf_file));
+        elf_file.strtab.appendAssumeCapacity(0);
+        local.setOutputSym(elf_file, out_sym);
+    }
+
+    for (self.globals()) |global_index| {
+        const global = elf_file.symbol(global_index);
+        const file_ptr = global.file(elf_file) orelse continue;
+        if (file_ptr.index() != self.index) continue;
+        const idx = global.outputSymtabIndex(elf_file) orelse continue;
+        const st_name = @as(u32, @intCast(elf_file.strtab.items.len));
+        elf_file.strtab.appendSliceAssumeCapacity(global.name(elf_file));
+        elf_file.strtab.appendAssumeCapacity(0);
+        const out_sym = &elf_file.symtab.items[idx];
+        out_sym.st_name = st_name;
+        global.setOutputSym(elf_file, out_sym);
+    }
+}
+
 pub fn asFile(self: *ZigObject) File {
     return .{ .zig_object = self };
 }