authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2026-08-15 09:04:07+01:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2026-08-16 10:37:20+01:00
log29bcd2d54376f6b15a6900b264e8b4d99e7b186a
tree61a654a3729424bf2f67589221cc440489c1092a
parentede0017eb9e72cb5a799ad000ebe45cf326524d6
signaturelock-open Commit is signed but in an unrecognized format.

std.posix.test: fix `dl_iterate_phdr` test

The old test was relying on the following properties: * There is a segment containing the ehdr, i.e. whose file offset is 0 * That segment is the first phdr with type `PT_LOAD`; because `PT_LOAD` segments are sorted on `p_vaddr`, this means its virtual address is the lowest of all loadable segments The first assumption, although not standard, is somewhat reasonable, and the commit prior to this one makes `Elf2` obey it. However, the second assumption is not based on anything, and to my knowledge the linker is entirely welcome to lay out the virtual address space as it sees fit. Therefore, refactor this test to eliminate that bad assumption.

1 files changed, 16 insertions(+), 25 deletions(-)

lib/std/posix/test.zig+16-25
......@@ -64,42 +64,33 @@ const have_dl_phdr_info = posix.system.dl_phdr_info != void;
6464const dl_phdr_info = if (have_dl_phdr_info) posix.dl_phdr_info else anyopaque;
6565
6666const IterFnError = error{
67 MissingPtLoadSegment,
68 MissingLoad,
67 MissingLoadSegment,
68 MissingEhdrLoadSegment,
6969 BadElfMagic,
70 FailedConsistencyCheck,
70 PhnumMismatch,
7171};
7272
7373fn iter_fn(info: *dl_phdr_info, size: usize, counter: *usize) IterFnError!void {
7474 _ = size;
7575 // Count how many libraries are loaded
76 counter.* += @as(usize, 1);
76 counter.* += 1;
7777
78 // The image should contain at least a PT.LOAD segment
79 if (info.phnum < 1) return error.MissingPtLoadSegment;
80
81 // Quick & dirty validation of the phdr pointers, make sure we're not
82 // pointing to some random gibberish
83 var i: usize = 0;
84 var found_load = false;
85 while (i < info.phnum) : (i += 1) {
86 const phdr = info.phdr[i];
78 // The image should contain at least one loadable segment
79 if (info.phnum < 1) return error.MissingLoadSegment;
8780
81 // For some quick and dirty validation, find the phdr which contains the ELF
82 // header, and check it makes sense.
83 for (info.phdr[0..info.phnum]) |phdr| {
8884 if (phdr.type != .LOAD) continue;
89
90 const reloc_addr = info.addr + phdr.vaddr;
91 // Find the ELF header
92 const elf_header = @as(*elf.Ehdr, @ptrFromInt(reloc_addr - phdr.offset));
93 // Validate the magic
94 if (!mem.eql(u8, elf_header.e_ident[0..4], elf.MAGIC)) return error.BadElfMagic;
95 // Consistency check
96 if (elf_header.e_phnum != info.phnum) return error.FailedConsistencyCheck;
97
98 found_load = true;
85 if (phdr.offset != 0) continue;
86 // This segment holds the ELF header at the start
87 const ehdr: *elf.Ehdr = @ptrFromInt(info.addr + phdr.vaddr);
88 if (!mem.eql(u8, ehdr.e_ident[0..4], elf.MAGIC)) return error.BadElfMagic;
89 if (ehdr.e_phnum != info.phnum) return error.PhnumMismatch;
9990 break;
91 } else {
92 return error.MissingEhdrLoadSegment;
10093 }
101
102 if (!found_load) return error.MissingLoad;
10394}
10495
10596test "dl_iterate_phdr" {