LDR_RO: pass memory in CROHelper

This commit is contained in:
Weiyi Wang 2018-11-21 14:20:55 -05:00
parent 76e0a4ece7
commit 1ec9ed6827
4 changed files with 51 additions and 45 deletions

View File

@ -548,7 +548,7 @@ ResultCode CROHelper::ApplyStaticAnonymousSymbolToCRS(VAddr crs_address) {
static_relocation_table_offset + static_relocation_table_offset +
GetField(StaticRelocationNum) * sizeof(StaticRelocationEntry); GetField(StaticRelocationNum) * sizeof(StaticRelocationEntry);
CROHelper crs(crs_address, process); CROHelper crs(crs_address, process, memory);
u32 offset_export_num = GetField(StaticAnonymousSymbolNum); u32 offset_export_num = GetField(StaticAnonymousSymbolNum);
LOG_INFO(Service_LDR, "CRO \"{}\" exports {} static anonymous symbols", ModuleName(), LOG_INFO(Service_LDR, "CRO \"{}\" exports {} static anonymous symbols", ModuleName(),
offset_export_num); offset_export_num);
@ -758,8 +758,8 @@ ResultCode CROHelper::ApplyImportNamedSymbol(VAddr crs_address) {
sizeof(ExternalRelocationEntry)); sizeof(ExternalRelocationEntry));
if (!relocation_entry.is_batch_resolved) { if (!relocation_entry.is_batch_resolved) {
ResultCode result = ResultCode result = ForEachAutoLinkCRO(
ForEachAutoLinkCRO(process, crs_address, [&](CROHelper source) -> ResultVal<bool> { process, memory, crs_address, [&](CROHelper source) -> ResultVal<bool> {
std::string symbol_name = std::string symbol_name =
Memory::ReadCString(entry.name_offset, import_strings_size); Memory::ReadCString(entry.name_offset, import_strings_size);
u32 symbol_address = source.FindExportNamedSymbol(symbol_name); u32 symbol_address = source.FindExportNamedSymbol(symbol_name);
@ -860,8 +860,8 @@ ResultCode CROHelper::ApplyModuleImport(VAddr crs_address) {
GetEntry(i, entry); GetEntry(i, entry);
std::string want_cro_name = Memory::ReadCString(entry.name_offset, import_strings_size); std::string want_cro_name = Memory::ReadCString(entry.name_offset, import_strings_size);
ResultCode result = ResultCode result = ForEachAutoLinkCRO(
ForEachAutoLinkCRO(process, crs_address, [&](CROHelper source) -> ResultVal<bool> { process, memory, crs_address, [&](CROHelper source) -> ResultVal<bool> {
if (want_cro_name == source.ModuleName()) { if (want_cro_name == source.ModuleName()) {
LOG_INFO(Service_LDR, "CRO \"{}\" imports {} indexed symbols from \"{}\"", LOG_INFO(Service_LDR, "CRO \"{}\" imports {} indexed symbols from \"{}\"",
ModuleName(), entry.import_indexed_symbol_num, source.ModuleName()); ModuleName(), entry.import_indexed_symbol_num, source.ModuleName());
@ -1070,8 +1070,8 @@ ResultCode CROHelper::ApplyExitRelocations(VAddr crs_address) {
sizeof(ExternalRelocationEntry)); sizeof(ExternalRelocationEntry));
if (Memory::ReadCString(entry.name_offset, import_strings_size) == "__aeabi_atexit") { if (Memory::ReadCString(entry.name_offset, import_strings_size) == "__aeabi_atexit") {
ResultCode result = ResultCode result = ForEachAutoLinkCRO(
ForEachAutoLinkCRO(process, crs_address, [&](CROHelper source) -> ResultVal<bool> { process, memory, crs_address, [&](CROHelper source) -> ResultVal<bool> {
u32 symbol_address = source.FindExportNamedSymbol("nnroAeabiAtexit_"); u32 symbol_address = source.FindExportNamedSymbol("nnroAeabiAtexit_");
if (symbol_address != 0) { if (symbol_address != 0) {
@ -1299,17 +1299,18 @@ ResultCode CROHelper::Link(VAddr crs_address, bool link_on_load_bug_fix) {
} }
// Exports symbols to other modules // Exports symbols to other modules
result = ForEachAutoLinkCRO(process, crs_address, [this](CROHelper target) -> ResultVal<bool> { result = ForEachAutoLinkCRO(process, memory, crs_address,
ResultCode result = ApplyExportNamedSymbol(target); [this](CROHelper target) -> ResultVal<bool> {
if (result.IsError()) ResultCode result = ApplyExportNamedSymbol(target);
return result; if (result.IsError())
return result;
result = ApplyModuleExport(target); result = ApplyModuleExport(target);
if (result.IsError()) if (result.IsError())
return result; return result;
return MakeResult<bool>(true); return MakeResult<bool>(true);
}); });
if (result.IsError()) { if (result.IsError()) {
LOG_ERROR(Service_LDR, "Error applying export {:08X}", result.raw); LOG_ERROR(Service_LDR, "Error applying export {:08X}", result.raw);
return result; return result;
@ -1343,17 +1344,18 @@ ResultCode CROHelper::Unlink(VAddr crs_address) {
// Resets all symbols in other modules imported from this module // Resets all symbols in other modules imported from this module
// Note: the RO service seems only searching in auto-link modules // Note: the RO service seems only searching in auto-link modules
result = ForEachAutoLinkCRO(process, crs_address, [this](CROHelper target) -> ResultVal<bool> { result = ForEachAutoLinkCRO(process, memory, crs_address,
ResultCode result = ResetExportNamedSymbol(target); [this](CROHelper target) -> ResultVal<bool> {
if (result.IsError()) ResultCode result = ResetExportNamedSymbol(target);
return result; if (result.IsError())
return result;
result = ResetModuleExport(target); result = ResetModuleExport(target);
if (result.IsError()) if (result.IsError())
return result; return result;
return MakeResult<bool>(true); return MakeResult<bool>(true);
}); });
if (result.IsError()) { if (result.IsError()) {
LOG_ERROR(Service_LDR, "Error resetting export {:08X}", result.raw); LOG_ERROR(Service_LDR, "Error resetting export {:08X}", result.raw);
return result; return result;
@ -1383,13 +1385,13 @@ void CROHelper::InitCRS() {
} }
void CROHelper::Register(VAddr crs_address, bool auto_link) { void CROHelper::Register(VAddr crs_address, bool auto_link) {
CROHelper crs(crs_address, process); CROHelper crs(crs_address, process, memory);
CROHelper head(auto_link ? crs.NextModule() : crs.PreviousModule(), process); CROHelper head(auto_link ? crs.NextModule() : crs.PreviousModule(), process, memory);
if (head.module_address) { if (head.module_address) {
// there are already CROs registered // there are already CROs registered
// register as the new tail // register as the new tail
CROHelper tail(head.PreviousModule(), process); CROHelper tail(head.PreviousModule(), process, memory);
// link with the old tail // link with the old tail
ASSERT(tail.NextModule() == 0); ASSERT(tail.NextModule() == 0);
@ -1415,9 +1417,10 @@ void CROHelper::Register(VAddr crs_address, bool auto_link) {
} }
void CROHelper::Unregister(VAddr crs_address) { void CROHelper::Unregister(VAddr crs_address) {
CROHelper crs(crs_address, process); CROHelper crs(crs_address, process, memory);
CROHelper next_head(crs.NextModule(), process), previous_head(crs.PreviousModule(), process); CROHelper next_head(crs.NextModule(), process, memory),
CROHelper next(NextModule(), process), previous(PreviousModule(), process); previous_head(crs.PreviousModule(), process, memory);
CROHelper next(NextModule(), process, memory), previous(PreviousModule(), process, memory);
if (module_address == next_head.module_address || if (module_address == next_head.module_address ||
module_address == previous_head.module_address) { module_address == previous_head.module_address) {

View File

@ -40,8 +40,8 @@ static constexpr u32 CRO_HASH_SIZE = 0x80;
class CROHelper final { class CROHelper final {
public: public:
// TODO (wwylele): pass in the process handle for memory access // TODO (wwylele): pass in the process handle for memory access
explicit CROHelper(VAddr cro_address, Kernel::Process& process) explicit CROHelper(VAddr cro_address, Kernel::Process& process, Memory::MemorySystem& memory)
: module_address(cro_address), process(process) {} : module_address(cro_address), process(process), memory(memory) {}
std::string ModuleName() const { std::string ModuleName() const {
return Memory::ReadCString(GetField(ModuleNameOffset), GetField(ModuleNameSize)); return Memory::ReadCString(GetField(ModuleNameOffset), GetField(ModuleNameSize));
@ -150,6 +150,7 @@ public:
private: private:
const VAddr module_address; ///< the virtual address of this module const VAddr module_address; ///< the virtual address of this module
Kernel::Process& process; ///< the owner process of this module Kernel::Process& process; ///< the owner process of this module
Memory::MemorySystem& memory;
/** /**
* Each item in this enum represents a u32 field in the header begin from address+0x80, * Each item in this enum represents a u32 field in the header begin from address+0x80,
@ -478,11 +479,11 @@ private:
* otherwise error code of the last iteration. * otherwise error code of the last iteration.
*/ */
template <typename FunctionObject> template <typename FunctionObject>
static ResultCode ForEachAutoLinkCRO(Kernel::Process& process, VAddr crs_address, static ResultCode ForEachAutoLinkCRO(Kernel::Process& process, Memory::MemorySystem& memory,
FunctionObject func) { VAddr crs_address, FunctionObject func) {
VAddr current = crs_address; VAddr current = crs_address;
while (current != 0) { while (current != 0) {
CROHelper cro(current, process); CROHelper cro(current, process, memory);
CASCADE_RESULT(bool next, func(cro)); CASCADE_RESULT(bool next, func(cro));
if (!next) if (!next)
break; break;

View File

@ -115,7 +115,7 @@ void RO::Initialize(Kernel::HLERequestContext& ctx) {
return; return;
} }
CROHelper crs(crs_address, *process); CROHelper crs(crs_address, *process, system.Memory());
crs.InitCRS(); crs.InitCRS();
result = crs.Rebase(0, crs_size, 0, 0, 0, 0, true); result = crs.Rebase(0, crs_size, 0, 0, 0, 0, true);
@ -249,7 +249,7 @@ void RO::LoadCRO(Kernel::HLERequestContext& ctx, bool link_on_load_bug_fix) {
return; return;
} }
CROHelper cro(cro_address, *process); CROHelper cro(cro_address, *process, system.Memory());
result = cro.VerifyHash(cro_size, crr_address); result = cro.VerifyHash(cro_size, crr_address);
if (result.IsError()) { if (result.IsError()) {
@ -331,7 +331,7 @@ void RO::UnloadCRO(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_LDR, "called, cro_address=0x{:08X}, zero={}, cro_buffer_ptr=0x{:08X}", LOG_DEBUG(Service_LDR, "called, cro_address=0x{:08X}, zero={}, cro_buffer_ptr=0x{:08X}",
cro_address, zero, cro_buffer_ptr); cro_address, zero, cro_buffer_ptr);
CROHelper cro(cro_address, *process); CROHelper cro(cro_address, *process, system.Memory());
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
@ -398,7 +398,7 @@ void RO::LinkCRO(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_LDR, "called, cro_address=0x{:08X}", cro_address); LOG_DEBUG(Service_LDR, "called, cro_address=0x{:08X}", cro_address);
CROHelper cro(cro_address, *process); CROHelper cro(cro_address, *process, system.Memory());
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
@ -438,7 +438,7 @@ void RO::UnlinkCRO(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_LDR, "called, cro_address=0x{:08X}", cro_address); LOG_DEBUG(Service_LDR, "called, cro_address=0x{:08X}", cro_address);
CROHelper cro(cro_address, *process); CROHelper cro(cro_address, *process, system.Memory());
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
@ -487,7 +487,7 @@ void RO::Shutdown(Kernel::HLERequestContext& ctx) {
return; return;
} }
CROHelper crs(slot->loaded_crs, *process); CROHelper crs(slot->loaded_crs, *process, system.Memory());
crs.Unrebase(true); crs.Unrebase(true);
ResultCode result = RESULT_SUCCESS; ResultCode result = RESULT_SUCCESS;
@ -502,7 +502,7 @@ void RO::Shutdown(Kernel::HLERequestContext& ctx) {
rb.Push(result); rb.Push(result);
} }
RO::RO() : ServiceFramework("ldr:ro", 2) { RO::RO(Core::System& system) : ServiceFramework("ldr:ro", 2), system(system) {
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{0x000100C2, &RO::Initialize, "Initialize"}, {0x000100C2, &RO::Initialize, "Initialize"},
{0x00020082, &RO::LoadCRR, "LoadCRR"}, {0x00020082, &RO::LoadCRR, "LoadCRR"},
@ -519,7 +519,7 @@ RO::RO() : ServiceFramework("ldr:ro", 2) {
void InstallInterfaces(Core::System& system) { void InstallInterfaces(Core::System& system) {
auto& service_manager = system.ServiceManager(); auto& service_manager = system.ServiceManager();
std::make_shared<RO>()->InstallAsService(service_manager); std::make_shared<RO>(system)->InstallAsService(service_manager);
} }
} // namespace Service::LDR } // namespace Service::LDR

View File

@ -18,7 +18,7 @@ struct ClientSlot : public Kernel::SessionRequestHandler::SessionDataBase {
class RO final : public ServiceFramework<RO, ClientSlot> { class RO final : public ServiceFramework<RO, ClientSlot> {
public: public:
RO(); explicit RO(Core::System& system);
private: private:
/** /**
@ -149,6 +149,8 @@ private:
* 1 : Result of function, 0 on success, otherwise error code * 1 : Result of function, 0 on success, otherwise error code
*/ */
void Shutdown(Kernel::HLERequestContext& self); void Shutdown(Kernel::HLERequestContext& self);
Core::System& system;
}; };
void InstallInterfaces(Core::System& system); void InstallInterfaces(Core::System& system);