authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2026-05-07 12:58:19+01:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2026-05-17 18:08:58+01:00
loge8ef01f2221a8588ab86863fdb109b47fd6ceb50
treed8c5e45778d03c77d558a0231fabda9ac5e000e7
parent65c3a07709156a721090635ae6e6a16d7ccb95da
signaturelock-open Commit is signed but in an unrecognized format.

Elf2: fix expected_nodes_len calculation

I'm not sure what the basis was for the old logic here, but it was incorrect and caused an assertion failure in some cases. The dependencies on `maybe_interp` and `any_non_single_threaded` are already correctly modeled by `phnum`, so do not need to be accounted for a second time.

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

src/link/Elf2.zig+4-4
......@@ -1123,13 +1123,13 @@ fn initHeaders(
11231123 const expected_nodes_len = expected_nodes_len: switch (@"type") {
11241124 .NONE, .CORE, _ => unreachable,
11251125 .REL => {
1126 // Each phdr is actually going to be an shdr.
11261127 defer phnum = 0;
11271128 break :expected_nodes_len 5 + phnum;
11281129 },
1129 .EXEC, .DYN => break :expected_nodes_len 8 + phnum * 2 +
1130 @intFromBool(maybe_interp != null) +
1131 @as(usize, 4) * @intFromBool(have_dynamic_section) +
1132 @intFromBool(comp.config.any_non_single_threaded),
1130 .EXEC, .DYN => break :expected_nodes_len 10 +
1131 phnum * 2 - 1 + // each phdr also has a matching shdr, except for the PT_PHDR phdr
1132 @as(usize, 4) * @intFromBool(have_dynamic_section), // .dynstr, .dynsym, .rela.dyn, .rela.plt
11331133 };
11341134 try elf.nodes.ensureTotalCapacity(gpa, expected_nodes_len);
11351135 try elf.shdrs.ensureTotalCapacity(gpa, shnum);