| ... | ... | @@ -1573,6 +1573,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 1573 | 1573 | |
| 1574 | 1574 | self.allocatePhdrTable(); |
| 1575 | 1575 | try self.allocateAllocSections(); |
| 1576 | try self.sortPhdrs(); |
| 1576 | 1577 | try self.allocateNonAllocSections(); |
| 1577 | 1578 | self.allocateSpecialPhdrs(); |
| 1578 | 1579 | self.allocateAtoms(); |
| ... | ... | @@ -4076,6 +4077,77 @@ fn setHashSections(self: *Elf) !void { |
| 4076 | 4077 | } |
| 4077 | 4078 | } |
| 4078 | 4079 | |
| 4080 | fn phdrRank(self: *Elf, phndx: u16) u8 { |
| 4081 | const phdr = self.phdrs.items[phndx]; |
| 4082 | const flags = phdr.p_flags; |
| 4083 | switch (phdr.p_type) { |
| 4084 | elf.PT_NULL => return 0, |
| 4085 | elf.PT_PHDR => return 1, |
| 4086 | elf.PT_INTERP => return 2, |
| 4087 | elf.PT_LOAD => if (flags & elf.PF_X != 0) { |
| 4088 | return 4; |
| 4089 | } else if (flags & elf.PF_W != 0) { |
| 4090 | return 5; |
| 4091 | } else { |
| 4092 | return 3; |
| 4093 | }, |
| 4094 | elf.PT_DYNAMIC, elf.PT_TLS => return 6, |
| 4095 | elf.PT_GNU_EH_FRAME => return 7, |
| 4096 | elf.PT_GNU_STACK => return 8, |
| 4097 | else => return 0xf, |
| 4098 | } |
| 4099 | } |
| 4100 | |
| 4101 | fn sortPhdrs(self: *Elf) error{OutOfMemory}!void { |
| 4102 | const Entry = struct { |
| 4103 | phndx: u16, |
| 4104 | |
| 4105 | pub fn lessThan(elf_file: *Elf, lhs: @This(), rhs: @This()) bool { |
| 4106 | return elf_file.phdrRank(lhs.phndx) < elf_file.phdrRank(rhs.phndx); |
| 4107 | } |
| 4108 | }; |
| 4109 | |
| 4110 | const gpa = self.base.allocator; |
| 4111 | var entries = try std.ArrayList(Entry).initCapacity(gpa, self.phdrs.items.len); |
| 4112 | defer entries.deinit(); |
| 4113 | for (0..self.phdrs.items.len) |phndx| { |
| 4114 | entries.appendAssumeCapacity(.{ .phndx = @as(u16, @intCast(phndx)) }); |
| 4115 | } |
| 4116 | |
| 4117 | mem.sort(Entry, entries.items, self, Entry.lessThan); |
| 4118 | |
| 4119 | const backlinks = try gpa.alloc(u16, entries.items.len); |
| 4120 | defer gpa.free(backlinks); |
| 4121 | for (entries.items, 0..) |entry, i| { |
| 4122 | backlinks[entry.phndx] = @as(u16, @intCast(i)); |
| 4123 | } |
| 4124 | |
| 4125 | var slice = try self.phdrs.toOwnedSlice(gpa); |
| 4126 | defer gpa.free(slice); |
| 4127 | |
| 4128 | try self.phdrs.ensureTotalCapacityPrecise(gpa, slice.len); |
| 4129 | for (entries.items) |sorted| { |
| 4130 | self.phdrs.appendAssumeCapacity(slice[sorted.phndx]); |
| 4131 | } |
| 4132 | |
| 4133 | for (&[_]*?u16{ |
| 4134 | &self.phdr_zig_load_re_index, |
| 4135 | &self.phdr_zig_got_index, |
| 4136 | &self.phdr_zig_load_ro_index, |
| 4137 | &self.phdr_zig_load_zerofill_index, |
| 4138 | &self.phdr_table_index, |
| 4139 | &self.phdr_table_load_index, |
| 4140 | &self.phdr_interp_index, |
| 4141 | &self.phdr_dynamic_index, |
| 4142 | &self.phdr_gnu_eh_frame_index, |
| 4143 | &self.phdr_tls_index, |
| 4144 | }) |maybe_index| { |
| 4145 | if (maybe_index.*) |*index| { |
| 4146 | index.* = backlinks[index.*]; |
| 4147 | } |
| 4148 | } |
| 4149 | } |
| 4150 | |
| 4079 | 4151 | fn sectionRank(self: *Elf, shndx: u16) u8 { |
| 4080 | 4152 | const shdr = self.shdrs.items[shndx]; |
| 4081 | 4153 | const name = self.shstrtab.getAssumeExists(shdr.sh_name); |