Merge pull request #8668 from sepalani/rso-autodetect
RSO: Auto-detect RSO location in RAM
This commit is contained in:
commit
7390767008
|
@ -68,8 +68,8 @@ Accessors::iterator Accessors::end() const
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
std::optional<u32> Accessors::Search(u32 haystack_start, u8* needle_start, u32 needle_size,
|
||||
bool forwards) const
|
||||
std::optional<u32> Accessors::Search(u32 haystack_start, const u8* needle_start,
|
||||
std::size_t needle_size, bool forwards) const
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
@ -91,7 +91,7 @@ struct EffectiveAddressSpaceAccessors : Accessors
|
|||
void WriteU64(u32 address, u64 value) override { PowerPC::HostWrite_U64(value, address); }
|
||||
float ReadF32(u32 address) const override { return PowerPC::HostRead_F32(address); };
|
||||
|
||||
bool Matches(u32 haystack_start, u8* needle_start, u32 needle_size) const
|
||||
bool Matches(u32 haystack_start, const u8* needle_start, std::size_t needle_size) const
|
||||
{
|
||||
u32 page_base = haystack_start & 0xfffff000;
|
||||
u32 offset = haystack_start & 0x0000fff;
|
||||
|
@ -121,7 +121,7 @@ struct EffectiveAddressSpaceAccessors : Accessors
|
|||
return false;
|
||||
}
|
||||
|
||||
u32 chunk_size = std::min(0x1000 - offset, needle_size);
|
||||
std::size_t chunk_size = std::min<std::size_t>(0x1000 - offset, needle_size);
|
||||
if (memcmp(needle_start, page_ptr + offset, chunk_size) != 0)
|
||||
{
|
||||
return false;
|
||||
|
@ -134,7 +134,7 @@ struct EffectiveAddressSpaceAccessors : Accessors
|
|||
return (needle_size == 0);
|
||||
}
|
||||
|
||||
std::optional<u32> Search(u32 haystack_start, u8* needle_start, u32 needle_size,
|
||||
std::optional<u32> Search(u32 haystack_start, const u8* needle_start, std::size_t needle_size,
|
||||
bool forward) const override
|
||||
{
|
||||
u32 haystack_address = haystack_start;
|
||||
|
@ -190,7 +190,7 @@ struct AuxiliaryAddressSpaceAccessors : Accessors
|
|||
|
||||
iterator end() const override { return DSP::GetARAMPtr() + GetSize(); }
|
||||
|
||||
std::optional<u32> Search(u32 haystack_offset, u8* needle_start, u32 needle_size,
|
||||
std::optional<u32> Search(u32 haystack_offset, const u8* needle_start, std::size_t needle_size,
|
||||
bool forward) const override
|
||||
{
|
||||
if (!IsValidAddress(haystack_offset))
|
||||
|
@ -264,7 +264,7 @@ struct CompositeAddressSpaceAccessors : Accessors
|
|||
return it->accessors->WriteU8(address, value);
|
||||
}
|
||||
|
||||
std::optional<u32> Search(u32 haystack_offset, u8* needle_start, u32 needle_size,
|
||||
std::optional<u32> Search(u32 haystack_offset, const u8* needle_start, std::size_t needle_size,
|
||||
bool forward) const override
|
||||
{
|
||||
for (const AccessorMapping& mapping : m_accessor_mappings)
|
||||
|
@ -320,10 +320,11 @@ struct SmallBlockAccessors : Accessors
|
|||
return (*alloc_base == nullptr) ? nullptr : (*alloc_base + size);
|
||||
}
|
||||
|
||||
std::optional<u32> Search(u32 haystack_offset, u8* needle_start, u32 needle_size,
|
||||
std::optional<u32> Search(u32 haystack_offset, const u8* needle_start, std::size_t needle_size,
|
||||
bool forward) const override
|
||||
{
|
||||
if (!IsValidAddress(haystack_offset) || !IsValidAddress(haystack_offset + needle_size - 1))
|
||||
if (!IsValidAddress(haystack_offset) ||
|
||||
!IsValidAddress(haystack_offset + static_cast<u32>(needle_size) - 1))
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
|
|
@ -40,8 +40,8 @@ struct Accessors
|
|||
virtual iterator begin() const;
|
||||
virtual iterator end() const;
|
||||
|
||||
virtual std::optional<u32> Search(u32 haystack_offset, u8* needle_start, u32 needle_size,
|
||||
bool forward) const;
|
||||
virtual std::optional<u32> Search(u32 haystack_offset, const u8* needle_start,
|
||||
std::size_t needle_size, bool forward) const;
|
||||
virtual ~Accessors();
|
||||
};
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "Core/Core.h"
|
||||
#include "Core/Debugger/RSO.h"
|
||||
#include "Core/HLE/HLE.h"
|
||||
#include "Core/HW/AddressSpace.h"
|
||||
#include "Core/HW/WiiSave.h"
|
||||
#include "Core/HW/Wiimote.h"
|
||||
#include "Core/IOS/ES/ES.h"
|
||||
|
@ -1205,6 +1206,12 @@ void MenuBar::GenerateSymbolsFromSignatureDB()
|
|||
|
||||
void MenuBar::GenerateSymbolsFromRSO()
|
||||
{
|
||||
// i18n: RSO refers to a proprietary format for shared objects (like DLL files).
|
||||
const int ret =
|
||||
ModalMessageBox::question(this, tr("RSO auto-detection"), tr("Auto-detect RSO modules?"));
|
||||
if (ret == QMessageBox::Yes)
|
||||
return GenerateSymbolsFromRSOAuto();
|
||||
|
||||
QString text = QInputDialog::getText(this, tr("Input"), tr("Enter the RSO module address:"));
|
||||
bool good;
|
||||
uint address = text.toUInt(&good, 16);
|
||||
|
@ -1227,6 +1234,79 @@ void MenuBar::GenerateSymbolsFromRSO()
|
|||
}
|
||||
}
|
||||
|
||||
void MenuBar::GenerateSymbolsFromRSOAuto()
|
||||
{
|
||||
constexpr std::array<std::string_view, 2> search_for = {".elf", ".plf"};
|
||||
const AddressSpace::Accessors* accessors =
|
||||
AddressSpace::GetAccessors(AddressSpace::Type::Effective);
|
||||
std::vector<std::pair<u32, std::string>> matches;
|
||||
|
||||
// Find filepath to elf/plf commonly used by RSO modules
|
||||
for (const auto& str : search_for)
|
||||
{
|
||||
u32 next = 0;
|
||||
while (true)
|
||||
{
|
||||
auto found_addr =
|
||||
accessors->Search(next, reinterpret_cast<const u8*>(str.data()), str.size() + 1, true);
|
||||
|
||||
if (!found_addr.has_value())
|
||||
break;
|
||||
next = *found_addr + 1;
|
||||
|
||||
// Get the beginning of the string
|
||||
found_addr = accessors->Search(*found_addr, reinterpret_cast<const u8*>(""), 1, false);
|
||||
if (!found_addr.has_value())
|
||||
continue;
|
||||
|
||||
// Get the string reference
|
||||
const u32 ref_addr = *found_addr + 1;
|
||||
const std::array<u8, 4> ref = {static_cast<u8>(ref_addr >> 24),
|
||||
static_cast<u8>(ref_addr >> 16),
|
||||
static_cast<u8>(ref_addr >> 8), static_cast<u8>(ref_addr)};
|
||||
found_addr = accessors->Search(ref_addr, ref.data(), ref.size(), false);
|
||||
if (!found_addr.has_value() || *found_addr < 16)
|
||||
continue;
|
||||
|
||||
// Go to the beginning of the RSO header
|
||||
matches.emplace_back(*found_addr - 16, PowerPC::HostGetString(ref_addr, 128));
|
||||
}
|
||||
}
|
||||
|
||||
QStringList items;
|
||||
for (const auto& match : matches)
|
||||
{
|
||||
const QString item = QLatin1String("%1 %2");
|
||||
|
||||
items << item.arg(QString::number(match.first, 16), QString::fromStdString(match.second));
|
||||
}
|
||||
|
||||
if (items.empty())
|
||||
{
|
||||
ModalMessageBox::warning(this, tr("Error"), tr("Unable to auto-detect RSO module"));
|
||||
return;
|
||||
}
|
||||
|
||||
bool ok;
|
||||
const QString item = QInputDialog::getItem(
|
||||
this, tr("Input"), tr("Select the RSO module address:"), items, 0, false, &ok);
|
||||
|
||||
if (!ok)
|
||||
return;
|
||||
|
||||
RSOChainView rso_chain;
|
||||
const u32 address = item.mid(0, item.indexOf(QLatin1Char(' '))).toUInt(nullptr, 16);
|
||||
if (rso_chain.Load(address))
|
||||
{
|
||||
rso_chain.Apply(&g_symbolDB);
|
||||
emit NotifySymbolsUpdated();
|
||||
}
|
||||
else
|
||||
{
|
||||
ModalMessageBox::warning(this, tr("Error"), tr("Failed to load RSO module at %1").arg(address));
|
||||
}
|
||||
}
|
||||
|
||||
void MenuBar::LoadSymbolMap()
|
||||
{
|
||||
std::string existing_map_file, writable_map_file;
|
||||
|
|
|
@ -153,6 +153,7 @@ private:
|
|||
void GenerateSymbolsFromAddress();
|
||||
void GenerateSymbolsFromSignatureDB();
|
||||
void GenerateSymbolsFromRSO();
|
||||
void GenerateSymbolsFromRSOAuto();
|
||||
void LoadSymbolMap();
|
||||
void LoadOtherSymbolMap();
|
||||
void LoadBadSymbolMap();
|
||||
|
|
Loading…
Reference in New Issue