authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-11-09 17:41:14+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-11-09 17:41:14+01:00
logacd7cbf0b51dbc8039387de285e2b391a78f59ae
treeff25ff13f548d88379c42ed7d645b159713c4dc3
parent031d9faf022eb58c688033148f5a1fa145c6d84c

elf: init output COMDAT group sections


4 files changed, 76 insertions(+), 5 deletions(-)

lib/std/elf.zig+2
......@@ -1664,6 +1664,8 @@ pub const EM = enum(u16) {
16641664 }
16651665};
16661666
1667pub const GRP_COMDAT = 1;
1668
16671669/// Section data should be writable during execution.
16681670pub const SHF_WRITE = 0x1;
16691671
src/link/Elf.zig+46-2
......@@ -102,6 +102,9 @@ copy_rel: CopyRelSection = .{},
102102rela_plt: std.ArrayListUnmanaged(elf.Elf64_Rela) = .{},
103103/// .got.zig section
104104zig_got: ZigGotSection = .{},
105/// SHT_GROUP sections
106/// Applies only to a relocatable.
107comdat_group_sections: std.ArrayListUnmanaged(ComdatGroupSection) = .{},
105108
106109/// Tracked section headers with incremental updates to Zig object.
107110/// .rela.* sections are only used when emitting a relocatable object file.
......@@ -394,6 +397,7 @@ pub fn deinit(self: *Elf) void {
394397 self.rela_dyn.deinit(gpa);
395398 self.rela_plt.deinit(gpa);
396399 self.zig_got.deinit(gpa);
400 self.comdat_group_sections.deinit(gpa);
397401}
398402
399403pub fn getDeclVAddr(self: *Elf, decl_index: Module.Decl.Index, reloc_info: link.File.RelocInfo) !u64 {
......@@ -3585,10 +3589,35 @@ fn initSectionsObject(self: *Elf) !void {
35853589 self.eh_frame_rela_section_index = try self.addRelaShdr(".rela.eh_frame", self.eh_frame_section_index.?);
35863590 }
35873591
3592 try self.initComdatGroups();
35883593 try self.initSymtab();
35893594 try self.initShStrtab();
35903595}
35913596
3597fn initComdatGroups(self: *Elf) !void {
3598 const gpa = self.base.allocator;
3599
3600 for (self.objects.items) |index| {
3601 const object = self.file(index).?.object;
3602
3603 for (object.comdat_groups.items) |cg_index| {
3604 const cg = self.comdatGroup(cg_index);
3605 const cg_owner = self.comdatGroupOwner(cg.owner);
3606 if (cg_owner.file != index) continue;
3607
3608 const cg_sec = try self.comdat_group_sections.addOne(gpa);
3609 cg_sec.* = .{
3610 .shndx = try self.addSection(.{
3611 .name = ".group",
3612 .type = elf.SHT_GROUP,
3613 .entsize = @sizeOf(u32),
3614 }),
3615 .cg_index = cg_index,
3616 };
3617 }
3618 }
3619}
3620
35923621fn initSymtab(self: *Elf) !void {
35933622 const small_ptr = switch (self.ptr_width) {
35943623 .p32 => true,
......@@ -3892,7 +3921,7 @@ fn shdrRank(self: *Elf, shndx: u16) u8 {
38923921
38933922 elf.SHT_DYNAMIC => return 0xf3,
38943923
3895 elf.SHT_RELA => return 0xf,
3924 elf.SHT_RELA, elf.SHT_GROUP => return 0xf,
38963925
38973926 elf.SHT_PROGBITS => if (flags & elf.SHF_ALLOC != 0) {
38983927 if (flags & elf.SHF_EXECINSTR != 0) {
......@@ -4131,6 +4160,10 @@ fn resetShdrIndexes(self: *Elf, backlinks: []const u16) !void {
41314160 shdr.sh_link = self.symtab_section_index.?;
41324161 shdr.sh_info = shndx;
41334162 }
4163
4164 for (self.comdat_group_sections.items) |*cg| {
4165 cg.shndx = backlinks[cg.shndx];
4166 }
41344167}
41354168
41364169fn updateSectionSizes(self: *Elf) !void {
......@@ -4260,10 +4293,15 @@ fn updateSectionSizesObject(self: *Elf) !void {
42604293 shdr.sh_size = eh_frame.calcEhFrameRelocs(self) * shdr.sh_entsize;
42614294 }
42624295
4296 self.updateComdatGroupsSizes();
42634297 try self.updateSymtabSize();
42644298 self.updateShStrtabSize();
42654299}
42664300
4301fn updateComdatGroupsSizes(self: *Elf) void {
4302 _ = self;
4303}
4304
42674305fn updateShStrtabSize(self: *Elf) void {
42684306 if (self.shstrtab_section_index) |index| {
42694307 self.shdrs.items[index].sh_size = self.shstrtab.items.len;
......@@ -6168,7 +6206,12 @@ fn fmtDumpState(
61686206 try writer.print("{}\n", .{self.got.fmt(self)});
61696207 try writer.print("{}\n", .{self.zig_got.fmt(self)});
61706208
6171 try writer.writeAll("Output shdrs\n");
6209 try writer.writeAll("Output COMDAT groups\n");
6210 for (self.comdat_group_sections.items) |cg| {
6211 try writer.print("shdr({d}) : COMDAT({d})\n", .{ cg.shndx, cg.cg_index });
6212 }
6213
6214 try writer.writeAll("\nOutput shdrs\n");
61726215 for (self.shdrs.items, 0..) |shdr, shndx| {
61736216 try writer.print("shdr({d}) : phdr({?d}) : {}\n", .{
61746217 shndx,
......@@ -6332,6 +6375,7 @@ const Archive = @import("Elf/Archive.zig");
63326375pub const Atom = @import("Elf/Atom.zig");
63336376const Cache = std.Build.Cache;
63346377const Compilation = @import("../Compilation.zig");
6378const ComdatGroupSection = synthetic_sections.ComdatGroupSection;
63356379const CopyRelSection = synthetic_sections.CopyRelSection;
63366380const DynamicSection = synthetic_sections.DynamicSection;
63376381const DynsymSection = synthetic_sections.DynsymSection;
src/link/Elf/Object.zig+4-3
......@@ -142,7 +142,7 @@ fn initAtoms(self: *Object, elf_file: *Elf) !void {
142142 const group_nmembers = @divExact(group_raw_data.len, @sizeOf(u32));
143143 const group_members = @as([*]align(1) const u32, @ptrCast(group_raw_data.ptr))[0..group_nmembers];
144144
145 if (group_members[0] != 0x1) { // GRP_COMDAT
145 if (group_members[0] != elf.GRP_COMDAT) {
146146 // TODO convert into an error
147147 log.debug("{}: unknown SHT_GROUP format", .{self.fmtPath()});
148148 continue;
......@@ -939,16 +939,17 @@ fn formatComdatGroups(
939939 _ = options;
940940 const object = ctx.object;
941941 const elf_file = ctx.elf_file;
942 try writer.writeAll(" comdat groups\n");
942 try writer.writeAll(" COMDAT groups\n");
943943 for (object.comdat_groups.items) |cg_index| {
944944 const cg = elf_file.comdatGroup(cg_index);
945945 const cg_owner = elf_file.comdatGroupOwner(cg.owner);
946946 if (cg_owner.file != object.index) continue;
947 try writer.print(" COMDAT({d})\n", .{cg_index});
947948 const cg_members = object.comdatGroupMembers(cg.shndx);
948949 for (cg_members) |shndx| {
949950 const atom_index = object.atoms.items[shndx];
950951 const atom = elf_file.atom(atom_index) orelse continue;
951 try writer.print(" atom({d}) : {s}\n", .{ atom_index, atom.name(elf_file) });
952 try writer.print(" atom({d}) : {s}\n", .{ atom_index, atom.name(elf_file) });
952953 }
953954 }
954955}
src/link/Elf/synthetic_sections.zig+24
......@@ -1499,6 +1499,30 @@ pub const VerneedSection = struct {
14991499 }
15001500};
15011501
1502pub const ComdatGroupSection = struct {
1503 shndx: u32,
1504 cg_index: u32,
1505
1506 // pub fn size(cg: ComdatGroupSection) usize {
1507 // return cg.members.items.len + 1;
1508 // }
1509
1510 // pub fn write(cg: ComdatGroupSection, elf_file: *Elf, writer: anytype) !void {
1511 // try writeInt(@as(u32, elf.GRP_COMDAT), elf_file, writer);
1512 // for (cg.members.items) |atom_index| {
1513 // const atom = elf_file.atom(atom_index);
1514 // const input_shdr = atom.inputShdr(elf_file);
1515 // switch (input_shdr.sh_type) {
1516 // elf.SHT_RELA => {
1517
1518 // },
1519 // else => {},
1520 // }
1521 // }
1522 // try writer.writeAll(mem.sliceAsBytes(cg.members.items));
1523 // }
1524};
1525
15021526fn writeInt(value: anytype, elf_file: *Elf, writer: anytype) !void {
15031527 const entry_size = elf_file.archPtrWidthBytes();
15041528 const endian = elf_file.base.options.target.cpu.arch.endian();