diff --git a/src/xenia/cpu/entry_table.cc b/src/xenia/cpu/entry_table.cc index 8770fe332..1d82f0538 100644 --- a/src/xenia/cpu/entry_table.cc +++ b/src/xenia/cpu/entry_table.cc @@ -73,6 +73,15 @@ Entry::Status EntryTable::GetOrCreate(uint32_t address, Entry** out_entry) { return status; } +void EntryTable::Delete(uint32_t address) { + auto global_lock = global_critical_region_.Acquire(); + const auto itr = map_.find(address); + + if (itr != map_.cend()) { + map_.erase(itr); + } +} + std::vector EntryTable::FindWithAddress(uint32_t address) { auto global_lock = global_critical_region_.Acquire(); std::vector fns; diff --git a/src/xenia/cpu/entry_table.h b/src/xenia/cpu/entry_table.h index e3c4bc271..14a3e6c82 100644 --- a/src/xenia/cpu/entry_table.h +++ b/src/xenia/cpu/entry_table.h @@ -41,6 +41,7 @@ class EntryTable { Entry* Get(uint32_t address); Entry::Status GetOrCreate(uint32_t address, Entry** out_entry); + void Delete(uint32_t address); std::vector FindWithAddress(uint32_t address); diff --git a/src/xenia/cpu/module.cc b/src/xenia/cpu/module.cc index 4c582763f..17ad99790 100644 --- a/src/xenia/cpu/module.cc +++ b/src/xenia/cpu/module.cc @@ -147,6 +147,15 @@ Symbol::Status Module::DefineVariable(Symbol* symbol) { return DefineSymbol(symbol); } +const std::vector Module::GetAddressedFunctions() { + std::vector addresses; + + for (const auto& [key, _] : map_) { + addresses.push_back(key); + } + return addresses; +} + void Module::ForEachFunction(std::function callback) { auto global_lock = global_critical_region_.Acquire(); for (auto& symbol : list_) { diff --git a/src/xenia/cpu/module.h b/src/xenia/cpu/module.h index f958b4309..fd85ab9ed 100644 --- a/src/xenia/cpu/module.h +++ b/src/xenia/cpu/module.h @@ -46,6 +46,7 @@ class Module { Symbol::Status DefineFunction(Function* symbol); Symbol::Status DefineVariable(Symbol* symbol); + const std::vector GetAddressedFunctions(); void ForEachFunction(std::function callback); void ForEachSymbol(size_t start_index, size_t end_index, std::function callback); diff --git a/src/xenia/cpu/processor.cc b/src/xenia/cpu/processor.cc index 2fe459dc4..944dd598f 100644 --- a/src/xenia/cpu/processor.cc +++ b/src/xenia/cpu/processor.cc @@ -170,6 +170,27 @@ bool Processor::AddModule(std::unique_ptr module) { return true; } +void Processor::RemoveModule(const std::string_view name) { + auto global_lock = global_critical_region_.Acquire(); + + auto itr = + std::find_if(modules_.cbegin(), modules_.cend(), + [name](std::unique_ptr const& module) { + return module->name() == name; + }); + + if (itr != modules_.cend()) { + const std::vector addressed_functions = + (*itr)->GetAddressedFunctions(); + + modules_.erase(itr); + + for (const uint32_t entry : addressed_functions) { + RemoveFunctionByAddress(entry); + } + } +} + Module* Processor::GetModule(const std::string_view name) { auto global_lock = global_critical_region_.Acquire(); for (const auto& module : modules_) { @@ -219,6 +240,10 @@ std::vector Processor::FindFunctionsWithAddress(uint32_t address) { return entry_table_.FindWithAddress(address); } +void Processor::RemoveFunctionByAddress(uint32_t address) { + entry_table_.Delete(address); +} + Function* Processor::ResolveFunction(uint32_t address) { Entry* entry; Entry::Status status = entry_table_.GetOrCreate(address, &entry); diff --git a/src/xenia/cpu/processor.h b/src/xenia/cpu/processor.h index 2a004548c..c0b956572 100644 --- a/src/xenia/cpu/processor.h +++ b/src/xenia/cpu/processor.h @@ -101,6 +101,7 @@ class Processor { } bool AddModule(std::unique_ptr module); + void RemoveModule(const std::string_view name); Module* GetModule(const std::string_view name); std::vector GetModules(); @@ -111,6 +112,7 @@ class Processor { Function* QueryFunction(uint32_t address); std::vector FindFunctionsWithAddress(uint32_t address); + void RemoveFunctionByAddress(uint32_t address); Function* LookupFunction(uint32_t address); Function* LookupFunction(Module* module, uint32_t address); diff --git a/src/xenia/kernel/xmodule.cc b/src/xenia/kernel/xmodule.cc index 5807fbc88..96880958c 100644 --- a/src/xenia/kernel/xmodule.cc +++ b/src/xenia/kernel/xmodule.cc @@ -12,6 +12,7 @@ #include "xenia/base/byte_stream.h" #include "xenia/base/logging.h" #include "xenia/base/string.h" +#include "xenia/cpu/processor.h" #include "xenia/kernel/kernel_state.h" #include "xenia/kernel/user_module.h" @@ -48,7 +49,10 @@ bool XModule::Matches(const std::string_view name) const { void XModule::OnLoad() { kernel_state_->RegisterModule(this); } -void XModule::OnUnload() { kernel_state_->UnregisterModule(this); } +void XModule::OnUnload() { + kernel_state_->processor()->RemoveModule(this->name()); + kernel_state_->UnregisterModule(this); +} X_STATUS XModule::GetSection(const std::string_view name, uint32_t* out_section_data,