| ... | @@ -24,6 +24,7 @@ shdr_table_offset: ?u64 = null, | ... | @@ -24,6 +24,7 @@ shdr_table_offset: ?u64 = null, |
| 24 | /// Table of lists of atoms per output section. | 24 | /// Table of lists of atoms per output section. |
| 25 | /// This table is not used to track incrementally generated atoms. | 25 | /// This table is not used to track incrementally generated atoms. |
| 26 | output_sections: std.AutoArrayHashMapUnmanaged(u16, std.ArrayListUnmanaged(Atom.Index)) = .{}, | 26 | output_sections: std.AutoArrayHashMapUnmanaged(u16, std.ArrayListUnmanaged(Atom.Index)) = .{}, |
| | 27 | output_rela_sections: std.AutoArrayHashMapUnmanaged(u16, std.ArrayListUnmanaged(Atom.Index)) = .{}, |
| 27 | | 28 | |
| 28 | /// Stored in native-endian format, depending on target endianness needs to be bswapped on read/write. | 29 | /// Stored in native-endian format, depending on target endianness needs to be bswapped on read/write. |
| 29 | /// Same order as in the file. | 30 | /// Same order as in the file. |
| ... | @@ -105,11 +106,8 @@ zig_got: ZigGotSection = .{}, | ... | @@ -105,11 +106,8 @@ zig_got: ZigGotSection = .{}, |
| 105 | /// Tracked section headers with incremental updates to Zig object. | 106 | /// Tracked section headers with incremental updates to Zig object. |
| 106 | /// .rela.* sections are only used when emitting a relocatable object file. | 107 | /// .rela.* sections are only used when emitting a relocatable object file. |
| 107 | zig_text_section_index: ?u16 = null, | 108 | zig_text_section_index: ?u16 = null, |
| 108 | zig_text_rela_section_index: ?u16 = null, | | |
| 109 | zig_data_rel_ro_section_index: ?u16 = null, | 109 | zig_data_rel_ro_section_index: ?u16 = null, |
| 110 | zig_data_rel_ro_rela_section_index: ?u16 = null, | | |
| 111 | zig_data_section_index: ?u16 = null, | 110 | zig_data_section_index: ?u16 = null, |
| 112 | zig_data_rela_section_index: ?u16 = null, | | |
| 113 | zig_bss_section_index: ?u16 = null, | 111 | zig_bss_section_index: ?u16 = null, |
| 114 | zig_got_section_index: ?u16 = null, | 112 | zig_got_section_index: ?u16 = null, |
| 115 | | 113 | |
| ... | @@ -357,6 +355,10 @@ pub fn deinit(self: *Elf) void { | ... | @@ -357,6 +355,10 @@ pub fn deinit(self: *Elf) void { |
| 357 | list.deinit(gpa); | 355 | list.deinit(gpa); |
| 358 | } | 356 | } |
| 359 | self.output_sections.deinit(gpa); | 357 | self.output_sections.deinit(gpa); |
| | 358 | for (self.output_rela_sections.values()) |*list| { |
| | 359 | list.deinit(gpa); |
| | 360 | } |
| | 361 | self.output_rela_sections.deinit(gpa); |
| 360 | self.shstrtab.deinit(gpa); | 362 | self.shstrtab.deinit(gpa); |
| 361 | self.symtab.deinit(gpa); | 363 | self.symtab.deinit(gpa); |
| 362 | self.strtab.deinit(gpa); | 364 | self.strtab.deinit(gpa); |
| ... | @@ -597,10 +599,8 @@ pub fn initMetadata(self: *Elf) !void { | ... | @@ -597,10 +599,8 @@ pub fn initMetadata(self: *Elf) !void { |
| 597 | const shdr = &self.shdrs.items[self.zig_text_section_index.?]; | 599 | const shdr = &self.shdrs.items[self.zig_text_section_index.?]; |
| 598 | fillSection(self, shdr, self.base.options.program_code_size_hint, self.phdr_zig_load_re_index); | 600 | fillSection(self, shdr, self.base.options.program_code_size_hint, self.phdr_zig_load_re_index); |
| 599 | if (self.isRelocatable()) { | 601 | if (self.isRelocatable()) { |
| 600 | self.zig_text_rela_section_index = try self.addRelaShdr( | 602 | const rela_shndx = try self.addRelaShdr(".rela.text.zig", self.zig_text_section_index.?); |
| 601 | ".rela.text.zig", | 603 | try self.output_rela_sections.putNoClobber(gpa, rela_shndx, .{}); |
| 602 | self.zig_text_section_index.?, | | |
| 603 | ); | | |
| 604 | } else { | 604 | } else { |
| 605 | try self.phdr_to_shdr_table.putNoClobber( | 605 | try self.phdr_to_shdr_table.putNoClobber( |
| 606 | gpa, | 606 | gpa, |
| ... | @@ -644,10 +644,11 @@ pub fn initMetadata(self: *Elf) !void { | ... | @@ -644,10 +644,11 @@ pub fn initMetadata(self: *Elf) !void { |
| 644 | const shdr = &self.shdrs.items[self.zig_data_rel_ro_section_index.?]; | 644 | const shdr = &self.shdrs.items[self.zig_data_rel_ro_section_index.?]; |
| 645 | fillSection(self, shdr, 1024, self.phdr_zig_load_ro_index); | 645 | fillSection(self, shdr, 1024, self.phdr_zig_load_ro_index); |
| 646 | if (self.isRelocatable()) { | 646 | if (self.isRelocatable()) { |
| 647 | self.zig_data_rel_ro_rela_section_index = try self.addRelaShdr( | 647 | const rela_shndx = try self.addRelaShdr( |
| 648 | ".rela.data.rel.ro.zig", | 648 | ".rela.data.rel.ro.zig", |
| 649 | self.zig_data_rel_ro_section_index.?, | 649 | self.zig_data_rel_ro_section_index.?, |
| 650 | ); | 650 | ); |
| | 651 | try self.output_rela_sections.putNoClobber(gpa, rela_shndx, .{}); |
| 651 | } else { | 652 | } else { |
| 652 | try self.phdr_to_shdr_table.putNoClobber( | 653 | try self.phdr_to_shdr_table.putNoClobber( |
| 653 | gpa, | 654 | gpa, |
| ... | @@ -670,10 +671,11 @@ pub fn initMetadata(self: *Elf) !void { | ... | @@ -670,10 +671,11 @@ pub fn initMetadata(self: *Elf) !void { |
| 670 | const shdr = &self.shdrs.items[self.zig_data_section_index.?]; | 671 | const shdr = &self.shdrs.items[self.zig_data_section_index.?]; |
| 671 | fillSection(self, shdr, 1024, self.phdr_zig_load_rw_index); | 672 | fillSection(self, shdr, 1024, self.phdr_zig_load_rw_index); |
| 672 | if (self.isRelocatable()) { | 673 | if (self.isRelocatable()) { |
| 673 | self.zig_data_rela_section_index = try self.addRelaShdr( | 674 | const rela_shndx = try self.addRelaShdr( |
| 674 | ".rela.data.zig", | 675 | ".rela.data.zig", |
| 675 | self.zig_data_section_index.?, | 676 | self.zig_data_section_index.?, |
| 676 | ); | 677 | ); |
| | 678 | try self.output_rela_sections.putNoClobber(gpa, rela_shndx, .{}); |
| 677 | } else { | 679 | } else { |
| 678 | try self.phdr_to_shdr_table.putNoClobber( | 680 | try self.phdr_to_shdr_table.putNoClobber( |
| 679 | gpa, | 681 | gpa, |
| ... | @@ -1514,16 +1516,13 @@ pub fn flushStaticLib(self: *Elf) link.File.FlushError!void { | ... | @@ -1514,16 +1516,13 @@ pub fn flushStaticLib(self: *Elf) link.File.FlushError!void { |
| 1514 | try self.initSymtab(); | 1516 | try self.initSymtab(); |
| 1515 | try self.initShStrtab(); | 1517 | try self.initShStrtab(); |
| 1516 | try self.sortShdrs(); | 1518 | try self.sortShdrs(); |
| 1517 | zig_object.updateRelaSectionsSizes(self); | 1519 | try zig_object.addAtomsToRelaSections(self); |
| 1518 | self.updateSymtabSizeZigObject(zig_object); | 1520 | try self.updateSectionSizesObject(); |
| 1519 | self.updateShStrtabSize(); | | |
| 1520 | | 1521 | |
| 1521 | try self.allocateNonAllocSections(); | 1522 | try self.allocateNonAllocSections(); |
| 1522 | | 1523 | |
| 1523 | try self.writeShdrTable(); | 1524 | try self.writeShdrTable(); |
| 1524 | try zig_object.writeRelaSections(self); | 1525 | try self.writeSyntheticSectionsObject(); |
| 1525 | try self.writeSymtabZigObject(zig_object); | | |
| 1526 | try self.writeShStrtab(); | | |
| 1527 | try self.writeElfHeader(); | 1526 | try self.writeElfHeader(); |
| 1528 | } | 1527 | } |
| 1529 | | 1528 | |
| ... | @@ -1620,7 +1619,9 @@ pub fn flushObject(self: *Elf) link.File.FlushError!void { | ... | @@ -1620,7 +1619,9 @@ pub fn flushObject(self: *Elf) link.File.FlushError!void { |
| 1620 | try self.initSectionsObject(); | 1619 | try self.initSectionsObject(); |
| 1621 | try self.sortShdrs(); | 1620 | try self.sortShdrs(); |
| 1622 | for (self.objects.items) |index| { | 1621 | for (self.objects.items) |index| { |
| 1623 | try self.file(index).?.object.addAtomsToOutputSections(self); | 1622 | const object = self.file(index).?.object; |
| | 1623 | try object.addAtomsToOutputSections(self); |
| | 1624 | try object.addAtomsToRelaSections(self); |
| 1624 | } | 1625 | } |
| 1625 | try self.updateSectionSizesObject(); | 1626 | try self.updateSectionSizesObject(); |
| 1626 | | 1627 | |
| ... | @@ -3452,7 +3453,7 @@ fn initSectionsObject(self: *Elf) !void { | ... | @@ -3452,7 +3453,7 @@ fn initSectionsObject(self: *Elf) !void { |
| 3452 | .addralign = ptr_size, | 3453 | .addralign = ptr_size, |
| 3453 | .offset = std.math.maxInt(u64), | 3454 | .offset = std.math.maxInt(u64), |
| 3454 | }); | 3455 | }); |
| 3455 | _ = try self.addRelaShdr(".rela.eh_frame", self.eh_frame_section_index.?); | 3456 | // _ = try self.addRelaShdr(".rela.eh_frame", self.eh_frame_section_index.?); |
| 3456 | } | 3457 | } |
| 3457 | | 3458 | |
| 3458 | try self.initSymtab(); | 3459 | try self.initSymtab(); |
| ... | @@ -3841,12 +3842,9 @@ fn sortShdrs(self: *Elf) !void { | ... | @@ -3841,12 +3842,9 @@ fn sortShdrs(self: *Elf) !void { |
| 3841 | &self.versym_section_index, | 3842 | &self.versym_section_index, |
| 3842 | &self.verneed_section_index, | 3843 | &self.verneed_section_index, |
| 3843 | &self.zig_text_section_index, | 3844 | &self.zig_text_section_index, |
| 3844 | &self.zig_text_rela_section_index, | | |
| 3845 | &self.zig_got_section_index, | 3845 | &self.zig_got_section_index, |
| 3846 | &self.zig_data_rel_ro_section_index, | 3846 | &self.zig_data_rel_ro_section_index, |
| 3847 | &self.zig_data_rel_ro_rela_section_index, | | |
| 3848 | &self.zig_data_section_index, | 3847 | &self.zig_data_section_index, |
| 3849 | &self.zig_data_rela_section_index, | | |
| 3850 | &self.zig_bss_section_index, | 3848 | &self.zig_bss_section_index, |
| 3851 | &self.debug_str_section_index, | 3849 | &self.debug_str_section_index, |
| 3852 | &self.debug_info_section_index, | 3850 | &self.debug_info_section_index, |
| ... | @@ -4066,7 +4064,7 @@ fn updateSectionSizes(self: *Elf) !void { | ... | @@ -4066,7 +4064,7 @@ fn updateSectionSizes(self: *Elf) !void { |
| 4066 | self.shdrs.items[index].sh_size = self.verneed.size(); | 4064 | self.shdrs.items[index].sh_size = self.verneed.size(); |
| 4067 | } | 4065 | } |
| 4068 | | 4066 | |
| 4069 | self.updateSymtabSize(); | 4067 | try self.updateSymtabSize(); |
| 4070 | self.updateShStrtabSize(); | 4068 | self.updateShStrtabSize(); |
| 4071 | } | 4069 | } |
| 4072 | | 4070 | |
| ... | @@ -4084,19 +4082,21 @@ fn updateSectionSizesObject(self: *Elf) !void { | ... | @@ -4084,19 +4082,21 @@ fn updateSectionSizesObject(self: *Elf) !void { |
| 4084 | } | 4082 | } |
| 4085 | } | 4083 | } |
| 4086 | | 4084 | |
| 4087 | if (self.zigObjectPtr()) |zig_object| { | 4085 | for (self.output_rela_sections.keys(), self.output_rela_sections.values()) |shndx, atom_list| { |
| 4088 | zig_object.updateRelaSectionsSizes(self); | 4086 | const shdr = &self.shdrs.items[shndx]; |
| 4089 | } | 4087 | for (atom_list.items) |atom_index| { |
| 4090 | | 4088 | const atom_ptr = self.atom(atom_index) orelse continue; |
| 4091 | for (self.objects.items) |index| { | 4089 | if (!atom_ptr.flags.alive) continue; |
| 4092 | self.file(index).?.object.updateRelaSectionsSizes(self); | 4090 | const relocs = atom_ptr.relocs(self); |
| | 4091 | shdr.sh_size += shdr.sh_entsize * relocs.len; |
| | 4092 | } |
| 4093 | } | 4093 | } |
| 4094 | | 4094 | |
| 4095 | if (self.eh_frame_section_index) |index| { | 4095 | if (self.eh_frame_section_index) |index| { |
| 4096 | self.shdrs.items[index].sh_size = try eh_frame.calcEhFrameSize(self); | 4096 | self.shdrs.items[index].sh_size = try eh_frame.calcEhFrameSize(self); |
| 4097 | } | 4097 | } |
| 4098 | | 4098 | |
| 4099 | self.updateSymtabSize(); | 4099 | try self.updateSymtabSize(); |
| 4100 | self.updateShStrtabSize(); | 4100 | self.updateShStrtabSize(); |
| 4101 | } | 4101 | } |
| 4102 | | 4102 | |
| ... | @@ -4597,96 +4597,123 @@ fn writeAtomsObject(self: *Elf) !void { | ... | @@ -4597,96 +4597,123 @@ fn writeAtomsObject(self: *Elf) !void { |
| 4597 | } | 4597 | } |
| 4598 | } | 4598 | } |
| 4599 | | 4599 | |
| 4600 | fn updateSymtabSize(self: *Elf) void { | 4600 | fn updateSymtabSize(self: *Elf) !void { |
| 4601 | var sizes = SymtabSize{}; | 4601 | var nlocals: u32 = 0; |
| | 4602 | var nglobals: u32 = 0; |
| | 4603 | var strsize: u32 = 0; |
| 4602 | | 4604 | |
| 4603 | if (self.zigObjectPtr()) |zig_object| { | 4605 | const gpa = self.base.allocator; |
| 4604 | zig_object.asFile().updateSymtabSize(self); | 4606 | var files = std.ArrayList(File.Index).init(gpa); |
| 4605 | sizes.add(zig_object.output_symtab_size); | 4607 | defer files.deinit(); |
| 4606 | } | 4608 | try files.ensureTotalCapacityPrecise(self.objects.items.len + self.shared_objects.items.len + 1); |
| 4607 | | 4609 | |
| | 4610 | if (self.zig_object_index) |index| files.appendAssumeCapacity(index); |
| 4608 | for (self.objects.items) |index| { | 4611 | for (self.objects.items) |index| { |
| 4609 | const file_ptr = self.file(index).?; | 4612 | files.appendAssumeCapacity(index); |
| 4610 | file_ptr.updateSymtabSize(self); | | |
| 4611 | sizes.add(file_ptr.object.output_symtab_size); | | |
| 4612 | } | 4613 | } |
| 4613 | | | |
| 4614 | for (self.shared_objects.items) |index| { | 4614 | for (self.shared_objects.items) |index| { |
| | 4615 | files.appendAssumeCapacity(index); |
| | 4616 | } |
| | 4617 | |
| | 4618 | // Section symbols |
| | 4619 | for (self.output_sections.keys()) |_| { |
| | 4620 | nlocals += 1; |
| | 4621 | } |
| | 4622 | |
| | 4623 | for (files.items) |index| { |
| 4615 | const file_ptr = self.file(index).?; | 4624 | const file_ptr = self.file(index).?; |
| 4616 | file_ptr.updateSymtabSize(self); | 4625 | const ctx = switch (file_ptr) { |
| 4617 | sizes.add(file_ptr.shared_object.output_symtab_size); | 4626 | inline else => |x| &x.output_symtab_ctx, |
| | 4627 | }; |
| | 4628 | ctx.ilocal = nlocals + 1; |
| | 4629 | ctx.iglobal = nglobals + 1; |
| | 4630 | try file_ptr.updateSymtabSize(self); |
| | 4631 | nlocals += ctx.nlocals; |
| | 4632 | nglobals += ctx.nglobals; |
| | 4633 | strsize += ctx.strsize; |
| 4618 | } | 4634 | } |
| 4619 | | 4635 | |
| 4620 | if (self.zig_got_section_index) |_| { | 4636 | if (self.zig_got_section_index) |_| { |
| | 4637 | self.zig_got.output_symtab_ctx.ilocal = nlocals + 1; |
| 4621 | self.zig_got.updateSymtabSize(self); | 4638 | self.zig_got.updateSymtabSize(self); |
| 4622 | sizes.add(self.zig_got.output_symtab_size); | 4639 | nlocals += self.zig_got.output_symtab_ctx.nlocals; |
| | 4640 | strsize += self.zig_got.output_symtab_ctx.strsize; |
| 4623 | } | 4641 | } |
| 4624 | | 4642 | |
| 4625 | if (self.got_section_index) |_| { | 4643 | if (self.got_section_index) |_| { |
| | 4644 | self.got.output_symtab_ctx.ilocal = nlocals + 1; |
| 4626 | self.got.updateSymtabSize(self); | 4645 | self.got.updateSymtabSize(self); |
| 4627 | sizes.add(self.got.output_symtab_size); | 4646 | nlocals += self.got.output_symtab_ctx.nlocals; |
| | 4647 | strsize += self.got.output_symtab_ctx.strsize; |
| 4628 | } | 4648 | } |
| 4629 | | 4649 | |
| 4630 | if (self.plt_section_index) |_| { | 4650 | if (self.plt_section_index) |_| { |
| | 4651 | self.plt.output_symtab_ctx.ilocal = nlocals + 1; |
| 4631 | self.plt.updateSymtabSize(self); | 4652 | self.plt.updateSymtabSize(self); |
| 4632 | sizes.add(self.plt.output_symtab_size); | 4653 | nlocals += self.plt.output_symtab_ctx.nlocals; |
| | 4654 | strsize += self.plt.output_symtab_ctx.strsize; |
| 4633 | } | 4655 | } |
| 4634 | | 4656 | |
| 4635 | if (self.plt_got_section_index) |_| { | 4657 | if (self.plt_got_section_index) |_| { |
| | 4658 | self.plt_got.output_symtab_ctx.ilocal = nlocals + 1; |
| 4636 | self.plt_got.updateSymtabSize(self); | 4659 | self.plt_got.updateSymtabSize(self); |
| 4637 | sizes.add(self.plt_got.output_symtab_size); | 4660 | nlocals += self.plt_got.output_symtab_ctx.nlocals; |
| | 4661 | strsize += self.plt_got.output_symtab_ctx.strsize; |
| 4638 | } | 4662 | } |
| 4639 | | 4663 | |
| 4640 | if (self.linker_defined_index) |index| { | 4664 | for (files.items) |index| { |
| 4641 | const file_ptr = self.file(index).?; | 4665 | const file_ptr = self.file(index).?; |
| 4642 | file_ptr.updateSymtabSize(self); | 4666 | const ctx = switch (file_ptr) { |
| 4643 | sizes.add(file_ptr.linker_defined.output_symtab_size); | 4667 | inline else => |x| &x.output_symtab_ctx, |
| 4644 | } | 4668 | }; |
| 4645 | | 4669 | ctx.iglobal += nlocals; |
| 4646 | // Section symbols | | |
| 4647 | for (self.output_sections.keys()) |_| { | | |
| 4648 | sizes.nlocals += 1; | | |
| 4649 | } | 4670 | } |
| 4650 | | 4671 | |
| 4651 | const symtab_shdr = &self.shdrs.items[self.symtab_section_index.?]; | 4672 | const symtab_shdr = &self.shdrs.items[self.symtab_section_index.?]; |
| 4652 | symtab_shdr.sh_info = sizes.nlocals + 1; | 4673 | symtab_shdr.sh_info = nlocals + 1; |
| 4653 | symtab_shdr.sh_link = self.strtab_section_index.?; | 4674 | symtab_shdr.sh_link = self.strtab_section_index.?; |
| 4654 | | 4675 | |
| 4655 | const sym_size: u64 = switch (self.ptr_width) { | 4676 | const sym_size: u64 = switch (self.ptr_width) { |
| 4656 | .p32 => @sizeOf(elf.Elf32_Sym), | 4677 | .p32 => @sizeOf(elf.Elf32_Sym), |
| 4657 | .p64 => @sizeOf(elf.Elf64_Sym), | 4678 | .p64 => @sizeOf(elf.Elf64_Sym), |
| 4658 | }; | 4679 | }; |
| 4659 | const needed_size = (sizes.nlocals + sizes.nglobals + 1) * sym_size; | 4680 | const needed_size = (nlocals + nglobals + 1) * sym_size; |
| 4660 | symtab_shdr.sh_size = needed_size; | 4681 | symtab_shdr.sh_size = needed_size; |
| 4661 | | 4682 | |
| 4662 | const strtab = &self.shdrs.items[self.strtab_section_index.?]; | 4683 | const strtab = &self.shdrs.items[self.strtab_section_index.?]; |
| 4663 | strtab.sh_size = sizes.strsize + 1; | 4684 | strtab.sh_size = strsize + 1; |
| 4664 | } | 4685 | } |
| 4665 | | 4686 | |
| 4666 | fn updateSymtabSizeZigObject(self: *Elf, zig_object: *ZigObject) void { | 4687 | fn updateSymtabSizeZigObject(self: *Elf, zig_object: *ZigObject) void { |
| 4667 | var sizes = SymtabSize{}; | 4688 | var nlocals: u32 = 0; |
| 4668 | | 4689 | var nglobals: u32 = 0; |
| 4669 | zig_object.asFile().updateSymtabSize(self); | 4690 | var strsize: u32 = 0; |
| 4670 | sizes.add(zig_object.output_symtab_size); | | |
| 4671 | | 4691 | |
| 4672 | // Section symbols | 4692 | // Section symbols |
| 4673 | for (self.output_sections.keys()) |_| { | 4693 | for (self.output_sections.keys()) |_| { |
| 4674 | sizes.nlocals += 1; | 4694 | nlocals += 1; |
| 4675 | } | 4695 | } |
| 4676 | | 4696 | |
| | 4697 | zig_object.output_symtab_ctx.ilocal = nlocals + 1; |
| | 4698 | try zig_object.asFile().updateSymtabSize(self); |
| | 4699 | nlocals += zig_object.output_symtab_ctx.nlocals; |
| | 4700 | nglobals += zig_object.output_symtab_ctx.nglobals; |
| | 4701 | strsize += zig_object.output_symtab_ctx.strsize; |
| | 4702 | zig_object.output_symtab_ctx.iglobal = nlocals + 1; |
| | 4703 | |
| 4677 | const symtab_shdr = &self.shdrs.items[self.symtab_section_index.?]; | 4704 | const symtab_shdr = &self.shdrs.items[self.symtab_section_index.?]; |
| 4678 | symtab_shdr.sh_info = sizes.nlocals + 1; | 4705 | symtab_shdr.sh_info = nlocals + 1; |
| 4679 | symtab_shdr.sh_link = self.strtab_section_index.?; | 4706 | symtab_shdr.sh_link = self.strtab_section_index.?; |
| 4680 | | 4707 | |
| 4681 | const sym_size: u64 = switch (self.ptr_width) { | 4708 | const sym_size: u64 = switch (self.ptr_width) { |
| 4682 | .p32 => @sizeOf(elf.Elf32_Sym), | 4709 | .p32 => @sizeOf(elf.Elf32_Sym), |
| 4683 | .p64 => @sizeOf(elf.Elf64_Sym), | 4710 | .p64 => @sizeOf(elf.Elf64_Sym), |
| 4684 | }; | 4711 | }; |
| 4685 | const needed_size = (sizes.nlocals + sizes.nglobals + 1) * sym_size; | 4712 | const needed_size = (nlocals + nglobals + 1) * sym_size; |
| 4686 | symtab_shdr.sh_size = needed_size; | 4713 | symtab_shdr.sh_size = needed_size; |
| 4687 | | 4714 | |
| 4688 | const strtab = &self.shdrs.items[self.strtab_section_index.?]; | 4715 | const strtab = &self.shdrs.items[self.strtab_section_index.?]; |
| 4689 | strtab.sh_size = sizes.strsize + 1; | 4716 | strtab.sh_size = strsize + 1; |
| 4690 | } | 4717 | } |
| 4691 | | 4718 | |
| 4692 | fn writeSyntheticSections(self: *Elf) !void { | 4719 | fn writeSyntheticSections(self: *Elf) !void { |
| ... | @@ -4822,12 +4849,31 @@ fn writeSyntheticSections(self: *Elf) !void { | ... | @@ -4822,12 +4849,31 @@ fn writeSyntheticSections(self: *Elf) !void { |
| 4822 | fn writeSyntheticSectionsObject(self: *Elf) !void { | 4849 | fn writeSyntheticSectionsObject(self: *Elf) !void { |
| 4823 | const gpa = self.base.allocator; | 4850 | const gpa = self.base.allocator; |
| 4824 | | 4851 | |
| 4825 | if (self.zigObjectPtr()) |zig_object| { | 4852 | for (self.output_rela_sections.keys(), self.output_rela_sections.values()) |shndx, atom_list| { |
| 4826 | try zig_object.writeRelaSections(self); | 4853 | if (atom_list.items.len == 0) continue; |
| 4827 | } | | |
| 4828 | | 4854 | |
| 4829 | for (self.objects.items) |index| { | 4855 | const shdr = self.shdrs.items[shndx]; |
| 4830 | try self.file(index).?.object.writeRelaSections(self); | 4856 | |
| | 4857 | const num_relocs = @divExact(shdr.sh_size, shdr.sh_entsize); |
| | 4858 | var relocs = try std.ArrayList(elf.Elf64_Rela).initCapacity(gpa, num_relocs); |
| | 4859 | defer relocs.deinit(); |
| | 4860 | |
| | 4861 | for (atom_list.items) |atom_index| { |
| | 4862 | const atom_ptr = self.atom(atom_index) orelse continue; |
| | 4863 | if (!atom_ptr.flags.alive) continue; |
| | 4864 | try atom_ptr.writeRelocs(self, &relocs); |
| | 4865 | } |
| | 4866 | |
| | 4867 | const SortRelocs = struct { |
| | 4868 | pub fn lessThan(ctx: void, lhs: elf.Elf64_Rela, rhs: elf.Elf64_Rela) bool { |
| | 4869 | _ = ctx; |
| | 4870 | return lhs.r_offset < rhs.r_offset; |
| | 4871 | } |
| | 4872 | }; |
| | 4873 | |
| | 4874 | mem.sort(elf.Elf64_Rela, relocs.items, {}, SortRelocs.lessThan); |
| | 4875 | |
| | 4876 | try self.base.file.?.pwriteAll(mem.sliceAsBytes(relocs.items), shdr.sh_offset); |
| 4831 | } | 4877 | } |
| 4832 | | 4878 | |
| 4833 | if (self.eh_frame_section_index) |shndx| { | 4879 | if (self.eh_frame_section_index) |shndx| { |
| ... | @@ -4836,7 +4882,7 @@ fn writeSyntheticSectionsObject(self: *Elf) !void { | ... | @@ -4836,7 +4882,7 @@ fn writeSyntheticSectionsObject(self: *Elf) !void { |
| 4836 | var buffer = try std.ArrayList(u8).initCapacity(gpa, sh_size); | 4882 | var buffer = try std.ArrayList(u8).initCapacity(gpa, sh_size); |
| 4837 | defer buffer.deinit(); | 4883 | defer buffer.deinit(); |
| 4838 | try eh_frame.writeEhFrame(self, buffer.writer()); | 4884 | try eh_frame.writeEhFrame(self, buffer.writer()); |
| 4839 | // try self.base.file.?.pwriteAll(buffer.items, shdr.sh_offset); | 4885 | try self.base.file.?.pwriteAll(buffer.items, shdr.sh_offset); |
| 4840 | } | 4886 | } |
| 4841 | | 4887 | |
| 4842 | try self.writeSymtab(); | 4888 | try self.writeSymtab(); |
| ... | @@ -4850,16 +4896,6 @@ fn writeShStrtab(self: *Elf) !void { | ... | @@ -4850,16 +4896,6 @@ fn writeShStrtab(self: *Elf) !void { |
| 4850 | } | 4896 | } |
| 4851 | } | 4897 | } |
| 4852 | | 4898 | |
| 4853 | const WriteSymtabCtx = struct { | | |
| 4854 | ilocal: usize, | | |
| 4855 | iglobal: usize, | | |
| 4856 | | | |
| 4857 | fn incr(this: *@This(), ss: SymtabSize) void { | | |
| 4858 | this.ilocal += ss.nlocals; | | |
| 4859 | this.iglobal += ss.nglobals; | | |
| 4860 | } | | |
| 4861 | }; | | |
| 4862 | | | |
| 4863 | fn writeSymtab(self: *Elf) !void { | 4899 | fn writeSymtab(self: *Elf) !void { |
| 4864 | const gpa = self.base.allocator; | 4900 | const gpa = self.base.allocator; |
| 4865 | const symtab_shdr = self.shdrs.items[self.symtab_section_index.?]; | 4901 | const symtab_shdr = self.shdrs.items[self.symtab_section_index.?]; |
| ... | @@ -4876,54 +4912,41 @@ fn writeSymtab(self: *Elf) !void { | ... | @@ -4876,54 +4912,41 @@ fn writeSymtab(self: *Elf) !void { |
| 4876 | const needed_strtab_size = math.cast(usize, strtab_shdr.sh_size - 1) orelse return error.Overflow; | 4912 | const needed_strtab_size = math.cast(usize, strtab_shdr.sh_size - 1) orelse return error.Overflow; |
| 4877 | try self.strtab.ensureUnusedCapacity(gpa, needed_strtab_size); | 4913 | try self.strtab.ensureUnusedCapacity(gpa, needed_strtab_size); |
| 4878 | | 4914 | |
| 4879 | var ctx: WriteSymtabCtx = .{ | 4915 | self.writeSectionSymbols(); |
| 4880 | .ilocal = 1, | | |
| 4881 | .iglobal = symtab_shdr.sh_info, | | |
| 4882 | }; | | |
| 4883 | | | |
| 4884 | ctx.incr(self.writeSectionSymbols(ctx)); | | |
| 4885 | | 4916 | |
| 4886 | if (self.zigObjectPtr()) |zig_object| { | 4917 | if (self.zigObjectPtr()) |zig_object| { |
| 4887 | zig_object.asFile().writeSymtab(self, ctx); | 4918 | zig_object.asFile().writeSymtab(self); |
| 4888 | ctx.incr(zig_object.output_symtab_size); | | |
| 4889 | } | 4919 | } |
| 4890 | | 4920 | |
| 4891 | for (self.objects.items) |index| { | 4921 | for (self.objects.items) |index| { |
| 4892 | const file_ptr = self.file(index).?; | 4922 | const file_ptr = self.file(index).?; |
| 4893 | file_ptr.writeSymtab(self, ctx); | 4923 | file_ptr.writeSymtab(self); |
| 4894 | ctx.incr(file_ptr.object.output_symtab_size); | | |
| 4895 | } | 4924 | } |
| 4896 | | 4925 | |
| 4897 | for (self.shared_objects.items) |index| { | 4926 | for (self.shared_objects.items) |index| { |
| 4898 | const file_ptr = self.file(index).?; | 4927 | const file_ptr = self.file(index).?; |
| 4899 | file_ptr.writeSymtab(self, ctx); | 4928 | file_ptr.writeSymtab(self); |
| 4900 | ctx.incr(file_ptr.shared_object.output_symtab_size); | | |
| 4901 | } | 4929 | } |
| 4902 | | 4930 | |
| 4903 | if (self.zig_got_section_index) |_| { | 4931 | if (self.zig_got_section_index) |_| { |
| 4904 | self.zig_got.writeSymtab(self, ctx); | 4932 | self.zig_got.writeSymtab(self); |
| 4905 | ctx.incr(self.zig_got.output_symtab_size); | | |
| 4906 | } | 4933 | } |
| 4907 | | 4934 | |
| 4908 | if (self.got_section_index) |_| { | 4935 | if (self.got_section_index) |_| { |
| 4909 | self.got.writeSymtab(self, ctx); | 4936 | self.got.writeSymtab(self); |
| 4910 | ctx.incr(self.got.output_symtab_size); | | |
| 4911 | } | 4937 | } |
| 4912 | | 4938 | |
| 4913 | if (self.plt_section_index) |_| { | 4939 | if (self.plt_section_index) |_| { |
| 4914 | self.plt.writeSymtab(self, ctx); | 4940 | self.plt.writeSymtab(self); |
| 4915 | ctx.incr(self.plt.output_symtab_size); | | |
| 4916 | } | 4941 | } |
| 4917 | | 4942 | |
| 4918 | if (self.plt_got_section_index) |_| { | 4943 | if (self.plt_got_section_index) |_| { |
| 4919 | self.plt_got.writeSymtab(self, ctx); | 4944 | self.plt_got.writeSymtab(self); |
| 4920 | ctx.incr(self.plt_got.output_symtab_size); | | |
| 4921 | } | 4945 | } |
| 4922 | | 4946 | |
| 4923 | if (self.linker_defined_index) |index| { | 4947 | if (self.linker_defined_index) |index| { |
| 4924 | const file_ptr = self.file(index).?; | 4948 | const file_ptr = self.file(index).?; |
| 4925 | file_ptr.writeSymtab(self, ctx); | 4949 | file_ptr.writeSymtab(self); |
| 4926 | ctx.incr(file_ptr.linker_defined.output_symtab_size); | | |
| 4927 | } | 4950 | } |
| 4928 | | 4951 | |
| 4929 | const foreign_endian = self.base.options.target.cpu.arch.endian() != builtin.cpu.arch.endian(); | 4952 | const foreign_endian = self.base.options.target.cpu.arch.endian() != builtin.cpu.arch.endian(); |
| ... | @@ -4972,15 +4995,8 @@ fn writeSymtabZigObject(self: *Elf, zig_object: *ZigObject) !void { | ... | @@ -4972,15 +4995,8 @@ fn writeSymtabZigObject(self: *Elf, zig_object: *ZigObject) !void { |
| 4972 | const needed_strtab_size = math.cast(usize, strtab_shdr.sh_size - 1) orelse return error.Overflow; | 4995 | const needed_strtab_size = math.cast(usize, strtab_shdr.sh_size - 1) orelse return error.Overflow; |
| 4973 | try self.strtab.ensureUnusedCapacity(gpa, needed_strtab_size); | 4996 | try self.strtab.ensureUnusedCapacity(gpa, needed_strtab_size); |
| 4974 | | 4997 | |
| 4975 | var ctx: WriteSymtabCtx = .{ | 4998 | self.writeSectionSymbols(); |
| 4976 | .ilocal = 1, | 4999 | zig_object.asFile().writeSymtab(self); |
| 4977 | .iglobal = symtab_shdr.sh_info, | | |
| 4978 | }; | | |
| 4979 | | | |
| 4980 | ctx.incr(self.writeSectionSymbols(ctx)); | | |
| 4981 | | | |
| 4982 | zig_object.asFile().writeSymtab(self, ctx); | | |
| 4983 | ctx.incr(zig_object.output_symtab_size); | | |
| 4984 | | 5000 | |
| 4985 | const foreign_endian = self.base.options.target.cpu.arch.endian() != builtin.cpu.arch.endian(); | 5001 | const foreign_endian = self.base.options.target.cpu.arch.endian() != builtin.cpu.arch.endian(); |
| 4986 | switch (self.ptr_width) { | 5002 | switch (self.ptr_width) { |
| ... | @@ -5012,8 +5028,8 @@ fn writeSymtabZigObject(self: *Elf, zig_object: *ZigObject) !void { | ... | @@ -5012,8 +5028,8 @@ fn writeSymtabZigObject(self: *Elf, zig_object: *ZigObject) !void { |
| 5012 | try self.base.file.?.pwriteAll(self.strtab.items, strtab_shdr.sh_offset); | 5028 | try self.base.file.?.pwriteAll(self.strtab.items, strtab_shdr.sh_offset); |
| 5013 | } | 5029 | } |
| 5014 | | 5030 | |
| 5015 | fn writeSectionSymbols(self: *Elf, ctx: WriteSymtabCtx) SymtabSize { | 5031 | fn writeSectionSymbols(self: *Elf) void { |
| 5016 | var ilocal = ctx.ilocal; | 5032 | var ilocal: u32 = 1; |
| 5017 | for (self.output_sections.keys()) |shndx| { | 5033 | for (self.output_sections.keys()) |shndx| { |
| 5018 | const shdr = self.shdrs.items[shndx]; | 5034 | const shdr = self.shdrs.items[shndx]; |
| 5019 | const out_sym = &self.symtab.items[ilocal]; | 5035 | const out_sym = &self.symtab.items[ilocal]; |
| ... | @@ -5027,7 +5043,6 @@ fn writeSectionSymbols(self: *Elf, ctx: WriteSymtabCtx) SymtabSize { | ... | @@ -5027,7 +5043,6 @@ fn writeSectionSymbols(self: *Elf, ctx: WriteSymtabCtx) SymtabSize { |
| 5027 | }; | 5043 | }; |
| 5028 | ilocal += 1; | 5044 | ilocal += 1; |
| 5029 | } | 5045 | } |
| 5030 | return .{ .nlocals = @intCast(ilocal - ctx.ilocal) }; | | |
| 5031 | } | 5046 | } |
| 5032 | | 5047 | |
| 5033 | /// Always 4 or 8 depending on whether this is 32-bit ELF or 64-bit ELF. | 5048 | /// Always 4 or 8 depending on whether this is 32-bit ELF or 64-bit ELF. |
| ... | @@ -6056,16 +6071,12 @@ pub const ComdatGroup = struct { | ... | @@ -6056,16 +6071,12 @@ pub const ComdatGroup = struct { |
| 6056 | pub const Index = u32; | 6071 | pub const Index = u32; |
| 6057 | }; | 6072 | }; |
| 6058 | | 6073 | |
| 6059 | pub const SymtabSize = struct { | 6074 | pub const SymtabCtx = struct { |
| | 6075 | ilocal: u32 = 0, |
| | 6076 | iglobal: u32 = 0, |
| 6060 | nlocals: u32 = 0, | 6077 | nlocals: u32 = 0, |
| 6061 | nglobals: u32 = 0, | 6078 | nglobals: u32 = 0, |
| 6062 | strsize: u32 = 0, | 6079 | strsize: u32 = 0, |
| 6063 | | | |
| 6064 | fn add(ss: *SymtabSize, other: SymtabSize) void { | | |
| 6065 | ss.nlocals += other.nlocals; | | |
| 6066 | ss.nglobals += other.nglobals; | | |
| 6067 | ss.strsize += other.strsize; | | |
| 6068 | } | | |
| 6069 | }; | 6080 | }; |
| 6070 | | 6081 | |
| 6071 | pub const null_sym = elf.Elf64_Sym{ | 6082 | pub const null_sym = elf.Elf64_Sym{ |