VoltMod
C++23 framework for CS2 server plugins
Loading...
Searching...
No Matches
VtableLookup.hpp
Go to the documentation of this file.
1#pragma once
2
4
6#include <cstddef>
7#include <cstdint>
8#include <span>
9#include <string>
10
11namespace VoltMod
12{
13
14/**
15 * Find `className`'s primary vtable in loaded `moduleName`, or nullptr. It uses compiler metadata:
16 * MSVC RTTI on Windows (top-level, non-template classes only), and on Linux the Itanium `_ZTV`
17 * symbol, or the Itanium RTTI when the module hides that symbol.
18 */
19void* FindVirtualTable(std::string_view moduleName, std::string_view className);
20
21void* FindVirtualTableIn(const Image& module, std::string_view className);
22
23void* FindVirtualTableByTypeName(std::span<const ScanRange> ranges, std::string_view className);
24
25std::string LengthPrefixedName(std::string_view className);
26
27bool IsInstanceOf(const void* object, const void* table);
28
30{
31 int Offset = 0;
32 void* Table = nullptr;
33};
34
35/**
36 * Find base @p baseName inside @p className in @p module through RTTI.
37 *
38 * @return NotFound when either class is missing, Invalid when the base is in the class more than
39 * once, Unsupported for a virtual base. Table is null when the base has no vtable.
40 */
41Result<BaseSubobject> FindBaseIn(const Image& module, std::string_view className, std::string_view baseName);
42
43/**
44 * The vptr values of Itanium `__si_class_type_info` (one base) and `__vmi_class_type_info`
45 * (several). Zero when unknown; each typeinfo is then told apart by its shape.
46 */
52
53/**
54 * Find @p baseName in the class described by Itanium @p typeInfo.
55 * Uses the same NotFound, Invalid, and Unsupported errors as @ref FindBaseIn.
56 */
57Result<int> FindBaseOffsetByTypeInfo(const void* typeInfo, std::string_view baseName, const TypeInfoKinds& kinds);
58
59/**
60 * Find the single vtable with @p typeInfo and @p offsetToTop whose first slot holds code.
61 * Returns nullptr when no candidate exists or the metadata is ambiguous.
62 */
63void* FindVirtualTableByTypeInfo(std::span<const ScanRange> ranges, const void* typeInfo, intptr_t offsetToTop);
64
65#ifdef _WIN32
66/** A PE module's span and RTTI sections. */
67struct PeRtti
68{
69 const uint8_t* Base = nullptr;
70 size_t Size = 0;
71 ScanRange Data{}; ///< `.data`: type descriptors.
72 ScanRange ReadOnlyData{}; ///< `.rdata`: object locators, class hierarchies, vtables.
73};
74
75void* FindVirtualTableInRtti(const PeRtti& rtti, std::string_view className);
76
77Result<BaseSubobject> FindBaseInRtti(const PeRtti& rtti, std::string_view className, std::string_view baseName);
78#endif
79
80} // namespace VoltMod
void * FindVirtualTableByTypeInfo(std::span< const ScanRange > ranges, const void *typeInfo, intptr_t offsetToTop)
Result< BaseSubobject > FindBaseInRtti(const PeRtti &rtti, std::string_view className, std::string_view baseName)
static std::string ReadFile(const std::filesystem::path &path)
Definition Loader.cpp:56
Result< int > FindBaseOffsetByTypeInfo(const void *typeInfo, std::string_view baseName, const TypeInfoKinds &kinds)
Result< BaseSubobject > FindBaseIn(const Image &module, std::string_view className, std::string_view baseName)
void * FindVirtualTableByTypeName(std::span< const ScanRange > ranges, std::string_view className)
void * FindVirtualTableInRtti(const PeRtti &rtti, std::string_view className)
std::string LengthPrefixedName(std::string_view className)
void * FindVirtualTable(std::string_view moduleName, std::string_view className)
std::expected< T, Error > Result
Definition Result.hpp:64
bool IsInstanceOf(const void *object, const void *table)
void * FindVirtualTableIn(const Image &module, std::string_view className)