authorgravatar for alex14fr@gmail.comAlexandre Janon <alex14fr@gmail.com> 2024-04-28 11:45:50+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-05-01 12:04:19-07:00
log704f8f4013dee59c899f8900ee2289983bb9d5da
tree7ee0eeed0512a41213bd023241f722fab224c0dd
parentef9fb428b7433238b9c0bd38d3ff36accf0f3d12

Fix ELF alignment for freestanding targets (#19766)

* Fix the ELF binaries for freestanding target created with the self-hosted linker. The ELF specification (generic ABI) states that ``loadable process segments must have congruent values for p_vaddr and p_offset, modulo the page size''. Linux refuses to load binaries that don't meet this requirement (execve() fails with EINVAL).

1 files changed, 4 insertions(+), 7 deletions(-)

src/link/Elf.zig+4-7
......@@ -648,7 +648,6 @@ pub fn initMetadata(self: *Elf, options: InitMetadataOptions) !void {
648648 const ptr_size = self.ptrWidthBytes();
649649 const target = self.base.comp.root_mod.resolved_target.result;
650650 const ptr_bit_width = target.ptrBitWidth();
651 const has_os = target.os.tag != .freestanding;
652651 const zig_object = self.zigObjectPtr().?;
653652
654653 const fillSection = struct {
......@@ -684,9 +683,7 @@ pub fn initMetadata(self: *Elf, options: InitMetadataOptions) !void {
684683 }
685684
686685 if (self.phdr_zig_got_index == null) {
687 // We really only need ptr alignment but since we are using PROGBITS, linux requires
688 // page align.
689 const alignment = if (has_os) self.page_size else @as(u16, ptr_size);
686 const alignment = self.page_size;
690687 const filesz = @as(u64, ptr_size) * options.symbol_count_hint;
691688 const off = self.findFreeSpace(filesz, alignment);
692689 self.phdr_zig_got_index = try self.addPhdr(.{
......@@ -701,7 +698,7 @@ pub fn initMetadata(self: *Elf, options: InitMetadataOptions) !void {
701698 }
702699
703700 if (self.phdr_zig_load_ro_index == null) {
704 const alignment = if (has_os) self.page_size else @as(u16, ptr_size);
701 const alignment = self.page_size;
705702 const filesz: u64 = 1024;
706703 const off = self.findFreeSpace(filesz, alignment);
707704 self.phdr_zig_load_ro_index = try self.addPhdr(.{
......@@ -716,7 +713,7 @@ pub fn initMetadata(self: *Elf, options: InitMetadataOptions) !void {
716713 }
717714
718715 if (self.phdr_zig_load_rw_index == null) {
719 const alignment = if (has_os) self.page_size else @as(u16, ptr_size);
716 const alignment = self.page_size;
720717 const filesz: u64 = 1024;
721718 const off = self.findFreeSpace(filesz, alignment);
722719 self.phdr_zig_load_rw_index = try self.addPhdr(.{
......@@ -731,7 +728,7 @@ pub fn initMetadata(self: *Elf, options: InitMetadataOptions) !void {
731728 }
732729
733730 if (self.phdr_zig_load_zerofill_index == null) {
734 const alignment = if (has_os) self.page_size else @as(u16, ptr_size);
731 const alignment = self.page_size;
735732 self.phdr_zig_load_zerofill_index = try self.addPhdr(.{
736733 .type = elf.PT_LOAD,
737734 .addr = if (ptr_bit_width >= 32) 0x14000000 else 0xf000,