Kernel/IPC: Implement StaticBuffer translation for HLE services that use the HLERequestContext architecture.

The real kernel requires services to set up their static buffer targets ahead of time. This implementation does not require that and will simply create the storage for the buffers as they are processed in the incoming IPC request.

Static buffers are kept in an unordered_map keyed by their buffer id, and are written into the already-setup area of the request thread when responding an IPC request.

This fixes a regression (crash) introduced in #2992.

This PR introduces more warnings due to the [[deprecated]] attribute being added to void PushStaticBuffer(VAddr buffer_vaddr, size_t size, u8 buffer_id); and VAddr PopStaticBuffer(size_t* data_size);
This commit is contained in:
Subv 2017-11-05 12:50:22 -05:00
parent 4fc0448093
commit c9c1ba0952
10 changed files with 113 additions and 40 deletions

View file

@ -2,6 +2,7 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include <vector>
#include "common/common_types.h"
#include "common/logging/log.h"
#include "core/hle/ipc.h"
@ -19,17 +20,12 @@ namespace AC {
void Module::Interface::CreateDefaultConfig(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x1, 0, 0);
std::size_t desc_size;
VAddr ac_config_addr = rp.PeekStaticBuffer(0, &desc_size);
ASSERT_MSG(desc_size >= sizeof(Module::ACConfig),
"Output buffer size can't fit ACConfig structure");
Memory::WriteBlock(ac_config_addr, &ac->default_config, sizeof(ACConfig));
std::vector<u8> buffer(sizeof(ACConfig));
std::memcpy(buffer.data(), &ac->default_config, buffer.size());
IPC::RequestBuilder rb = rp.MakeBuilder(1, 2);
rb.Push(RESULT_SUCCESS);
rb.PushStaticBuffer(ac_config_addr, sizeof(ACConfig), 0);
rb.PushStaticBuffer(std::move(buffer), 0);
LOG_WARNING(Service_AC, "(STUBBED) called");
}
@ -106,7 +102,7 @@ void Module::Interface::GetWifiStatus(Kernel::HLERequestContext& ctx) {
void Module::Interface::GetInfraPriority(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x27, 0, 2);
VAddr ac_config = rp.PopStaticBuffer();
const std::vector<u8>& ac_config = rp.PopStaticBuffer();
IPC::RequestBuilder rb = rp.MakeBuilder(2, 0);
rb.Push(RESULT_SUCCESS);
@ -121,13 +117,13 @@ void Module::Interface::SetRequestEulaVersion(Kernel::HLERequestContext& ctx) {
u32 major = rp.Pop<u8>();
u32 minor = rp.Pop<u8>();
VAddr ac_config = rp.PopStaticBuffer();
const std::vector<u8>& ac_config = rp.PopStaticBuffer();
// TODO(Subv): Copy over the input ACConfig to the stored ACConfig.
IPC::RequestBuilder rb = rp.MakeBuilder(1, 2);
rb.Push(RESULT_SUCCESS);
rb.PushStaticBuffer(ac_config, sizeof(ACConfig), 0);
rb.PushStaticBuffer(std::move(ac_config), 0);
LOG_WARNING(Service_AC, "(STUBBED) called, major=%u, minor=%u", major, minor);
}

View file

@ -720,7 +720,7 @@ void AppletUtility(Service::Interface* self) {
u32 utility_command = rp.Pop<u32>();
u32 input_size = rp.Pop<u32>();
u32 output_size = rp.Pop<u32>();
VAddr input_addr = rp.PopStaticBuffer();
VAddr input_addr = rp.PopStaticBuffer(nullptr);
VAddr output_addr = rp.PeekStaticBuffer(0);
@ -823,7 +823,7 @@ void StartLibraryApplet(Service::Interface* self) {
size_t buffer_size = rp.Pop<u32>();
Kernel::Handle handle = rp.PopHandle();
VAddr buffer_addr = rp.PopStaticBuffer();
VAddr buffer_addr = rp.PopStaticBuffer(nullptr);
LOG_DEBUG(Service_APT, "called applet_id=%08X", static_cast<u32>(applet_id));

View file

@ -113,7 +113,7 @@ void UnscrambleLocalFriendCode(Service::Interface* self) {
IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x1C, 1, 2);
const u32 friend_code_count = rp.Pop<u32>();
size_t in_buffer_size;
const VAddr scrambled_friend_codes = rp.PopStaticBuffer(&in_buffer_size, false);
const VAddr scrambled_friend_codes = rp.PopStaticBuffer(&in_buffer_size);
ASSERT_MSG(in_buffer_size == (friend_code_count * scrambled_friend_code_size),
"Wrong input buffer size");

View file

@ -72,7 +72,7 @@ static void OpenFile(Service::Interface* self) {
FileSys::Mode mode;
mode.hex = rp.Pop<u32>();
u32 attributes = rp.Pop<u32>(); // TODO(Link Mauve): do something with those attributes.
VAddr filename_ptr = rp.PopStaticBuffer();
VAddr filename_ptr = rp.PopStaticBuffer(nullptr);
FileSys::Path file_path(filename_type, filename_size, filename_ptr);
LOG_DEBUG(Service_FS, "path=%s, mode=%u attrs=%u", file_path.DebugStr().c_str(), mode.hex,

View file

@ -433,7 +433,7 @@ static void FinalizeIrNop(Interface* self) {
static void SendIrNop(Interface* self) {
IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x0D, 1, 2);
const u32 size = rp.Pop<u32>();
const VAddr address = rp.PopStaticBuffer();
const VAddr address = rp.PopStaticBuffer(nullptr);
std::vector<u8> buffer(size);
Memory::ReadBlock(address, buffer.data(), size);

View file

@ -771,9 +771,9 @@ static void BeginHostingNetwork(Interface* self) {
const u32 passphrase_size = rp.Pop<u32>();
size_t desc_size;
const VAddr network_info_address = rp.PopStaticBuffer(&desc_size, false);
const VAddr network_info_address = rp.PopStaticBuffer(&desc_size);
ASSERT(desc_size == sizeof(NetworkInfo));
const VAddr passphrase_address = rp.PopStaticBuffer(&desc_size, false);
const VAddr passphrase_address = rp.PopStaticBuffer(&desc_size);
ASSERT(desc_size == passphrase_size);
// TODO(Subv): Store the passphrase and verify it when attempting a connection.
@ -907,7 +907,7 @@ static void SendTo(Interface* self) {
u32 flags = rp.Pop<u32>();
size_t desc_size;
const VAddr input_address = rp.PopStaticBuffer(&desc_size, false);
const VAddr input_address = rp.PopStaticBuffer(&desc_size);
ASSERT(desc_size >= data_size);
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
@ -1093,7 +1093,7 @@ static void SetApplicationData(Interface* self) {
u32 size = rp.Pop<u32>();
size_t desc_size;
const VAddr address = rp.PopStaticBuffer(&desc_size, false);
const VAddr address = rp.PopStaticBuffer(&desc_size);
ASSERT(desc_size == size);
LOG_DEBUG(Service_NWM, "called");