mirror of
https://github.com/ziglang/zig.git
synced 2026-02-13 12:59:04 +00:00
elf: sort phdr table
This commit is contained in:
parent
5423778f6f
commit
46cf4c5d93
@ -1573,6 +1573,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
|
||||
|
||||
self.allocatePhdrTable();
|
||||
try self.allocateAllocSections();
|
||||
try self.sortPhdrs();
|
||||
try self.allocateNonAllocSections();
|
||||
self.allocateSpecialPhdrs();
|
||||
self.allocateAtoms();
|
||||
@ -4076,6 +4077,77 @@ fn setHashSections(self: *Elf) !void {
|
||||
}
|
||||
}
|
||||
|
||||
fn phdrRank(self: *Elf, phndx: u16) u8 {
|
||||
const phdr = self.phdrs.items[phndx];
|
||||
const flags = phdr.p_flags;
|
||||
switch (phdr.p_type) {
|
||||
elf.PT_NULL => return 0,
|
||||
elf.PT_PHDR => return 1,
|
||||
elf.PT_INTERP => return 2,
|
||||
elf.PT_LOAD => if (flags & elf.PF_X != 0) {
|
||||
return 4;
|
||||
} else if (flags & elf.PF_W != 0) {
|
||||
return 5;
|
||||
} else {
|
||||
return 3;
|
||||
},
|
||||
elf.PT_DYNAMIC, elf.PT_TLS => return 6,
|
||||
elf.PT_GNU_EH_FRAME => return 7,
|
||||
elf.PT_GNU_STACK => return 8,
|
||||
else => return 0xf,
|
||||
}
|
||||
}
|
||||
|
||||
fn sortPhdrs(self: *Elf) error{OutOfMemory}!void {
|
||||
const Entry = struct {
|
||||
phndx: u16,
|
||||
|
||||
pub fn lessThan(elf_file: *Elf, lhs: @This(), rhs: @This()) bool {
|
||||
return elf_file.phdrRank(lhs.phndx) < elf_file.phdrRank(rhs.phndx);
|
||||
}
|
||||
};
|
||||
|
||||
const gpa = self.base.allocator;
|
||||
var entries = try std.ArrayList(Entry).initCapacity(gpa, self.phdrs.items.len);
|
||||
defer entries.deinit();
|
||||
for (0..self.phdrs.items.len) |phndx| {
|
||||
entries.appendAssumeCapacity(.{ .phndx = @as(u16, @intCast(phndx)) });
|
||||
}
|
||||
|
||||
mem.sort(Entry, entries.items, self, Entry.lessThan);
|
||||
|
||||
const backlinks = try gpa.alloc(u16, entries.items.len);
|
||||
defer gpa.free(backlinks);
|
||||
for (entries.items, 0..) |entry, i| {
|
||||
backlinks[entry.phndx] = @as(u16, @intCast(i));
|
||||
}
|
||||
|
||||
var slice = try self.phdrs.toOwnedSlice(gpa);
|
||||
defer gpa.free(slice);
|
||||
|
||||
try self.phdrs.ensureTotalCapacityPrecise(gpa, slice.len);
|
||||
for (entries.items) |sorted| {
|
||||
self.phdrs.appendAssumeCapacity(slice[sorted.phndx]);
|
||||
}
|
||||
|
||||
for (&[_]*?u16{
|
||||
&self.phdr_zig_load_re_index,
|
||||
&self.phdr_zig_got_index,
|
||||
&self.phdr_zig_load_ro_index,
|
||||
&self.phdr_zig_load_zerofill_index,
|
||||
&self.phdr_table_index,
|
||||
&self.phdr_table_load_index,
|
||||
&self.phdr_interp_index,
|
||||
&self.phdr_dynamic_index,
|
||||
&self.phdr_gnu_eh_frame_index,
|
||||
&self.phdr_tls_index,
|
||||
}) |maybe_index| {
|
||||
if (maybe_index.*) |*index| {
|
||||
index.* = backlinks[index.*];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn sectionRank(self: *Elf, shndx: u16) u8 {
|
||||
const shdr = self.shdrs.items[shndx];
|
||||
const name = self.shstrtab.getAssumeExists(shdr.sh_name);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user