NSMBW-Decomp
A decompilation of New Super Mario Bros. Wii
Loading...
Searching...
No Matches
c_dylink.hpp
1#pragma once
2
3#include <game/mLib/m_dvd.hpp>
4#include <lib/egg/core/eggExpHeap.h>
5#include <lib/egg/core/eggDvdFile.h>
6#include <lib/nw4r/db.h>
7
8/// @brief A debug map file wrapper.
9/// @details Wraps nw4r::db::MapFile to provide a simpler interface for managing debug map files.
10/// @ingroup clib
11class DbMapFile {
12public:
13 /// @brief Creates the map file.
14 DbMapFile() : mpMapFile(nullptr) {}
15
16 /// @brief Destroys the map file.
17 /// @note The map file is unregistered automatically on destruction.
18 ~DbMapFile();
19
20 /// @brief Loads and registers a map file from disc.
21 /// @param path The path to the map file on disc.
22 /// @param moduleInfo The module information associated with this map file,
23 /// or @p nullptr if the map file belongs to a non-relocatable module.
24 void RegisterOnDvd(const char *path, const OSModuleInfo *moduleInfo);
25
26 /// @brief Unregisters the map file.
27 /// @note Safe to call multiple times; subsequent calls have no effect.
28 void Unregister();
29
30 nw4r::db::MapFile *mpMapFile; ///< A pointer to the internal MapFile instance.
31 u8 mBuf[sizeof(nw4r::db::MapFile)]; ///< The raw storage for the MapFile instance.
32};
33
34/**
35 * @brief Base class for managing a relocatable module.
36 *
37 * The class tracks how many times a module is being used via reference counting.
38 * It automatically handles the physical loading/linking when the first user requests it,
39 * and unloads it only when the last user is finished. All active modules are tracked in a
40 * global doubly-linked list.
41 *
42 * Derived classes are expected to override the @p do_* methods to implement
43 * module-specific behavior.
44 * @ingroup clib
45 */
47protected:
48 u16 mUsageCount; ///< The number of active users of this module. When this reaches zero, the module may be unloaded.
49 u16 mLinkCount; ///< The number of times this module has been successfully linked.
50 DynamicModuleControlBase *mpPrev; ///< The previous module in the linked list.
51 DynamicModuleControlBase *mpNext; ///< The next module in the linked list.
52
53public:
54 DynamicModuleControlBase(); ///< Constructs a new DynamicModuleControlBase and adds it to the linked list.
55 virtual ~DynamicModuleControlBase(); ///< Destroys the DynamicModuleControlBase and removes it from the linked list.
56
57 /// @brief Gets the module name.
58 /// @return A string identifying the module, or @p nullptr if unnamed.
59 virtual const char *getModuleName() const { return nullptr; }
60
61 /// @brief Gets the module size in bytes.
62 /// @return The size of the module, or @p 0 if unknown.
63 virtual size_t getModuleSize() const;
64
65 /// @brief Gets a human-readable module type string.
66 virtual const char *getModuleTypeString() const { return "Base"; }
67
68 /// @brief Outputs debug information about the module.
69 /// @decompnote{This function has been stubbed, but was likely used for debugging purposes during development.}
70 virtual void dump();
71
72 /// @brief Module-specific implementation for loading the module into memory.
73 /// @return Whether the operation was successful.
74 virtual bool do_load() { return true; }
75
76 /// @brief Module-specific implementation for loading the module into memory asynchronously.
77 /// @return Whether the operation was successfully started.
78 virtual bool do_load_async() { return true; }
79
80 /// @brief Module-specific implementation for unloading the module from memory.
81 /// @return Whether the operation was successful.
82 virtual bool do_unload() { return true; }
83
84 /// @brief Module-specific implementation for linking the module, making it ready for use.
85 /// @return Whether the operation was successful.
86 virtual bool do_link() { return true; }
87
88 /// @brief Module-specific implementation for unlinking the module.
89 /// @return Whether the operation was successful.
90 virtual bool do_unlink() { return true; }
91
92 /// @brief Loads and links the module if needed.
93 /// @return Whether the operation was successful.
94 bool link();
95
96 /// @brief Unlinks and unloads the module if needed.
97 /// @decompnote{This function is not present in the final binary and was reconstructed based on
98 /// surrounding logic and expected behavior.}
99 /// @return Whether the operation was successful.
100 bool unlink();
101
102 /// @brief Loads the module asynchronously if needed.
103 /// @return @p true if the load is finished, @p false if it is still in progress.
104 bool load_async();
105
106 static DynamicModuleControlBase *mFirst; ///< The first module in the linked list.
107 static DynamicModuleControlBase *mLast; ///< The last module in the linked list.
108};
109
110/// @brief Full implementation of a dynamic module handler.
111/// @ingroup clib
113public:
114 /// @brief Identifies where the module data is physically located.
115 /// @unofficial
117 MODULE_TYPE_UNKNOWN, ///< The module type has not yet been determined.
118 MODULE_TYPE_MEM, ///< The module is loaded from main RAM. @unused
119 MODULE_TYPE_ARAM, ///< The module is loaded from ARAM. @unused
120 MODULE_TYPE_DVD ///< The module is loaded from the disc.
121 };
122
123 /// @brief Constructs a new DynamicModuleControl.
124 /// @param name The module name.
125 /// @param heap The heap to load the module into, or @p nullptr to use @ref sDylinkHeap "the default heap".
126 DynamicModuleControl(const char *name, EGG::ExpHeap *heap);
127 virtual ~DynamicModuleControl(); ///< Destroys the DynamicModuleControl.
128
129 virtual const char *getModuleName() const override;
130 virtual size_t getModuleSize() const override;
131 virtual const char *getModuleTypeString() const override;
132 virtual void dump() override;
133 virtual bool do_load() override;
134 virtual bool do_load_async() override;
135 virtual bool do_unload() override;
136 virtual bool do_link() override;
137 virtual bool do_unlink() override;
138
139 /// @brief Updates the @ref sDylinkHeap "module linking heap" statistics.
140 /// @details The function tracks the @ref sHeapMinAllocatableSize "minimum allocatable space" and
141 /// @ref sHeapMinTotalFreeSize "minimum free space" size during module operations, probably to aid in debugging.
142 void checkHeapStatus();
143
144 /// @brief Initializes the global dynamic linking system.
145 /// @param heap The heap where all modules will be allocated by default.
146 static void initialize(EGG::ExpHeap *heap);
147
148 /// @brief Internal callback used for asynchronous loading operations.
149 /// @details The return type is @p void* to satisfy the type required by mDvd_callback_c.
150 /// @param self Pointer to the DynamicModuleControl instance.
151 /// @return The result of do_load().
152 static void *callback(void *self);
153
154 u8 mPad[4];
155 OSModuleHeader *mpModule; ///< The data of the module, including the header.
156 void *mpBss; ///< The BSS section of the module.
157 u32 mPrologReturn; ///< The return value of the module's prolog function.
158 const char *mModuleName; ///< The module name.
159 u8 mType; ///< The module type. See ModuleType_e.
160 u8 mLoadCount; ///< The number of times this module has been loaded.
161 u16 mChecksum; ///< The checksum of the module.
162 int mModuleSize; ///< The module size, in bytes.
163 mDvd_callback_c *mpDvdCallback; ///< The DVD command used to load the module asynchronously.
164 EGG::ExpHeap *mpHeap; ///< The heap used for module loading and BSS allocation.
165 DbMapFile mDebugMapFile; ///< The debug map file for this module.
166
167 static EGG::ExpHeap *sDylinkHeap; ///< The heap used for dynamic module loading and BSS allocation.
168 static EGG::DvdFile *sDvdFile; ///< The DVD file handle used for loading the string table file.
169 static size_t sAllocBytes; ///< The total number of bytes allocated across all active modules.
170 static size_t sHeapMinAllocatableSize;///< The lowest observed allocatable space in #sDylinkHeap during module loading.
171 static size_t sHeapMinTotalFreeSize; ///< The lowest observed free space in #sDylinkHeap during module loading.
172 static const char *sModulesDir; ///< The directory on the disk where the modules are located.
173};
A debug map file wrapper.
Definition c_dylink.hpp:11
u8 mBuf[sizeof(nw4r::db::MapFile)]
The raw storage for the MapFile instance.
Definition c_dylink.hpp:31
void RegisterOnDvd(const char *path, const OSModuleInfo *moduleInfo)
Loads and registers a map file from disc.
Definition c_dylink.cpp:351
~DbMapFile()
Destroys the map file.
Definition c_dylink.cpp:345
nw4r::db::MapFile * mpMapFile
A pointer to the internal MapFile instance.
Definition c_dylink.hpp:30
void Unregister()
Unregisters the map file.
Definition c_dylink.cpp:355
DbMapFile()
Creates the map file.
Definition c_dylink.hpp:14
static DynamicModuleControlBase * mLast
The last module in the linked list.
Definition c_dylink.hpp:107
virtual void dump()
Outputs debug information about the module.
Definition c_dylink.cpp:71
DynamicModuleControlBase()
Constructs a new DynamicModuleControlBase and adds it to the linked list.
Definition c_dylink.cpp:25
virtual bool do_unload()
Module-specific implementation for unloading the module from memory.
Definition c_dylink.hpp:82
virtual const char * getModuleTypeString() const
Gets a human-readable module type string.
Definition c_dylink.hpp:66
bool unlink()
Unlinks and unloads the module if needed.
Definition c_dylink.cpp:54
virtual ~DynamicModuleControlBase()
Destroys the DynamicModuleControlBase and removes it from the linked list.
Definition c_dylink.cpp:8
virtual bool do_unlink()
Module-specific implementation for unlinking the module.
Definition c_dylink.hpp:90
bool link()
Loads and links the module if needed.
Definition c_dylink.cpp:36
DynamicModuleControlBase * mpPrev
The previous module in the linked list.
Definition c_dylink.hpp:50
virtual const char * getModuleName() const
Gets the module name.
Definition c_dylink.hpp:59
virtual bool do_load()
Module-specific implementation for loading the module into memory.
Definition c_dylink.hpp:74
virtual bool do_link()
Module-specific implementation for linking the module, making it ready for use.
Definition c_dylink.hpp:86
static DynamicModuleControlBase * mFirst
The first module in the linked list.
Definition c_dylink.hpp:106
bool load_async()
Loads the module asynchronously if needed.
Definition c_dylink.cpp:64
virtual bool do_load_async()
Module-specific implementation for loading the module into memory asynchronously.
Definition c_dylink.hpp:78
DynamicModuleControlBase * mpNext
The next module in the linked list.
Definition c_dylink.hpp:51
u16 mLinkCount
The number of times this module has been successfully linked.
Definition c_dylink.hpp:49
virtual size_t getModuleSize() const
Gets the module size in bytes.
Definition c_dylink.cpp:73
u16 mUsageCount
The number of active users of this module. When this reaches zero, the module may be unloaded.
Definition c_dylink.hpp:48
virtual bool do_link() override
Module-specific implementation for linking the module, making it ready for use.
Definition c_dylink.cpp:247
static EGG::DvdFile * sDvdFile
The DVD file handle used for loading the string table file.
Definition c_dylink.hpp:168
static const char * sModulesDir
The directory on the disk where the modules are located.
Definition c_dylink.hpp:172
ModuleType_e
Identifies where the module data is physically located.
Definition c_dylink.hpp:116
@ MODULE_TYPE_UNKNOWN
The module type has not yet been determined.
Definition c_dylink.hpp:117
@ MODULE_TYPE_DVD
The module is loaded from the disc.
Definition c_dylink.hpp:120
@ MODULE_TYPE_MEM
The module is loaded from main RAM.
Definition c_dylink.hpp:118
@ MODULE_TYPE_ARAM
The module is loaded from ARAM.
Definition c_dylink.hpp:119
u32 mPrologReturn
The return value of the module's prolog function.
Definition c_dylink.hpp:157
virtual ~DynamicModuleControl()
Destroys the DynamicModuleControl.
Definition c_dylink.cpp:100
virtual size_t getModuleSize() const override
Gets the module size in bytes.
Definition c_dylink.cpp:329
static size_t sAllocBytes
The total number of bytes allocated across all active modules.
Definition c_dylink.hpp:169
void * mpBss
The BSS section of the module.
Definition c_dylink.hpp:156
static void initialize(EGG::ExpHeap *heap)
Initializes the global dynamic linking system.
Definition c_dylink.cpp:106
virtual const char * getModuleTypeString() const override
Gets a human-readable module type string.
Definition c_dylink.cpp:340
EGG::ExpHeap * mpHeap
The heap used for module loading and BSS allocation.
Definition c_dylink.hpp:164
virtual bool do_load() override
Module-specific implementation for loading the module into memory.
Definition c_dylink.cpp:146
OSModuleHeader * mpModule
The data of the module, including the header.
Definition c_dylink.hpp:155
virtual const char * getModuleName() const override
Gets the module name.
Definition c_dylink.cpp:102
DbMapFile mDebugMapFile
The debug map file for this module.
Definition c_dylink.hpp:165
DynamicModuleControl(const char *name, EGG::ExpHeap *heap)
Constructs a new DynamicModuleControl.
Definition c_dylink.cpp:86
virtual bool do_load_async() override
Module-specific implementation for loading the module into memory asynchronously.
Definition c_dylink.cpp:220
mDvd_callback_c * mpDvdCallback
The DVD command used to load the module asynchronously.
Definition c_dylink.hpp:163
u16 mChecksum
The checksum of the module.
Definition c_dylink.hpp:161
int mModuleSize
The module size, in bytes.
Definition c_dylink.hpp:162
static EGG::ExpHeap * sDylinkHeap
The heap used for dynamic module loading and BSS allocation.
Definition c_dylink.hpp:167
static size_t sHeapMinAllocatableSize
The lowest observed allocatable space in sDylinkHeap during module loading.
Definition c_dylink.hpp:170
virtual bool do_unlink() override
Module-specific implementation for unlinking the module.
Definition c_dylink.cpp:313
virtual void dump() override
Outputs debug information about the module.
Definition c_dylink.cpp:245
void checkHeapStatus()
Updates the module linking heap statistics.
Definition c_dylink.cpp:122
u8 mLoadCount
The number of times this module has been loaded.
Definition c_dylink.hpp:160
static size_t sHeapMinTotalFreeSize
The lowest observed free space in sDylinkHeap during module loading.
Definition c_dylink.hpp:171
virtual bool do_unload() override
Module-specific implementation for unloading the module from memory.
Definition c_dylink.cpp:237
static void * callback(void *self)
Internal callback used for asynchronous loading operations.
Definition c_dylink.cpp:117
u8 mType
The module type. See ModuleType_e.
Definition c_dylink.hpp:159
const char * mModuleName
The module name.
Definition c_dylink.hpp:158