authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-07-24 10:15:09+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-07-30 10:00:50+02:00
logf1fedb3a51d4d9a37e4568ce1a80149bb5a610f7
tree4e0b3d7182b829eae539738d27e29bf8727cda5c
parent733d25000bcb50104253d879734c89abde5e33b5

elf: move ownership of comdat groups to Object


4 files changed, 51 insertions(+), 37 deletions(-)

src/link/Elf.zig+19-19
...@@ -219,7 +219,6 @@ merge_subsections: std.ArrayListUnmanaged(MergeSubsection) = .{},...@@ -219,7 +219,6 @@ merge_subsections: std.ArrayListUnmanaged(MergeSubsection) = .{},
219/// Table of last atom index in a section and matching atom free list if any.219/// Table of last atom index in a section and matching atom free list if any.
220last_atom_and_free_list_table: LastAtomAndFreeListTable = .{},220last_atom_and_free_list_table: LastAtomAndFreeListTable = .{},
221221
222comdat_groups: std.ArrayListUnmanaged(ComdatGroup) = .{},
223comdat_groups_owners: std.ArrayListUnmanaged(ComdatGroupOwner) = .{},222comdat_groups_owners: std.ArrayListUnmanaged(ComdatGroupOwner) = .{},
224comdat_groups_table: std.AutoHashMapUnmanaged(u32, ComdatGroupOwner.Index) = .{},223comdat_groups_table: std.AutoHashMapUnmanaged(u32, ComdatGroupOwner.Index) = .{},
225224
...@@ -516,7 +515,6 @@ pub fn deinit(self: *Elf) void {...@@ -516,7 +515,6 @@ pub fn deinit(self: *Elf) void {
516 }515 }
517 self.last_atom_and_free_list_table.deinit(gpa);516 self.last_atom_and_free_list_table.deinit(gpa);
518517
519 self.comdat_groups.deinit(gpa);
520 self.comdat_groups_owners.deinit(gpa);518 self.comdat_groups_owners.deinit(gpa);
521 self.comdat_groups_table.deinit(gpa);519 self.comdat_groups_table.deinit(gpa);
522 self.strings.deinit(gpa);520 self.strings.deinit(gpa);
...@@ -1998,8 +1996,7 @@ pub fn resolveSymbols(self: *Elf) void {...@@ -1998,8 +1996,7 @@ pub fn resolveSymbols(self: *Elf) void {
1998 // Dedup comdat groups.1996 // Dedup comdat groups.
1999 for (self.objects.items) |index| {1997 for (self.objects.items) |index| {
2000 const object = self.file(index).?.object;1998 const object = self.file(index).?.object;
2001 for (object.comdat_groups.items) |cg_index| {1999 for (object.comdat_groups.items) |cg| {
2002 const cg = self.comdatGroup(cg_index);
2003 const cg_owner = self.comdatGroupOwner(cg.owner);2000 const cg_owner = self.comdatGroupOwner(cg.owner);
2004 const owner_file_index = if (self.file(cg_owner.file)) |file_ptr|2001 const owner_file_index = if (self.file(cg_owner.file)) |file_ptr|
2005 file_ptr.object.index2002 file_ptr.object.index
...@@ -2011,8 +2008,7 @@ pub fn resolveSymbols(self: *Elf) void {...@@ -2011,8 +2008,7 @@ pub fn resolveSymbols(self: *Elf) void {
20112008
2012 for (self.objects.items) |index| {2009 for (self.objects.items) |index| {
2013 const object = self.file(index).?.object;2010 const object = self.file(index).?.object;
2014 for (object.comdat_groups.items) |cg_index| {2011 for (object.comdat_groups.items) |cg| {
2015 const cg = self.comdatGroup(cg_index);
2016 const cg_owner = self.comdatGroupOwner(cg.owner);2012 const cg_owner = self.comdatGroupOwner(cg.owner);
2017 if (cg_owner.file != index) {2013 if (cg_owner.file != index) {
2018 for (cg.comdatGroupMembers(self)) |shndx| {2014 for (cg.comdatGroupMembers(self)) |shndx| {
...@@ -5822,18 +5818,6 @@ pub fn getOrCreateComdatGroupOwner(self: *Elf, name: [:0]const u8) !GetOrCreateC...@@ -5822,18 +5818,6 @@ pub fn getOrCreateComdatGroupOwner(self: *Elf, name: [:0]const u8) !GetOrCreateC
5822 };5818 };
5823}5819}
58245820
5825pub fn addComdatGroup(self: *Elf) !ComdatGroup.Index {
5826 const gpa = self.base.comp.gpa;
5827 const index = @as(ComdatGroup.Index, @intCast(self.comdat_groups.items.len));
5828 _ = try self.comdat_groups.addOne(gpa);
5829 return index;
5830}
5831
5832pub fn comdatGroup(self: *Elf, index: ComdatGroup.Index) *ComdatGroup {
5833 assert(index < self.comdat_groups.items.len);
5834 return &self.comdat_groups.items[index];
5835}
5836
5837pub fn comdatGroupOwner(self: *Elf, index: ComdatGroupOwner.Index) *ComdatGroupOwner {5821pub fn comdatGroupOwner(self: *Elf, index: ComdatGroupOwner.Index) *ComdatGroupOwner {
5838 assert(index < self.comdat_groups_owners.items.len);5822 assert(index < self.comdat_groups_owners.items.len);
5839 return &self.comdat_groups_owners.items[index];5823 return &self.comdat_groups_owners.items[index];
...@@ -6233,7 +6217,7 @@ fn fmtDumpState(...@@ -6233,7 +6217,7 @@ fn fmtDumpState(
62336217
6234 try writer.writeAll("Output COMDAT groups\n");6218 try writer.writeAll("Output COMDAT groups\n");
6235 for (self.comdat_group_sections.items) |cg| {6219 for (self.comdat_group_sections.items) |cg| {
6236 try writer.print(" shdr({d}) : COMDAT({d})\n", .{ cg.shndx, cg.cg_index });6220 try writer.print(" shdr({d}) : COMDAT({})\n", .{ cg.shndx, cg.cg_ref });
6237 }6221 }
62386222
6239 try writer.writeAll("\nOutput merge sections\n");6223 try writer.writeAll("\nOutput merge sections\n");
...@@ -6376,6 +6360,22 @@ pub const SystemLib = struct {...@@ -6376,6 +6360,22 @@ pub const SystemLib = struct {
6376 path: []const u8,6360 path: []const u8,
6377};6361};
63786362
6363pub const Ref = struct {
6364 index: u32,
6365 file: u32,
6366
6367 pub fn format(
6368 ref: Ref,
6369 comptime unused_fmt_string: []const u8,
6370 options: std.fmt.FormatOptions,
6371 writer: anytype,
6372 ) !void {
6373 _ = unused_fmt_string;
6374 _ = options;
6375 try writer.print("ref({},{})", .{ ref.index, ref.file });
6376 }
6377};
6378
6379const LastAtomAndFreeList = struct {6379const LastAtomAndFreeList = struct {
6380 /// Index of the last allocated atom in this section.6380 /// Index of the last allocated atom in this section.
6381 last_atom_index: Atom.Index = 0,6381 last_atom_index: Atom.Index = 0,
src/link/Elf/Object.zig+17-7
...@@ -11,10 +11,11 @@ strtab: std.ArrayListUnmanaged(u8) = .{},...@@ -11,10 +11,11 @@ strtab: std.ArrayListUnmanaged(u8) = .{},
11first_global: ?Symbol.Index = null,11first_global: ?Symbol.Index = null,
12symbols: std.ArrayListUnmanaged(Symbol.Index) = .{},12symbols: std.ArrayListUnmanaged(Symbol.Index) = .{},
13atoms: std.ArrayListUnmanaged(Atom.Index) = .{},13atoms: std.ArrayListUnmanaged(Atom.Index) = .{},
14comdat_groups: std.ArrayListUnmanaged(Elf.ComdatGroup.Index) = .{},
15comdat_group_data: std.ArrayListUnmanaged(u32) = .{},
16relocs: std.ArrayListUnmanaged(elf.Elf64_Rela) = .{},14relocs: std.ArrayListUnmanaged(elf.Elf64_Rela) = .{},
1715
16comdat_groups: std.ArrayListUnmanaged(Elf.ComdatGroup) = .{},
17comdat_group_data: std.ArrayListUnmanaged(u32) = .{},
18
18input_merge_sections: std.ArrayListUnmanaged(InputMergeSection) = .{},19input_merge_sections: std.ArrayListUnmanaged(InputMergeSection) = .{},
19input_merge_sections_indexes: std.ArrayListUnmanaged(InputMergeSection.Index) = .{},20input_merge_sections_indexes: std.ArrayListUnmanaged(InputMergeSection.Index) = .{},
2021
...@@ -218,8 +219,8 @@ fn initAtoms(self: *Object, allocator: Allocator, handle: std.fs.File, elf_file:...@@ -218,8 +219,8 @@ fn initAtoms(self: *Object, allocator: Allocator, handle: std.fs.File, elf_file:
218 try self.comdat_group_data.appendUnalignedSlice(allocator, group_members[1..]);219 try self.comdat_group_data.appendUnalignedSlice(allocator, group_members[1..]);
219220
220 const gop = try elf_file.getOrCreateComdatGroupOwner(group_signature);221 const gop = try elf_file.getOrCreateComdatGroupOwner(group_signature);
221 const comdat_group_index = try elf_file.addComdatGroup();222 const comdat_group_index = try self.addComdatGroup(allocator);
222 const comdat_group = elf_file.comdatGroup(comdat_group_index);223 const comdat_group = self.comdatGroup(comdat_group_index);
223 comdat_group.* = .{224 comdat_group.* = .{
224 .owner = gop.index,225 .owner = gop.index,
225 .file = self.index,226 .file = self.index,
...@@ -227,7 +228,6 @@ fn initAtoms(self: *Object, allocator: Allocator, handle: std.fs.File, elf_file:...@@ -227,7 +228,6 @@ fn initAtoms(self: *Object, allocator: Allocator, handle: std.fs.File, elf_file:
227 .members_start = group_start,228 .members_start = group_start,
228 .members_len = @intCast(group_nmembers - 1),229 .members_len = @intCast(group_nmembers - 1),
229 };230 };
230 try self.comdat_groups.append(allocator, comdat_group_index);
231 },231 },
232232
233 elf.SHT_SYMTAB_SHNDX => @panic("TODO SHT_SYMTAB_SHNDX"),233 elf.SHT_SYMTAB_SHNDX => @panic("TODO SHT_SYMTAB_SHNDX"),
...@@ -1206,6 +1206,17 @@ fn inputMergeSection(self: *Object, index: InputMergeSection.Index) ?*InputMerge...@@ -1206,6 +1206,17 @@ fn inputMergeSection(self: *Object, index: InputMergeSection.Index) ?*InputMerge
1206 return &self.input_merge_sections.items[index];1206 return &self.input_merge_sections.items[index];
1207}1207}
12081208
1209fn addComdatGroup(self: *Object, allocator: Allocator) !Elf.ComdatGroup.Index {
1210 const index = @as(Elf.ComdatGroup.Index, @intCast(self.comdat_groups.items.len));
1211 _ = try self.comdat_groups.addOne(allocator);
1212 return index;
1213}
1214
1215pub fn comdatGroup(self: *Object, index: Elf.ComdatGroup.Index) *Elf.ComdatGroup {
1216 assert(index < self.comdat_groups.items.len);
1217 return &self.comdat_groups.items[index];
1218}
1219
1209pub fn format(1220pub fn format(
1210 self: *Object,1221 self: *Object,
1211 comptime unused_fmt_string: []const u8,1222 comptime unused_fmt_string: []const u8,
...@@ -1337,8 +1348,7 @@ fn formatComdatGroups(...@@ -1337,8 +1348,7 @@ fn formatComdatGroups(
1337 const object = ctx.object;1348 const object = ctx.object;
1338 const elf_file = ctx.elf_file;1349 const elf_file = ctx.elf_file;
1339 try writer.writeAll(" COMDAT groups\n");1350 try writer.writeAll(" COMDAT groups\n");
1340 for (object.comdat_groups.items) |cg_index| {1351 for (object.comdat_groups.items, 0..) |cg, cg_index| {
1341 const cg = elf_file.comdatGroup(cg_index);
1342 const cg_owner = elf_file.comdatGroupOwner(cg.owner);1352 const cg_owner = elf_file.comdatGroupOwner(cg.owner);
1343 if (cg_owner.file != object.index) continue;1353 if (cg_owner.file != object.index) continue;
1344 try writer.print(" COMDAT({d})\n", .{cg_index});1354 try writer.print(" COMDAT({d})\n", .{cg_index});
src/link/Elf/relocatable.zig+2-3
...@@ -319,8 +319,7 @@ fn initComdatGroups(elf_file: *Elf) !void {...@@ -319,8 +319,7 @@ fn initComdatGroups(elf_file: *Elf) !void {
319 for (elf_file.objects.items) |index| {319 for (elf_file.objects.items) |index| {
320 const object = elf_file.file(index).?.object;320 const object = elf_file.file(index).?.object;
321321
322 for (object.comdat_groups.items) |cg_index| {322 for (object.comdat_groups.items, 0..) |cg, cg_index| {
323 const cg = elf_file.comdatGroup(cg_index);
324 const cg_owner = elf_file.comdatGroupOwner(cg.owner);323 const cg_owner = elf_file.comdatGroupOwner(cg.owner);
325 if (cg_owner.file != index) continue;324 if (cg_owner.file != index) continue;
326325
...@@ -333,7 +332,7 @@ fn initComdatGroups(elf_file: *Elf) !void {...@@ -333,7 +332,7 @@ fn initComdatGroups(elf_file: *Elf) !void {
333 .addralign = @alignOf(u32),332 .addralign = @alignOf(u32),
334 .offset = std.math.maxInt(u64),333 .offset = std.math.maxInt(u64),
335 }),334 }),
336 .cg_index = cg_index,335 .cg_ref = .{ .index = @intCast(cg_index), .file = index },
337 };336 };
338 }337 }
339 }338 }
src/link/Elf/synthetic_sections.zig+13-8
...@@ -1670,30 +1670,35 @@ pub const VerneedSection = struct {...@@ -1670,30 +1670,35 @@ pub const VerneedSection = struct {
16701670
1671pub const ComdatGroupSection = struct {1671pub const ComdatGroupSection = struct {
1672 shndx: u32,1672 shndx: u32,
1673 cg_index: u32,1673 cg_ref: Elf.Ref,
16741674
1675 fn file(cgs: ComdatGroupSection, elf_file: *Elf) ?File {1675 fn ownerFile(cgs: ComdatGroupSection, elf_file: *Elf) ?File {
1676 const cg = elf_file.comdatGroup(cgs.cg_index);1676 const cg = cgs.comdatGroup(elf_file);
1677 const cg_owner = elf_file.comdatGroupOwner(cg.owner);1677 const cg_owner = elf_file.comdatGroupOwner(cg.owner);
1678 return elf_file.file(cg_owner.file);1678 return elf_file.file(cg_owner.file);
1679 }1679 }
16801680
1681 fn comdatGroup(cgs: ComdatGroupSection, elf_file: *Elf) *Elf.ComdatGroup {
1682 const cg_file = elf_file.file(cgs.cg_ref.file).?;
1683 return cg_file.object.comdatGroup(cgs.cg_ref.index);
1684 }
1685
1681 pub fn symbol(cgs: ComdatGroupSection, elf_file: *Elf) Symbol.Index {1686 pub fn symbol(cgs: ComdatGroupSection, elf_file: *Elf) Symbol.Index {
1682 const cg = elf_file.comdatGroup(cgs.cg_index);1687 const cg = cgs.comdatGroup(elf_file);
1683 const object = cgs.file(elf_file).?.object;1688 const object = cgs.ownerFile(elf_file).?.object;
1684 const shdr = object.shdrs.items[cg.shndx];1689 const shdr = object.shdrs.items[cg.shndx];
1685 return object.symbols.items[shdr.sh_info];1690 return object.symbols.items[shdr.sh_info];
1686 }1691 }
16871692
1688 pub fn size(cgs: ComdatGroupSection, elf_file: *Elf) usize {1693 pub fn size(cgs: ComdatGroupSection, elf_file: *Elf) usize {
1689 const cg = elf_file.comdatGroup(cgs.cg_index);1694 const cg = cgs.comdatGroup(elf_file);
1690 const members = cg.comdatGroupMembers(elf_file);1695 const members = cg.comdatGroupMembers(elf_file);
1691 return (members.len + 1) * @sizeOf(u32);1696 return (members.len + 1) * @sizeOf(u32);
1692 }1697 }
16931698
1694 pub fn write(cgs: ComdatGroupSection, elf_file: *Elf, writer: anytype) !void {1699 pub fn write(cgs: ComdatGroupSection, elf_file: *Elf, writer: anytype) !void {
1695 const cg = elf_file.comdatGroup(cgs.cg_index);1700 const cg = cgs.comdatGroup(elf_file);
1696 const object = cgs.file(elf_file).?.object;1701 const object = cgs.ownerFile(elf_file).?.object;
1697 const members = cg.comdatGroupMembers(elf_file);1702 const members = cg.comdatGroupMembers(elf_file);
1698 try writer.writeInt(u32, elf.GRP_COMDAT, .little);1703 try writer.writeInt(u32, elf.GRP_COMDAT, .little);
1699 for (members) |shndx| {1704 for (members) |shndx| {