| author | |
| committer | |
| log | 5e78600f0f5e790c0429817d8249020fd65b49f8 |
| tree | f3715b5e5999e44f09a65a7793a40ae4a155a18d |
| parent | ecf6ed7d9bc9bcd61d619fae985ce9ebdc4d5562 |
9 files changed, 234 insertions(+), 264 deletions(-)
src/link/Elf.zig+131-120| ... | ... | @@ -24,6 +24,7 @@ shdr_table_offset: ?u64 = null, |
| 24 | 24 | /// Table of lists of atoms per output section. |
| 25 | 25 | /// This table is not used to track incrementally generated atoms. |
| 26 | 26 | output_sections: std.AutoArrayHashMapUnmanaged(u16, std.ArrayListUnmanaged(Atom.Index)) = .{}, |
| 27 | output_rela_sections: std.AutoArrayHashMapUnmanaged(u16, std.ArrayListUnmanaged(Atom.Index)) = .{}, | |
| 27 | 28 | |
| 28 | 29 | /// Stored in native-endian format, depending on target endianness needs to be bswapped on read/write. |
| 29 | 30 | /// Same order as in the file. |
| ... | ... | @@ -105,11 +106,8 @@ zig_got: ZigGotSection = .{}, |
| 105 | 106 | /// Tracked section headers with incremental updates to Zig object. |
| 106 | 107 | /// .rela.* sections are only used when emitting a relocatable object file. |
| 107 | 108 | zig_text_section_index: ?u16 = null, |
| 108 | zig_text_rela_section_index: ?u16 = null, | |
| 109 | 109 | zig_data_rel_ro_section_index: ?u16 = null, |
| 110 | zig_data_rel_ro_rela_section_index: ?u16 = null, | |
| 111 | 110 | zig_data_section_index: ?u16 = null, |
| 112 | zig_data_rela_section_index: ?u16 = null, | |
| 113 | 111 | zig_bss_section_index: ?u16 = null, |
| 114 | 112 | zig_got_section_index: ?u16 = null, |
| 115 | 113 | |
| ... | ... | @@ -357,6 +355,10 @@ pub fn deinit(self: *Elf) void { |
| 357 | 355 | list.deinit(gpa); |
| 358 | 356 | } |
| 359 | 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 | 362 | self.shstrtab.deinit(gpa); |
| 361 | 363 | self.symtab.deinit(gpa); |
| 362 | 364 | self.strtab.deinit(gpa); |
| ... | ... | @@ -597,10 +599,8 @@ pub fn initMetadata(self: *Elf) !void { |
| 597 | 599 | const shdr = &self.shdrs.items[self.zig_text_section_index.?]; |
| 598 | 600 | fillSection(self, shdr, self.base.options.program_code_size_hint, self.phdr_zig_load_re_index); |
| 599 | 601 | if (self.isRelocatable()) { |
| 600 | self.zig_text_rela_section_index = try self.addRelaShdr( | |
| 601 | ".rela.text.zig", | |
| 602 | self.zig_text_section_index.?, | |
| 603 | ); | |
| 602 | const rela_shndx = try self.addRelaShdr(".rela.text.zig", self.zig_text_section_index.?); | |
| 603 | try self.output_rela_sections.putNoClobber(gpa, rela_shndx, .{}); | |
| 604 | 604 | } else { |
| 605 | 605 | try self.phdr_to_shdr_table.putNoClobber( |
| 606 | 606 | gpa, |
| ... | ... | @@ -644,10 +644,11 @@ pub fn initMetadata(self: *Elf) !void { |
| 644 | 644 | const shdr = &self.shdrs.items[self.zig_data_rel_ro_section_index.?]; |
| 645 | 645 | fillSection(self, shdr, 1024, self.phdr_zig_load_ro_index); |
| 646 | 646 | if (self.isRelocatable()) { |
| 647 | self.zig_data_rel_ro_rela_section_index = try self.addRelaShdr( | |
| 647 | const rela_shndx = try self.addRelaShdr( | |
| 648 | 648 | ".rela.data.rel.ro.zig", |
| 649 | 649 | self.zig_data_rel_ro_section_index.?, |
| 650 | 650 | ); |
| 651 | try self.output_rela_sections.putNoClobber(gpa, rela_shndx, .{}); | |
| 651 | 652 | } else { |
| 652 | 653 | try self.phdr_to_shdr_table.putNoClobber( |
| 653 | 654 | gpa, |
| ... | ... | @@ -670,10 +671,11 @@ pub fn initMetadata(self: *Elf) !void { |
| 670 | 671 | const shdr = &self.shdrs.items[self.zig_data_section_index.?]; |
| 671 | 672 | fillSection(self, shdr, 1024, self.phdr_zig_load_rw_index); |
| 672 | 673 | if (self.isRelocatable()) { |
| 673 | self.zig_data_rela_section_index = try self.addRelaShdr( | |
| 674 | const rela_shndx = try self.addRelaShdr( | |
| 674 | 675 | ".rela.data.zig", |
| 675 | 676 | self.zig_data_section_index.?, |
| 676 | 677 | ); |
| 678 | try self.output_rela_sections.putNoClobber(gpa, rela_shndx, .{}); | |
| 677 | 679 | } else { |
| 678 | 680 | try self.phdr_to_shdr_table.putNoClobber( |
| 679 | 681 | gpa, |
| ... | ... | @@ -1514,16 +1516,13 @@ pub fn flushStaticLib(self: *Elf) link.File.FlushError!void { |
| 1514 | 1516 | try self.initSymtab(); |
| 1515 | 1517 | try self.initShStrtab(); |
| 1516 | 1518 | try self.sortShdrs(); |
| 1517 | zig_object.updateRelaSectionsSizes(self); | |
| 1518 | self.updateSymtabSizeZigObject(zig_object); | |
| 1519 | self.updateShStrtabSize(); | |
| 1519 | try zig_object.addAtomsToRelaSections(self); | |
| 1520 | try self.updateSectionSizesObject(); | |
| 1520 | 1521 | |
| 1521 | 1522 | try self.allocateNonAllocSections(); |
| 1522 | 1523 | |
| 1523 | 1524 | try self.writeShdrTable(); |
| 1524 | try zig_object.writeRelaSections(self); | |
| 1525 | try self.writeSymtabZigObject(zig_object); | |
| 1526 | try self.writeShStrtab(); | |
| 1525 | try self.writeSyntheticSectionsObject(); | |
| 1527 | 1526 | try self.writeElfHeader(); |
| 1528 | 1527 | } |
| 1529 | 1528 | |
| ... | ... | @@ -1620,7 +1619,9 @@ pub fn flushObject(self: *Elf) link.File.FlushError!void { |
| 1620 | 1619 | try self.initSectionsObject(); |
| 1621 | 1620 | try self.sortShdrs(); |
| 1622 | 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 | 1626 | try self.updateSectionSizesObject(); |
| 1626 | 1627 | |
| ... | ... | @@ -3452,7 +3453,7 @@ fn initSectionsObject(self: *Elf) !void { |
| 3452 | 3453 | .addralign = ptr_size, |
| 3453 | 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 | 3459 | try self.initSymtab(); |
| ... | ... | @@ -3841,12 +3842,9 @@ fn sortShdrs(self: *Elf) !void { |
| 3841 | 3842 | &self.versym_section_index, |
| 3842 | 3843 | &self.verneed_section_index, |
| 3843 | 3844 | &self.zig_text_section_index, |
| 3844 | &self.zig_text_rela_section_index, | |
| 3845 | 3845 | &self.zig_got_section_index, |
| 3846 | 3846 | &self.zig_data_rel_ro_section_index, |
| 3847 | &self.zig_data_rel_ro_rela_section_index, | |
| 3848 | 3847 | &self.zig_data_section_index, |
| 3849 | &self.zig_data_rela_section_index, | |
| 3850 | 3848 | &self.zig_bss_section_index, |
| 3851 | 3849 | &self.debug_str_section_index, |
| 3852 | 3850 | &self.debug_info_section_index, |
| ... | ... | @@ -4066,7 +4064,7 @@ fn updateSectionSizes(self: *Elf) !void { |
| 4066 | 4064 | self.shdrs.items[index].sh_size = self.verneed.size(); |
| 4067 | 4065 | } |
| 4068 | 4066 | |
| 4069 | self.updateSymtabSize(); | |
| 4067 | try self.updateSymtabSize(); | |
| 4070 | 4068 | self.updateShStrtabSize(); |
| 4071 | 4069 | } |
| 4072 | 4070 | |
| ... | ... | @@ -4084,19 +4082,21 @@ fn updateSectionSizesObject(self: *Elf) !void { |
| 4084 | 4082 | } |
| 4085 | 4083 | } |
| 4086 | 4084 | |
| 4087 | if (self.zigObjectPtr()) |zig_object| { | |
| 4088 | zig_object.updateRelaSectionsSizes(self); | |
| 4089 | } | |
| 4090 | ||
| 4091 | for (self.objects.items) |index| { | |
| 4092 | self.file(index).?.object.updateRelaSectionsSizes(self); | |
| 4085 | for (self.output_rela_sections.keys(), self.output_rela_sections.values()) |shndx, atom_list| { | |
| 4086 | const shdr = &self.shdrs.items[shndx]; | |
| 4087 | for (atom_list.items) |atom_index| { | |
| 4088 | const atom_ptr = self.atom(atom_index) orelse continue; | |
| 4089 | if (!atom_ptr.flags.alive) continue; | |
| 4090 | const relocs = atom_ptr.relocs(self); | |
| 4091 | shdr.sh_size += shdr.sh_entsize * relocs.len; | |
| 4092 | } | |
| 4093 | 4093 | } |
| 4094 | 4094 | |
| 4095 | 4095 | if (self.eh_frame_section_index) |index| { |
| 4096 | 4096 | self.shdrs.items[index].sh_size = try eh_frame.calcEhFrameSize(self); |
| 4097 | 4097 | } |
| 4098 | 4098 | |
| 4099 | self.updateSymtabSize(); | |
| 4099 | try self.updateSymtabSize(); | |
| 4100 | 4100 | self.updateShStrtabSize(); |
| 4101 | 4101 | } |
| 4102 | 4102 | |
| ... | ... | @@ -4597,96 +4597,123 @@ fn writeAtomsObject(self: *Elf) !void { |
| 4597 | 4597 | } |
| 4598 | 4598 | } |
| 4599 | 4599 | |
| 4600 | fn updateSymtabSize(self: *Elf) void { | |
| 4601 | var sizes = SymtabSize{}; | |
| 4600 | fn updateSymtabSize(self: *Elf) !void { | |
| 4601 | var nlocals: u32 = 0; | |
| 4602 | var nglobals: u32 = 0; | |
| 4603 | var strsize: u32 = 0; | |
| 4602 | 4604 | |
| 4603 | if (self.zigObjectPtr()) |zig_object| { | |
| 4604 | zig_object.asFile().updateSymtabSize(self); | |
| 4605 | sizes.add(zig_object.output_symtab_size); | |
| 4606 | } | |
| 4605 | const gpa = self.base.allocator; | |
| 4606 | var files = std.ArrayList(File.Index).init(gpa); | |
| 4607 | defer files.deinit(); | |
| 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 | 4611 | for (self.objects.items) |index| { |
| 4609 | const file_ptr = self.file(index).?; | |
| 4610 | file_ptr.updateSymtabSize(self); | |
| 4611 | sizes.add(file_ptr.object.output_symtab_size); | |
| 4612 | files.appendAssumeCapacity(index); | |
| 4612 | 4613 | } |
| 4613 | ||
| 4614 | 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 | 4624 | const file_ptr = self.file(index).?; |
| 4616 | file_ptr.updateSymtabSize(self); | |
| 4617 | sizes.add(file_ptr.shared_object.output_symtab_size); | |
| 4625 | const ctx = switch (file_ptr) { | |
| 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 | 4636 | if (self.zig_got_section_index) |_| { |
| 4637 | self.zig_got.output_symtab_ctx.ilocal = nlocals + 1; | |
| 4621 | 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 | 4643 | if (self.got_section_index) |_| { |
| 4644 | self.got.output_symtab_ctx.ilocal = nlocals + 1; | |
| 4626 | 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 | 4650 | if (self.plt_section_index) |_| { |
| 4651 | self.plt.output_symtab_ctx.ilocal = nlocals + 1; | |
| 4631 | 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 | 4657 | if (self.plt_got_section_index) |_| { |
| 4658 | self.plt_got.output_symtab_ctx.ilocal = nlocals + 1; | |
| 4636 | 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 | 4665 | const file_ptr = self.file(index).?; |
| 4642 | file_ptr.updateSymtabSize(self); | |
| 4643 | sizes.add(file_ptr.linker_defined.output_symtab_size); | |
| 4644 | } | |
| 4645 | ||
| 4646 | // Section symbols | |
| 4647 | for (self.output_sections.keys()) |_| { | |
| 4648 | sizes.nlocals += 1; | |
| 4666 | const ctx = switch (file_ptr) { | |
| 4667 | inline else => |x| &x.output_symtab_ctx, | |
| 4668 | }; | |
| 4669 | ctx.iglobal += nlocals; | |
| 4649 | 4670 | } |
| 4650 | 4671 | |
| 4651 | 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 | 4674 | symtab_shdr.sh_link = self.strtab_section_index.?; |
| 4654 | 4675 | |
| 4655 | 4676 | const sym_size: u64 = switch (self.ptr_width) { |
| 4656 | 4677 | .p32 => @sizeOf(elf.Elf32_Sym), |
| 4657 | 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 | 4681 | symtab_shdr.sh_size = needed_size; |
| 4661 | 4682 | |
| 4662 | 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 | 4687 | fn updateSymtabSizeZigObject(self: *Elf, zig_object: *ZigObject) void { |
| 4667 | var sizes = SymtabSize{}; | |
| 4668 | ||
| 4669 | zig_object.asFile().updateSymtabSize(self); | |
| 4670 | sizes.add(zig_object.output_symtab_size); | |
| 4688 | var nlocals: u32 = 0; | |
| 4689 | var nglobals: u32 = 0; | |
| 4690 | var strsize: u32 = 0; | |
| 4671 | 4691 | |
| 4672 | 4692 | // Section symbols |
| 4673 | 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 | 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 | 4706 | symtab_shdr.sh_link = self.strtab_section_index.?; |
| 4680 | 4707 | |
| 4681 | 4708 | const sym_size: u64 = switch (self.ptr_width) { |
| 4682 | 4709 | .p32 => @sizeOf(elf.Elf32_Sym), |
| 4683 | 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 | 4713 | symtab_shdr.sh_size = needed_size; |
| 4687 | 4714 | |
| 4688 | 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 | 4719 | fn writeSyntheticSections(self: *Elf) !void { |
| ... | ... | @@ -4822,12 +4849,31 @@ fn writeSyntheticSections(self: *Elf) !void { |
| 4822 | 4849 | fn writeSyntheticSectionsObject(self: *Elf) !void { |
| 4823 | 4850 | const gpa = self.base.allocator; |
| 4824 | 4851 | |
| 4825 | if (self.zigObjectPtr()) |zig_object| { | |
| 4826 | try zig_object.writeRelaSections(self); | |
| 4827 | } | |
| 4852 | for (self.output_rela_sections.keys(), self.output_rela_sections.values()) |shndx, atom_list| { | |
| 4853 | if (atom_list.items.len == 0) continue; | |
| 4828 | 4854 | |
| 4829 | for (self.objects.items) |index| { | |
| 4830 | try self.file(index).?.object.writeRelaSections(self); | |
| 4855 | const shdr = self.shdrs.items[shndx]; | |
| 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 | 4879 | if (self.eh_frame_section_index) |shndx| { |
| ... | ... | @@ -4836,7 +4882,7 @@ fn writeSyntheticSectionsObject(self: *Elf) !void { |
| 4836 | 4882 | var buffer = try std.ArrayList(u8).initCapacity(gpa, sh_size); |
| 4837 | 4883 | defer buffer.deinit(); |
| 4838 | 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 | 4888 | try self.writeSymtab(); |
| ... | ... | @@ -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 | 4899 | fn writeSymtab(self: *Elf) !void { |
| 4864 | 4900 | const gpa = self.base.allocator; |
| 4865 | 4901 | const symtab_shdr = self.shdrs.items[self.symtab_section_index.?]; |
| ... | ... | @@ -4876,54 +4912,41 @@ fn writeSymtab(self: *Elf) !void { |
| 4876 | 4912 | const needed_strtab_size = math.cast(usize, strtab_shdr.sh_size - 1) orelse return error.Overflow; |
| 4877 | 4913 | try self.strtab.ensureUnusedCapacity(gpa, needed_strtab_size); |
| 4878 | 4914 | |
| 4879 | var ctx: WriteSymtabCtx = .{ | |
| 4880 | .ilocal = 1, | |
| 4881 | .iglobal = symtab_shdr.sh_info, | |
| 4882 | }; | |
| 4883 | ||
| 4884 | ctx.incr(self.writeSectionSymbols(ctx)); | |
| 4915 | self.writeSectionSymbols(); | |
| 4885 | 4916 | |
| 4886 | 4917 | if (self.zigObjectPtr()) |zig_object| { |
| 4887 | zig_object.asFile().writeSymtab(self, ctx); | |
| 4888 | ctx.incr(zig_object.output_symtab_size); | |
| 4918 | zig_object.asFile().writeSymtab(self); | |
| 4889 | 4919 | } |
| 4890 | 4920 | |
| 4891 | 4921 | for (self.objects.items) |index| { |
| 4892 | 4922 | const file_ptr = self.file(index).?; |
| 4893 | file_ptr.writeSymtab(self, ctx); | |
| 4894 | ctx.incr(file_ptr.object.output_symtab_size); | |
| 4923 | file_ptr.writeSymtab(self); | |
| 4895 | 4924 | } |
| 4896 | 4925 | |
| 4897 | 4926 | for (self.shared_objects.items) |index| { |
| 4898 | 4927 | const file_ptr = self.file(index).?; |
| 4899 | file_ptr.writeSymtab(self, ctx); | |
| 4900 | ctx.incr(file_ptr.shared_object.output_symtab_size); | |
| 4928 | file_ptr.writeSymtab(self); | |
| 4901 | 4929 | } |
| 4902 | 4930 | |
| 4903 | 4931 | if (self.zig_got_section_index) |_| { |
| 4904 | self.zig_got.writeSymtab(self, ctx); | |
| 4905 | ctx.incr(self.zig_got.output_symtab_size); | |
| 4932 | self.zig_got.writeSymtab(self); | |
| 4906 | 4933 | } |
| 4907 | 4934 | |
| 4908 | 4935 | if (self.got_section_index) |_| { |
| 4909 | self.got.writeSymtab(self, ctx); | |
| 4910 | ctx.incr(self.got.output_symtab_size); | |
| 4936 | self.got.writeSymtab(self); | |
| 4911 | 4937 | } |
| 4912 | 4938 | |
| 4913 | 4939 | if (self.plt_section_index) |_| { |
| 4914 | self.plt.writeSymtab(self, ctx); | |
| 4915 | ctx.incr(self.plt.output_symtab_size); | |
| 4940 | self.plt.writeSymtab(self); | |
| 4916 | 4941 | } |
| 4917 | 4942 | |
| 4918 | 4943 | if (self.plt_got_section_index) |_| { |
| 4919 | self.plt_got.writeSymtab(self, ctx); | |
| 4920 | ctx.incr(self.plt_got.output_symtab_size); | |
| 4944 | self.plt_got.writeSymtab(self); | |
| 4921 | 4945 | } |
| 4922 | 4946 | |
| 4923 | 4947 | if (self.linker_defined_index) |index| { |
| 4924 | 4948 | const file_ptr = self.file(index).?; |
| 4925 | file_ptr.writeSymtab(self, ctx); | |
| 4926 | ctx.incr(file_ptr.linker_defined.output_symtab_size); | |
| 4949 | file_ptr.writeSymtab(self); | |
| 4927 | 4950 | } |
| 4928 | 4951 | |
| 4929 | 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 | 4995 | const needed_strtab_size = math.cast(usize, strtab_shdr.sh_size - 1) orelse return error.Overflow; |
| 4973 | 4996 | try self.strtab.ensureUnusedCapacity(gpa, needed_strtab_size); |
| 4974 | 4997 | |
| 4975 | var ctx: WriteSymtabCtx = .{ | |
| 4976 | .ilocal = 1, | |
| 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); | |
| 4998 | self.writeSectionSymbols(); | |
| 4999 | zig_object.asFile().writeSymtab(self); | |
| 4984 | 5000 | |
| 4985 | 5001 | const foreign_endian = self.base.options.target.cpu.arch.endian() != builtin.cpu.arch.endian(); |
| 4986 | 5002 | switch (self.ptr_width) { |
| ... | ... | @@ -5012,8 +5028,8 @@ fn writeSymtabZigObject(self: *Elf, zig_object: *ZigObject) !void { |
| 5012 | 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 { | |
| 5016 | var ilocal = ctx.ilocal; | |
| 5031 | fn writeSectionSymbols(self: *Elf) void { | |
| 5032 | var ilocal: u32 = 1; | |
| 5017 | 5033 | for (self.output_sections.keys()) |shndx| { |
| 5018 | 5034 | const shdr = self.shdrs.items[shndx]; |
| 5019 | 5035 | const out_sym = &self.symtab.items[ilocal]; |
| ... | ... | @@ -5027,7 +5043,6 @@ fn writeSectionSymbols(self: *Elf, ctx: WriteSymtabCtx) SymtabSize { |
| 5027 | 5043 | }; |
| 5028 | 5044 | ilocal += 1; |
| 5029 | 5045 | } |
| 5030 | return .{ .nlocals = @intCast(ilocal - ctx.ilocal) }; | |
| 5031 | 5046 | } |
| 5032 | 5047 | |
| 5033 | 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 | 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 | 6077 | nlocals: u32 = 0, |
| 6061 | 6078 | nglobals: u32 = 0, |
| 6062 | 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 | 6082 | pub const null_sym = elf.Elf64_Sym{ |
src/link/Elf/Atom.zig+26| ... | ... | @@ -293,6 +293,32 @@ pub fn relocs(self: Atom, elf_file: *Elf) []align(1) const elf.Elf64_Rela { |
| 293 | 293 | }; |
| 294 | 294 | } |
| 295 | 295 | |
| 296 | pub fn writeRelocs(self: Atom, elf_file: *Elf, out_relocs: *std.ArrayList(elf.Elf64_Rela)) !void { | |
| 297 | const file_ptr = self.file(elf_file).?; | |
| 298 | for (self.relocs(elf_file)) |rel| { | |
| 299 | const target_index = switch (file_ptr) { | |
| 300 | .zig_object => |x| x.symbol(rel.r_sym()), | |
| 301 | .object => |x| x.symbols.items[rel.r_sym()], | |
| 302 | else => unreachable, | |
| 303 | }; | |
| 304 | const target = elf_file.symbol(target_index); | |
| 305 | const r_sym = target.outputSymtabIndex(elf_file); | |
| 306 | const r_offset = self.value + rel.r_offset; | |
| 307 | const r_addend = rel.r_addend; | |
| 308 | const r_type = switch (rel.r_type()) { | |
| 309 | Elf.R_X86_64_ZIG_GOT32, | |
| 310 | Elf.R_X86_64_ZIG_GOTPCREL, | |
| 311 | => unreachable, // Sanity check if we accidentally emitted those. | |
| 312 | else => |r_type| r_type, | |
| 313 | }; | |
| 314 | out_relocs.appendAssumeCapacity(.{ | |
| 315 | .r_offset = r_offset, | |
| 316 | .r_addend = r_addend, | |
| 317 | .r_info = (@as(u64, @intCast(r_sym)) << 32) | r_type, | |
| 318 | }); | |
| 319 | } | |
| 320 | } | |
| 321 | ||
| 296 | 322 | pub fn fdes(self: Atom, elf_file: *Elf) []Fde { |
| 297 | 323 | if (self.fde_start == self.fde_end) return &[0]Fde{}; |
| 298 | 324 | const object = self.file(elf_file).?.object; |
src/link/Elf/LinkerDefined.zig+1-1| ... | ... | @@ -3,7 +3,7 @@ symtab: std.ArrayListUnmanaged(elf.Elf64_Sym) = .{}, |
| 3 | 3 | strtab: std.ArrayListUnmanaged(u8) = .{}, |
| 4 | 4 | symbols: std.ArrayListUnmanaged(Symbol.Index) = .{}, |
| 5 | 5 | |
| 6 | output_symtab_size: Elf.SymtabSize = .{}, | |
| 6 | output_symtab_ctx: Elf.SymtabCtx = .{}, | |
| 7 | 7 | |
| 8 | 8 | pub fn deinit(self: *LinkerDefined, allocator: Allocator) void { |
| 9 | 9 | self.symtab.deinit(allocator); |
src/link/Elf/Object.zig+7-10| ... | ... | @@ -19,7 +19,7 @@ cies: std.ArrayListUnmanaged(Cie) = .{}, |
| 19 | 19 | alive: bool = true, |
| 20 | 20 | num_dynrelocs: u32 = 0, |
| 21 | 21 | |
| 22 | output_symtab_size: Elf.SymtabSize = .{}, | |
| 22 | output_symtab_ctx: Elf.SymtabCtx = .{}, | |
| 23 | 23 | output_ar_state: Archive.ArState = .{}, |
| 24 | 24 | |
| 25 | 25 | pub fn isObject(path: []const u8) !bool { |
| ... | ... | @@ -672,22 +672,19 @@ pub fn initRelaSections(self: Object, elf_file: *Elf) !void { |
| 672 | 672 | } |
| 673 | 673 | } |
| 674 | 674 | |
| 675 | pub fn updateRelaSectionsSizes(self: Object, elf_file: *Elf) void { | |
| 675 | pub fn addAtomsToRelaSections(self: Object, elf_file: *Elf) !void { | |
| 676 | 676 | for (self.atoms.items) |atom_index| { |
| 677 | 677 | const atom = elf_file.atom(atom_index) orelse continue; |
| 678 | 678 | if (!atom.flags.alive) continue; |
| 679 | 679 | const shndx = atom.relocsShndx() orelse continue; |
| 680 | 680 | const shdr = self.shdrs.items[shndx]; |
| 681 | 681 | const out_shndx = self.initOutputSection(elf_file, shdr) catch unreachable; |
| 682 | const out_shdr = &elf_file.shdrs.items[out_shndx]; | |
| 683 | const relocs = atom.relocs(elf_file); | |
| 684 | out_shdr.sh_size += out_shdr.sh_entsize * relocs.len; | |
| 685 | } | |
| 686 | } | |
| 687 | 682 | |
| 688 | pub fn writeRelaSections(self: Object, elf_file: *Elf) !void { | |
| 689 | _ = self; | |
| 690 | _ = elf_file; | |
| 683 | const gpa = elf_file.base.allocator; | |
| 684 | const gop = try elf_file.output_rela_sections.getOrPut(gpa, out_shndx); | |
| 685 | if (!gop.found_existing) gop.value_ptr.* = .{}; | |
| 686 | try gop.value_ptr.append(gpa, atom_index); | |
| 687 | } | |
| 691 | 688 | } |
| 692 | 689 | |
| 693 | 690 | pub fn updateArSymtab(self: Object, ar_symtab: *Archive.ArSymtab, elf_file: *Elf) !void { |
src/link/Elf/SharedObject.zig+1-1| ... | ... | @@ -21,7 +21,7 @@ verdef_sect_index: ?u16 = null, |
| 21 | 21 | needed: bool, |
| 22 | 22 | alive: bool, |
| 23 | 23 | |
| 24 | output_symtab_size: Elf.SymtabSize = .{}, | |
| 24 | output_symtab_ctx: Elf.SymtabCtx = .{}, | |
| 25 | 25 | |
| 26 | 26 | pub fn isSharedObject(path: []const u8) !bool { |
| 27 | 27 | const file = try std.fs.cwd().openFile(path, .{}); |
src/link/Elf/Symbol.zig+19| ... | ... | @@ -107,6 +107,24 @@ pub fn address(symbol: Symbol, opts: struct { plt: bool = true }, elf_file: *Elf |
| 107 | 107 | return symbol.value; |
| 108 | 108 | } |
| 109 | 109 | |
| 110 | pub fn outputSymtabIndex(symbol: Symbol, elf_file: *Elf) u32 { | |
| 111 | assert(symbol.flags.output_symtab); | |
| 112 | const file_ptr = symbol.file(elf_file).?; | |
| 113 | const symtab_ctx = switch (file_ptr) { | |
| 114 | inline else => |x| x.output_symtab_ctx, | |
| 115 | }; | |
| 116 | const idx = symbol.extra(elf_file).?.symtab; | |
| 117 | return if (symbol.isLocal(elf_file)) idx + symtab_ctx.ilocal else idx + symtab_ctx.iglobal; | |
| 118 | } | |
| 119 | ||
| 120 | pub fn setOutputSymtabIndex(symbol: *Symbol, index: u32, elf_file: *Elf) !void { | |
| 121 | if (symbol.extra(elf_file)) |extras| { | |
| 122 | var new_extras = extras; | |
| 123 | new_extras.symtab = index; | |
| 124 | symbol.setExtra(new_extras, elf_file); | |
| 125 | } else try symbol.addExtra(.{ .symtab = index }, elf_file); | |
| 126 | } | |
| 127 | ||
| 110 | 128 | pub fn gotAddress(symbol: Symbol, elf_file: *Elf) u64 { |
| 111 | 129 | if (!symbol.flags.has_got) return 0; |
| 112 | 130 | const extras = symbol.extra(elf_file).?; |
| ... | ... | @@ -388,6 +406,7 @@ pub const Extra = struct { |
| 388 | 406 | plt: u32 = 0, |
| 389 | 407 | plt_got: u32 = 0, |
| 390 | 408 | dynamic: u32 = 0, |
| 409 | symtab: u32 = 0, | |
| 391 | 410 | copy_rel: u32 = 0, |
| 392 | 411 | tlsgd: u32 = 0, |
| 393 | 412 | gottp: u32 = 0, |
src/link/Elf/ZigObject.zig+11-88| ... | ... | @@ -18,7 +18,7 @@ relocs: std.ArrayListUnmanaged(std.ArrayListUnmanaged(elf.Elf64_Rela)) = .{}, |
| 18 | 18 | |
| 19 | 19 | num_dynrelocs: u32 = 0, |
| 20 | 20 | |
| 21 | output_symtab_size: Elf.SymtabSize = .{}, | |
| 21 | output_symtab_ctx: Elf.SymtabCtx = .{}, | |
| 22 | 22 | output_ar_state: Archive.ArState = .{}, |
| 23 | 23 | |
| 24 | 24 | dwarf: ?Dwarf = null, |
| ... | ... | @@ -533,94 +533,17 @@ pub fn writeAr(self: ZigObject, elf_file: *Elf, writer: anytype) !void { |
| 533 | 533 | try writer.writeAll(contents); |
| 534 | 534 | } |
| 535 | 535 | |
| 536 | pub fn updateRelaSectionsSizes(self: ZigObject, elf_file: *Elf) void { | |
| 537 | _ = self; | |
| 538 | ||
| 539 | for (&[_]?u16{ | |
| 540 | elf_file.zig_text_rela_section_index, | |
| 541 | elf_file.zig_data_rel_ro_rela_section_index, | |
| 542 | elf_file.zig_data_rela_section_index, | |
| 543 | }) |maybe_index| { | |
| 544 | const index = maybe_index orelse continue; | |
| 545 | const shdr = &elf_file.shdrs.items[index]; | |
| 546 | const meta = elf_file.last_atom_and_free_list_table.get(@intCast(shdr.sh_info)).?; | |
| 547 | const last_atom_index = meta.last_atom_index; | |
| 548 | ||
| 549 | var atom = elf_file.atom(last_atom_index) orelse continue; | |
| 550 | while (true) { | |
| 551 | const relocs = atom.relocs(elf_file); | |
| 552 | shdr.sh_size += relocs.len * shdr.sh_entsize; | |
| 553 | if (elf_file.atom(atom.prev_index)) |prev| { | |
| 554 | atom = prev; | |
| 555 | } else break; | |
| 556 | } | |
| 557 | } | |
| 558 | ||
| 559 | for (&[_]?u16{ | |
| 560 | elf_file.zig_text_rela_section_index, | |
| 561 | elf_file.zig_data_rel_ro_rela_section_index, | |
| 562 | elf_file.zig_data_rela_section_index, | |
| 563 | }) |maybe_index| { | |
| 564 | const index = maybe_index orelse continue; | |
| 565 | const shdr = &elf_file.shdrs.items[index]; | |
| 566 | if (shdr.sh_size == 0) shdr.sh_offset = 0; | |
| 567 | } | |
| 568 | } | |
| 569 | ||
| 570 | pub fn writeRelaSections(self: ZigObject, elf_file: *Elf) !void { | |
| 571 | const gpa = elf_file.base.allocator; | |
| 572 | ||
| 573 | for (&[_]?u16{ | |
| 574 | elf_file.zig_text_rela_section_index, | |
| 575 | elf_file.zig_data_rel_ro_rela_section_index, | |
| 576 | elf_file.zig_data_rela_section_index, | |
| 577 | }) |maybe_index| { | |
| 578 | const index = maybe_index orelse continue; | |
| 579 | const shdr = elf_file.shdrs.items[index]; | |
| 580 | const meta = elf_file.last_atom_and_free_list_table.get(@intCast(shdr.sh_info)).?; | |
| 581 | const last_atom_index = meta.last_atom_index; | |
| 582 | ||
| 583 | var atom = elf_file.atom(last_atom_index) orelse continue; | |
| 584 | ||
| 585 | var relocs = std.ArrayList(elf.Elf64_Rela).init(gpa); | |
| 586 | defer relocs.deinit(); | |
| 587 | try relocs.ensureTotalCapacityPrecise(@intCast(@divExact(shdr.sh_size, shdr.sh_entsize))); | |
| 588 | ||
| 589 | while (true) { | |
| 590 | for (atom.relocs(elf_file)) |rel| { | |
| 591 | const target = elf_file.symbol(self.symbol(rel.r_sym())); | |
| 592 | const r_offset = atom.value + rel.r_offset; | |
| 593 | const r_sym: u32 = if (target.flags.global) | |
| 594 | (target.esym_index & symbol_mask) + @as(u32, @intCast(self.local_esyms.slice().len)) | |
| 595 | else | |
| 596 | target.esym_index; | |
| 597 | const r_type = switch (rel.r_type()) { | |
| 598 | Elf.R_X86_64_ZIG_GOT32, | |
| 599 | Elf.R_X86_64_ZIG_GOTPCREL, | |
| 600 | => unreachable, // Sanity check if we accidentally emitted those. | |
| 601 | else => |r_type| r_type, | |
| 602 | }; | |
| 603 | relocs.appendAssumeCapacity(.{ | |
| 604 | .r_offset = r_offset, | |
| 605 | .r_addend = rel.r_addend, | |
| 606 | .r_info = (@as(u64, @intCast(r_sym + 1)) << 32) | r_type, | |
| 607 | }); | |
| 608 | } | |
| 609 | if (elf_file.atom(atom.prev_index)) |prev| { | |
| 610 | atom = prev; | |
| 611 | } else break; | |
| 612 | } | |
| 613 | ||
| 614 | const SortRelocs = struct { | |
| 615 | pub fn lessThan(ctx: void, lhs: elf.Elf64_Rela, rhs: elf.Elf64_Rela) bool { | |
| 616 | _ = ctx; | |
| 617 | return lhs.r_offset < rhs.r_offset; | |
| 618 | } | |
| 619 | }; | |
| 620 | ||
| 621 | mem.sort(elf.Elf64_Rela, relocs.items, {}, SortRelocs.lessThan); | |
| 536 | pub fn addAtomsToRelaSections(self: ZigObject, elf_file: *Elf) !void { | |
| 537 | for (self.atoms.items) |atom_index| { | |
| 538 | const atom = elf_file.atom(atom_index) orelse continue; | |
| 539 | if (!atom.flags.alive) continue; | |
| 540 | _ = atom.relocsShndx() orelse continue; | |
| 541 | const out_shndx = atom.outputShndx().?; | |
| 622 | 542 | |
| 623 | try elf_file.base.file.?.pwriteAll(mem.sliceAsBytes(relocs.items), shdr.sh_offset); | |
| 543 | const gpa = elf_file.base.allocator; | |
| 544 | const gop = try elf_file.output_rela_sections.getOrPut(gpa, out_shndx); | |
| 545 | if (!gop.found_existing) gop.value_ptr.* = .{}; | |
| 546 | try gop.value_ptr.append(gpa, atom_index); | |
| 624 | 547 | } |
| 625 | 548 | } |
| 626 | 549 |
src/link/Elf/file.zig+18-24| ... | ... | @@ -127,9 +127,9 @@ pub const File = union(enum) { |
| 127 | 127 | }; |
| 128 | 128 | } |
| 129 | 129 | |
| 130 | pub fn updateSymtabSize(file: File, elf_file: *Elf) void { | |
| 131 | const output_symtab_size = switch (file) { | |
| 132 | inline else => |x| &x.output_symtab_size, | |
| 130 | pub fn updateSymtabSize(file: File, elf_file: *Elf) !void { | |
| 131 | const output_symtab_ctx = switch (file) { | |
| 132 | inline else => |x| &x.output_symtab_ctx, | |
| 133 | 133 | }; |
| 134 | 134 | for (file.locals()) |local_index| { |
| 135 | 135 | const local = elf_file.symbol(local_index); |
| ... | ... | @@ -140,8 +140,9 @@ pub const File = union(enum) { |
| 140 | 140 | else => {}, |
| 141 | 141 | } |
| 142 | 142 | local.flags.output_symtab = true; |
| 143 | output_symtab_size.nlocals += 1; | |
| 144 | output_symtab_size.strsize += @as(u32, @intCast(local.name(elf_file).len)) + 1; | |
| 143 | try local.setOutputSymtabIndex(output_symtab_ctx.nlocals, elf_file); | |
| 144 | output_symtab_ctx.nlocals += 1; | |
| 145 | output_symtab_ctx.strsize += @as(u32, @intCast(local.name(elf_file).len)) + 1; | |
| 145 | 146 | } |
| 146 | 147 | |
| 147 | 148 | for (file.globals()) |global_index| { |
| ... | ... | @@ -151,28 +152,28 @@ pub const File = union(enum) { |
| 151 | 152 | if (global.atom(elf_file)) |atom| if (!atom.flags.alive) continue; |
| 152 | 153 | global.flags.output_symtab = true; |
| 153 | 154 | if (global.isLocal(elf_file)) { |
| 154 | output_symtab_size.nlocals += 1; | |
| 155 | try global.setOutputSymtabIndex(output_symtab_ctx.nlocals, elf_file); | |
| 156 | output_symtab_ctx.nlocals += 1; | |
| 155 | 157 | } else { |
| 156 | output_symtab_size.nglobals += 1; | |
| 158 | try global.setOutputSymtabIndex(output_symtab_ctx.nglobals, elf_file); | |
| 159 | output_symtab_ctx.nglobals += 1; | |
| 157 | 160 | } |
| 158 | output_symtab_size.strsize += @as(u32, @intCast(global.name(elf_file).len)) + 1; | |
| 161 | output_symtab_ctx.strsize += @as(u32, @intCast(global.name(elf_file).len)) + 1; | |
| 159 | 162 | } |
| 160 | 163 | } |
| 161 | 164 | |
| 162 | pub fn writeSymtab(file: File, elf_file: *Elf, ctx: anytype) void { | |
| 163 | var ilocal: usize = ctx.ilocal; | |
| 165 | pub fn writeSymtab(file: File, elf_file: *Elf) void { | |
| 164 | 166 | for (file.locals()) |local_index| { |
| 165 | 167 | const local = elf_file.symbol(local_index); |
| 166 | 168 | if (!local.flags.output_symtab) continue; |
| 167 | const out_sym = &elf_file.symtab.items[ilocal]; | |
| 169 | const idx = local.outputSymtabIndex(elf_file); | |
| 170 | const out_sym = &elf_file.symtab.items[idx]; | |
| 168 | 171 | out_sym.st_name = @intCast(elf_file.strtab.items.len); |
| 169 | 172 | elf_file.strtab.appendSliceAssumeCapacity(local.name(elf_file)); |
| 170 | 173 | elf_file.strtab.appendAssumeCapacity(0); |
| 171 | 174 | local.setOutputSym(elf_file, out_sym); |
| 172 | ilocal += 1; | |
| 173 | 175 | } |
| 174 | 176 | |
| 175 | var iglobal: usize = ctx.iglobal; | |
| 176 | 177 | for (file.globals()) |global_index| { |
| 177 | 178 | const global = elf_file.symbol(global_index); |
| 178 | 179 | const file_ptr = global.file(elf_file) orelse continue; |
| ... | ... | @@ -181,17 +182,10 @@ pub const File = union(enum) { |
| 181 | 182 | const st_name = @as(u32, @intCast(elf_file.strtab.items.len)); |
| 182 | 183 | elf_file.strtab.appendSliceAssumeCapacity(global.name(elf_file)); |
| 183 | 184 | elf_file.strtab.appendAssumeCapacity(0); |
| 184 | if (global.isLocal(elf_file)) { | |
| 185 | const out_sym = &elf_file.symtab.items[ilocal]; | |
| 186 | out_sym.st_name = st_name; | |
| 187 | global.setOutputSym(elf_file, out_sym); | |
| 188 | ilocal += 1; | |
| 189 | } else { | |
| 190 | const out_sym = &elf_file.symtab.items[iglobal]; | |
| 191 | out_sym.st_name = st_name; | |
| 192 | global.setOutputSym(elf_file, out_sym); | |
| 193 | iglobal += 1; | |
| 194 | } | |
| 185 | const idx = global.outputSymtabIndex(elf_file); | |
| 186 | const out_sym = &elf_file.symtab.items[idx]; | |
| 187 | out_sym.st_name = st_name; | |
| 188 | global.setOutputSym(elf_file, out_sym); | |
| 195 | 189 | } |
| 196 | 190 | } |
| 197 | 191 |
src/link/Elf/synthetic_sections.zig+20-20| ... | ... | @@ -222,7 +222,7 @@ pub const DynamicSection = struct { |
| 222 | 222 | |
| 223 | 223 | pub const ZigGotSection = struct { |
| 224 | 224 | entries: std.ArrayListUnmanaged(Symbol.Index) = .{}, |
| 225 | output_symtab_size: Elf.SymtabSize = .{}, | |
| 225 | output_symtab_ctx: Elf.SymtabCtx = .{}, | |
| 226 | 226 | flags: Flags = .{}, |
| 227 | 227 | |
| 228 | 228 | const Flags = packed struct { |
| ... | ... | @@ -359,15 +359,15 @@ pub const ZigGotSection = struct { |
| 359 | 359 | } |
| 360 | 360 | |
| 361 | 361 | pub fn updateSymtabSize(zig_got: *ZigGotSection, elf_file: *Elf) void { |
| 362 | zig_got.output_symtab_size.nlocals = @as(u32, @intCast(zig_got.entries.items.len)); | |
| 362 | zig_got.output_symtab_ctx.nlocals = @as(u32, @intCast(zig_got.entries.items.len)); | |
| 363 | 363 | for (zig_got.entries.items) |entry| { |
| 364 | 364 | const name = elf_file.symbol(entry).name(elf_file); |
| 365 | zig_got.output_symtab_size.strsize += @as(u32, @intCast(name.len + "$ziggot".len)) + 1; | |
| 365 | zig_got.output_symtab_ctx.strsize += @as(u32, @intCast(name.len + "$ziggot".len)) + 1; | |
| 366 | 366 | } |
| 367 | 367 | } |
| 368 | 368 | |
| 369 | pub fn writeSymtab(zig_got: ZigGotSection, elf_file: *Elf, ctx: anytype) void { | |
| 370 | for (zig_got.entries.items, ctx.ilocal.., 0..) |entry, ilocal, index| { | |
| 369 | pub fn writeSymtab(zig_got: ZigGotSection, elf_file: *Elf) void { | |
| 370 | for (zig_got.entries.items, zig_got.output_symtab_ctx.ilocal.., 0..) |entry, ilocal, index| { | |
| 371 | 371 | const symbol = elf_file.symbol(entry); |
| 372 | 372 | const symbol_name = symbol.name(elf_file); |
| 373 | 373 | const st_name = @as(u32, @intCast(elf_file.strtab.items.len)); |
| ... | ... | @@ -420,7 +420,7 @@ pub const ZigGotSection = struct { |
| 420 | 420 | |
| 421 | 421 | pub const GotSection = struct { |
| 422 | 422 | entries: std.ArrayListUnmanaged(Entry) = .{}, |
| 423 | output_symtab_size: Elf.SymtabSize = .{}, | |
| 423 | output_symtab_ctx: Elf.SymtabCtx = .{}, | |
| 424 | 424 | tlsld_index: ?u32 = null, |
| 425 | 425 | flags: Flags = .{}, |
| 426 | 426 | |
| ... | ... | @@ -760,18 +760,18 @@ pub const GotSection = struct { |
| 760 | 760 | } |
| 761 | 761 | |
| 762 | 762 | pub fn updateSymtabSize(got: *GotSection, elf_file: *Elf) void { |
| 763 | got.output_symtab_size.nlocals = @as(u32, @intCast(got.entries.items.len)); | |
| 763 | got.output_symtab_ctx.nlocals = @as(u32, @intCast(got.entries.items.len)); | |
| 764 | 764 | for (got.entries.items) |entry| { |
| 765 | 765 | const symbol_name = switch (entry.tag) { |
| 766 | 766 | .tlsld => "", |
| 767 | 767 | inline else => elf_file.symbol(entry.symbol_index).name(elf_file), |
| 768 | 768 | }; |
| 769 | got.output_symtab_size.strsize += @as(u32, @intCast(symbol_name.len + @tagName(entry.tag).len)) + 1 + 1; | |
| 769 | got.output_symtab_ctx.strsize += @as(u32, @intCast(symbol_name.len + @tagName(entry.tag).len)) + 1 + 1; | |
| 770 | 770 | } |
| 771 | 771 | } |
| 772 | 772 | |
| 773 | pub fn writeSymtab(got: GotSection, elf_file: *Elf, ctx: anytype) void { | |
| 774 | for (got.entries.items, ctx.ilocal..) |entry, ilocal| { | |
| 773 | pub fn writeSymtab(got: GotSection, elf_file: *Elf) void { | |
| 774 | for (got.entries.items, got.output_symtab_ctx.ilocal..) |entry, ilocal| { | |
| 775 | 775 | const symbol = switch (entry.tag) { |
| 776 | 776 | .tlsld => null, |
| 777 | 777 | inline else => elf_file.symbol(entry.symbol_index), |
| ... | ... | @@ -831,7 +831,7 @@ pub const GotSection = struct { |
| 831 | 831 | |
| 832 | 832 | pub const PltSection = struct { |
| 833 | 833 | symbols: std.ArrayListUnmanaged(Symbol.Index) = .{}, |
| 834 | output_symtab_size: Elf.SymtabSize = .{}, | |
| 834 | output_symtab_ctx: Elf.SymtabCtx = .{}, | |
| 835 | 835 | |
| 836 | 836 | pub const preamble_size = 32; |
| 837 | 837 | |
| ... | ... | @@ -909,15 +909,15 @@ pub const PltSection = struct { |
| 909 | 909 | } |
| 910 | 910 | |
| 911 | 911 | pub fn updateSymtabSize(plt: *PltSection, elf_file: *Elf) void { |
| 912 | plt.output_symtab_size.nlocals = @as(u32, @intCast(plt.symbols.items.len)); | |
| 912 | plt.output_symtab_ctx.nlocals = @as(u32, @intCast(plt.symbols.items.len)); | |
| 913 | 913 | for (plt.symbols.items) |sym_index| { |
| 914 | 914 | const name = elf_file.symbol(sym_index).name(elf_file); |
| 915 | plt.output_symtab_size.strsize += @as(u32, @intCast(name.len + "$plt".len)) + 1; | |
| 915 | plt.output_symtab_ctx.strsize += @as(u32, @intCast(name.len + "$plt".len)) + 1; | |
| 916 | 916 | } |
| 917 | 917 | } |
| 918 | 918 | |
| 919 | pub fn writeSymtab(plt: PltSection, elf_file: *Elf, ctx: anytype) void { | |
| 920 | var ilocal = ctx.ilocal; | |
| 919 | pub fn writeSymtab(plt: PltSection, elf_file: *Elf) void { | |
| 920 | var ilocal = plt.output_symtab_ctx.ilocal; | |
| 921 | 921 | for (plt.symbols.items) |sym_index| { |
| 922 | 922 | const sym = elf_file.symbol(sym_index); |
| 923 | 923 | const st_name = @as(u32, @intCast(elf_file.strtab.items.len)); |
| ... | ... | @@ -968,7 +968,7 @@ pub const GotPltSection = struct { |
| 968 | 968 | |
| 969 | 969 | pub const PltGotSection = struct { |
| 970 | 970 | symbols: std.ArrayListUnmanaged(Symbol.Index) = .{}, |
| 971 | output_symtab_size: Elf.SymtabSize = .{}, | |
| 971 | output_symtab_ctx: Elf.SymtabCtx = .{}, | |
| 972 | 972 | |
| 973 | 973 | pub fn deinit(plt_got: *PltGotSection, allocator: Allocator) void { |
| 974 | 974 | plt_got.symbols.deinit(allocator); |
| ... | ... | @@ -1008,15 +1008,15 @@ pub const PltGotSection = struct { |
| 1008 | 1008 | } |
| 1009 | 1009 | |
| 1010 | 1010 | pub fn updateSymtabSize(plt_got: *PltGotSection, elf_file: *Elf) void { |
| 1011 | plt_got.output_symtab_size.nlocals = @as(u32, @intCast(plt_got.symbols.items.len)); | |
| 1011 | plt_got.output_symtab_ctx.nlocals = @as(u32, @intCast(plt_got.symbols.items.len)); | |
| 1012 | 1012 | for (plt_got.symbols.items) |sym_index| { |
| 1013 | 1013 | const name = elf_file.symbol(sym_index).name(elf_file); |
| 1014 | plt_got.output_symtab_size.strsize += @as(u32, @intCast(name.len + "$pltgot".len)) + 1; | |
| 1014 | plt_got.output_symtab_ctx.strsize += @as(u32, @intCast(name.len + "$pltgot".len)) + 1; | |
| 1015 | 1015 | } |
| 1016 | 1016 | } |
| 1017 | 1017 | |
| 1018 | pub fn writeSymtab(plt_got: PltGotSection, elf_file: *Elf, ctx: anytype) void { | |
| 1019 | var ilocal = ctx.ilocal; | |
| 1018 | pub fn writeSymtab(plt_got: PltGotSection, elf_file: *Elf) void { | |
| 1019 | var ilocal = plt_got.output_symtab_ctx.ilocal; | |
| 1020 | 1020 | for (plt_got.symbols.items) |sym_index| { |
| 1021 | 1021 | const sym = elf_file.symbol(sym_index); |
| 1022 | 1022 | const st_name = @as(u32, @intCast(elf_file.strtab.items.len)); |