| ... | @@ -3927,20 +3927,9 @@ fn initSpecialPhdrs(self: *Elf) !void { | ... | @@ -3927,20 +3927,9 @@ fn initSpecialPhdrs(self: *Elf) !void { |
| 3927 | .@"align" = 1, | 3927 | .@"align" = 1, |
| 3928 | }); | 3928 | }); |
| 3929 | | 3929 | |
| 3930 | const has_tls = has_tls: { | 3930 | const has_tls = for (self.shdrs.items) |shdr| { |
| 3931 | if (self.base.options.link_libc and self.isStatic()) { | 3931 | if (shdr.sh_flags & elf.SHF_TLS != 0) break true; |
| 3932 | // Even if we don't emit any TLS data, linking against musl-libc without | 3932 | } else false; |
| 3933 | // empty TLS phdr leads to a bizarre segfault in `__copy_tls` function. | | |
| 3934 | // So far I haven't been able to work out why that is, but adding an empty | | |
| 3935 | // TLS phdr seems to fix it, so let's go with it for now. | | |
| 3936 | // TODO try to investigate more | | |
| 3937 | break :has_tls true; | | |
| 3938 | } | | |
| 3939 | for (self.shdrs.items) |shdr| { | | |
| 3940 | if (shdr.sh_flags & elf.SHF_TLS != 0) break :has_tls true; | | |
| 3941 | } | | |
| 3942 | break :has_tls false; | | |
| 3943 | }; | | |
| 3944 | if (has_tls) { | 3933 | if (has_tls) { |
| 3945 | self.phdr_tls_index = try self.addPhdr(.{ | 3934 | self.phdr_tls_index = try self.addPhdr(.{ |
| 3946 | .type = elf.PT_TLS, | 3935 | .type = elf.PT_TLS, |
| ... | @@ -4076,24 +4065,16 @@ fn setHashSections(self: *Elf) !void { | ... | @@ -4076,24 +4065,16 @@ fn setHashSections(self: *Elf) !void { |
| 4076 | } | 4065 | } |
| 4077 | } | 4066 | } |
| 4078 | | 4067 | |
| 4079 | fn phdrRank(self: *Elf, phndx: u16) u8 { | 4068 | fn phdrRank(phdr: elf.Elf64_Phdr) u8 { |
| 4080 | const phdr = self.phdrs.items[phndx]; | | |
| 4081 | const flags = phdr.p_flags; | | |
| 4082 | switch (phdr.p_type) { | 4069 | switch (phdr.p_type) { |
| 4083 | elf.PT_NULL => return 0, | 4070 | elf.PT_NULL => return 0, |
| 4084 | elf.PT_PHDR => return 1, | 4071 | elf.PT_PHDR => return 1, |
| 4085 | elf.PT_INTERP => return 2, | 4072 | elf.PT_INTERP => return 2, |
| 4086 | elf.PT_LOAD => if (flags & elf.PF_X != 0) { | 4073 | elf.PT_LOAD => return 3, |
| 4087 | return 4; | 4074 | elf.PT_DYNAMIC, elf.PT_TLS => return 4, |
| 4088 | } else if (flags & elf.PF_W != 0) { | 4075 | elf.PT_GNU_EH_FRAME => return 5, |
| 4089 | return 5; | 4076 | elf.PT_GNU_STACK => return 6, |
| 4090 | } else { | 4077 | else => return 7, |
| 4091 | return 3; | | |
| 4092 | }, | | |
| 4093 | elf.PT_DYNAMIC, elf.PT_TLS => return 6, | | |
| 4094 | elf.PT_GNU_EH_FRAME => return 7, | | |
| 4095 | elf.PT_GNU_STACK => return 8, | | |
| 4096 | else => return 0xf, | | |
| 4097 | } | 4078 | } |
| 4098 | } | 4079 | } |
| 4099 | | 4080 | |
| ... | @@ -4102,7 +4083,12 @@ fn sortPhdrs(self: *Elf) error{OutOfMemory}!void { | ... | @@ -4102,7 +4083,12 @@ fn sortPhdrs(self: *Elf) error{OutOfMemory}!void { |
| 4102 | phndx: u16, | 4083 | phndx: u16, |
| 4103 | | 4084 | |
| 4104 | pub fn lessThan(elf_file: *Elf, lhs: @This(), rhs: @This()) bool { | 4085 | pub fn lessThan(elf_file: *Elf, lhs: @This(), rhs: @This()) bool { |
| 4105 | return elf_file.phdrRank(lhs.phndx) < elf_file.phdrRank(rhs.phndx); | 4086 | const lhs_phdr = elf_file.phdrs.items[lhs.phndx]; |
| | 4087 | const rhs_phdr = elf_file.phdrs.items[rhs.phndx]; |
| | 4088 | const lhs_rank = phdrRank(lhs_phdr); |
| | 4089 | const rhs_rank = phdrRank(rhs_phdr); |
| | 4090 | if (lhs_rank == rhs_rank) return lhs_phdr.p_vaddr < rhs_phdr.p_vaddr; |
| | 4091 | return lhs_rank < rhs_rank; |
| 4106 | } | 4092 | } |
| 4107 | }; | 4093 | }; |
| 4108 | | 4094 | |
| ... | @@ -4674,7 +4660,7 @@ fn allocateAllocSections(self: *Elf) error{OutOfMemory}!void { | ... | @@ -4674,7 +4660,7 @@ fn allocateAllocSections(self: *Elf) error{OutOfMemory}!void { |
| 4674 | try self.phdr_to_shdr_table.putNoClobber(gpa, shndx, phndx); | 4660 | try self.phdr_to_shdr_table.putNoClobber(gpa, shndx, phndx); |
| 4675 | } | 4661 | } |
| 4676 | | 4662 | |
| 4677 | addr += self.page_size; | 4663 | addr = mem.alignForward(u64, addr, self.page_size); |
| 4678 | } | 4664 | } |
| 4679 | } | 4665 | } |
| 4680 | | 4666 | |