elf: skip storing comdat group signature globally

This commit is contained in:
Jakub Konka 2024-07-24 22:06:12 +02:00
parent 669f285943
commit 494ae149e0
3 changed files with 42 additions and 7 deletions

View File

@ -216,7 +216,7 @@ merge_subsections: std.ArrayListUnmanaged(MergeSubsection) = .{},
last_atom_and_free_list_table: LastAtomAndFreeListTable = .{},
comdat_groups_owners: std.ArrayListUnmanaged(ComdatGroupOwner) = .{},
comdat_groups_table: std.AutoHashMapUnmanaged(u32, ComdatGroupOwner.Index) = .{},
comdat_groups_table: std.ArrayHashMapUnmanaged(ComdatGroupKey, ComdatGroupOwner.Index, ComdatGroupContext, false) = .{},
/// Global string table used to provide quick access to global symbol resolvers
/// such as `resolver` and `comdat_groups_table`.
@ -5742,10 +5742,9 @@ const GetOrCreateComdatGroupOwnerResult = struct {
index: ComdatGroupOwner.Index,
};
pub fn getOrCreateComdatGroupOwner(self: *Elf, name: [:0]const u8) !GetOrCreateComdatGroupOwnerResult {
pub fn getOrCreateComdatGroupOwner(self: *Elf, key: ComdatGroupKey) !GetOrCreateComdatGroupOwnerResult {
const gpa = self.base.comp.gpa;
const off = try self.strings.insert(gpa, name);
const gop = try self.comdat_groups_table.getOrPut(gpa, off);
const gop = try self.comdat_groups_table.getOrPutContext(gpa, key, .{ .elf_file = self });
if (!gop.found_existing) {
const index: ComdatGroupOwner.Index = @intCast(self.comdat_groups_owners.items.len);
const owner = try self.comdat_groups_owners.addOne(gpa);
@ -6244,6 +6243,33 @@ const default_entry_addr = 0x8000000;
pub const base_tag: link.File.Tag = .elf;
const ComdatGroupKey = struct {
/// String table offset.
off: u32,
/// File index.
file_index: File.Index,
pub fn get(key: ComdatGroupKey, elf_file: *Elf) [:0]const u8 {
const file_ptr = elf_file.file(key.file_index).?;
return file_ptr.getString(key.off);
}
};
const ComdatGroupContext = struct {
elf_file: *Elf,
pub fn eql(ctx: ComdatGroupContext, a: ComdatGroupKey, b: ComdatGroupKey, b_index: usize) bool {
_ = b_index;
const elf_file = ctx.elf_file;
return mem.eql(u8, a.get(elf_file), b.get(elf_file));
}
pub fn hash(ctx: ComdatGroupContext, a: ComdatGroupKey) u32 {
return std.array_hash_map.hashString(a.get(ctx.elf_file));
}
};
const ComdatGroupOwner = struct {
file: File.Index = 0,

View File

@ -208,9 +208,9 @@ fn initAtoms(self: *Object, allocator: Allocator, handle: std.fs.File, elf_file:
const group_signature = blk: {
if (group_info_sym.st_name == 0 and group_info_sym.st_type() == elf.STT_SECTION) {
const sym_shdr = shdrs[group_info_sym.st_shndx];
break :blk self.getString(sym_shdr.sh_name);
break :blk sym_shdr.sh_name;
}
break :blk self.getString(group_info_sym.st_name);
break :blk group_info_sym.st_name;
};
const shndx = @as(u32, @intCast(i));
@ -228,7 +228,10 @@ fn initAtoms(self: *Object, allocator: Allocator, handle: std.fs.File, elf_file:
const group_start = @as(u32, @intCast(self.comdat_group_data.items.len));
try self.comdat_group_data.appendUnalignedSlice(allocator, group_members[1..]);
const gop = try elf_file.getOrCreateComdatGroupOwner(group_signature);
const gop = try elf_file.getOrCreateComdatGroupOwner(.{
.off = group_signature,
.file_index = self.index,
});
const comdat_group_index = try self.addComdatGroup(allocator);
const comdat_group = self.comdatGroup(comdat_group_index);
comdat_group.* = .{

View File

@ -157,6 +157,12 @@ pub const File = union(enum) {
};
}
pub fn getString(file: File, off: u32) [:0]const u8 {
return switch (file) {
inline else => |x| x.getString(off),
};
}
pub fn updateSymtabSize(file: File, elf_file: *Elf) !void {
return switch (file) {
inline else => |x| x.updateSymtabSize(elf_file),