Skip to content

TibboddiT/dyn-loader

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

75 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Loading dynamic libraries from non libc static executable

Proof of concept

Warning: prototype quality: lots of bugs, lots of TODOs remaining.

Tested on x86_64-linux-gnu, with libraries compiled agasint glibc 2.41 and musl 1.2.5.

See this thread for further information.

Usage

const std = @import("std");
const dll = @import("dll");

pub const debug = struct {
    pub const SelfInfo = dll.CustomSelfInfo;
};

pub fn main() !void {
    var gpa: std.heap.DebugAllocator(.{}) = .init;
    const allocator = gpa.allocator();
    defer if (gpa.deinit() != .ok) @panic("memory check failed");

    // `dll` is a singleton, it should be initialized early and only once, on the main thread
    try dll.init(.{ .allocator = allocator, .log_level = .warn });
    defer dll.deinit();

    const lib_c = try dll.loadSystemLibC();

    const printf_sym = try lib_c.getSymbol("printf");
    const printf_addr = printf_sym.addr;
    const printf: *const fn ([*:0]const u8, ...) callconv(.c) c_int = @ptrFromInt(printf_addr);

    _ = printf("Hello, %s!\n", "World");
}

Current limitations

  • Loading libraries should be done before having started any thread.
  • Some (rare) relocation types are still missing.
  • Dirty tricks are used to accomodate with patched libc.

Notes

A musl's libc.so is included, compiled from sources without any modification. You should load it first before loading libraries compiled against musl on a non musl based system (see the musl printf example). The library is stripped (strip --strip-unneeded lib/libc.so) as it is often the case when it is packaged for linux distros.

An original copy of libvulkan.so.1.4.326 from the vulkan-loader package of Chimera Linux is also included (renamed libvulkan.so.1), to make the vulkan_version_musl example work.


An original copy of libraylib.so.5.5.0 from the raylib repository release assets is included, to make the raylib example work. Since this library is compiled against glibc, it will not work on musl based systems.

It is in the resources/raylib directory.


It is recommended that you produce these binary artifacts by yourself.

Run examples

zig build run-printf
zig build run-printf_musl
zig build run-vulkan_version
zig build run-vulkan_version_musl
zig build run-x11_window
zig build run-x11_egl
zig build run-x11_vulkan_triangle

The vulkan examples might need validation layer. The EGL one will need libEGL.so.

The following examples will only work on glibc based systems (because this lib is compiled against glibc):

zig build run-raylib

About

dlopen for zig, from static executables and without libc

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages