aboutsummaryrefslogtreecommitdiff
path: root/lib/std/os.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2020-02-17 15:23:59 -0500
committerAndrew Kelley <andrew@ziglang.org>2020-02-17 15:23:59 -0500
commit2f9c5c0644dd516ec0d96f33333a35e6b4deea91 (patch)
tree852e7d7273da760a3a36ea551343f5e01bfe8f5a /lib/std/os.zig
parentc784c52819e505620fb1fcb48e59a48c6d8f487e (diff)
downloadzig-2f9c5c0644dd516ec0d96f33333a35e6b4deea91.tar.gz
zig-2f9c5c0644dd516ec0d96f33333a35e6b4deea91.zip
self-host dynamic linker detection
Diffstat (limited to 'lib/std/os.zig')
-rw-r--r--lib/std/os.zig32
1 files changed, 18 insertions, 14 deletions
diff --git a/lib/std/os.zig b/lib/std/os.zig
index c5fdc41d83..0f492a25f2 100644
--- a/lib/std/os.zig
+++ b/lib/std/os.zig
@@ -2974,18 +2974,26 @@ pub fn nanosleep(seconds: u64, nanoseconds: u64) void {
}
pub fn dl_iterate_phdr(
- comptime T: type,
- callback: extern fn (info: *dl_phdr_info, size: usize, data: ?*T) i32,
- data: ?*T,
-) isize {
+ context: var,
+ comptime Error: type,
+ comptime callback: fn (info: *dl_phdr_info, size: usize, context: @TypeOf(context)) Error!void,
+) Error!void {
+ const Context = @TypeOf(context);
+
if (builtin.object_format != .elf)
@compileError("dl_iterate_phdr is not available for this target");
if (builtin.link_libc) {
- return system.dl_iterate_phdr(
- @ptrCast(std.c.dl_iterate_phdr_callback, callback),
- @ptrCast(?*c_void, data),
- );
+ switch (system.dl_iterate_phdr(struct {
+ fn callbackC(info: *dl_phdr_info, size: usize, data: ?*c_void) callconv(.C) c_int {
+ const context_ptr = @ptrCast(*const Context, @alignCast(@alignOf(*const Context), data));
+ callback(info, size, context_ptr.*) catch |err| return @errorToInt(err);
+ return 0;
+ }
+ }.callbackC, @intToPtr(?*c_void, @ptrToInt(&context)))) {
+ 0 => return,
+ else => |err| return @errSetCast(Error, @intToError(@intCast(u16, err))), // TODO don't hardcode u16
+ }
}
const elf_base = std.process.getBaseAddress();
@@ -3007,11 +3015,10 @@ pub fn dl_iterate_phdr(
.dlpi_phnum = ehdr.e_phnum,
};
- return callback(&info, @sizeOf(dl_phdr_info), data);
+ return callback(&info, @sizeOf(dl_phdr_info), context);
}
// Last return value from the callback function
- var last_r: isize = 0;
while (it.next()) |entry| {
var dlpi_phdr: [*]elf.Phdr = undefined;
var dlpi_phnum: u16 = undefined;
@@ -3033,11 +3040,8 @@ pub fn dl_iterate_phdr(
.dlpi_phnum = dlpi_phnum,
};
- last_r = callback(&info, @sizeOf(dl_phdr_info), data);
- if (last_r != 0) break;
+ try callback(&info, @sizeOf(dl_phdr_info), context);
}
-
- return last_r;
}
pub const ClockGetTimeError = error{UnsupportedClock} || UnexpectedError;