diff --git a/std/os/linux/test.zig b/std/os/linux/test.zig index 286748b70c..1949d00298 100644 --- a/std/os/linux/test.zig +++ b/std/os/linux/test.zig @@ -1,6 +1,8 @@ const std = @import("../../std.zig"); const builtin = @import("builtin"); const linux = std.os.linux; +const mem = std.mem; +const elf = std.elf; const expect = std.testing.expect; test "getpid" { @@ -42,3 +44,42 @@ test "timer" { // TODO implicit cast from *[N]T to [*]T err = linux.epoll_wait(@intCast(i32, epoll_fd), @ptrCast([*]linux.epoll_event, &events), 8, -1); } + +export fn iter_fn(info: *linux.dl_phdr_info, size: usize, data: ?*usize) i32 { + var counter = data.?; + // Count how many libraries are loaded + counter.* += usize(1); + + // The image should contain at least a PT_LOAD segment + if (info.dlpi_phnum < 1) return -1; + + // Quick & dirty validation of the phdr pointers, make sure we're not + // pointing to some random gibberish + var i: usize = 0; + var found_load = false; + while (i < info.dlpi_phnum) : (i += 1) { + const phdr = info.dlpi_phdr[i]; + + if (phdr.p_type != elf.PT_LOAD) continue; + + // Find the ELF header + const elf_header = @intToPtr(*elf.Ehdr, phdr.p_vaddr - phdr.p_offset); + // Validate the magic + if (!mem.eql(u8, elf_header.e_ident[0..], "\x7fELF")) return -1; + // Consistency check + if (elf_header.e_phnum != info.dlpi_phnum) return -1; + + found_load = true; + break; + } + + if (!found_load) return -1; + + return 42; +} + +test "dl_iterate_phdr" { + var counter: usize = 0; + expect(linux.dl_iterate_phdr(usize, iter_fn, &counter) != 0); + expect(counter != 0); +}