Commit f1fedb3a51

Jakub Konka <kubkon@jakubkonka.com>
2024-07-24 10:15:09
elf: move ownership of comdat groups to Object
1 parent 733d250
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});
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 },
             };
         }
     }
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| {
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,