Commit 1efc0519ce
Changed files (2)
src
link
src/link/Elf/Object.zig
@@ -630,7 +630,6 @@ pub fn addAtomsToOutputSections(self: *Object, elf_file: *Elf) !void {
const shdr = atom.inputShdr(elf_file);
atom.output_section_index = self.initOutputSection(elf_file, shdr) catch unreachable;
- if (shdr.sh_type == elf.SHT_NOBITS) continue;
const gpa = elf_file.base.allocator;
const gop = try elf_file.output_sections.getOrPut(gpa, atom.output_section_index);
if (!gop.found_existing) gop.value_ptr.* = .{};
@@ -638,19 +637,6 @@ pub fn addAtomsToOutputSections(self: *Object, elf_file: *Elf) !void {
}
}
-pub fn updateSectionSizes(self: Object, elf_file: *Elf) void {
- for (self.atoms.items) |atom_index| {
- const atom = elf_file.atom(atom_index) orelse continue;
- if (!atom.flags.alive) continue;
- const shdr = &elf_file.shdrs.items[atom.output_section_index];
- const offset = atom.alignment.forward(shdr.sh_size);
- const padding = offset - shdr.sh_size;
- atom.value = offset;
- shdr.sh_size += padding + atom.size;
- shdr.sh_addralign = @max(shdr.sh_addralign, atom.alignment.toByteUnits(1));
- }
-}
-
pub fn allocateAtoms(self: Object, elf_file: *Elf) void {
for (self.atoms.items) |atom_index| {
const atom = elf_file.atom(atom_index) orelse continue;
src/link/Elf.zig
@@ -4123,6 +4123,21 @@ fn initSections(self: *Elf) !void {
}
}
+/// We need to sort constructors/destuctors in the following sections:
+/// * .init_array
+/// * .fini_array
+/// * .preinit_array
+/// * .ctors
+/// * .dtors
+/// The prority of inclusion is defined as part of the input section's name. For example, .init_array.10000.
+/// If no priority value has been specified,
+/// * for .init_array, .fini_array and .preinit_array, we automatically assign that section max value of maxInt(i32)
+/// and push it to the back of the queue,
+/// * for .ctors and .dtors, we automatically assign that section min value of -1
+/// and push it to the front of the queue,
+/// crtbegin and ctrend are assigned minInt(i32) and maxInt(i32) respectively.
+/// Ties are broken by the file prority which corresponds to the inclusion of input sections in this output section
+/// we are about to sort.
fn sortInitFini(self: *Elf) !void {
const gpa = self.base.allocator;
@@ -4130,8 +4145,10 @@ fn sortInitFini(self: *Elf) !void {
priority: i32,
atom_index: Atom.Index,
- pub fn lessThan(ctx: void, lhs: @This(), rhs: @This()) bool {
- _ = ctx;
+ pub fn lessThan(ctx: *Elf, lhs: @This(), rhs: @This()) bool {
+ if (lhs.priority == rhs.priority) {
+ return ctx.atom(lhs.atom_index).?.priority(ctx) < ctx.atom(rhs.atom_index).?.priority(ctx);
+ }
return lhs.priority < rhs.priority;
}
};
@@ -4177,7 +4194,7 @@ fn sortInitFini(self: *Elf) !void {
entries.appendAssumeCapacity(.{ .priority = priority, .atom_index = atom_index });
}
- mem.sort(Entry, entries.items, {}, Entry.lessThan);
+ mem.sort(Entry, entries.items, self, Entry.lessThan);
atom_list.clearRetainingCapacity();
for (entries.items) |entry| {
@@ -4387,8 +4404,18 @@ fn sortSections(self: *Elf) !void {
}
fn updateSectionSizes(self: *Elf) !void {
- for (self.objects.items) |index| {
- self.file(index).?.object.updateSectionSizes(self);
+ for (self.output_sections.keys(), self.output_sections.values()) |shndx, atom_list| {
+ if (atom_list.items.len == 0) continue;
+ const shdr = &self.shdrs.items[shndx];
+ for (atom_list.items) |atom_index| {
+ const atom_ptr = self.atom(atom_index) orelse continue;
+ if (!atom_ptr.flags.alive) continue;
+ const offset = atom_ptr.alignment.forward(shdr.sh_size);
+ const padding = offset - shdr.sh_size;
+ atom_ptr.value = offset;
+ shdr.sh_size += padding + atom_ptr.size;
+ shdr.sh_addralign = @max(shdr.sh_addralign, atom_ptr.alignment.toByteUnits(1));
+ }
}
if (self.eh_frame_section_index) |index| {
@@ -4668,12 +4695,12 @@ fn allocateSectionsInMemory(self: *Elf, base_offset: u64) !void {
tls_start_align: u64 = 1,
first_tls_index: ?usize = null,
- inline fn isFirstTlsShdr(this: @This(), other: usize) bool {
+ fn isFirstTlsShdr(this: @This(), other: usize) bool {
if (this.first_tls_index) |index| return index == other;
return false;
}
- inline fn @"align"(this: @This(), index: usize, sh_addralign: u64, addr: u64) u64 {
+ fn @"align"(this: @This(), index: usize, sh_addralign: u64, addr: u64) u64 {
const alignment = if (this.isFirstTlsShdr(index)) this.tls_start_align else sh_addralign;
return mem.alignForward(u64, addr, alignment);
}