[XModule] Remove module and its functions while unloading

This commit is contained in:
Gliniak 2021-12-25 15:11:05 +01:00
parent f2c0ae46c1
commit 371441ec3a
7 changed files with 52 additions and 1 deletions

View File

@ -73,6 +73,15 @@ Entry::Status EntryTable::GetOrCreate(uint32_t address, Entry** out_entry) {
return status; 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<Function*> EntryTable::FindWithAddress(uint32_t address) { std::vector<Function*> EntryTable::FindWithAddress(uint32_t address) {
auto global_lock = global_critical_region_.Acquire(); auto global_lock = global_critical_region_.Acquire();
std::vector<Function*> fns; std::vector<Function*> fns;

View File

@ -41,6 +41,7 @@ class EntryTable {
Entry* Get(uint32_t address); Entry* Get(uint32_t address);
Entry::Status GetOrCreate(uint32_t address, Entry** out_entry); Entry::Status GetOrCreate(uint32_t address, Entry** out_entry);
void Delete(uint32_t address);
std::vector<Function*> FindWithAddress(uint32_t address); std::vector<Function*> FindWithAddress(uint32_t address);

View File

@ -147,6 +147,15 @@ Symbol::Status Module::DefineVariable(Symbol* symbol) {
return DefineSymbol(symbol); return DefineSymbol(symbol);
} }
const std::vector<uint32_t> Module::GetAddressedFunctions() {
std::vector<uint32_t> addresses;
for (const auto& [key, _] : map_) {
addresses.push_back(key);
}
return addresses;
}
void Module::ForEachFunction(std::function<void(Function*)> callback) { void Module::ForEachFunction(std::function<void(Function*)> callback) {
auto global_lock = global_critical_region_.Acquire(); auto global_lock = global_critical_region_.Acquire();
for (auto& symbol : list_) { for (auto& symbol : list_) {

View File

@ -46,6 +46,7 @@ class Module {
Symbol::Status DefineFunction(Function* symbol); Symbol::Status DefineFunction(Function* symbol);
Symbol::Status DefineVariable(Symbol* symbol); Symbol::Status DefineVariable(Symbol* symbol);
const std::vector<uint32_t> GetAddressedFunctions();
void ForEachFunction(std::function<void(Function*)> callback); void ForEachFunction(std::function<void(Function*)> callback);
void ForEachSymbol(size_t start_index, size_t end_index, void ForEachSymbol(size_t start_index, size_t end_index,
std::function<void(Symbol*)> callback); std::function<void(Symbol*)> callback);

View File

@ -167,6 +167,27 @@ bool Processor::AddModule(std::unique_ptr<Module> module) {
return true; 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<xe::cpu::Module> const& module) {
return module->name() == name;
});
if (itr != modules_.cend()) {
const std::vector<uint32_t> addressed_functions =
(*itr)->GetAddressedFunctions();
modules_.erase(itr);
for (const uint32_t entry : addressed_functions) {
RemoveFunctionByAddress(entry);
}
}
}
Module* Processor::GetModule(const std::string_view name) { Module* Processor::GetModule(const std::string_view name) {
auto global_lock = global_critical_region_.Acquire(); auto global_lock = global_critical_region_.Acquire();
for (const auto& module : modules_) { for (const auto& module : modules_) {
@ -216,6 +237,10 @@ std::vector<Function*> Processor::FindFunctionsWithAddress(uint32_t address) {
return entry_table_.FindWithAddress(address); return entry_table_.FindWithAddress(address);
} }
void Processor::RemoveFunctionByAddress(uint32_t address) {
entry_table_.Delete(address);
}
Function* Processor::ResolveFunction(uint32_t address) { Function* Processor::ResolveFunction(uint32_t address) {
Entry* entry; Entry* entry;
Entry::Status status = entry_table_.GetOrCreate(address, &entry); Entry::Status status = entry_table_.GetOrCreate(address, &entry);

View File

@ -101,6 +101,7 @@ class Processor {
} }
bool AddModule(std::unique_ptr<Module> module); bool AddModule(std::unique_ptr<Module> module);
void RemoveModule(const std::string_view name);
Module* GetModule(const std::string_view name); Module* GetModule(const std::string_view name);
std::vector<Module*> GetModules(); std::vector<Module*> GetModules();
@ -111,6 +112,7 @@ class Processor {
Function* QueryFunction(uint32_t address); Function* QueryFunction(uint32_t address);
std::vector<Function*> FindFunctionsWithAddress(uint32_t address); std::vector<Function*> FindFunctionsWithAddress(uint32_t address);
void RemoveFunctionByAddress(uint32_t address);
Function* LookupFunction(uint32_t address); Function* LookupFunction(uint32_t address);
Function* LookupFunction(Module* module, uint32_t address); Function* LookupFunction(Module* module, uint32_t address);

View File

@ -12,6 +12,7 @@
#include "xenia/base/byte_stream.h" #include "xenia/base/byte_stream.h"
#include "xenia/base/logging.h" #include "xenia/base/logging.h"
#include "xenia/base/string.h" #include "xenia/base/string.h"
#include "xenia/cpu/processor.h"
#include "xenia/kernel/kernel_state.h" #include "xenia/kernel/kernel_state.h"
#include "xenia/kernel/user_module.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::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, X_STATUS XModule::GetSection(const std::string_view name,
uint32_t* out_section_data, uint32_t* out_section_data,