diff --git a/include/mach_detours.h b/include/mach_detours.h index 5fa69a0..d6af642 100644 --- a/include/mach_detours.h +++ b/include/mach_detours.h @@ -205,11 +205,20 @@ bool detour_set_ignore_too_small(bool value); /// @brief Toggle whether to free memory allocated for trampoline regions when they are empty. /// /// Default is `true` - free unused regions upon commit.
-/// `false` means they are not freed upon commit. Note that there is no way to manually free unused regions. +/// `false` means they are not freed upon commit. See also `detour_free_unused_regions`. /// /// @returns the previous state of the flag bool detour_set_retain_regions(bool value); +/// @brief Frees unused trampoline memory regions +/// +/// @note Must be called from within a transaction to maintain thread saefty. +/// +/// @returns `err_none` on success, else:
+/// * `detour_err_wrong_thread` if the calling thread is not the owner of the transaction, or if there is no +/// transaction. See `detour_transaction_begin`. +mach_error_t detour_free_unused_regions(); + /// @brief Sets the lower bound of the memory area that will not be used for detours trampoline regions /// /// Default is `0x70000000` diff --git a/src/mach_detours.c b/src/mach_detours.c index d459486..6999286 100644 --- a/src/mach_detours.c +++ b/src/mach_detours.c @@ -1001,6 +1001,16 @@ bool detour_set_retain_regions(const bool value) return previous; } +mach_error_t detour_free_unused_regions() +{ + if (s_transaction_thread != mach_thread_self()) { + return detour_err_wrong_thread; + } + + internal_detour_free_unused_trampoline_regions(); + return err_none; +} + void* detour_set_system_region_lower_bound(void* value) { void* previous = s_system_region_lower_bound;