Skip to main content

imping_ir/
items.rs

1//! Globals and vtables.
2
3use crate::TypeId;
4use serde::{Deserialize, Serialize};
5
6/// A global variable in a module.
7#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
8#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
9pub struct Global {
10    /// The global's name.
11    pub name: String,
12    /// The namespace path, outermost first. Empty for a free global.
13    #[serde(default, skip_serializing_if = "Vec::is_empty")]
14    pub namespace: Vec<String>,
15    /// The global's address, relative to the module's image base.
16    #[serde(with = "crate::hex::int")]
17    #[cfg_attr(feature = "schema", schemars(with = "String"))]
18    pub rva: u32,
19    /// The global's type.
20    #[serde(rename = "type")]
21    pub type_id: TypeId,
22}
23
24/// A virtual function table in a module.
25#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
26#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
27pub struct Vtable {
28    /// The vtable's name (typically its class name).
29    pub name: String,
30    /// The namespace path, outermost first. Empty for a free vtable.
31    #[serde(default, skip_serializing_if = "Vec::is_empty")]
32    pub namespace: Vec<String>,
33    /// The vtable's address, relative to the module's image base.
34    #[serde(with = "crate::hex::int")]
35    #[cfg_attr(feature = "schema", schemars(with = "String"))]
36    pub rva: u32,
37    /// The class's run-time type information, which finds the vtable in another
38    /// build.
39    #[serde(default, skip_serializing_if = "Option::is_none")]
40    pub rtti: Option<Rtti>,
41    /// The entries, in slot order.
42    #[serde(default)]
43    pub entries: Vec<VtableEntry>,
44}
45
46/// Which vtable this is, by the class's MSVC run-time type information.
47#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
48#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
49pub struct Rtti {
50    /// The class's decorated type name, e.g. `".?AVEntity@game@@"`.
51    pub type_name: String,
52    /// Where the vtable's pointer sits in the class's objects, which tells
53    /// apart the vtables of a class with several bases.
54    #[serde(default, skip_serializing_if = "is_zero")]
55    pub offset: u32,
56}
57
58fn is_zero(value: &u32) -> bool {
59    *value == 0
60}
61
62/// One slot of a [`Vtable`].
63#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
64#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
65pub struct VtableEntry {
66    /// The slot's index in the vtable.
67    pub index: u32,
68    /// The slot's method name, if known.
69    #[serde(default, skip_serializing_if = "Option::is_none")]
70    pub name: Option<String>,
71    /// The target function's address, relative to the module's image base.
72    #[serde(with = "crate::hex::int")]
73    #[cfg_attr(feature = "schema", schemars(with = "String"))]
74    pub rva: u32,
75    /// The slot's function (pointer) type, if known.
76    #[serde(default, skip_serializing_if = "Option::is_none")]
77    pub signature: Option<TypeId>,
78}