| ... | ... | @@ -4123,6 +4123,21 @@ fn initSections(self: *Elf) !void { |
| 4123 | 4123 | } |
| 4124 | 4124 | } |
| 4125 | 4125 | |
| 4126 | /// We need to sort constructors/destuctors in the following sections: |
| 4127 | /// * .init_array |
| 4128 | /// * .fini_array |
| 4129 | /// * .preinit_array |
| 4130 | /// * .ctors |
| 4131 | /// * .dtors |
| 4132 | /// The prority of inclusion is defined as part of the input section's name. For example, .init_array.10000. |
| 4133 | /// If no priority value has been specified, |
| 4134 | /// * for .init_array, .fini_array and .preinit_array, we automatically assign that section max value of maxInt(i32) |
| 4135 | /// and push it to the back of the queue, |
| 4136 | /// * for .ctors and .dtors, we automatically assign that section min value of -1 |
| 4137 | /// and push it to the front of the queue, |
| 4138 | /// crtbegin and ctrend are assigned minInt(i32) and maxInt(i32) respectively. |
| 4139 | /// Ties are broken by the file prority which corresponds to the inclusion of input sections in this output section |
| 4140 | /// we are about to sort. |
| 4126 | 4141 | fn sortInitFini(self: *Elf) !void { |
| 4127 | 4142 | const gpa = self.base.allocator; |
| 4128 | 4143 | |
| ... | ... | @@ -4130,8 +4145,10 @@ fn sortInitFini(self: *Elf) !void { |
| 4130 | 4145 | priority: i32, |
| 4131 | 4146 | atom_index: Atom.Index, |
| 4132 | 4147 | |
| 4133 | | pub fn lessThan(ctx: void, lhs: @This(), rhs: @This()) bool { |
| 4134 | | _ = ctx; |
| 4148 | pub fn lessThan(ctx: *Elf, lhs: @This(), rhs: @This()) bool { |
| 4149 | if (lhs.priority == rhs.priority) { |
| 4150 | return ctx.atom(lhs.atom_index).?.priority(ctx) < ctx.atom(rhs.atom_index).?.priority(ctx); |
| 4151 | } |
| 4135 | 4152 | return lhs.priority < rhs.priority; |
| 4136 | 4153 | } |
| 4137 | 4154 | }; |
| ... | ... | @@ -4177,7 +4194,7 @@ fn sortInitFini(self: *Elf) !void { |
| 4177 | 4194 | entries.appendAssumeCapacity(.{ .priority = priority, .atom_index = atom_index }); |
| 4178 | 4195 | } |
| 4179 | 4196 | |
| 4180 | | mem.sort(Entry, entries.items, {}, Entry.lessThan); |
| 4197 | mem.sort(Entry, entries.items, self, Entry.lessThan); |
| 4181 | 4198 | |
| 4182 | 4199 | atom_list.clearRetainingCapacity(); |
| 4183 | 4200 | for (entries.items) |entry| { |
| ... | ... | @@ -4387,8 +4404,18 @@ fn sortSections(self: *Elf) !void { |
| 4387 | 4404 | } |
| 4388 | 4405 | |
| 4389 | 4406 | fn updateSectionSizes(self: *Elf) !void { |
| 4390 | | for (self.objects.items) |index| { |
| 4391 | | self.file(index).?.object.updateSectionSizes(self); |
| 4407 | for (self.output_sections.keys(), self.output_sections.values()) |shndx, atom_list| { |
| 4408 | if (atom_list.items.len == 0) continue; |
| 4409 | const shdr = &self.shdrs.items[shndx]; |
| 4410 | for (atom_list.items) |atom_index| { |
| 4411 | const atom_ptr = self.atom(atom_index) orelse continue; |
| 4412 | if (!atom_ptr.flags.alive) continue; |
| 4413 | const offset = atom_ptr.alignment.forward(shdr.sh_size); |
| 4414 | const padding = offset - shdr.sh_size; |
| 4415 | atom_ptr.value = offset; |
| 4416 | shdr.sh_size += padding + atom_ptr.size; |
| 4417 | shdr.sh_addralign = @max(shdr.sh_addralign, atom_ptr.alignment.toByteUnits(1)); |
| 4418 | } |
| 4392 | 4419 | } |
| 4393 | 4420 | |
| 4394 | 4421 | if (self.eh_frame_section_index) |index| { |
| ... | ... | @@ -4668,12 +4695,12 @@ fn allocateSectionsInMemory(self: *Elf, base_offset: u64) !void { |
| 4668 | 4695 | tls_start_align: u64 = 1, |
| 4669 | 4696 | first_tls_index: ?usize = null, |
| 4670 | 4697 | |
| 4671 | | inline fn isFirstTlsShdr(this: @This(), other: usize) bool { |
| 4698 | fn isFirstTlsShdr(this: @This(), other: usize) bool { |
| 4672 | 4699 | if (this.first_tls_index) |index| return index == other; |
| 4673 | 4700 | return false; |
| 4674 | 4701 | } |
| 4675 | 4702 | |
| 4676 | | inline fn @"align"(this: @This(), index: usize, sh_addralign: u64, addr: u64) u64 { |
| 4703 | fn @"align"(this: @This(), index: usize, sh_addralign: u64, addr: u64) u64 { |
| 4677 | 4704 | const alignment = if (this.isFirstTlsShdr(index)) this.tls_start_align else sh_addralign; |
| 4678 | 4705 | return mem.alignForward(u64, addr, alignment); |
| 4679 | 4706 | } |