Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions libmimalloc-sys/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,47 @@ extern "C" {
pub fn mi_free(p: *mut c_void);
}

/// When using the `"override"` feature flag, the user wants us to globally
/// override the system allocator.
///
/// However, since we build and link `mimalloc` as a static library/archive,
/// the linker may decide to not care about our overrides if it can't directly
/// see references to the symbols, see the following link for details:
/// <https://maskray.me/blog/2021-06-20-symbol-processing#archive-processing>
///
/// This is problematic if `mimalloc` is used from a library that by itself
/// doesn't allocate, yet invokes other shared libraries that do, since then
/// the linker wouldn't see any references to `malloc`/`free`, and the symbols
/// would not be overridden.
///
/// To avoid this problem, we make sure that the allocator functions are
/// visible to the linker.
///
/// To avoid this problem, we reference `mi_malloc` in a `#[used]` static.
/// This makes it known to `rustc`, which will create a reference to it in a
/// `symbols.o` stub file that is later passed directly to the linker (instead
/// of being in an archive). See the following link for details on how this
/// works: <https://github.com/rust-lang/rust/pull/95604>
///
/// NOTE: This works because `mimalloc` is compiled into a single object file
/// in `static.c`. If it was split across multiple files, we'd need to
/// reference each symbol. See also the comment at the top of `static.c`.
///
/// NOTE: On macOS, mimalloc doesn't just override malloc/free, but also
/// registers itself with the allocator's zone APIs in a ctor
/// (`_mi_macos_override_malloc`, marked with `__attribute__((constructor))`).
/// Similarly to above, for the Mach-O linker to actually consider ctors as
/// "used" when defined in an archive member in a static library, so we need
/// to explicitly reference something in the object file. The constructor
/// symbol itself is static, so we can't get a reference to that, so instead
/// we reference `mi_malloc` here too).
#[cfg(feature = "override")]
mod set_up_statics {
use super::*;
#[used] // Could be `#[used(linker)]` once stable
static USED: unsafe extern "C" fn(usize) -> *mut c_void = mi_malloc;
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
Loading