Make PluginLinkInformation not optional anymore in PluginContainer, add stub link data if missing

This commit is contained in:
Maschell 2024-08-04 14:12:52 +02:00
parent dc67b11b21
commit 629dc0393f
10 changed files with 59 additions and 57 deletions

View File

@ -46,10 +46,10 @@ PluginManagement::loadPlugins(const std::set<std::shared_ptr<PluginData>, Plugin
DisplayErrorNotificationMessage(errMsg, 15.0f);
continue;
}
plugins.emplace_back(std::move(*metaInfo), std::move(linkInfo), pluginData);
plugins.emplace_back(std::move(*metaInfo), std::move(*linkInfo), pluginData);
} else {
DEBUG_FUNCTION_LINE_INFO("We want to skip %s by %s", metaInfo->getName().c_str(), metaInfo->getAuthor().c_str());
plugins.emplace_back(std::move(*metaInfo), std::nullopt, pluginData);
plugins.emplace_back(std::move(*metaInfo), PluginLinkInformation::CreateStub(), pluginData);
}
} else {
auto errMsg = string_format("Failed to load plugin: %s", pluginData->getSource().c_str());
@ -157,13 +157,13 @@ bool PluginManagement::doRelocations(const std::vector<PluginContainer> &plugins
OSDynLoad_SetAllocator(CustomDynLoadAlloc, CustomDynLoadFree);
for (const auto &pluginContainer : plugins) {
if (!pluginContainer.isPluginLinkedAndLoaded()) {
if (pluginContainer.isLinkedAndLoaded()) {
continue;
}
DEBUG_FUNCTION_LINE_VERBOSE("Doing relocations for plugin: %s", pluginContainer.getMetaInformation().getName().c_str());
if (!PluginManagement::doRelocation(pluginContainer.getPluginLinkInformation()->getRelocationDataList(),
if (!PluginManagement::doRelocation(pluginContainer.getPluginLinkInformation().getRelocationDataList(),
trampData,
pluginContainer.getPluginLinkInformation()->getTrampolineId(),
pluginContainer.getPluginLinkInformation().getTrampolineId(),
usedRPls)) {
return false;
}
@ -176,10 +176,7 @@ bool PluginManagement::doRelocations(const std::vector<PluginContainer> &plugins
bool PluginManagement::RestoreFunctionPatches(std::vector<PluginContainer> &plugins) {
for (auto &cur : std::ranges::reverse_view(plugins)) {
if (!cur.isPluginLinkedAndLoaded()) {
continue;
}
for (auto &curFunction : std::ranges::reverse_view(cur.getPluginLinkInformation()->getFunctionDataList())) {
for (auto &curFunction : std::ranges::reverse_view(cur.getPluginLinkInformation().getFunctionDataList())) {
if (!curFunction.RemovePatch()) {
DEBUG_FUNCTION_LINE_ERR("Failed to remove function patch for: plugin %s", cur.getMetaInformation().getName().c_str());
return false;
@ -191,10 +188,7 @@ bool PluginManagement::RestoreFunctionPatches(std::vector<PluginContainer> &plug
bool PluginManagement::DoFunctionPatches(std::vector<PluginContainer> &plugins) {
for (auto &cur : plugins) {
if (!cur.isPluginLinkedAndLoaded()) {
continue;
}
for (auto &curFunction : cur.getPluginLinkInformation()->getFunctionDataList()) {
for (auto &curFunction : cur.getPluginLinkInformation().getFunctionDataList()) {
if (!curFunction.AddPatch()) {
DEBUG_FUNCTION_LINE_ERR("Failed to add function patch for: plugin %s", cur.getMetaInformation().getName().c_str());
return false;

View File

@ -44,9 +44,6 @@ void CallHook(const std::vector<PluginContainer> &plugins, const wups_loader_hoo
void CallHook(const std::vector<PluginContainer> &plugins, const wups_loader_hook_type_t hook_type, const std::function<bool(const PluginContainer &)> &pred) {
DEBUG_FUNCTION_LINE_VERBOSE("Calling hook of type %s [%d]", hook_names[hook_type], hook_type);
for (const auto &plugin : plugins) {
if (!plugin.isPluginLinkedAndLoaded()) {
return;
}
if (pred(plugin)) {
CallHook(plugin, hook_type);
}
@ -54,10 +51,7 @@ void CallHook(const std::vector<PluginContainer> &plugins, const wups_loader_hoo
}
void CallHook(const PluginContainer &plugin, wups_loader_hook_type_t hook_type) {
if (!plugin.isPluginLinkedAndLoaded()) {
return;
}
for (const auto &hook : plugin.getPluginLinkInformation()->getHookDataList()) {
for (const auto &hook : plugin.getPluginLinkInformation().getHookDataList()) {
if (hook.getType() == hook_type) {
DEBUG_FUNCTION_LINE_VERBOSE("Calling hook of type %s for plugin %s [%d]", hook_names[hook.getType()], plugin.getMetaInformation().getName().c_str(), hook_type);
void *func_ptr = hook.getFunctionPointer();

View File

@ -227,10 +227,11 @@ void CleanupPlugins(std::vector<PluginContainer> &&pluginsToDeinit) {
void CheckCleanupCallbackUsage(const std::vector<PluginContainer> &plugins) {
auto *curThread = OSGetCurrentThread();
for (const auto &cur : plugins) {
if (!cur.isPluginLinkedAndLoaded()) {
if (!cur.isLinkedAndLoaded()) {
continue;
}
const auto textSection = cur.getPluginLinkInformation()->getSectionInfo(".text");
const auto textSection = cur.getPluginLinkInformation().getSectionInfo(".text");
if (!textSection) {
continue;
}

View File

@ -148,10 +148,10 @@ DECL_FUNCTION(uint32_t, SC17_FindClosestSymbol,
char *moduleNameBuffer,
uint32_t moduleNameBufferLength) {
for (const auto &plugin : gLoadedPlugins) {
if (!plugin.isPluginLinkedAndLoaded()) {
if (!plugin.isLinkedAndLoaded()) {
continue;
}
const auto sectionInfo = plugin.getPluginLinkInformation()->getSectionInfo(".text");
const auto sectionInfo = plugin.getPluginLinkInformation().getSectionInfo(".text");
if (!sectionInfo) {
continue;
}
@ -161,7 +161,7 @@ DECL_FUNCTION(uint32_t, SC17_FindClosestSymbol,
}
strncpy(moduleNameBuffer, plugin.getMetaInformation().getName().c_str(), moduleNameBufferLength - 1);
if (const auto functionSymbolData = plugin.getPluginLinkInformation()->getNearestFunctionSymbolData(addr)) {
if (const auto functionSymbolData = plugin.getPluginLinkInformation().getNearestFunctionSymbolData(addr)) {
strncpy(symbolNameBuffer, functionSymbolData->getName().c_str(), moduleNameBufferLength - 1);
if (outDistance) {
*outDistance = addr - reinterpret_cast<uint32_t>(functionSymbolData->getAddress());
@ -183,10 +183,10 @@ DECL_FUNCTION(uint32_t, SC17_FindClosestSymbol,
DECL_FUNCTION(uint32_t, KiGetAppSymbolName, uint32_t addr, char *buffer, int32_t bufSize) {
for (const auto &plugin : gLoadedPlugins) {
if (!plugin.isPluginLinkedAndLoaded()) {
if (!plugin.isLinkedAndLoaded()) {
continue;
}
const auto sectionInfo = plugin.getPluginLinkInformation()->getSectionInfo(".text");
const auto sectionInfo = plugin.getPluginLinkInformation().getSectionInfo(".text");
if (!sectionInfo) {
continue;
}
@ -202,7 +202,7 @@ DECL_FUNCTION(uint32_t, KiGetAppSymbolName, uint32_t addr, char *buffer, int32_t
}
strncpy(buffer, plugin.getMetaInformation().getName().c_str(), bufSize - 1);
if (const auto functionSymbolData = plugin.getPluginLinkInformation()->getNearestFunctionSymbolData(addr)) {
if (const auto functionSymbolData = plugin.getPluginLinkInformation().getNearestFunctionSymbolData(addr)) {
buffer[pluginNameLen] = '|';
buffer[pluginNameLen + 1] = '\0';
strncpy(buffer + pluginNameLen + 1, functionSymbolData->getName().c_str(), spaceLeftInBuffer - 1);

View File

@ -1,7 +1,7 @@
#include "PluginContainer.h"
#include "utils/storage/StorageUtils.h"
PluginContainer::PluginContainer(PluginMetaInformation metaInformation, std::optional<PluginLinkInformation> pluginLinkInformation, std::shared_ptr<PluginData> pluginData)
PluginContainer::PluginContainer(PluginMetaInformation metaInformation, PluginLinkInformation pluginLinkInformation, std::shared_ptr<PluginData> pluginData)
: mMetaInformation(std::move(metaInformation)),
mPluginLinkInformation(std::move(pluginLinkInformation)),
mPluginData(std::move(pluginData)) {
@ -39,22 +39,13 @@ const PluginMetaInformation &PluginContainer::getMetaInformation() const {
return this->mMetaInformation;
}
bool PluginContainer::isPluginLinkedAndLoaded() const {
return this->mPluginLinkInformation.has_value();
const PluginLinkInformation &PluginContainer::getPluginLinkInformation() const {
return this->mPluginLinkInformation;
}
const PluginLinkInformation *PluginContainer::getPluginLinkInformation() const {
if (this->mPluginLinkInformation.has_value()) {
return this->mPluginLinkInformation.operator->();
}
return nullptr;
}
PluginLinkInformation *PluginContainer::getPluginLinkInformation() {
if (this->mPluginLinkInformation.has_value()) {
return this->mPluginLinkInformation.operator->();
}
return nullptr;
PluginLinkInformation &PluginContainer::getPluginLinkInformation() {
return this->mPluginLinkInformation;
}
std::shared_ptr<PluginData> PluginContainer::getPluginDataCopy() const {
@ -73,6 +64,10 @@ void PluginContainer::setConfigData(const PluginConfigData &pluginConfigData) {
mPluginConfigData = pluginConfigData;
}
bool PluginContainer::isLinkedAndLoaded() const {
return mPluginLinkInformation.hasValidData();
}
WUPSStorageError PluginContainer::OpenStorage() {
if (getMetaInformation().getWUPSVersion() < WUPSVersion(0, 8, 0)) {
return WUPS_STORAGE_ERROR_SUCCESS;

View File

@ -28,7 +28,7 @@
class PluginContainer {
public:
PluginContainer(PluginMetaInformation metaInformation, std::optional<PluginLinkInformation> pluginLinkInformation, std::shared_ptr<PluginData> pluginData);
PluginContainer(PluginMetaInformation metaInformation, PluginLinkInformation pluginLinkInformation, std::shared_ptr<PluginData> pluginData);
PluginContainer(const PluginContainer &) = delete;
@ -38,18 +38,18 @@ public:
[[nodiscard]] const PluginMetaInformation &getMetaInformation() const;
[[nodiscard]] const PluginLinkInformation *getPluginLinkInformation() const;
[[nodiscard]] const PluginLinkInformation &getPluginLinkInformation() const;
[[nodiscard]] PluginLinkInformation *getPluginLinkInformation();
[[nodiscard]] PluginLinkInformation &getPluginLinkInformation();
[[nodiscard]] std::shared_ptr<PluginData> getPluginDataCopy() const;
[[nodiscard]] bool isPluginLinkedAndLoaded() const;
[[nodiscard]] uint32_t getHandle() const;
[[nodiscard]] const std::optional<PluginConfigData> &getConfigData() const;
[[nodiscard]] bool isLinkedAndLoaded() const;
void setConfigData(const PluginConfigData &pluginConfigData);
WUPSStorageError OpenStorage();
@ -64,7 +64,7 @@ public:
private:
PluginMetaInformation mMetaInformation;
std::optional<PluginLinkInformation> mPluginLinkInformation;
PluginLinkInformation mPluginLinkInformation;
std::shared_ptr<PluginData> mPluginData;
std::optional<PluginConfigData> mPluginConfigData = std::nullopt;

View File

@ -111,3 +111,11 @@ const HeapMemoryFixedSize &PluginLinkInformation::getTextMemory() const {
const HeapMemoryFixedSize &PluginLinkInformation::getDataMemory() const {
return mAllocatedDataMemoryAddress;
}
PluginLinkInformation PluginLinkInformation::CreateStub() {
return {};
}
bool PluginLinkInformation::hasValidData() const {
return mAllocatedDataMemoryAddress.size() > 0 && mAllocatedTextMemoryAddress.size() > 0;
}

View File

@ -39,6 +39,8 @@ struct FunctionSymbolDataComparator {
class PluginLinkInformation {
public:
static PluginLinkInformation CreateStub();
PluginLinkInformation(const PluginLinkInformation &) = delete;
PluginLinkInformation(PluginLinkInformation &&src) noexcept;
@ -65,6 +67,8 @@ public:
[[nodiscard]] const HeapMemoryFixedSize &getDataMemory() const;
[[nodiscard]] bool hasValidData() const;
private:
PluginLinkInformation() = default;

View File

@ -77,7 +77,7 @@ void ConfigUtils::displayMenu() {
std::vector<ConfigDisplayItem> configs;
for (const auto &plugin : gLoadedPlugins) {
if (!plugin.isPluginLinkedAndLoaded()) {
if (!plugin.isLinkedAndLoaded()) {
continue;
}
GeneralConfigInformation info;
@ -102,7 +102,7 @@ void ConfigUtils::displayMenu() {
DEBUG_FUNCTION_LINE_ERR("Failed to create config for plugin: \"%s\"", info.name.c_str());
}
} else {
for (const auto &hook : plugin.getPluginLinkInformation()->getHookDataList()) {
for (const auto &hook : plugin.getPluginLinkInformation().getHookDataList()) {
if (hook.getType() == WUPS_LOADER_HOOK_GET_CONFIG_DEPRECATED) {
if (hook.getFunctionPointer() == nullptr) {
DEBUG_FUNCTION_LINE_ERR("Hook had invalid ptr");

View File

@ -264,7 +264,7 @@ extern "C" PluginBackendApiErrorType WUPSGetNumberOfLoadedPlugins(uint32_t *outC
if (outCount == nullptr) {
return PLUGIN_BACKEND_API_ERROR_INVALID_ARG;
}
*outCount = gLoadedPlugins.size();
*outCount = std::count_if(gLoadedPlugins.begin(), gLoadedPlugins.end(), [](const auto &cur) { return cur.isLinkedAndLoaded(); });
return PLUGIN_BACKEND_API_ERROR_NONE;
}
@ -276,9 +276,12 @@ extern "C" PluginBackendApiErrorType WUPSGetSectionInformationForPlugin(const wu
if (handle != 0 && plugin_section_list != nullptr && buffer_size != 0) {
bool found = false;
for (const auto &curContainer : gLoadedPlugins) {
if (curContainer.isPluginLinkedAndLoaded() && curContainer.getHandle() == handle) {
if (!curContainer.isLinkedAndLoaded()) {
continue;
}
if (curContainer.getHandle() == handle) {
found = true;
const auto &sectionInfoList = curContainer.getPluginLinkInformation()->getSectionInfoList();
const auto &sectionInfoList = curContainer.getPluginLinkInformation().getSectionInfoList();
uint32_t offset = 0;
for (auto const &sectionInfo : sectionInfoList | std::views::values) {
@ -320,9 +323,12 @@ extern "C" PluginBackendApiErrorType WUPSGetSectionMemoryAddresses(const wups_ba
return PLUGIN_BACKEND_API_ERROR_INVALID_ARG;
}
for (const auto &curContainer : gLoadedPlugins) {
if (curContainer.isPluginLinkedAndLoaded() && curContainer.getHandle() == handle) {
*textAddress = const_cast<void *>(curContainer.getPluginLinkInformation()->getTextMemory().data());
*dataAddress = const_cast<void *>(curContainer.getPluginLinkInformation()->getDataMemory().data());
if (!curContainer.isLinkedAndLoaded()) {
continue;
}
if (curContainer.getHandle() == handle) {
*textAddress = static_cast<void *>(curContainer.getPluginLinkInformation().getTextMemory().data());
*dataAddress = static_cast<void *>(curContainer.getPluginLinkInformation().getDataMemory().data());
return PLUGIN_BACKEND_API_ERROR_NONE;
}
}