feature. See also
. The project being documented here (as the example) is the Zig library itself.
posix.dl_iterate_phdr
pub fn dl_iterate_phdr(
context: anytype,
comptime Error: type,
comptime callback: fn (info: *dl_phdr_info, size: usize, context: @TypeOf(context)) Error!void,
) Error!void
File
Code
pub fn dl_iterate_phdr(
context: anytype,
comptime Error: type,
comptime callback: fn (info: *dl_phdr_info, size: usize, context: @TypeOf(context)) Error!void,
) Error!void {
const Context = @TypeOf(context);
const elf = std.elf;
const dl = @import("dynamic_library.zig");
switch (builtin.object_format) {
.elf, .c => {},
else => @compileError("dl_iterate_phdr is not available for this target"),
}
if (builtin.link_libc) {
switch (system.dl_iterate_phdr(struct {
fn callbackC(info: *dl_phdr_info, size: usize, data: ?*anyopaque) callconv(.c) c_int {
const context_ptr: *const Context = @ptrCast(@alignCast(data));
callback(info, size, context_ptr.*) catch |err| return @intFromError(err);
return 0;
}
}.callbackC, @ptrCast(@constCast(&context)))) {
0 => return,
else => |err| return @as(Error, @errorCast(@errorFromInt(@as(@Int(.unsigned, @bitSizeOf(anyerror)), @intCast(err))))),
}
}
var it = dl.linkmap_iterator() catch unreachable;
// the whole ELF image.
if (it.end()) {
const getauxval = if (builtin.link_libc) std.c.getauxval else std.os.linux.getauxval;
const phdrs = getSelfPhdrs();
var info: dl_phdr_info = .{
.addr = for (phdrs) |phdr| switch (phdr.type) {
.PHDR => break @intFromPtr(phdrs.ptr) - phdr.vaddr,
else => {},
} else unreachable,
.name = switch (getauxval(std.elf.AT_EXECFN)) {
0 => "/proc/self/exe",
else => |name| @ptrFromInt(name),
},
.phdr = phdrs.ptr,
.phnum = @intCast(phdrs.len),
};
return callback(&info, @sizeOf(dl_phdr_info), context);
}
while (it.next()) |entry| {
const phdrs: []elf.ElfN.Phdr = if (entry.addr != 0) phdrs: {
const ehdr: *elf.ElfN.Ehdr = @ptrFromInt(entry.addr);
assert(mem.eql(u8, &ehdr.ident.magic, elf.MAGIC));
const phdrs: [*]elf.ElfN.Phdr = @ptrFromInt(entry.addr + ehdr.phoff);
break :phdrs phdrs[0..ehdr.phnum];
} else getSelfPhdrs();
var info: dl_phdr_info = .{
.addr = entry.addr,
.name = entry.name,
.phdr = phdrs.ptr,
.phnum = @intCast(phdrs.len),
};
try callback(&info, @sizeOf(dl_phdr_info), context);
}
}