use crate::trampoline;
use std::ffi::CStr;
unsafe fn real_dlsym(handle: *mut libc::c_void, symbol: *const libc::c_char) -> *mut libc::c_void {
unsafe extern "C" {
fn dlvsym(
handle: *mut libc::c_void,
symbol: *const libc::c_char,
version: *const libc::c_char,
) -> *mut libc::c_void;
}
let dlsym_name = c"dlsym".as_ptr();
let glibc_version = c"GLIBC_2.2.5".as_ptr();
let real_dlsym_ptr = unsafe {
dlvsym(libc::RTLD_NEXT, dlsym_name, glibc_version)
};
if real_dlsym_ptr.is_null() {
return std::ptr::null_mut();
}
let real_dlsym: unsafe extern "C" fn(
*mut libc::c_void,
*const libc::c_char,
) -> *mut libc::c_void = unsafe { std::mem::transmute(real_dlsym_ptr) };
unsafe { real_dlsym(handle, symbol) }
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn dlsym(
handle: *mut libc::c_void,
symbol: *const libc::c_char,
) -> *mut libc::c_void {
let result = unsafe { real_dlsym(handle, symbol) };
if result.is_null() || symbol.is_null() {
return result;
}
let sym_name = unsafe { CStr::from_ptr(symbol) };
let sym_bytes = sym_name.to_bytes();
if !sym_bytes.starts_with(b"__rustc_proc_macro_decls_") {
return result;
}
unsafe { trampoline::intercept_proc_macro_table(result) }
}