mirror of https://github.com/PCSX2/pcsx2.git
Merge 690c6dc812
into de9d08075e
This commit is contained in:
commit
3e22dd38e9
|
@ -97,11 +97,20 @@ void SymbolImporter::OnElfChanged(std::vector<u8> elf, const std::string& elf_fi
|
|||
return;
|
||||
}
|
||||
|
||||
AnalyseElf(std::move(elf), elf_file_name, EmuConfig.DebuggerAnalysis);
|
||||
AnalyseElf(std::move(elf), elf_file_name, EmuConfig.DebuggerAnalysis, true);
|
||||
|
||||
m_symbol_table_loaded_on_boot = true;
|
||||
}
|
||||
|
||||
void SymbolImporter::OnElfLoadedInMemory()
|
||||
{
|
||||
{
|
||||
std::lock_guard lock(m_elf_loaded_in_memory_mutex);
|
||||
m_elf_loaded_in_memory = true;
|
||||
}
|
||||
m_elf_loaded_in_memory_condition_variable.notify_one();
|
||||
}
|
||||
|
||||
void SymbolImporter::OnDebuggerOpened()
|
||||
{
|
||||
m_debugger_open = true;
|
||||
|
@ -165,11 +174,23 @@ void SymbolImporter::LoadAndAnalyseElf(Pcsx2Config::DebugAnalysisOptions options
|
|||
return;
|
||||
}
|
||||
|
||||
AnalyseElf(elfo.ReleaseData(), elf_path, options);
|
||||
AnalyseElf(elfo.ReleaseData(), elf_path, options, false);
|
||||
}
|
||||
|
||||
struct SymbolImporterThreadParameters
|
||||
{
|
||||
std::vector<u8> elf;
|
||||
std::string elf_file_name;
|
||||
std::string nocash_path;
|
||||
Pcsx2Config::DebugAnalysisOptions options;
|
||||
bool wait_until_elf_is_loaded;
|
||||
};
|
||||
|
||||
void SymbolImporter::AnalyseElf(
|
||||
std::vector<u8> elf, const std::string& elf_file_name, Pcsx2Config::DebugAnalysisOptions options)
|
||||
std::vector<u8> elf,
|
||||
const std::string& elf_file_name,
|
||||
Pcsx2Config::DebugAnalysisOptions options,
|
||||
bool wait_until_elf_is_loaded)
|
||||
{
|
||||
// Search for a .sym file to load symbols from.
|
||||
std::string nocash_path;
|
||||
|
@ -185,38 +206,63 @@ void SymbolImporter::AnalyseElf(
|
|||
nocash_path = iso_file_path.substr(0, n) + ".sym";
|
||||
}
|
||||
|
||||
ccc::Result<ccc::ElfFile> parsed_elf = ccc::ElfFile::parse(std::move(elf));
|
||||
if (!parsed_elf.success())
|
||||
{
|
||||
ccc::report_error(parsed_elf.error());
|
||||
return;
|
||||
}
|
||||
|
||||
ccc::ElfSymbolFile symbol_file(std::move(*parsed_elf), std::move(elf_file_name));
|
||||
SymbolImporterThreadParameters parameters;
|
||||
parameters.elf = std::move(elf);
|
||||
parameters.elf_file_name = elf_file_name;
|
||||
parameters.nocash_path = std::move(nocash_path);
|
||||
parameters.options = std::move(options);
|
||||
parameters.wait_until_elf_is_loaded = wait_until_elf_is_loaded;
|
||||
|
||||
ShutdownWorkerThread();
|
||||
|
||||
m_import_thread = std::thread([this, nocash_path, options, worker_symbol_file = std::move(symbol_file), builtins = m_builtin_types]() {
|
||||
m_import_thread = std::thread([this, params = std::move(parameters)]() {
|
||||
Threading::SetNameOfCurrentThread("Symbol Worker");
|
||||
|
||||
ccc::Result<ccc::ElfFile> parsed_elf = ccc::ElfFile::parse(std::move(params.elf));
|
||||
if (!parsed_elf.success())
|
||||
{
|
||||
ccc::report_error(parsed_elf.error());
|
||||
return;
|
||||
}
|
||||
|
||||
ccc::ElfSymbolFile symbol_file(std::move(*parsed_elf), std::move(params.elf_file_name));
|
||||
|
||||
ccc::SymbolDatabase temp_database;
|
||||
|
||||
ImportSymbols(temp_database, worker_symbol_file, nocash_path, options, builtins, &m_interrupt_import_thread);
|
||||
ImportSymbols(
|
||||
temp_database,
|
||||
symbol_file,
|
||||
params.nocash_path,
|
||||
params.options,
|
||||
m_builtin_types,
|
||||
&m_interrupt_import_thread);
|
||||
|
||||
if (m_interrupt_import_thread)
|
||||
return;
|
||||
|
||||
if (options.GenerateFunctionHashes)
|
||||
if (params.options.GenerateFunctionHashes)
|
||||
{
|
||||
ElfMemoryReader reader(worker_symbol_file.elf());
|
||||
ElfMemoryReader reader(symbol_file.elf());
|
||||
SymbolGuardian::GenerateFunctionHashes(temp_database, reader);
|
||||
}
|
||||
|
||||
if (m_interrupt_import_thread)
|
||||
return;
|
||||
|
||||
if (params.wait_until_elf_is_loaded && params.options.FunctionScanMode == DebugFunctionScanMode::SCAN_MEMORY)
|
||||
{
|
||||
// Wait for the entry point to start compiling on the CPU thread so
|
||||
// we know the functions we want to scan are loaded in memory.
|
||||
std::unique_lock lock(m_elf_loaded_in_memory_mutex);
|
||||
m_elf_loaded_in_memory_condition_variable.wait(lock,
|
||||
[this]() { return m_elf_loaded_in_memory; });
|
||||
|
||||
if (m_interrupt_import_thread)
|
||||
return;
|
||||
}
|
||||
|
||||
m_guardian.ReadWrite([&](ccc::SymbolDatabase& database) {
|
||||
ClearExistingSymbols(database, options);
|
||||
ClearExistingSymbols(database, params.options);
|
||||
|
||||
if (m_interrupt_import_thread)
|
||||
return;
|
||||
|
@ -229,7 +275,7 @@ void SymbolImporter::AnalyseElf(
|
|||
// The function scanner has to be run on the main database so that
|
||||
// functions created before the importer was run are still
|
||||
// considered. Otherwise, duplicate functions will be created.
|
||||
ScanForFunctions(database, worker_symbol_file, options);
|
||||
ScanForFunctions(database, symbol_file, params.options);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -239,9 +285,23 @@ void SymbolImporter::ShutdownWorkerThread()
|
|||
if (m_import_thread.joinable())
|
||||
{
|
||||
m_interrupt_import_thread = true;
|
||||
|
||||
// Make sure the import thread is woken up so we can shut it down.
|
||||
{
|
||||
std::lock_guard lock(m_elf_loaded_in_memory_mutex);
|
||||
m_elf_loaded_in_memory = true;
|
||||
}
|
||||
m_elf_loaded_in_memory_condition_variable.notify_one();
|
||||
|
||||
m_import_thread.join();
|
||||
|
||||
m_interrupt_import_thread = false;
|
||||
}
|
||||
|
||||
{
|
||||
std::lock_guard lock(m_elf_loaded_in_memory_mutex);
|
||||
m_elf_loaded_in_memory = false;
|
||||
}
|
||||
}
|
||||
|
||||
void SymbolImporter::ClearExistingSymbols(ccc::SymbolDatabase& database, const Pcsx2Config::DebugAnalysisOptions& options)
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
#include "Config.h"
|
||||
#include "SymbolGuardian.h"
|
||||
|
||||
#include <condition_variable>
|
||||
|
||||
class DebugInterface;
|
||||
|
||||
class SymbolImporter
|
||||
|
@ -17,6 +19,7 @@ public:
|
|||
// that are used to determine when symbol tables should be loaded, and
|
||||
// should be called from the CPU thread.
|
||||
void OnElfChanged(std::vector<u8> elf, const std::string& elf_file_name);
|
||||
void OnElfLoadedInMemory();
|
||||
void OnDebuggerOpened();
|
||||
void OnDebuggerClosed();
|
||||
|
||||
|
@ -30,7 +33,11 @@ public:
|
|||
|
||||
// Import symbols from the ELF file, nocash symbols, and scan for functions.
|
||||
// Should be called from the CPU thread.
|
||||
void AnalyseElf(std::vector<u8> elf, const std::string& elf_file_name, Pcsx2Config::DebugAnalysisOptions options);
|
||||
void AnalyseElf(
|
||||
std::vector<u8> elf,
|
||||
const std::string& elf_file_name,
|
||||
Pcsx2Config::DebugAnalysisOptions options,
|
||||
bool wait_until_elf_is_loaded);
|
||||
|
||||
// Interrupt the import thread. Should be called from the CPU thread.
|
||||
void ShutdownWorkerThread();
|
||||
|
@ -77,6 +84,10 @@ protected:
|
|||
std::thread m_import_thread;
|
||||
std::atomic_bool m_interrupt_import_thread = false;
|
||||
|
||||
std::mutex m_elf_loaded_in_memory_mutex;
|
||||
std::condition_variable m_elf_loaded_in_memory_condition_variable;
|
||||
bool m_elf_loaded_in_memory = false;
|
||||
|
||||
std::map<std::string, ccc::DataTypeHandle> m_builtin_types;
|
||||
};
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "Config.h"
|
||||
#include "Counters.h"
|
||||
#include "DebugTools/Breakpoints.h"
|
||||
#include "DebugTools/SymbolImporter.h"
|
||||
#include "Elfheader.h"
|
||||
#include "GS.h"
|
||||
#include "GS/GS.h"
|
||||
|
@ -80,6 +81,9 @@ static void PostLoadPrep()
|
|||
CBreakPoints::SetSkipFirst(BREAKPOINT_IOP, 0);
|
||||
|
||||
UpdateVSyncRate(true);
|
||||
|
||||
if (VMManager::Internal::HasBootedELF())
|
||||
R5900SymbolImporter.OnElfLoadedInMemory();
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
|
|
|
@ -2779,6 +2779,8 @@ void VMManager::Internal::EntryPointCompilingOnCPUThread()
|
|||
// Toss all the recs, we're going to be executing new code.
|
||||
mmap_ResetBlockTracking();
|
||||
ClearCPUExecutionCaches();
|
||||
|
||||
R5900SymbolImporter.OnElfLoadedInMemory();
|
||||
}
|
||||
|
||||
void VMManager::Internal::VSyncOnCPUThread()
|
||||
|
|
Loading…
Reference in New Issue