commit 6f3bbd5eaa61a93f96245bfec8d9429f4ea9f88e (tree)
parent 760ce69734e8c6fca02356c53729909ccb5d8ff9
Author: Jakub Konka <kubkon@jakubkonka.com>
Date: Wed, 15 Nov 2023 19:00:13 +0100
elf: we were writing too many symbols in the symtab
Diffstat:
5 files changed, 180 insertions(+), 54 deletions(-)
diff --git a/src/link/Elf/LinkerDefined.zig b/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 };
}
diff --git a/src/link/Elf/Object.zig b/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;
diff --git a/src/link/Elf/SharedObject.zig b/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];
diff --git a/src/link/Elf/ZigObject.zig b/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 };
}
diff --git a/src/link/Elf/file.zig b/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 {