| ... | ... | @@ -597,7 +597,6 @@ pub fn initMetadata(self: *Elf) !void { |
| 597 | 597 | const shdr = &self.shdrs.items[self.zig_text_section_index.?]; |
| 598 | 598 | fillSection(self, shdr, self.base.options.program_code_size_hint, self.phdr_zig_load_re_index); |
| 599 | 599 | if (self.isRelocatable()) { |
| 600 | | try zig_object.addSectionSymbol(self.zig_text_section_index.?, self); |
| 601 | 600 | self.zig_text_rela_section_index = try self.addRelaShdr( |
| 602 | 601 | ".rela.text.zig", |
| 603 | 602 | self.zig_text_section_index.?, |
| ... | ... | @@ -609,6 +608,7 @@ pub fn initMetadata(self: *Elf) !void { |
| 609 | 608 | self.phdr_zig_load_re_index.?, |
| 610 | 609 | ); |
| 611 | 610 | } |
| 611 | try self.output_sections.putNoClobber(gpa, self.zig_text_section_index.?, .{}); |
| 612 | 612 | try self.last_atom_and_free_list_table.putNoClobber(gpa, self.zig_text_section_index.?, .{}); |
| 613 | 613 | } |
| 614 | 614 | |
| ... | ... | @@ -644,7 +644,6 @@ 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 | | try zig_object.addSectionSymbol(self.zig_data_rel_ro_section_index.?, self); |
| 648 | 647 | self.zig_data_rel_ro_rela_section_index = try self.addRelaShdr( |
| 649 | 648 | ".rela.data.rel.ro.zig", |
| 650 | 649 | self.zig_data_rel_ro_section_index.?, |
| ... | ... | @@ -656,6 +655,7 @@ pub fn initMetadata(self: *Elf) !void { |
| 656 | 655 | self.phdr_zig_load_ro_index.?, |
| 657 | 656 | ); |
| 658 | 657 | } |
| 658 | try self.output_sections.putNoClobber(gpa, self.zig_data_rel_ro_section_index.?, .{}); |
| 659 | 659 | try self.last_atom_and_free_list_table.putNoClobber(gpa, self.zig_data_rel_ro_section_index.?, .{}); |
| 660 | 660 | } |
| 661 | 661 | |
| ... | ... | @@ -670,7 +670,6 @@ pub fn initMetadata(self: *Elf) !void { |
| 670 | 670 | const shdr = &self.shdrs.items[self.zig_data_section_index.?]; |
| 671 | 671 | fillSection(self, shdr, 1024, self.phdr_zig_load_rw_index); |
| 672 | 672 | if (self.isRelocatable()) { |
| 673 | | try zig_object.addSectionSymbol(self.zig_data_section_index.?, self); |
| 674 | 673 | self.zig_data_rela_section_index = try self.addRelaShdr( |
| 675 | 674 | ".rela.data.zig", |
| 676 | 675 | self.zig_data_section_index.?, |
| ... | ... | @@ -682,6 +681,7 @@ pub fn initMetadata(self: *Elf) !void { |
| 682 | 681 | self.phdr_zig_load_rw_index.?, |
| 683 | 682 | ); |
| 684 | 683 | } |
| 684 | try self.output_sections.putNoClobber(gpa, self.zig_data_section_index.?, .{}); |
| 685 | 685 | try self.last_atom_and_free_list_table.putNoClobber(gpa, self.zig_data_section_index.?, .{}); |
| 686 | 686 | } |
| 687 | 687 | |
| ... | ... | @@ -700,9 +700,9 @@ pub fn initMetadata(self: *Elf) !void { |
| 700 | 700 | shdr.sh_size = phdr.p_memsz; |
| 701 | 701 | try self.phdr_to_shdr_table.putNoClobber(gpa, self.zig_bss_section_index.?, phndx); |
| 702 | 702 | } else { |
| 703 | | try zig_object.addSectionSymbol(self.zig_bss_section_index.?, self); |
| 704 | 703 | shdr.sh_size = 1024; |
| 705 | 704 | } |
| 705 | try self.output_sections.putNoClobber(gpa, self.zig_bss_section_index.?, .{}); |
| 706 | 706 | try self.last_atom_and_free_list_table.putNoClobber(gpa, self.zig_bss_section_index.?, .{}); |
| 707 | 707 | } |
| 708 | 708 | |
| ... | ... | @@ -724,6 +724,7 @@ pub fn initMetadata(self: *Elf) !void { |
| 724 | 724 | shdr.sh_offset = off; |
| 725 | 725 | shdr.sh_size = size; |
| 726 | 726 | zig_object.debug_strtab_dirty = true; |
| 727 | try self.output_sections.putNoClobber(gpa, self.debug_str_section_index.?, .{}); |
| 727 | 728 | } |
| 728 | 729 | |
| 729 | 730 | if (self.debug_info_section_index == null) { |
| ... | ... | @@ -739,6 +740,7 @@ pub fn initMetadata(self: *Elf) !void { |
| 739 | 740 | shdr.sh_offset = off; |
| 740 | 741 | shdr.sh_size = size; |
| 741 | 742 | zig_object.debug_info_header_dirty = true; |
| 743 | try self.output_sections.putNoClobber(gpa, self.debug_info_section_index.?, .{}); |
| 742 | 744 | } |
| 743 | 745 | |
| 744 | 746 | if (self.debug_abbrev_section_index == null) { |
| ... | ... | @@ -754,6 +756,7 @@ pub fn initMetadata(self: *Elf) !void { |
| 754 | 756 | shdr.sh_offset = off; |
| 755 | 757 | shdr.sh_size = size; |
| 756 | 758 | zig_object.debug_abbrev_section_dirty = true; |
| 759 | try self.output_sections.putNoClobber(gpa, self.debug_abbrev_section_index.?, .{}); |
| 757 | 760 | } |
| 758 | 761 | |
| 759 | 762 | if (self.debug_aranges_section_index == null) { |
| ... | ... | @@ -769,6 +772,7 @@ pub fn initMetadata(self: *Elf) !void { |
| 769 | 772 | shdr.sh_offset = off; |
| 770 | 773 | shdr.sh_size = size; |
| 771 | 774 | zig_object.debug_aranges_section_dirty = true; |
| 775 | try self.output_sections.putNoClobber(gpa, self.debug_aranges_section_index.?, .{}); |
| 772 | 776 | } |
| 773 | 777 | |
| 774 | 778 | if (self.debug_line_section_index == null) { |
| ... | ... | @@ -784,6 +788,7 @@ pub fn initMetadata(self: *Elf) !void { |
| 784 | 788 | shdr.sh_offset = off; |
| 785 | 789 | shdr.sh_size = size; |
| 786 | 790 | zig_object.debug_line_header_dirty = true; |
| 791 | try self.output_sections.putNoClobber(gpa, self.debug_line_section_index.?, .{}); |
| 787 | 792 | } |
| 788 | 793 | } |
| 789 | 794 | } |
| ... | ... | @@ -1510,14 +1515,14 @@ pub fn flushStaticLib(self: *Elf) link.File.FlushError!void { |
| 1510 | 1515 | try self.initShStrtab(); |
| 1511 | 1516 | try self.sortShdrs(); |
| 1512 | 1517 | zig_object.updateRelaSectionsSizes(self); |
| 1513 | | self.updateSymtabSizeObject(zig_object); |
| 1518 | self.updateSymtabSizeZigObject(zig_object); |
| 1514 | 1519 | self.updateShStrtabSize(); |
| 1515 | 1520 | |
| 1516 | 1521 | try self.allocateNonAllocSections(); |
| 1517 | 1522 | |
| 1518 | 1523 | try self.writeShdrTable(); |
| 1519 | 1524 | try zig_object.writeRelaSections(self); |
| 1520 | | try self.writeSymtabObject(zig_object); |
| 1525 | try self.writeSymtabZigObject(zig_object); |
| 1521 | 1526 | try self.writeShStrtab(); |
| 1522 | 1527 | try self.writeElfHeader(); |
| 1523 | 1528 | } |
| ... | ... | @@ -3579,7 +3584,8 @@ fn sortInitFini(self: *Elf) !void { |
| 3579 | 3584 | |
| 3580 | 3585 | if (!is_init_fini and !is_ctor_dtor) continue; |
| 3581 | 3586 | |
| 3582 | | const atom_list = self.output_sections.getPtr(@intCast(shndx)) orelse continue; |
| 3587 | const atom_list = self.output_sections.getPtr(@intCast(shndx)).?; |
| 3588 | if (atom_list.items.len == 0) continue; |
| 3583 | 3589 | |
| 3584 | 3590 | var entries = std.ArrayList(Entry).init(gpa); |
| 3585 | 3591 | try entries.ensureTotalCapacityPrecise(atom_list.items.len); |
| ... | ... | @@ -3909,6 +3915,20 @@ fn sortShdrs(self: *Elf) !void { |
| 3909 | 3915 | shdr.sh_info = backlinks[shdr.sh_info]; |
| 3910 | 3916 | } |
| 3911 | 3917 | |
| 3918 | { |
| 3919 | var output_sections = try self.output_sections.clone(gpa); |
| 3920 | defer output_sections.deinit(gpa); |
| 3921 | |
| 3922 | self.output_sections.clearRetainingCapacity(); |
| 3923 | |
| 3924 | var it = output_sections.iterator(); |
| 3925 | while (it.next()) |entry| { |
| 3926 | const shndx = entry.key_ptr.*; |
| 3927 | const meta = entry.value_ptr.*; |
| 3928 | self.output_sections.putAssumeCapacityNoClobber(backlinks[shndx], meta); |
| 3929 | } |
| 3930 | } |
| 3931 | |
| 3912 | 3932 | { |
| 3913 | 3933 | var last_atom_and_free_list_table = try self.last_atom_and_free_list_table.clone(gpa); |
| 3914 | 3934 | defer last_atom_and_free_list_table.deinit(gpa); |
| ... | ... | @@ -3962,7 +3982,6 @@ fn sortShdrs(self: *Elf) !void { |
| 3962 | 3982 | |
| 3963 | 3983 | fn updateSectionSizes(self: *Elf) !void { |
| 3964 | 3984 | for (self.output_sections.keys(), self.output_sections.values()) |shndx, atom_list| { |
| 3965 | | if (atom_list.items.len == 0) continue; |
| 3966 | 3985 | const shdr = &self.shdrs.items[shndx]; |
| 3967 | 3986 | for (atom_list.items) |atom_index| { |
| 3968 | 3987 | const atom_ptr = self.atom(atom_index) orelse continue; |
| ... | ... | @@ -4056,7 +4075,6 @@ fn updateSectionSizes(self: *Elf) !void { |
| 4056 | 4075 | |
| 4057 | 4076 | fn updateSectionSizesObject(self: *Elf) !void { |
| 4058 | 4077 | for (self.output_sections.keys(), self.output_sections.values()) |shndx, atom_list| { |
| 4059 | | if (atom_list.items.len == 0) continue; |
| 4060 | 4078 | const shdr = &self.shdrs.items[shndx]; |
| 4061 | 4079 | for (atom_list.items) |atom_index| { |
| 4062 | 4080 | const atom_ptr = self.atom(atom_index) orelse continue; |
| ... | ... | @@ -4317,7 +4335,6 @@ fn allocateAllocSections(self: *Elf) error{OutOfMemory}!void { |
| 4317 | 4335 | /// Allocates alloc sections when merging relocatable objects files together. |
| 4318 | 4336 | fn allocateAllocSectionsObject(self: *Elf) !void { |
| 4319 | 4337 | _ = self; |
| 4320 | | @panic("TODO"); |
| 4321 | 4338 | } |
| 4322 | 4339 | |
| 4323 | 4340 | /// Allocates non-alloc sections (debug info, symtabs, etc.). |
| ... | ... | @@ -4444,6 +4461,7 @@ fn writeAtoms(self: *Elf) !void { |
| 4444 | 4461 | if (shdr.sh_type == elf.SHT_NOBITS) continue; |
| 4445 | 4462 | |
| 4446 | 4463 | const atom_list = self.output_sections.get(@intCast(shndx)) orelse continue; |
| 4464 | if (atom_list.items.len == 0) continue; |
| 4447 | 4465 | |
| 4448 | 4466 | log.debug("writing atoms in '{s}' section", .{self.getShString(shdr.sh_name)}); |
| 4449 | 4467 | |
| ... | ... | @@ -4519,6 +4537,7 @@ fn writeAtomsObject(self: *Elf) !void { |
| 4519 | 4537 | if (shdr.sh_type == elf.SHT_NOBITS) continue; |
| 4520 | 4538 | |
| 4521 | 4539 | const atom_list = self.output_sections.get(@intCast(shndx)) orelse continue; |
| 4540 | if (atom_list.items.len == 0) continue; |
| 4522 | 4541 | |
| 4523 | 4542 | log.debug("writing atoms in '{s}' section", .{self.getShString(shdr.sh_name)}); |
| 4524 | 4543 | |
| ... | ... | @@ -4617,6 +4636,11 @@ fn updateSymtabSize(self: *Elf) void { |
| 4617 | 4636 | sizes.add(file_ptr.linker_defined.output_symtab_size); |
| 4618 | 4637 | } |
| 4619 | 4638 | |
| 4639 | // Section symbols |
| 4640 | for (self.output_sections.keys()) |_| { |
| 4641 | sizes.nlocals += 1; |
| 4642 | } |
| 4643 | |
| 4620 | 4644 | const symtab_shdr = &self.shdrs.items[self.symtab_section_index.?]; |
| 4621 | 4645 | symtab_shdr.sh_info = sizes.nlocals + 1; |
| 4622 | 4646 | symtab_shdr.sh_link = self.strtab_section_index.?; |
| ... | ... | @@ -4632,9 +4656,16 @@ fn updateSymtabSize(self: *Elf) void { |
| 4632 | 4656 | strtab.sh_size = sizes.strsize + 1; |
| 4633 | 4657 | } |
| 4634 | 4658 | |
| 4635 | | fn updateSymtabSizeObject(self: *Elf, zig_object: *ZigObject) void { |
| 4659 | fn updateSymtabSizeZigObject(self: *Elf, zig_object: *ZigObject) void { |
| 4660 | var sizes = SymtabSize{}; |
| 4661 | |
| 4636 | 4662 | zig_object.asFile().updateSymtabSize(self); |
| 4637 | | const sizes = zig_object.output_symtab_size; |
| 4663 | sizes.add(zig_object.output_symtab_size); |
| 4664 | |
| 4665 | // Section symbols |
| 4666 | for (self.output_sections.keys()) |_| { |
| 4667 | sizes.nlocals += 1; |
| 4668 | } |
| 4638 | 4669 | |
| 4639 | 4670 | const symtab_shdr = &self.shdrs.items[self.symtab_section_index.?]; |
| 4640 | 4671 | symtab_shdr.sh_info = sizes.nlocals + 1; |
| ... | ... | @@ -4798,7 +4829,7 @@ fn writeSyntheticSectionsObject(self: *Elf) !void { |
| 4798 | 4829 | var buffer = try std.ArrayList(u8).initCapacity(gpa, sh_size); |
| 4799 | 4830 | defer buffer.deinit(); |
| 4800 | 4831 | try eh_frame.writeEhFrame(self, buffer.writer()); |
| 4801 | | try self.base.file.?.pwriteAll(buffer.items, shdr.sh_offset); |
| 4832 | // try self.base.file.?.pwriteAll(buffer.items, shdr.sh_offset); |
| 4802 | 4833 | } |
| 4803 | 4834 | |
| 4804 | 4835 | try self.writeSymtab(); |
| ... | ... | @@ -4812,6 +4843,16 @@ fn writeShStrtab(self: *Elf) !void { |
| 4812 | 4843 | } |
| 4813 | 4844 | } |
| 4814 | 4845 | |
| 4846 | const WriteSymtabCtx = struct { |
| 4847 | ilocal: usize, |
| 4848 | iglobal: usize, |
| 4849 | |
| 4850 | fn incr(this: *@This(), ss: SymtabSize) void { |
| 4851 | this.ilocal += ss.nlocals; |
| 4852 | this.iglobal += ss.nglobals; |
| 4853 | } |
| 4854 | }; |
| 4855 | |
| 4815 | 4856 | fn writeSymtab(self: *Elf) !void { |
| 4816 | 4857 | const gpa = self.base.allocator; |
| 4817 | 4858 | const symtab_shdr = self.shdrs.items[self.symtab_section_index.?]; |
| ... | ... | @@ -4828,20 +4869,13 @@ fn writeSymtab(self: *Elf) !void { |
| 4828 | 4869 | const needed_strtab_size = math.cast(usize, strtab_shdr.sh_size - 1) orelse return error.Overflow; |
| 4829 | 4870 | try self.strtab.ensureUnusedCapacity(gpa, needed_strtab_size); |
| 4830 | 4871 | |
| 4831 | | const Ctx = struct { |
| 4832 | | ilocal: usize, |
| 4833 | | iglobal: usize, |
| 4834 | | |
| 4835 | | fn incr(this: *@This(), ss: SymtabSize) void { |
| 4836 | | this.ilocal += ss.nlocals; |
| 4837 | | this.iglobal += ss.nglobals; |
| 4838 | | } |
| 4839 | | }; |
| 4840 | | var ctx: Ctx = .{ |
| 4872 | var ctx: WriteSymtabCtx = .{ |
| 4841 | 4873 | .ilocal = 1, |
| 4842 | 4874 | .iglobal = symtab_shdr.sh_info, |
| 4843 | 4875 | }; |
| 4844 | 4876 | |
| 4877 | ctx.incr(self.writeSectionSymbols(ctx)); |
| 4878 | |
| 4845 | 4879 | if (self.zigObjectPtr()) |zig_object| { |
| 4846 | 4880 | zig_object.asFile().writeSymtab(self, ctx); |
| 4847 | 4881 | ctx.incr(zig_object.output_symtab_size); |
| ... | ... | @@ -4915,7 +4949,7 @@ fn writeSymtab(self: *Elf) !void { |
| 4915 | 4949 | try self.base.file.?.pwriteAll(self.strtab.items, strtab_shdr.sh_offset); |
| 4916 | 4950 | } |
| 4917 | 4951 | |
| 4918 | | fn writeSymtabObject(self: *Elf, zig_object: *ZigObject) !void { |
| 4952 | fn writeSymtabZigObject(self: *Elf, zig_object: *ZigObject) !void { |
| 4919 | 4953 | const gpa = self.base.allocator; |
| 4920 | 4954 | const symtab_shdr = self.shdrs.items[self.symtab_section_index.?]; |
| 4921 | 4955 | const strtab_shdr = self.shdrs.items[self.strtab_section_index.?]; |
| ... | ... | @@ -4931,7 +4965,15 @@ fn writeSymtabObject(self: *Elf, zig_object: *ZigObject) !void { |
| 4931 | 4965 | const needed_strtab_size = math.cast(usize, strtab_shdr.sh_size - 1) orelse return error.Overflow; |
| 4932 | 4966 | try self.strtab.ensureUnusedCapacity(gpa, needed_strtab_size); |
| 4933 | 4967 | |
| 4934 | | zig_object.asFile().writeSymtab(self, .{ .ilocal = 1, .iglobal = symtab_shdr.sh_info }); |
| 4968 | var ctx: WriteSymtabCtx = .{ |
| 4969 | .ilocal = 1, |
| 4970 | .iglobal = symtab_shdr.sh_info, |
| 4971 | }; |
| 4972 | |
| 4973 | ctx.incr(self.writeSectionSymbols(ctx)); |
| 4974 | |
| 4975 | zig_object.asFile().writeSymtab(self, ctx); |
| 4976 | ctx.incr(zig_object.output_symtab_size); |
| 4935 | 4977 | |
| 4936 | 4978 | const foreign_endian = self.base.options.target.cpu.arch.endian() != builtin.cpu.arch.endian(); |
| 4937 | 4979 | switch (self.ptr_width) { |
| ... | ... | @@ -4963,6 +5005,24 @@ fn writeSymtabObject(self: *Elf, zig_object: *ZigObject) !void { |
| 4963 | 5005 | try self.base.file.?.pwriteAll(self.strtab.items, strtab_shdr.sh_offset); |
| 4964 | 5006 | } |
| 4965 | 5007 | |
| 5008 | fn writeSectionSymbols(self: *Elf, ctx: WriteSymtabCtx) SymtabSize { |
| 5009 | var ilocal = ctx.ilocal; |
| 5010 | for (self.output_sections.keys()) |shndx| { |
| 5011 | const shdr = self.shdrs.items[shndx]; |
| 5012 | const out_sym = &self.symtab.items[ilocal]; |
| 5013 | out_sym.* = .{ |
| 5014 | .st_name = 0, |
| 5015 | .st_value = shdr.sh_addr, |
| 5016 | .st_info = elf.STT_SECTION, |
| 5017 | .st_shndx = @intCast(shndx), |
| 5018 | .st_size = 0, |
| 5019 | .st_other = 0, |
| 5020 | }; |
| 5021 | ilocal += 1; |
| 5022 | } |
| 5023 | return .{ .nlocals = @intCast(ilocal - ctx.ilocal) }; |
| 5024 | } |
| 5025 | |
| 4966 | 5026 | /// Always 4 or 8 depending on whether this is 32-bit ELF or 64-bit ELF. |
| 4967 | 5027 | fn ptrWidthBytes(self: Elf) u8 { |
| 4968 | 5028 | return switch (self.ptr_width) { |