| ... | ... | @@ -32,11 +32,6 @@ output_sections: std.AutoArrayHashMapUnmanaged(u16, std.ArrayListUnmanaged(Atom. |
| 32 | 32 | phdrs: std.ArrayListUnmanaged(elf.Elf64_Phdr) = .{}, |
| 33 | 33 | |
| 34 | 34 | /// Tracked loadable segments during incremental linking. |
| 35 | | /// The index into the program headers of the PT_LOAD program header containing the phdr |
| 36 | | /// Most linkers would merge this with phdr_load_ro_index, |
| 37 | | /// but incremental linking means we can't ensure they are consecutive. |
| 38 | | /// If this segment is not needed, it won't get emitted. |
| 39 | | phdr_table_load_index: ?u16 = null, |
| 40 | 35 | /// The index into the program headers of a PT_LOAD program header with Read and Execute flags |
| 41 | 36 | phdr_load_re_zig_index: ?u16 = null, |
| 42 | 37 | /// The index into the program headers of the global offset table. |
| ... | ... | @@ -161,7 +156,6 @@ symbols_free_list: std.ArrayListUnmanaged(Symbol.Index) = .{}, |
| 161 | 156 | has_text_reloc: bool = false, |
| 162 | 157 | num_ifunc_dynrelocs: usize = 0, |
| 163 | 158 | |
| 164 | | phdr_table_dirty: bool = false, |
| 165 | 159 | shdr_table_dirty: bool = false, |
| 166 | 160 | |
| 167 | 161 | debug_strtab_dirty: bool = false, |
| ... | ... | @@ -291,14 +285,17 @@ pub fn openPath(allocator: Allocator, sub_path: []const u8, options: link.Option |
| 291 | 285 | .p32 => @alignOf(elf.Elf32_Phdr), |
| 292 | 286 | .p64 => @alignOf(elf.Elf64_Phdr), |
| 293 | 287 | }; |
| 288 | const offset: u64 = switch (self.ptr_width) { |
| 289 | .p32 => @sizeOf(elf.Elf32_Ehdr), |
| 290 | .p64 => @sizeOf(elf.Elf64_Ehdr), |
| 291 | }; |
| 294 | 292 | self.phdr_table_index = try self.addPhdr(.{ |
| 295 | 293 | .type = elf.PT_PHDR, |
| 296 | 294 | .flags = elf.PF_R, |
| 297 | 295 | .@"align" = p_align, |
| 298 | | .addr = self.calcImageBase() + @sizeOf(elf.Elf64_Ehdr), |
| 299 | | .offset = @sizeOf(elf.Elf64_Ehdr), |
| 296 | .addr = self.calcImageBase() + offset, |
| 297 | .offset = offset, |
| 300 | 298 | }); |
| 301 | | // self.phdr_table_dirty = true; |
| 302 | 299 | } |
| 303 | 300 | |
| 304 | 301 | if (options.module != null and !options.use_llvm) { |
| ... | ... | @@ -639,7 +636,6 @@ pub fn allocateSegment(self: *Elf, opts: AllocateSegmentOpts) error{OutOfMemory} |
| 639 | 636 | .p_align = opts.alignment, |
| 640 | 637 | .p_flags = opts.flags, |
| 641 | 638 | }); |
| 642 | | self.phdr_table_dirty = true; |
| 643 | 639 | return index; |
| 644 | 640 | } |
| 645 | 641 | |
| ... | ... | @@ -711,15 +707,6 @@ pub fn initMetadata(self: *Elf) !void { |
| 711 | 707 | const ptr_size: u8 = self.ptrWidthBytes(); |
| 712 | 708 | const is_linux = self.base.options.target.os.tag == .linux; |
| 713 | 709 | |
| 714 | | if (self.phdr_table_load_index == null) { |
| 715 | | self.phdr_table_load_index = try self.allocateSegment(.{ |
| 716 | | .addr = self.calcImageBase(), |
| 717 | | .size = 0, |
| 718 | | .alignment = self.page_size, |
| 719 | | }); |
| 720 | | self.phdr_table_dirty = true; |
| 721 | | } |
| 722 | | |
| 723 | 710 | if (self.phdr_load_re_zig_index == null) { |
| 724 | 711 | self.phdr_load_re_zig_index = try self.allocateSegment(.{ |
| 725 | 712 | .size = self.base.options.program_code_size_hint, |
| ... | ... | @@ -926,7 +913,7 @@ pub fn growAllocSection(self: *Elf, shdr_index: u16, needed_size: u64) !void { |
| 926 | 913 | |
| 927 | 914 | phdr.p_memsz = needed_size; |
| 928 | 915 | |
| 929 | | self.markDirty(shdr_index, phdr_index); |
| 916 | self.markDirty(shdr_index); |
| 930 | 917 | } |
| 931 | 918 | |
| 932 | 919 | fn growSegment(self: *Elf, shndx: u16, needed_size: u64) !void { |
| ... | ... | @@ -1021,16 +1008,12 @@ pub fn growNonAllocSection( |
| 1021 | 1008 | |
| 1022 | 1009 | shdr.sh_size = needed_size; // anticipating adding the global symbols later |
| 1023 | 1010 | |
| 1024 | | self.markDirty(shdr_index, null); |
| 1011 | self.markDirty(shdr_index); |
| 1025 | 1012 | } |
| 1026 | 1013 | |
| 1027 | | pub fn markDirty(self: *Elf, shdr_index: u16, phdr_index: ?u16) void { |
| 1014 | pub fn markDirty(self: *Elf, shdr_index: u16) void { |
| 1028 | 1015 | self.shdr_table_dirty = true; // TODO look into only writing one section |
| 1029 | 1016 | |
| 1030 | | if (phdr_index) |_| { |
| 1031 | | self.phdr_table_dirty = true; // TODO look into making only the one program header dirty |
| 1032 | | } |
| 1033 | | |
| 1034 | 1017 | if (self.dwarf) |_| { |
| 1035 | 1018 | if (self.debug_info_section_index.? == shdr_index) { |
| 1036 | 1019 | self.debug_info_header_dirty = true; |
| ... | ... | @@ -1722,68 +1705,6 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 1722 | 1705 | } |
| 1723 | 1706 | } |
| 1724 | 1707 | |
| 1725 | | // if (self.phdr_table_dirty) { |
| 1726 | | // const phsize: u64 = switch (self.ptr_width) { |
| 1727 | | // .p32 => @sizeOf(elf.Elf32_Phdr), |
| 1728 | | // .p64 => @sizeOf(elf.Elf64_Phdr), |
| 1729 | | // }; |
| 1730 | | |
| 1731 | | // const phdr_table_index = self.phdr_table_index.?; |
| 1732 | | // const phdr_table = &self.phdrs.items[phdr_table_index]; |
| 1733 | | // const phdr_table_load = &self.phdrs.items[self.phdr_table_load_index.?]; |
| 1734 | | |
| 1735 | | // const allocated_size = self.allocatedSize(phdr_table.p_offset); |
| 1736 | | // const needed_size = self.phdrs.items.len * phsize; |
| 1737 | | |
| 1738 | | // if (needed_size > allocated_size) { |
| 1739 | | // phdr_table.p_offset = 0; // free the space |
| 1740 | | // phdr_table.p_offset = self.findFreeSpace(needed_size, @as(u32, @intCast(phdr_table.p_align))); |
| 1741 | | // } |
| 1742 | | |
| 1743 | | // phdr_table_load.p_offset = mem.alignBackward(u64, phdr_table.p_offset, phdr_table_load.p_align); |
| 1744 | | // const load_align_offset = phdr_table.p_offset - phdr_table_load.p_offset; |
| 1745 | | // phdr_table_load.p_filesz = load_align_offset + needed_size; |
| 1746 | | // phdr_table_load.p_memsz = load_align_offset + needed_size; |
| 1747 | | |
| 1748 | | // phdr_table.p_filesz = needed_size; |
| 1749 | | // phdr_table.p_vaddr = phdr_table_load.p_vaddr + load_align_offset; |
| 1750 | | // phdr_table.p_paddr = phdr_table_load.p_paddr + load_align_offset; |
| 1751 | | // phdr_table.p_memsz = needed_size; |
| 1752 | | |
| 1753 | | // switch (self.ptr_width) { |
| 1754 | | // .p32 => { |
| 1755 | | // const buf = try gpa.alloc(elf.Elf32_Phdr, self.phdrs.items.len); |
| 1756 | | // defer gpa.free(buf); |
| 1757 | | |
| 1758 | | // for (buf, 0..) |*phdr, i| { |
| 1759 | | // phdr.* = phdrTo32(self.phdrs.items[i]); |
| 1760 | | // if (foreign_endian) { |
| 1761 | | // mem.byteSwapAllFields(elf.Elf32_Phdr, phdr); |
| 1762 | | // } |
| 1763 | | // } |
| 1764 | | // try self.base.file.?.pwriteAll(mem.sliceAsBytes(buf), phdr_table.p_offset); |
| 1765 | | // }, |
| 1766 | | // .p64 => { |
| 1767 | | // const buf = try gpa.alloc(elf.Elf64_Phdr, self.phdrs.items.len); |
| 1768 | | // defer gpa.free(buf); |
| 1769 | | |
| 1770 | | // for (buf, 0..) |*phdr, i| { |
| 1771 | | // phdr.* = self.phdrs.items[i]; |
| 1772 | | // if (foreign_endian) { |
| 1773 | | // mem.byteSwapAllFields(elf.Elf64_Phdr, phdr); |
| 1774 | | // } |
| 1775 | | // } |
| 1776 | | // try self.base.file.?.pwriteAll(mem.sliceAsBytes(buf), phdr_table.p_offset); |
| 1777 | | // }, |
| 1778 | | // } |
| 1779 | | |
| 1780 | | // // We don't actually care if the phdr load section overlaps, only the phdr section matters. |
| 1781 | | // phdr_table_load.p_offset = 0; |
| 1782 | | // phdr_table_load.p_filesz = 0; |
| 1783 | | |
| 1784 | | // self.phdr_table_dirty = false; |
| 1785 | | // } |
| 1786 | | |
| 1787 | 1708 | if (self.shdr_table_dirty) { |
| 1788 | 1709 | const shsize: u64 = switch (self.ptr_width) { |
| 1789 | 1710 | .p32 => @sizeOf(elf.Elf32_Shdr), |
| ... | ... | @@ -1834,7 +1755,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 1834 | 1755 | self.shdr_table_dirty = false; |
| 1835 | 1756 | } |
| 1836 | 1757 | |
| 1837 | | try self.writePhdrs(); |
| 1758 | try self.writePhdrTable(); |
| 1838 | 1759 | try self.writeAtoms(); |
| 1839 | 1760 | try self.writeSyntheticSections(); |
| 1840 | 1761 | |
| ... | ... | @@ -1859,7 +1780,6 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 1859 | 1780 | // such as debug_line_header_dirty and debug_info_header_dirty. |
| 1860 | 1781 | assert(!self.debug_abbrev_section_dirty); |
| 1861 | 1782 | assert(!self.debug_aranges_section_dirty); |
| 1862 | | assert(!self.phdr_table_dirty); |
| 1863 | 1783 | assert(!self.shdr_table_dirty); |
| 1864 | 1784 | assert(!self.debug_strtab_dirty); |
| 1865 | 1785 | } |
| ... | ... | @@ -2923,11 +2843,50 @@ fn writeDwarfAddrAssumeCapacity(self: *Elf, buf: *std.ArrayList(u8), addr: u64) |
| 2923 | 2843 | } |
| 2924 | 2844 | } |
| 2925 | 2845 | |
| 2926 | | fn writePhdrs(self: *Elf) !void { |
| 2927 | | const phoff = @sizeOf(elf.Elf64_Ehdr); |
| 2928 | | const phdrs_size = self.phdrs.items.len * @sizeOf(elf.Elf64_Phdr); |
| 2929 | | log.debug("writing program headers from 0x{x} to 0x{x}", .{ phoff, phoff + phdrs_size }); |
| 2930 | | try self.base.file.?.pwriteAll(mem.sliceAsBytes(self.phdrs.items), phoff); |
| 2846 | fn writePhdrTable(self: *Elf) !void { |
| 2847 | const gpa = self.base.allocator; |
| 2848 | const target_endian = self.base.options.target.cpu.arch.endian(); |
| 2849 | const foreign_endian = target_endian != builtin.cpu.arch.endian(); |
| 2850 | const phsize: u64 = switch (self.ptr_width) { |
| 2851 | .p32 => @sizeOf(elf.Elf32_Phdr), |
| 2852 | .p64 => @sizeOf(elf.Elf64_Phdr), |
| 2853 | }; |
| 2854 | const phdr_table = &self.phdrs.items[self.phdr_table_index.?]; |
| 2855 | const needed_size = self.phdrs.items.len * phsize; |
| 2856 | phdr_table.p_filesz = needed_size; |
| 2857 | phdr_table.p_memsz = needed_size; |
| 2858 | |
| 2859 | log.debug("writing program headers from 0x{x} to 0x{x}", .{ |
| 2860 | phdr_table.p_offset, |
| 2861 | phdr_table.p_offset + needed_size, |
| 2862 | }); |
| 2863 | |
| 2864 | switch (self.ptr_width) { |
| 2865 | .p32 => { |
| 2866 | const buf = try gpa.alloc(elf.Elf32_Phdr, self.phdrs.items.len); |
| 2867 | defer gpa.free(buf); |
| 2868 | |
| 2869 | for (buf, 0..) |*phdr, i| { |
| 2870 | phdr.* = phdrTo32(self.phdrs.items[i]); |
| 2871 | if (foreign_endian) { |
| 2872 | mem.byteSwapAllFields(elf.Elf32_Phdr, phdr); |
| 2873 | } |
| 2874 | } |
| 2875 | try self.base.file.?.pwriteAll(mem.sliceAsBytes(buf), phdr_table.p_offset); |
| 2876 | }, |
| 2877 | .p64 => { |
| 2878 | const buf = try gpa.alloc(elf.Elf64_Phdr, self.phdrs.items.len); |
| 2879 | defer gpa.free(buf); |
| 2880 | |
| 2881 | for (buf, 0..) |*phdr, i| { |
| 2882 | phdr.* = self.phdrs.items[i]; |
| 2883 | if (foreign_endian) { |
| 2884 | mem.byteSwapAllFields(elf.Elf64_Phdr, phdr); |
| 2885 | } |
| 2886 | } |
| 2887 | try self.base.file.?.pwriteAll(mem.sliceAsBytes(buf), phdr_table.p_offset); |
| 2888 | }, |
| 2889 | } |
| 2931 | 2890 | } |
| 2932 | 2891 | |
| 2933 | 2892 | fn writeHeader(self: *Elf) !void { |
| ... | ... | @@ -4065,7 +4024,6 @@ fn initSpecialPhdrs(self: *Elf) !void { |
| 4065 | 4024 | .memsz = self.base.options.stack_size_override orelse 0, |
| 4066 | 4025 | .@"align" = 1, |
| 4067 | 4026 | }); |
| 4068 | | // self.phdr_table_dirty = true; |
| 4069 | 4027 | } |
| 4070 | 4028 | |
| 4071 | 4029 | /// We need to sort constructors/destuctors in the following sections: |