diff --git a/src/link/Elf.zig b/src/link/Elf.zig index 5c06ccc00c..0ee8edf379 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -219,7 +219,6 @@ merge_subsections: std.ArrayListUnmanaged(MergeSubsection) = .{}, /// Table of last atom index in a section and matching atom free list if any. last_atom_and_free_list_table: LastAtomAndFreeListTable = .{}, -comdat_groups: std.ArrayListUnmanaged(ComdatGroup) = .{}, comdat_groups_owners: std.ArrayListUnmanaged(ComdatGroupOwner) = .{}, comdat_groups_table: std.AutoHashMapUnmanaged(u32, ComdatGroupOwner.Index) = .{}, @@ -516,7 +515,6 @@ pub fn deinit(self: *Elf) void { } self.last_atom_and_free_list_table.deinit(gpa); - self.comdat_groups.deinit(gpa); self.comdat_groups_owners.deinit(gpa); self.comdat_groups_table.deinit(gpa); self.strings.deinit(gpa); @@ -1998,8 +1996,7 @@ pub fn resolveSymbols(self: *Elf) void { // Dedup comdat groups. for (self.objects.items) |index| { const object = self.file(index).?.object; - for (object.comdat_groups.items) |cg_index| { - const cg = self.comdatGroup(cg_index); + for (object.comdat_groups.items) |cg| { const cg_owner = self.comdatGroupOwner(cg.owner); const owner_file_index = if (self.file(cg_owner.file)) |file_ptr| file_ptr.object.index @@ -2011,8 +2008,7 @@ pub fn resolveSymbols(self: *Elf) void { for (self.objects.items) |index| { const object = self.file(index).?.object; - for (object.comdat_groups.items) |cg_index| { - const cg = self.comdatGroup(cg_index); + for (object.comdat_groups.items) |cg| { const cg_owner = self.comdatGroupOwner(cg.owner); if (cg_owner.file != index) { for (cg.comdatGroupMembers(self)) |shndx| { @@ -5822,18 +5818,6 @@ pub fn getOrCreateComdatGroupOwner(self: *Elf, name: [:0]const u8) !GetOrCreateC }; } -pub fn addComdatGroup(self: *Elf) !ComdatGroup.Index { - const gpa = self.base.comp.gpa; - const index = @as(ComdatGroup.Index, @intCast(self.comdat_groups.items.len)); - _ = try self.comdat_groups.addOne(gpa); - return index; -} - -pub fn comdatGroup(self: *Elf, index: ComdatGroup.Index) *ComdatGroup { - assert(index < self.comdat_groups.items.len); - return &self.comdat_groups.items[index]; -} - pub fn comdatGroupOwner(self: *Elf, index: ComdatGroupOwner.Index) *ComdatGroupOwner { assert(index < self.comdat_groups_owners.items.len); return &self.comdat_groups_owners.items[index]; @@ -6233,7 +6217,7 @@ fn fmtDumpState( try writer.writeAll("Output COMDAT groups\n"); for (self.comdat_group_sections.items) |cg| { - try writer.print(" shdr({d}) : COMDAT({d})\n", .{ cg.shndx, cg.cg_index }); + try writer.print(" shdr({d}) : COMDAT({})\n", .{ cg.shndx, cg.cg_ref }); } try writer.writeAll("\nOutput merge sections\n"); @@ -6376,6 +6360,22 @@ pub const SystemLib = struct { path: []const u8, }; +pub const Ref = struct { + index: u32, + file: u32, + + pub fn format( + ref: Ref, + comptime unused_fmt_string: []const u8, + options: std.fmt.FormatOptions, + writer: anytype, + ) !void { + _ = unused_fmt_string; + _ = options; + try writer.print("ref({},{})", .{ ref.index, ref.file }); + } +}; + const LastAtomAndFreeList = struct { /// Index of the last allocated atom in this section. last_atom_index: Atom.Index = 0, diff --git a/src/link/Elf/Object.zig b/src/link/Elf/Object.zig index 108abf32fb..c7f1186c4b 100644 --- a/src/link/Elf/Object.zig +++ b/src/link/Elf/Object.zig @@ -11,10 +11,11 @@ strtab: std.ArrayListUnmanaged(u8) = .{}, first_global: ?Symbol.Index = null, symbols: std.ArrayListUnmanaged(Symbol.Index) = .{}, atoms: std.ArrayListUnmanaged(Atom.Index) = .{}, -comdat_groups: std.ArrayListUnmanaged(Elf.ComdatGroup.Index) = .{}, -comdat_group_data: std.ArrayListUnmanaged(u32) = .{}, relocs: std.ArrayListUnmanaged(elf.Elf64_Rela) = .{}, +comdat_groups: std.ArrayListUnmanaged(Elf.ComdatGroup) = .{}, +comdat_group_data: std.ArrayListUnmanaged(u32) = .{}, + input_merge_sections: std.ArrayListUnmanaged(InputMergeSection) = .{}, input_merge_sections_indexes: std.ArrayListUnmanaged(InputMergeSection.Index) = .{}, @@ -218,8 +219,8 @@ fn initAtoms(self: *Object, allocator: Allocator, handle: std.fs.File, elf_file: try self.comdat_group_data.appendUnalignedSlice(allocator, group_members[1..]); const gop = try elf_file.getOrCreateComdatGroupOwner(group_signature); - const comdat_group_index = try elf_file.addComdatGroup(); - const comdat_group = elf_file.comdatGroup(comdat_group_index); + const comdat_group_index = try self.addComdatGroup(allocator); + const comdat_group = self.comdatGroup(comdat_group_index); comdat_group.* = .{ .owner = gop.index, .file = self.index, @@ -227,7 +228,6 @@ fn initAtoms(self: *Object, allocator: Allocator, handle: std.fs.File, elf_file: .members_start = group_start, .members_len = @intCast(group_nmembers - 1), }; - try self.comdat_groups.append(allocator, comdat_group_index); }, elf.SHT_SYMTAB_SHNDX => @panic("TODO SHT_SYMTAB_SHNDX"), @@ -1206,6 +1206,17 @@ fn inputMergeSection(self: *Object, index: InputMergeSection.Index) ?*InputMerge return &self.input_merge_sections.items[index]; } +fn addComdatGroup(self: *Object, allocator: Allocator) !Elf.ComdatGroup.Index { + const index = @as(Elf.ComdatGroup.Index, @intCast(self.comdat_groups.items.len)); + _ = try self.comdat_groups.addOne(allocator); + return index; +} + +pub fn comdatGroup(self: *Object, index: Elf.ComdatGroup.Index) *Elf.ComdatGroup { + assert(index < self.comdat_groups.items.len); + return &self.comdat_groups.items[index]; +} + pub fn format( self: *Object, comptime unused_fmt_string: []const u8, @@ -1337,8 +1348,7 @@ fn formatComdatGroups( const object = ctx.object; const elf_file = ctx.elf_file; try writer.writeAll(" COMDAT groups\n"); - for (object.comdat_groups.items) |cg_index| { - const cg = elf_file.comdatGroup(cg_index); + for (object.comdat_groups.items, 0..) |cg, cg_index| { const cg_owner = elf_file.comdatGroupOwner(cg.owner); if (cg_owner.file != object.index) continue; try writer.print(" COMDAT({d})\n", .{cg_index}); diff --git a/src/link/Elf/relocatable.zig b/src/link/Elf/relocatable.zig index 1bbb320c98..d967b089ba 100644 --- a/src/link/Elf/relocatable.zig +++ b/src/link/Elf/relocatable.zig @@ -319,8 +319,7 @@ fn initComdatGroups(elf_file: *Elf) !void { for (elf_file.objects.items) |index| { const object = elf_file.file(index).?.object; - for (object.comdat_groups.items) |cg_index| { - const cg = elf_file.comdatGroup(cg_index); + for (object.comdat_groups.items, 0..) |cg, cg_index| { const cg_owner = elf_file.comdatGroupOwner(cg.owner); if (cg_owner.file != index) continue; @@ -333,7 +332,7 @@ fn initComdatGroups(elf_file: *Elf) !void { .addralign = @alignOf(u32), .offset = std.math.maxInt(u64), }), - .cg_index = cg_index, + .cg_ref = .{ .index = @intCast(cg_index), .file = index }, }; } } diff --git a/src/link/Elf/synthetic_sections.zig b/src/link/Elf/synthetic_sections.zig index 5a96650bc5..c483cfd749 100644 --- a/src/link/Elf/synthetic_sections.zig +++ b/src/link/Elf/synthetic_sections.zig @@ -1670,30 +1670,35 @@ pub const VerneedSection = struct { pub const ComdatGroupSection = struct { shndx: u32, - cg_index: u32, + cg_ref: Elf.Ref, - fn file(cgs: ComdatGroupSection, elf_file: *Elf) ?File { - const cg = elf_file.comdatGroup(cgs.cg_index); + fn ownerFile(cgs: ComdatGroupSection, elf_file: *Elf) ?File { + const cg = cgs.comdatGroup(elf_file); const cg_owner = elf_file.comdatGroupOwner(cg.owner); return elf_file.file(cg_owner.file); } + fn comdatGroup(cgs: ComdatGroupSection, elf_file: *Elf) *Elf.ComdatGroup { + const cg_file = elf_file.file(cgs.cg_ref.file).?; + return cg_file.object.comdatGroup(cgs.cg_ref.index); + } + pub fn symbol(cgs: ComdatGroupSection, elf_file: *Elf) Symbol.Index { - const cg = elf_file.comdatGroup(cgs.cg_index); - const object = cgs.file(elf_file).?.object; + const cg = cgs.comdatGroup(elf_file); + const object = cgs.ownerFile(elf_file).?.object; const shdr = object.shdrs.items[cg.shndx]; return object.symbols.items[shdr.sh_info]; } pub fn size(cgs: ComdatGroupSection, elf_file: *Elf) usize { - const cg = elf_file.comdatGroup(cgs.cg_index); + const cg = cgs.comdatGroup(elf_file); const members = cg.comdatGroupMembers(elf_file); return (members.len + 1) * @sizeOf(u32); } pub fn write(cgs: ComdatGroupSection, elf_file: *Elf, writer: anytype) !void { - const cg = elf_file.comdatGroup(cgs.cg_index); - const object = cgs.file(elf_file).?.object; + const cg = cgs.comdatGroup(elf_file); + const object = cgs.ownerFile(elf_file).?.object; const members = cg.comdatGroupMembers(elf_file); try writer.writeInt(u32, elf.GRP_COMDAT, .little); for (members) |shndx| {