Merge remote-tracking branch 'origin/main' into 26-07-25-audio-replacements

# Conflicts:
#	CMakeLists.txt
This commit is contained in:
PJB3005
2026-07-25 16:08:31 +02:00
75 changed files with 3709 additions and 646 deletions
+24 -1
View File
@@ -148,6 +148,7 @@ typedef enum ModMetaKind {
MOD_META_HOOK_FN = 4,
MOD_META_HOOK_MEM = 5,
MOD_META_HOOK_NAME = 6,
MOD_META_HOOK_MEM_EXT = 7,
} ModMetaKind;
typedef struct ModMetaRecord {
@@ -203,15 +204,37 @@ static_assert(sizeof(ModMetaHookFn) == 24);
* NUL-terminated strings follow `resolved`: the class vtable symbol (empty if the class name is not
* representable), then the stringified target for tooling display.
*/
#define MOD_META_HOOK_MEM_CAPACITY 16u
typedef struct MOD_META_ALIGN ModMetaHookMem {
ModMetaRecord rec;
uint32_t reserved;
unsigned char pmf[16];
unsigned char pmf[MOD_META_HOOK_MEM_CAPACITY];
void* resolved; /* runtime only */
} ModMetaHookMem;
static_assert(sizeof(ModMetaHookMem) == 32);
/*
* Extended member-function hook record. The Microsoft x64 ABI uses a 24-byte member pointer for
* classes whose inheritance model was fixed while the class was incomplete. Keep this a distinct
* record kind so loaders can continue to consume MOD_META_HOOK_MEM's original 16-byte layout.
*
* MSVC cannot constant-initialize that member pointer, so materialize points to a compiler-
* generated helper that writes its native representation to a caller-provided buffer. The record
* itself, including its trailing names and the helper relocation, remains constant-initialized and
* available to static tooling. pmf_size is the number of bytes the helper writes.
*/
#define MOD_META_HOOK_MEM_EXT_CAPACITY 24u
typedef void (*ModMetaHookMemMaterializeFn)(unsigned char* out_pmf);
typedef struct MOD_META_ALIGN ModMetaHookMemExt {
ModMetaRecord rec;
uint32_t pmf_size;
ModMetaHookMemMaterializeFn materialize;
void* resolved; /* runtime only */
} ModMetaHookMemExt;
static_assert(sizeof(ModMetaHookMemExt) == 24);
/*
* Hook on a function by symbol name, for targets that cannot be named in C++ (file-local statics,
* private members). One NUL-terminated string follows `resolved`; it may be either the platform
+40 -6
View File
@@ -4,6 +4,7 @@
#include <array>
#include <cstddef>
#include <cstring>
#include <string_view>
#include <type_traits>
#include <utility>
@@ -185,12 +186,21 @@ struct HookMemRecord {
uint32_t reserved;
union {
F fn;
unsigned char raw[16];
unsigned char raw[MOD_META_HOOK_MEM_CAPACITY];
} pmf;
void* resolved;
char names[N];
};
template <size_t N>
struct HookMemExtRecord {
ModMetaRecord rec;
uint32_t pmfSize;
ModMetaHookMemMaterializeFn materialize;
void* resolved;
char names[N];
};
template <size_t N>
struct HookNameRecord {
ModMetaRecord rec;
@@ -232,19 +242,43 @@ consteval auto make_hook_mem_names() {
}
/*
* MSVC constant-evaluates a pointer-to-member only when every other operand in the
* initializer is a literal: no consteval calls, constexpr-object copies, or default
* member initializers.
* MSVC constant-evaluates a compact pointer-to-member only when every other operand in the
* initializer is a literal: no consteval calls, constexpr-object copies, or default member
* initializers. It cannot constant-initialize the 24-byte general representation at all, so the
* extended record points at a compiler-generated materializer while keeping the metadata itself
* constant-initialized for static tooling.
*/
template <auto Target, bool Extended, char... Cs>
struct HookMemHolderImpl;
template <auto Target, char... Cs>
struct HookMemHolder {
struct HookMemHolderImpl<Target, false, Cs...> {
using F = decltype(Target);
static_assert(sizeof(F) <= 16, "unsupported pointer-to-member representation");
MOD_META_RECORD static constinit inline HookMemRecord<F, sizeof...(Cs)> record = {
{sizeof(HookMemRecord<F, sizeof...(Cs)>), MOD_META_HOOK_MEM, 0}, 0, {Target}, nullptr,
{Cs...}};
};
template <auto Target, char... Cs>
struct HookMemHolderImpl<Target, true, Cs...> {
using F = decltype(Target);
static void materialize(unsigned char* outPmf) {
const F target = Target;
std::memcpy(outPmf, &target, sizeof(target));
}
MOD_META_RECORD static constinit inline HookMemExtRecord<sizeof...(Cs)> record = {
{sizeof(HookMemExtRecord<sizeof...(Cs)>), MOD_META_HOOK_MEM_EXT, 0}, sizeof(F), materialize,
nullptr, {Cs...}};
};
template <auto Target, char... Cs>
struct HookMemHolder
: HookMemHolderImpl<Target, (sizeof(decltype(Target)) > MOD_META_HOOK_MEM_CAPACITY), Cs...> {
using F = decltype(Target);
static_assert(sizeof(F) <= MOD_META_HOOK_MEM_EXT_CAPACITY,
"unsupported pointer-to-member representation");
};
template <auto Target>
struct HookFnHolder {
using F = decltype(Target);