Add reverse name lookup services for better debugging and fix bugs

This commit is contained in:
◱ PixelyIon 2019-09-26 22:34:15 +05:30
parent 45f4255ff6
commit a5d63c9bbb
7 changed files with 53 additions and 16 deletions

View File

@ -1,7 +1,7 @@
#include "appletOE.h"
namespace skyline::kernel::service::am {
appletOE::appletOE(const DeviceState &state, ServiceManager& manager) : BaseService(state, manager, false, Service::apm, {
appletOE::appletOE(const DeviceState &state, ServiceManager& manager) : BaseService(state, manager, false, Service::am_appletOE, {
{0x0, SFunc(appletOE::OpenApplicationProxy)}
}) {}
@ -12,6 +12,7 @@ namespace skyline::kernel::service::am {
IApplicationProxy::IApplicationProxy(const DeviceState &state, ServiceManager& manager) : BaseService(state, manager, false, Service::am_IApplicationProxy, {
{0x0, SFunc(IApplicationProxy::GetCommonStateGetter)},
{0x1, SFunc(IApplicationProxy::GetSelfController)},
{0x2, SFunc(IApplicationProxy::GetWindowController)},
{0xB, SFunc(IApplicationProxy::GetLibraryAppletCreator)},
{0x14, SFunc(IApplicationProxy::GetApplicationFunctions)}
}) {}
@ -24,6 +25,10 @@ namespace skyline::kernel::service::am {
manager.NewService(Service::am_ISelfController, session, response);
}
void IApplicationProxy::GetWindowController(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
manager.NewService(Service::am_IWindowController, session, response);
}
void IApplicationProxy::GetLibraryAppletCreator(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
manager.NewService(Service::am_ILibraryAppletCreator, session, response);
}
@ -32,15 +37,18 @@ namespace skyline::kernel::service::am {
manager.NewService(Service::am_IApplicationFunctions, session, response);
}
ICommonStateGetter::ICommonStateGetter(const DeviceState &state, ServiceManager& manager) : BaseService(state, manager, false, Service::am_IApplicationProxy, {
ICommonStateGetter::ICommonStateGetter(const DeviceState &state, ServiceManager &manager) : BaseService(state, manager, false, Service::am_ICommonStateGetter, {
}) {}
ISelfController::ISelfController(const DeviceState &state, ServiceManager& manager) : BaseService(state, manager, false, Service::am_IApplicationProxy, {
ISelfController::ISelfController(const DeviceState &state, ServiceManager &manager) : BaseService(state, manager, false, Service::am_ISelfController, {
}) {}
ILibraryAppletCreator::ILibraryAppletCreator(const DeviceState &state, ServiceManager& manager) : BaseService(state, manager, false, Service::am_IApplicationProxy, {
IWindowController::IWindowController(const DeviceState &state, ServiceManager &manager) : BaseService(state, manager, false, Service::am_IWindowController, {
}) {}
IApplicationFunctions::IApplicationFunctions(const DeviceState &state, ServiceManager& manager) : BaseService(state, manager, false, Service::am_IApplicationProxy, {
ILibraryAppletCreator::ILibraryAppletCreator(const DeviceState &state, ServiceManager &manager) : BaseService(state, manager, false, Service::am_ILibraryAppletCreator, {
}) {}
IApplicationFunctions::IApplicationFunctions(const DeviceState &state, ServiceManager &manager) : BaseService(state, manager, false, Service::am_IApplicationFunctions, {
}) {}
}

View File

@ -34,6 +34,11 @@ namespace skyline::kernel::service::am {
*/
void GetSelfController(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This returns #IWindowController (https://switchbrew.org/wiki/Applet_Manager_services#IWindowController)
*/
void GetWindowController(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This returns #ILibraryAppletCreator (https://switchbrew.org/wiki/Applet_Manager_services#ILibraryAppletCreator)
*/
@ -55,6 +60,11 @@ namespace skyline::kernel::service::am {
ISelfController(const DeviceState &state, ServiceManager &manager);
};
class IWindowController : public BaseService {
public:
IWindowController(const DeviceState &state, ServiceManager &manager);
};
class ILibraryAppletCreator : public BaseService {
public:
ILibraryAppletCreator(const DeviceState &state, ServiceManager &manager);

View File

@ -9,7 +9,7 @@ namespace skyline::kernel::service::apm {
manager.NewService(Service::apm_ISession, session, response);
}
ISession::ISession(const DeviceState &state, ServiceManager& manager) : BaseService(state, manager, false, Service::apm, {
ISession::ISession(const DeviceState &state, ServiceManager& manager) : BaseService(state, manager, false, Service::apm_ISession, {
{0x0, SFunc(ISession::SetPerformanceConfiguration)},
{0x1, SFunc(ISession::GetPerformanceConfiguration)}
}) {}

View File

@ -14,7 +14,7 @@ namespace skyline::kernel::service {
* @brief This contains an enum for every service that's present
*/
enum class Service {
sm, set_sys, apm, apm_ISession, am_appletOE, am_IApplicationProxy, am_ICommonStateGetter, am_IApplicationFunctions, am_ISelfController, am_ILibraryAppletCreator
sm, set_sys, apm, apm_ISession, am_appletOE, am_IApplicationProxy, am_ICommonStateGetter, am_IApplicationFunctions, am_ISelfController, am_IWindowController, am_ILibraryAppletCreator
};
/**
@ -24,7 +24,14 @@ namespace skyline::kernel::service {
{"sm:", Service::sm},
{"set:sys", Service::set_sys},
{"apm", Service::apm},
{"apm:ISession", Service::apm_ISession},
{"appletOE", Service::am_appletOE},
{"am:IApplicationProxy", Service::am_IApplicationProxy},
{"am:ICommonStateGetter", Service::am_ICommonStateGetter},
{"am:ISelfController", Service::am_ISelfController},
{"am:IWindowController", Service::am_IWindowController},
{"am:ILibraryAppletCreator", Service::am_ILibraryAppletCreator},
{"am:IApplicationFunctions", Service::am_IApplicationFunctions},
};
class ServiceManager;
@ -41,14 +48,25 @@ namespace skyline::kernel::service {
public:
Service serviceType; //!< Which service this is
uint numSessions{}; //<! The amount of active sessions
const bool asLoop; //<! If the service has a loop or not
const bool hasLoop; //<! If the service has a loop or not
/**
* @param state The state of the device
* @param hasLoop If the service has a loop or not
* @param serviceType The type of the service
* @param serviceName The name of the service
* @param vTable The functions of the service
*/
BaseService(const DeviceState &state, ServiceManager& manager, bool hasLoop, Service serviceType, const std::unordered_map<u32, std::function<void(type::KSession &, ipc::IpcRequest &, ipc::IpcResponse &)>> &vTable) : state(state), manager(manager), hasLoop(hasLoop), serviceType(serviceType), vTable(vTable) {}
std::string getName() {
std::string serviceName = "";
for (const auto& [name, type] : ServiceString)
if(type == serviceType)
serviceName = name;
return serviceName;
}
/**
* @brief This handles all IPC commands with type request to a service
* @param request The corresponding IpcRequest object
@ -56,12 +74,9 @@ namespace skyline::kernel::service {
*/
void HandleRequest(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
try {
for(auto& i : vTable)
state.logger->Write(Logger::Info, "Service has cmdid [0x{:X}]", i.first);
vTable.at(request.payload->value)(session, request, response);
} catch (std::out_of_range&) {
state.logger->Write(Logger::Warn, "Cannot find function in service with type {0}: 0x{1:X} ({1})", serviceType, u32(request.payload->value));
state.logger->Write(Logger::Warn, "Cannot find function in service '{0}' (Type: {1}): 0x{2:X} ({2})", getName(), serviceType, u32(request.payload->value));
}
};

View File

@ -33,6 +33,9 @@ namespace skyline::kernel::service {
case Service::am_ICommonStateGetter:
serviceMap[serviceType] = std::make_shared<am::ICommonStateGetter>(state, *this);
break;
case Service::am_IWindowController:
serviceMap[serviceType] = std::make_shared<am::IWindowController>(state, *this);
break;
case Service::am_ISelfController:
serviceMap[serviceType] = std::make_shared<am::ISelfController>(state, *this);
break;
@ -55,11 +58,13 @@ namespace skyline::kernel::service {
}
void ServiceManager::NewService(const Service serviceType, type::KSession &session, ipc::IpcResponse &response) {
auto serviceObject = GetService(serviceType);
if (response.isDomain) {
session.domainTable[++session.handleIndex] = GetService(serviceType);
session.domainTable[++session.handleIndex] = serviceObject;
response.domainObjects.push_back(session.handleIndex);
} else
response.moveHandles.push_back(state.thisProcess->NewHandle<type::KSession>(GetService(serviceType), serviceType)->handle);
response.moveHandles.push_back(state.thisProcess->NewHandle<type::KSession>(serviceObject, serviceType)->handle);
state.logger->Write(Logger::Debug, "Service has been registered: \"{}\"", serviceObject->getName());
}
void ServiceManager::CloseSession(const handle_t handle) {

View File

@ -5,7 +5,7 @@ namespace skyline::kernel::service::set {
sys::sys(const DeviceState &state, ServiceManager& manager) : BaseService(state, manager, false, Service::set_sys, {{0x3, SFunc(sys::GetFirmwareVersion)}}) {}
void sys::GetFirmwareVersion(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
static SysVerTitle title{.minor=9, .major=0, .micro=0, .rev_major=4, .platform="NX", .ver_hash="4de65c071fd0869695b7629f75eb97b2551dbf2f", .disp_ver="9.0.0", .disp_title="NintendoSDK Firmware for NX 9.0.0-4.0"};
SysVerTitle title{.minor=9, .major=0, .micro=0, .rev_major=4, .platform="NX", .ver_hash="4de65c071fd0869695b7629f75eb97b2551dbf2f", .disp_ver="9.0.0", .disp_title="NintendoSDK Firmware for NX 9.0.0-4.0"};
state.thisProcess->WriteMemory(title, request.vecBufC[0]->address);
}
}

View File

@ -15,7 +15,6 @@ namespace skyline::kernel::service::sm {
else {
try {
manager.NewService(ServiceString.at(serviceName), session, response);
state.logger->Write(Logger::Debug, "Service has been registered: \"{}\"", serviceName);
} catch (std::out_of_range &) {
response.errorCode = constant::status::ServiceNotReg;
state.logger->Write(Logger::Error, "Service has not been implemented: \"{}\"", serviceName);