authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2026-04-28 16:01:44+02:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2026-04-28 16:42:06+02:00
log39064347460d1f8cd72ada1e77618fc2b83f8d0d
treead5277dd522f6b0d8110fce283eb341810370f62
parentce198b7c28e89c0bb502d215f9f9de99abb25f08
signaturebadge-check Signed by SSH key SHA256:7B/LJ7bpR1eX8aCXSr4mtd5M45VMPKcx9zY8e95b5QM

link.Elf: implement .preinit_array support


3 files changed, 17 insertions(+), 3 deletions(-)

src/link/Elf.zig+5-3
......@@ -1392,9 +1392,9 @@ pub fn initOutputSection(self: *Elf, args: struct {
13921392 if (self.base.isRelocatable()) break :blk args.name;
13931393 if (args.flags & elf.SHF_MERGE != 0) break :blk args.name;
13941394 const name_prefixes: []const [:0]const u8 = &.{
1395 ".text", ".data.rel.ro", ".data", ".rodata", ".bss.rel.ro", ".bss",
1396 ".init_array", ".fini_array", ".tbss", ".tdata", ".gcc_except_table", ".ctors",
1397 ".dtors", ".gnu.warning",
1395 ".text", ".data.rel.ro", ".data", ".rodata", ".bss.rel.ro", ".bss",
1396 ".preinit_array", ".init_array", ".fini_array", ".tbss", ".tdata", ".gcc_except_table",
1397 ".ctors", ".dtors", ".gnu.warning",
13981398 };
13991399 inline for (name_prefixes) |prefix| {
14001400 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 {
14091409 switch (args.type) {
14101410 elf.SHT_NULL => unreachable,
14111411 elf.SHT_PROGBITS => {
1412 if (mem.eql(u8, args.name, ".preinit_array") or mem.startsWith(u8, args.name, ".preinit_array."))
1413 break :tt elf.SHT_PREINIT_ARRAY;
14121414 if (mem.eql(u8, args.name, ".init_array") or mem.startsWith(u8, args.name, ".init_array."))
14131415 break :tt elf.SHT_INIT_ARRAY;
14141416 if (mem.eql(u8, args.name, ".fini_array") or mem.startsWith(u8, args.name, ".fini_array."))
src/link/Elf/ZigObject.zig+4
......@@ -1237,6 +1237,10 @@ fn getNavShdrIndex(
12371237 self.debug_rnglists_index = section_index;
12381238 } else if (std.mem.startsWith(u8, section_name, ".debug")) {
12391239 elf_file.sections.items(.shdr)[osec].sh_flags = 0;
1240 } else if (std.mem.eql(u8, section_name, ".preinit_array") or std.mem.startsWith(u8, section_name, ".preinit_array.")) {
1241 const shdr = &elf_file.sections.items(.shdr)[osec];
1242 shdr.sh_type = elf.SHT_PREINIT_ARRAY;
1243 shdr.sh_flags = elf.SHF_ALLOC | elf.SHF_WRITE;
12401244 } else if (std.mem.eql(u8, section_name, ".init_array") or std.mem.startsWith(u8, section_name, ".init_array.")) {
12411245 const shdr = &elf_file.sections.items(.shdr)[osec];
12421246 shdr.sh_type = elf.SHT_INIT_ARRAY;
src/link/Elf/synthetic_sections.zig+8
......@@ -73,6 +73,7 @@ pub const DynamicSection = struct {
7373 if (dt.rpath > 0) nentries += 1; // RUNPATH
7474 if (elf_file.sectionByName(".init") != null) nentries += 1; // INIT
7575 if (elf_file.sectionByName(".fini") != null) nentries += 1; // FINI
76 if (elf_file.sectionByName(".preinit_array") != null) nentries += 2; // PREINIT_ARRAY
7677 if (elf_file.sectionByName(".init_array") != null) nentries += 2; // INIT_ARRAY
7778 if (elf_file.sectionByName(".fini_array") != null) nentries += 2; // FINI_ARRAY
7879 if (elf_file.section_indexes.rela_dyn != null) nentries += 3; // RELA
......@@ -124,6 +125,13 @@ pub const DynamicSection = struct {
124125 try writer.writeStruct(@as(elf.Elf64_Dyn, .{ .d_tag = elf.DT_FINI, .d_val = addr }), .little);
125126 }
126127
128 // PREINIT_ARRAY
129 if (elf_file.sectionByName(".preinit_array")) |shndx| {
130 const shdr = shdrs[shndx];
131 try writer.writeStruct(@as(elf.Elf64_Dyn, .{ .d_tag = elf.DT_PREINIT_ARRAY, .d_val = shdr.sh_addr }), .little);
132 try writer.writeStruct(@as(elf.Elf64_Dyn, .{ .d_tag = elf.DT_PREINIT_ARRAYSZ, .d_val = shdr.sh_size }), .little);
133 }
134
127135 // INIT_ARRAY
128136 if (elf_file.sectionByName(".init_array")) |shndx| {
129137 const shdr = shdrs[shndx];