zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit 39064347460d1f8cd72ada1e77618fc2b83f8d0d (tree)
parent ce198b7c28e89c0bb502d215f9f9de99abb25f08
Author: Alex Rønne Petersen <alex@alexrp.com>
Date:   Tue, 28 Apr 2026 16:01:44 +0200

link.Elf: implement .preinit_array support

Diffstat:
Msrc/link/Elf.zig | 8+++++---
Msrc/link/Elf/ZigObject.zig | 4++++
Msrc/link/Elf/synthetic_sections.zig | 8++++++++
3 files changed, 17 insertions(+), 3 deletions(-)

diff --git a/src/link/Elf.zig b/src/link/Elf.zig @@ -1392,9 +1392,9 @@ pub fn initOutputSection(self: *Elf, args: struct { if (self.base.isRelocatable()) break :blk args.name; if (args.flags & elf.SHF_MERGE != 0) break :blk args.name; const name_prefixes: []const [:0]const u8 = &.{ - ".text", ".data.rel.ro", ".data", ".rodata", ".bss.rel.ro", ".bss", - ".init_array", ".fini_array", ".tbss", ".tdata", ".gcc_except_table", ".ctors", - ".dtors", ".gnu.warning", + ".text", ".data.rel.ro", ".data", ".rodata", ".bss.rel.ro", ".bss", + ".preinit_array", ".init_array", ".fini_array", ".tbss", ".tdata", ".gcc_except_table", + ".ctors", ".dtors", ".gnu.warning", }; inline for (name_prefixes) |prefix| { if (mem.eql(u8, args.name, prefix) or mem.startsWith(u8, args.name, prefix ++ ".")) { @@ -1409,6 +1409,8 @@ pub fn initOutputSection(self: *Elf, args: struct { switch (args.type) { elf.SHT_NULL => unreachable, elf.SHT_PROGBITS => { + if (mem.eql(u8, args.name, ".preinit_array") or mem.startsWith(u8, args.name, ".preinit_array.")) + break :tt elf.SHT_PREINIT_ARRAY; if (mem.eql(u8, args.name, ".init_array") or mem.startsWith(u8, args.name, ".init_array.")) break :tt elf.SHT_INIT_ARRAY; if (mem.eql(u8, args.name, ".fini_array") or mem.startsWith(u8, args.name, ".fini_array.")) diff --git a/src/link/Elf/ZigObject.zig b/src/link/Elf/ZigObject.zig @@ -1237,6 +1237,10 @@ fn getNavShdrIndex( self.debug_rnglists_index = section_index; } else if (std.mem.startsWith(u8, section_name, ".debug")) { elf_file.sections.items(.shdr)[osec].sh_flags = 0; + } else if (std.mem.eql(u8, section_name, ".preinit_array") or std.mem.startsWith(u8, section_name, ".preinit_array.")) { + const shdr = &elf_file.sections.items(.shdr)[osec]; + shdr.sh_type = elf.SHT_PREINIT_ARRAY; + shdr.sh_flags = elf.SHF_ALLOC | elf.SHF_WRITE; } else if (std.mem.eql(u8, section_name, ".init_array") or std.mem.startsWith(u8, section_name, ".init_array.")) { const shdr = &elf_file.sections.items(.shdr)[osec]; shdr.sh_type = elf.SHT_INIT_ARRAY; diff --git a/src/link/Elf/synthetic_sections.zig b/src/link/Elf/synthetic_sections.zig @@ -73,6 +73,7 @@ pub const DynamicSection = struct { if (dt.rpath > 0) nentries += 1; // RUNPATH if (elf_file.sectionByName(".init") != null) nentries += 1; // INIT if (elf_file.sectionByName(".fini") != null) nentries += 1; // FINI + if (elf_file.sectionByName(".preinit_array") != null) nentries += 2; // PREINIT_ARRAY if (elf_file.sectionByName(".init_array") != null) nentries += 2; // INIT_ARRAY if (elf_file.sectionByName(".fini_array") != null) nentries += 2; // FINI_ARRAY if (elf_file.section_indexes.rela_dyn != null) nentries += 3; // RELA @@ -124,6 +125,13 @@ pub const DynamicSection = struct { try writer.writeStruct(@as(elf.Elf64_Dyn, .{ .d_tag = elf.DT_FINI, .d_val = addr }), .little); } + // PREINIT_ARRAY + if (elf_file.sectionByName(".preinit_array")) |shndx| { + const shdr = shdrs[shndx]; + try writer.writeStruct(@as(elf.Elf64_Dyn, .{ .d_tag = elf.DT_PREINIT_ARRAY, .d_val = shdr.sh_addr }), .little); + try writer.writeStruct(@as(elf.Elf64_Dyn, .{ .d_tag = elf.DT_PREINIT_ARRAYSZ, .d_val = shdr.sh_size }), .little); + } + // INIT_ARRAY if (elf_file.sectionByName(".init_array")) |shndx| { const shdr = shdrs[shndx];