authorgravatar for alex14fr@gmail.comAlexandre Janon <alex14fr@gmail.com> 2024-04-28 11:45:50+02:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2024-04-28 11:45:50+02:00
log25f1526fe6424cef156724977b75a5b80a3d5833
tree5caffcd72f5baac64fe99482fc511db79525d77e
parentaecd9cc6d152443dc7c02dfe373be654d8adae64
signaturebadge-check Signed by PGP key B5690EEEBB952194

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,