UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
FunctionMapInlines.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5#if (defined(__AUTORTFM) && __AUTORTFM)
6
7#include "AutoRTFMDefines.h"
8#include "AutoRTFMConstants.h"
9#include "FunctionMap.h"
10#include "Utils.h"
11
12namespace AutoRTFM
13{
14
17{
18 constexpr uint64_t UbsanMagic = 0xc105'cafe;
19
20 // We use prefix data in our custom LLVM pass to stuff some data just
21 // before the address of all open function pointers (that we have
22 // definitions for!). We verify the special Magic Prefix constant in the
23 // top 16-bits of the function pointer address as a magic constant check
24 // to give us a much higher confidence that there is actually a closed
25 // variant pointer residing 8-bytes before our function address.
27 char* CharOpenFn = reinterpret_cast<char*>(OpenFn);
28 memcpy(&PrefixData, CharOpenFn - sizeof(uint64_t), sizeof(uint64_t));
29#if PLATFORM_LINUX
30 constexpr uint64_t Mask = 0xffff'0000'0000'0000;
31 if (AUTORTFM_LIKELY(Constants::PosOffsetMagicPrefix == (PrefixData & Mask)))
32 {
33 return reinterpret_cast<void*>(CharOpenFn + (PrefixData & ~Mask));
34 }
35 else if (AUTORTFM_LIKELY((Constants::NegOffsetMagicPrefix) == (PrefixData & Mask)))
36 {
37 // when NegOffsetMagicPrefix is matched, that means the offset was negative and we need to sign extend
38 return reinterpret_cast<void*>(CharOpenFn + (int64_t)(PrefixData | Mask));
39 }
40 // UBSAN adds a type hash prefix to the function as a "prologue" that
41 // ends preceding our Magic Prefix. They use 0xc105cafe in the
42 // lower 32-bits to distinguish the 64-bit word containing their type
43 // hash. If we see it, check the preceding 64-bit word for our prefix.
44 else if (AUTORTFM_UNLIKELY(UbsanMagic == (PrefixData & 0x0000'0000'ffff'ffff)))
45 {
46 memcpy(&PrefixData, reinterpret_cast<char*>(OpenFn) - sizeof(uint64_t) * 2, sizeof(uint64_t));
47 if (AUTORTFM_LIKELY(Constants::PosOffsetMagicPrefix == (PrefixData & Mask)))
48 {
49 return reinterpret_cast<void*>(CharOpenFn + (PrefixData & ~Mask));
50 }
51 else if (AUTORTFM_LIKELY((Constants::NegOffsetMagicPrefix) == (PrefixData & Mask)))
52 {
53 // when NegOffsetMagicPrefix is matched, that means the offset was negative and we need to sign extend
54 return reinterpret_cast<void*>(CharOpenFn + (int64_t)(PrefixData | Mask));
55 }
56 }
57#else
58 memcpy(&PrefixData, reinterpret_cast<char*>(OpenFn) - sizeof(uint64_t), sizeof(uint64_t));
59 if (AUTORTFM_LIKELY(Constants::MagicPrefix == (PrefixData & 0xffff'0000'0000'0000)))
60 {
61 return reinterpret_cast<void*>(PrefixData & 0x0000'ffff'ffff'ffff);
62 }
63 // UBSAN adds a type hash prefix to the function as a "prologue" that
64 // ends preceding our Magic Prefix. They use 0xc105cafe in the
65 // lower 32-bits to distinguish the 64-bit word containing their type
66 // hash. If we see it, check the preceding 64-bit word for our prefix.
67 else if (AUTORTFM_UNLIKELY(UbsanMagic == (PrefixData & 0x0000'0000'ffff'ffff)))
68 {
69 memcpy(&PrefixData, reinterpret_cast<char*>(OpenFn) - sizeof(uint64_t) * 2, sizeof(uint64_t));
70 if (AUTORTFM_LIKELY(Constants::MagicPrefix == (PrefixData & 0xffff'0000'0000'0000)))
71 {
72 return reinterpret_cast<void*>(PrefixData & 0x0000'ffff'ffff'ffff);
73 }
74 }
75#endif
76
77 return nullptr;
78}
79
80AUTORTFM_DISABLE inline void* FunctionMapLookup(void* OpenFn, const char* Where)
81{
83 {
84 return ClosedFn;
85 }
86
88}
89
90template<typename TReturnType, typename... TParameterTypes>
92{
93 return reinterpret_cast<TReturnType (*)(TParameterTypes...)>(FunctionMapLookup(reinterpret_cast<void*>(OpenFn), Where));
94}
95
96} // namespace AutoRTFM
97
98#endif // (defined(__AUTORTFM) && __AUTORTFM)
#define AUTORTFM_DISABLE
Definition AutoRTFMDefines.h:116
#define UE_AUTORTFM_FORCEINLINE
Definition AutoRTFMDefines.h:171
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
Interface OpenFn(DecoderMem, 48000, 1, false, false)
memcpy(InputBufferBase, BinkBlocksData, BinkBlocksSize)
Definition API.cpp:57