Skip to content
This repository was archived by the owner on Sep 16, 2025. It is now read-only.

Commit 417c17a

Browse files
authored
feat: improve Relocation & Utilities (#302)
changes: * add second template arg to applicable `Relocation::write_` funcs for address offset * remove `AllocTrampoline` from `stl::write_*` funcs, this is bad practice * normalize `stl::write_*` support for structs with `std::uintptr_t`, `REL::ID`, `REL::Offset`, `REL::Relocation<std::uintptr_t>` static `address` members
1 parent ed7f15e commit 417c17a

File tree

2 files changed

+69
-24
lines changed

2 files changed

+69
-24
lines changed

include/REL/Relocation.h

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -337,32 +337,32 @@ namespace REL
337337
safe_write(address(), a_data.data(), a_data.size_bytes());
338338
}
339339

340-
template <std::size_t N>
340+
template <std::size_t N, std::ptrdiff_t O = 0>
341341
std::uintptr_t write_branch(const std::uintptr_t a_dst)
342342
requires(std::same_as<value_type, std::uintptr_t>)
343343
{
344-
return SFSE::GetTrampoline().write_branch<N>(address(), a_dst);
344+
return SFSE::GetTrampoline().write_branch<N>(address() + O, a_dst);
345345
}
346346

347-
template <std::size_t N, class F>
347+
template <std::size_t N, std::ptrdiff_t O = 0, class F>
348348
std::uintptr_t write_branch(const F a_dst)
349349
requires(std::same_as<value_type, std::uintptr_t>)
350350
{
351-
return SFSE::GetTrampoline().write_branch<N>(address(), stl::unrestricted_cast<std::uintptr_t>(a_dst));
351+
return SFSE::GetTrampoline().write_branch<N>(address() + O, stl::unrestricted_cast<std::uintptr_t>(a_dst));
352352
}
353353

354-
template <std::size_t N>
354+
template <std::size_t N, std::ptrdiff_t O = 0>
355355
std::uintptr_t write_call(const std::uintptr_t a_dst)
356356
requires(std::same_as<value_type, std::uintptr_t>)
357357
{
358-
return SFSE::GetTrampoline().write_call<N>(address(), a_dst);
358+
return SFSE::GetTrampoline().write_call<N>(address() + O, a_dst);
359359
}
360360

361-
template <std::size_t N, class F>
361+
template <std::size_t N, std::ptrdiff_t O = 0, class F>
362362
std::uintptr_t write_call(const F a_dst)
363363
requires(std::same_as<value_type, std::uintptr_t>)
364364
{
365-
return SFSE::GetTrampoline().write_call<N>(address(), stl::unrestricted_cast<std::uintptr_t>(a_dst));
365+
return SFSE::GetTrampoline().write_call<N>(address() + O, stl::unrestricted_cast<std::uintptr_t>(a_dst));
366366
}
367367

368368
void write_fill(const std::uint8_t a_value, const std::size_t a_count)

include/SFSE/Utilities.h

Lines changed: 61 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,39 +5,84 @@
55

66
namespace SFSE::stl
77
{
8-
template <class T, std::size_t Size = 5>
8+
template <class T, std::size_t N = 5>
99
constexpr void write_thunk_call(const std::uintptr_t a_address) noexcept
1010
{
11-
AllocTrampoline(14);
12-
auto& trampoline = GetTrampoline();
13-
T::func = trampoline.write_call<Size>(a_address, T::thunk);
11+
T::func = GetTrampoline().write_call<N>(a_address, T::thunk);
1412
}
1513

16-
template <class T, std::size_t Size = 5>
14+
template <class T, std::size_t N = 5, class U>
15+
constexpr void write_thunk_call(const U a_id) noexcept
16+
requires(std::is_same_v<U, REL::ID> || std::is_same_v<U, REL::Offset>)
17+
{
18+
T::func = GetTrampoline().write_call<N>(a_id.address(), T::thunk);
19+
}
20+
21+
template <class T, std::size_t N = 5, class U>
22+
constexpr void write_thunk_call(const REL::Relocation<U> a_id) noexcept
23+
requires(std::is_same_v<typename REL::Relocation<U>::value_type, std::uintptr_t>)
24+
{
25+
T::func = GetTrampoline().write_call<N>(a_id.address(), T::thunk);
26+
}
27+
28+
template <class T, std::size_t N = 5>
1729
constexpr void write_thunk_call() noexcept
1830
{
19-
write_thunk_call<T, Size>(T::address);
31+
write_thunk_call<T, N>(T::address);
32+
}
33+
34+
template <class T, std::size_t N = 5>
35+
constexpr void write_thunk_jump(const std::uintptr_t a_address) noexcept
36+
{
37+
T::func = GetTrampoline().write_branch<N>(a_address, T::thunk);
38+
}
39+
40+
template <class T, std::size_t N = 5, class U>
41+
constexpr void write_thunk_jump(const U a_id) noexcept
42+
requires(std::is_same_v<U, REL::ID> || std::is_same_v<U, REL::Offset>)
43+
{
44+
T::func = GetTrampoline().write_branch<N>(a_id.address(), T::thunk);
45+
}
46+
47+
template <class T, std::size_t N = 5, class U>
48+
constexpr void write_thunk_jump(const REL::Relocation<U> a_id) noexcept
49+
requires(std::is_same_v<typename REL::Relocation<U>::value_type, std::uintptr_t>)
50+
{
51+
T::func = GetTrampoline().write_branch<N>(a_id.address(), T::thunk);
52+
}
53+
54+
template <class T, std::size_t N = 5>
55+
constexpr void write_thunk_jump() noexcept
56+
{
57+
write_thunk_jump<T, N>(T::address);
2058
}
2159

2260
template <class T>
23-
constexpr void write_vfunc(const REL::ID a_id) noexcept
61+
constexpr void write_vfunc(const std::uintptr_t a_address) noexcept
2462
{
25-
static REL::Relocation<std::uintptr_t> vtbl{ a_id };
63+
static REL::Relocation vtbl{ REL::Offset(a_address) };
2664
T::func = vtbl.write_vfunc(T::idx, T::thunk);
2765
}
2866

29-
template <class To, class From>
30-
constexpr void write_vfunc(const std::size_t a_vtableIdx = 0) noexcept
67+
template <class T, class U>
68+
constexpr void write_vfunc(const U a_id) noexcept
69+
requires(std::is_same_v<U, REL::ID> || std::is_same_v<U, REL::Offset>)
3170
{
32-
write_vfunc<From>(To::VTABLE[a_vtableIdx]);
71+
static REL::Relocation vtbl{ a_id };
72+
T::func = vtbl.write_vfunc(T::idx, T::thunk);
3373
}
3474

35-
template <class T, std::size_t Size = 5>
36-
constexpr void write_thunk_jump(const std::uintptr_t a_src) noexcept
75+
template <class T, class U>
76+
constexpr void write_vfunc(const REL::Relocation<U> a_id) noexcept
77+
requires(std::is_same_v<typename REL::Relocation<U>::value_type, std::uintptr_t>)
3778
{
38-
AllocTrampoline(14);
39-
auto& trampoline = GetTrampoline();
40-
T::func = trampoline.write_branch<Size>(a_src, T::thunk);
79+
T::func = a_id.write_vfunc(T::idx, T::thunk);
80+
}
81+
82+
template <class To, class From>
83+
constexpr void write_vfunc(const std::size_t a_vtableIdx = 0) noexcept
84+
{
85+
write_vfunc<From>(To::VTABLE[a_vtableIdx]);
4186
}
4287

4388
namespace detail

0 commit comments

Comments
 (0)