elf: we were writing too many symbols in the symtab

This commit is contained in:
Jakub Konka 2023-11-15 19:00:13 +01:00
parent 760ce69734
commit 6f3bbd5eaa
5 changed files with 180 additions and 54 deletions

View File

@ -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 };
}

View File

@ -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;

View File

@ -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];

View File

@ -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 };
}

View File

@ -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 {