ldpreloadhelpers

Rust macros to run code at load time and override C functions.

Mostly useful for LD_PRELOAD hooks, hence the name.

Examples

C function overrides

Here open is overridden to print something then forward to the real open. In the rare case that you should wish to recurse into the override, rather than call the real API, use crate::open. From anywhere else in the module, open will refer to the override. To refer to the real function from elsewhere in the program, use real_open (as named at the declaration).

Multiple overrides may be specified within a single macro invocation and multiple extern_c_overrides invocations are supported if desired. This is demonstrated below by an override of getuid which adds 2000 to the user's id.

In std mode (the default), panics in the override are caught and cause the catch block to execute. In no_std mode (not properly supported due to use of OnceLock; see below), there is no special panic handling and the catch block is ignored.

```rust externcoverrides! { unsafe fn open/realopen(pathname: *const cchar, flags: cint, mode: libc::modet) -> cint { println!("RUST OPEN {:?} {:x} {:x}", unsafe { CStr::fromptr(pathname) }, flags, mode); // panic!("oops"); return open(pathname, flags, mode); } catch { errno::set_errno(errno::Errno(libc::ENODEV)); return -1; }

unsafe fn getuid/realgetuid() -> libc::uidt { getuid() + 2000 } catch { u32::MAX } } ```

Image load hook

Called whenever the program/library is loaded, prior to the main entry point being run. Note this demonstrates calling the overridden getuid and real getuid.

Currently there can be only one of these owing to a fixed name being used for the generated function. But this may be extended in future to allow the user to pass a name.

rust on_load! {{ println!("INIT LIB {} {}", unsafe { getuid() }, unsafe { real_getuid() }); }}

Example runs

sh $ LD_PRELOAD=target/debug/liboverride.so id INIT LIB 2501 501 uid=2501 gid=501 euid=501

sh $ LD_PRELOAD=target/debug/liboverride.so wc Cargo.lock INIT LIB 2501 501 RUST OPEN "Cargo.lock" 0 52c47940 820 1588 21572 Cargo.lock

Notes on no_std usage