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 {...@@ -648,7 +648,6 @@ pub fn initMetadata(self: *Elf, options: InitMetadataOptions) !void {
648 const ptr_size = self.ptrWidthBytes();648 const ptr_size = self.ptrWidthBytes();
649 const target = self.base.comp.root_mod.resolved_target.result;649 const target = self.base.comp.root_mod.resolved_target.result;
650 const ptr_bit_width = target.ptrBitWidth();650 const ptr_bit_width = target.ptrBitWidth();
651 const has_os = target.os.tag != .freestanding;
652 const zig_object = self.zigObjectPtr().?;651 const zig_object = self.zigObjectPtr().?;
653652
654 const fillSection = struct {653 const fillSection = struct {
...@@ -684,9 +683,7 @@ pub fn initMetadata(self: *Elf, options: InitMetadataOptions) !void {...@@ -684,9 +683,7 @@ pub fn initMetadata(self: *Elf, options: InitMetadataOptions) !void {
684 }683 }
685684
686 if (self.phdr_zig_got_index == null) {685 if (self.phdr_zig_got_index == null) {
687 // We really only need ptr alignment but since we are using PROGBITS, linux requires686 const alignment = self.page_size;
688 // page align.
689 const alignment = if (has_os) self.page_size else @as(u16, ptr_size);
690 const filesz = @as(u64, ptr_size) * options.symbol_count_hint;687 const filesz = @as(u64, ptr_size) * options.symbol_count_hint;
691 const off = self.findFreeSpace(filesz, alignment);688 const off = self.findFreeSpace(filesz, alignment);
692 self.phdr_zig_got_index = try self.addPhdr(.{689 self.phdr_zig_got_index = try self.addPhdr(.{
...@@ -701,7 +698,7 @@ pub fn initMetadata(self: *Elf, options: InitMetadataOptions) !void {...@@ -701,7 +698,7 @@ pub fn initMetadata(self: *Elf, options: InitMetadataOptions) !void {
701 }698 }
702699
703 if (self.phdr_zig_load_ro_index == null) {700 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;
705 const filesz: u64 = 1024;702 const filesz: u64 = 1024;
706 const off = self.findFreeSpace(filesz, alignment);703 const off = self.findFreeSpace(filesz, alignment);
707 self.phdr_zig_load_ro_index = try self.addPhdr(.{704 self.phdr_zig_load_ro_index = try self.addPhdr(.{
...@@ -716,7 +713,7 @@ pub fn initMetadata(self: *Elf, options: InitMetadataOptions) !void {...@@ -716,7 +713,7 @@ pub fn initMetadata(self: *Elf, options: InitMetadataOptions) !void {
716 }713 }
717714
718 if (self.phdr_zig_load_rw_index == null) {715 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;
720 const filesz: u64 = 1024;717 const filesz: u64 = 1024;
721 const off = self.findFreeSpace(filesz, alignment);718 const off = self.findFreeSpace(filesz, alignment);
722 self.phdr_zig_load_rw_index = try self.addPhdr(.{719 self.phdr_zig_load_rw_index = try self.addPhdr(.{
...@@ -731,7 +728,7 @@ pub fn initMetadata(self: *Elf, options: InitMetadataOptions) !void {...@@ -731,7 +728,7 @@ pub fn initMetadata(self: *Elf, options: InitMetadataOptions) !void {
731 }728 }
732729
733 if (self.phdr_zig_load_zerofill_index == null) {730 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;
735 self.phdr_zig_load_zerofill_index = try self.addPhdr(.{732 self.phdr_zig_load_zerofill_index = try self.addPhdr(.{
736 .type = elf.PT_LOAD,733 .type = elf.PT_LOAD,
737 .addr = if (ptr_bit_width >= 32) 0x14000000 else 0xf000,734 .addr = if (ptr_bit_width >= 32) 0x14000000 else 0xf000,