Created
November 20, 2020 21:24
-
-
Save andrewrk/388c97fb525ee4f1769db5bf79ed86c9 to your computer and use it in GitHub Desktop.
experimenting with reloading a static binary to make it dynamic
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdbool.h> | |
#include <stddef.h> | |
void __attribute__((weak)) dlopen(const char *filename, int flags); | |
int __attribute__((weak)) dlclose(void *handle); | |
struct ZigWindowFns { | |
void (*dlopen)(const char *filename, int flags); | |
int (*dlclose)(void *handle); | |
}; | |
static struct ZigWindowFns global_fns; | |
struct ZigWindowFns *zig_window_get_fns(void) { | |
if (!dlopen) return NULL; | |
global_fns.dlopen = dlopen; | |
global_fns.dlclose = dlclose; | |
return &global_fns; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const std = @import("std"); | |
const ZigWindowFns = extern struct { | |
dlopen: fn ([*:0]const u8, c_int) callconv(.C) void, | |
dlclose: fn (?*c_void) callconv(.C) c_int, | |
}; | |
extern fn zig_window_get_fns() ?*ZigWindowFns; | |
var general_purpose_allocator = std.heap.GeneralPurposeAllocator(.{}){}; | |
pub fn main() anyerror!void { | |
const gpa = &general_purpose_allocator.allocator; | |
defer _ = general_purpose_allocator.deinit(); | |
var arena_instance = std.heap.ArenaAllocator.init(gpa); | |
defer arena_instance.deinit(); | |
const arena = &arena_instance.allocator; | |
std.log.debug("detecting whether we are running in the dynamic linker", .{}); | |
const fns = zig_window_get_fns() orelse { | |
std.log.debug("we're not. detecting the dynamic linker path", .{}); | |
const info = try std.zig.system.NativeTargetInfo.detect(arena, .{}); | |
const dyld_path = info.dynamic_linker.get() orelse @panic("OS has no dynamic linker"); | |
std.log.debug("dyld_path={}", .{dyld_path}); | |
const dyld_z = arena.dupeZ(u8, dyld_path) catch @panic("out of memory"); | |
const argv = arena.allocSentinel(?[*:0]const u8, std.os.argv.len + 1, null) catch @panic("out of memory"); | |
argv[0] = dyld_z; | |
for (std.os.argv) |arg, i| { | |
argv[i + 1] = arg; | |
} | |
// TODO make std.os.environ slice be also null terminated | |
const envp = @ptrCast([*:null]const ?[*:0]const u8, std.os.environ.ptr); | |
return std.os.execveZ(dyld_z, argv, envp); | |
}; | |
std.log.debug("got the fns", .{}); | |
// So far our goal is to call these 2 functions. | |
//XInitThreads(); | |
//XrmInitialize(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment