| ... | @@ -102,6 +102,9 @@ copy_rel: CopyRelSection = .{}, | ... | @@ -102,6 +102,9 @@ copy_rel: CopyRelSection = .{}, |
| 102 | rela_plt: std.ArrayListUnmanaged(elf.Elf64_Rela) = .{}, | 102 | rela_plt: std.ArrayListUnmanaged(elf.Elf64_Rela) = .{}, |
| 103 | /// .got.zig section | 103 | /// .got.zig section |
| 104 | zig_got: ZigGotSection = .{}, | 104 | zig_got: ZigGotSection = .{}, |
| | 105 | /// SHT_GROUP sections |
| | 106 | /// Applies only to a relocatable. |
| | 107 | comdat_group_sections: std.ArrayListUnmanaged(ComdatGroupSection) = .{}, |
| 105 | | 108 | |
| 106 | /// Tracked section headers with incremental updates to Zig object. | 109 | /// Tracked section headers with incremental updates to Zig object. |
| 107 | /// .rela.* sections are only used when emitting a relocatable object file. | 110 | /// .rela.* sections are only used when emitting a relocatable object file. |
| ... | @@ -394,6 +397,7 @@ pub fn deinit(self: *Elf) void { | ... | @@ -394,6 +397,7 @@ pub fn deinit(self: *Elf) void { |
| 394 | self.rela_dyn.deinit(gpa); | 397 | self.rela_dyn.deinit(gpa); |
| 395 | self.rela_plt.deinit(gpa); | 398 | self.rela_plt.deinit(gpa); |
| 396 | self.zig_got.deinit(gpa); | 399 | self.zig_got.deinit(gpa); |
| | 400 | self.comdat_group_sections.deinit(gpa); |
| 397 | } | 401 | } |
| 398 | | 402 | |
| 399 | pub fn getDeclVAddr(self: *Elf, decl_index: Module.Decl.Index, reloc_info: link.File.RelocInfo) !u64 { | 403 | pub fn getDeclVAddr(self: *Elf, decl_index: Module.Decl.Index, reloc_info: link.File.RelocInfo) !u64 { |
| ... | @@ -3585,10 +3589,35 @@ fn initSectionsObject(self: *Elf) !void { | ... | @@ -3585,10 +3589,35 @@ fn initSectionsObject(self: *Elf) !void { |
| 3585 | self.eh_frame_rela_section_index = try self.addRelaShdr(".rela.eh_frame", self.eh_frame_section_index.?); | 3589 | self.eh_frame_rela_section_index = try self.addRelaShdr(".rela.eh_frame", self.eh_frame_section_index.?); |
| 3586 | } | 3590 | } |
| 3587 | | 3591 | |
| | 3592 | try self.initComdatGroups(); |
| 3588 | try self.initSymtab(); | 3593 | try self.initSymtab(); |
| 3589 | try self.initShStrtab(); | 3594 | try self.initShStrtab(); |
| 3590 | } | 3595 | } |
| 3591 | | 3596 | |
| | 3597 | fn 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 | |
| 3592 | fn initSymtab(self: *Elf) !void { | 3621 | fn initSymtab(self: *Elf) !void { |
| 3593 | const small_ptr = switch (self.ptr_width) { | 3622 | const small_ptr = switch (self.ptr_width) { |
| 3594 | .p32 => true, | 3623 | .p32 => true, |
| ... | @@ -3892,7 +3921,7 @@ fn shdrRank(self: *Elf, shndx: u16) u8 { | ... | @@ -3892,7 +3921,7 @@ fn shdrRank(self: *Elf, shndx: u16) u8 { |
| 3892 | | 3921 | |
| 3893 | elf.SHT_DYNAMIC => return 0xf3, | 3922 | elf.SHT_DYNAMIC => return 0xf3, |
| 3894 | | 3923 | |
| 3895 | elf.SHT_RELA => return 0xf, | 3924 | elf.SHT_RELA, elf.SHT_GROUP => return 0xf, |
| 3896 | | 3925 | |
| 3897 | elf.SHT_PROGBITS => if (flags & elf.SHF_ALLOC != 0) { | 3926 | elf.SHT_PROGBITS => if (flags & elf.SHF_ALLOC != 0) { |
| 3898 | if (flags & elf.SHF_EXECINSTR != 0) { | 3927 | if (flags & elf.SHF_EXECINSTR != 0) { |
| ... | @@ -4131,6 +4160,10 @@ fn resetShdrIndexes(self: *Elf, backlinks: []const u16) !void { | ... | @@ -4131,6 +4160,10 @@ fn resetShdrIndexes(self: *Elf, backlinks: []const u16) !void { |
| 4131 | shdr.sh_link = self.symtab_section_index.?; | 4160 | shdr.sh_link = self.symtab_section_index.?; |
| 4132 | shdr.sh_info = shndx; | 4161 | shdr.sh_info = shndx; |
| 4133 | } | 4162 | } |
| | 4163 | |
| | 4164 | for (self.comdat_group_sections.items) |*cg| { |
| | 4165 | cg.shndx = backlinks[cg.shndx]; |
| | 4166 | } |
| 4134 | } | 4167 | } |
| 4135 | | 4168 | |
| 4136 | fn updateSectionSizes(self: *Elf) !void { | 4169 | fn updateSectionSizes(self: *Elf) !void { |
| ... | @@ -4260,10 +4293,15 @@ fn updateSectionSizesObject(self: *Elf) !void { | ... | @@ -4260,10 +4293,15 @@ fn updateSectionSizesObject(self: *Elf) !void { |
| 4260 | shdr.sh_size = eh_frame.calcEhFrameRelocs(self) * shdr.sh_entsize; | 4293 | shdr.sh_size = eh_frame.calcEhFrameRelocs(self) * shdr.sh_entsize; |
| 4261 | } | 4294 | } |
| 4262 | | 4295 | |
| | 4296 | self.updateComdatGroupsSizes(); |
| 4263 | try self.updateSymtabSize(); | 4297 | try self.updateSymtabSize(); |
| 4264 | self.updateShStrtabSize(); | 4298 | self.updateShStrtabSize(); |
| 4265 | } | 4299 | } |
| 4266 | | 4300 | |
| | 4301 | fn updateComdatGroupsSizes(self: *Elf) void { |
| | 4302 | _ = self; |
| | 4303 | } |
| | 4304 | |
| 4267 | fn updateShStrtabSize(self: *Elf) void { | 4305 | fn updateShStrtabSize(self: *Elf) void { |
| 4268 | if (self.shstrtab_section_index) |index| { | 4306 | if (self.shstrtab_section_index) |index| { |
| 4269 | self.shdrs.items[index].sh_size = self.shstrtab.items.len; | 4307 | self.shdrs.items[index].sh_size = self.shstrtab.items.len; |
| ... | @@ -6168,7 +6206,12 @@ fn fmtDumpState( | ... | @@ -6168,7 +6206,12 @@ fn fmtDumpState( |
| 6168 | try writer.print("{}\n", .{self.got.fmt(self)}); | 6206 | try writer.print("{}\n", .{self.got.fmt(self)}); |
| 6169 | try writer.print("{}\n", .{self.zig_got.fmt(self)}); | 6207 | try writer.print("{}\n", .{self.zig_got.fmt(self)}); |
| 6170 | | 6208 | |
| 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"); |
| 6172 | for (self.shdrs.items, 0..) |shdr, shndx| { | 6215 | for (self.shdrs.items, 0..) |shdr, shndx| { |
| 6173 | try writer.print("shdr({d}) : phdr({?d}) : {}\n", .{ | 6216 | try writer.print("shdr({d}) : phdr({?d}) : {}\n", .{ |
| 6174 | shndx, | 6217 | shndx, |
| ... | @@ -6332,6 +6375,7 @@ const Archive = @import("Elf/Archive.zig"); | ... | @@ -6332,6 +6375,7 @@ const Archive = @import("Elf/Archive.zig"); |
| 6332 | pub const Atom = @import("Elf/Atom.zig"); | 6375 | pub const Atom = @import("Elf/Atom.zig"); |
| 6333 | const Cache = std.Build.Cache; | 6376 | const Cache = std.Build.Cache; |
| 6334 | const Compilation = @import("../Compilation.zig"); | 6377 | const Compilation = @import("../Compilation.zig"); |
| | 6378 | const ComdatGroupSection = synthetic_sections.ComdatGroupSection; |
| 6335 | const CopyRelSection = synthetic_sections.CopyRelSection; | 6379 | const CopyRelSection = synthetic_sections.CopyRelSection; |
| 6336 | const DynamicSection = synthetic_sections.DynamicSection; | 6380 | const DynamicSection = synthetic_sections.DynamicSection; |
| 6337 | const DynsymSection = synthetic_sections.DynsymSection; | 6381 | const DynsymSection = synthetic_sections.DynsymSection; |