citra-emu
/
citra
Archived
1
0
Fork 0

Merge pull request #2991 from Subv/getpointer

Remove more usages of GetPointer.
This commit is contained in:
Sebastian Valle 2017-10-08 10:11:12 -05:00 committed by GitHub
commit 20e19a340c
3 changed files with 61 additions and 63 deletions

View File

@ -644,7 +644,7 @@ static void ReadMemory() {
auto start_offset = command_buffer + 1; auto start_offset = command_buffer + 1;
auto addr_pos = std::find(start_offset, command_buffer + command_length, ','); auto addr_pos = std::find(start_offset, command_buffer + command_length, ',');
PAddr addr = HexToInt(start_offset, static_cast<u32>(addr_pos - start_offset)); VAddr addr = HexToInt(start_offset, static_cast<u32>(addr_pos - start_offset));
start_offset = addr_pos + 1; start_offset = addr_pos + 1;
u32 len = u32 len =
@ -656,12 +656,14 @@ static void ReadMemory() {
SendReply("E01"); SendReply("E01");
} }
const u8* data = Memory::GetPointer(addr); if (!Memory::IsValidVirtualAddress(addr)) {
if (!data) {
return SendReply("E00"); return SendReply("E00");
} }
MemToGdbHex(reply, data, len); std::vector<u8> data(len);
Memory::ReadBlock(addr, data.data(), len);
MemToGdbHex(reply, data.data(), len);
reply[len * 2] = '\0'; reply[len * 2] = '\0';
SendReply(reinterpret_cast<char*>(reply)); SendReply(reinterpret_cast<char*>(reply));
} }
@ -670,18 +672,20 @@ static void ReadMemory() {
static void WriteMemory() { static void WriteMemory() {
auto start_offset = command_buffer + 1; auto start_offset = command_buffer + 1;
auto addr_pos = std::find(start_offset, command_buffer + command_length, ','); auto addr_pos = std::find(start_offset, command_buffer + command_length, ',');
PAddr addr = HexToInt(start_offset, static_cast<u32>(addr_pos - start_offset)); VAddr addr = HexToInt(start_offset, static_cast<u32>(addr_pos - start_offset));
start_offset = addr_pos + 1; start_offset = addr_pos + 1;
auto len_pos = std::find(start_offset, command_buffer + command_length, ':'); auto len_pos = std::find(start_offset, command_buffer + command_length, ':');
u32 len = HexToInt(start_offset, static_cast<u32>(len_pos - start_offset)); u32 len = HexToInt(start_offset, static_cast<u32>(len_pos - start_offset));
u8* dst = Memory::GetPointer(addr); if (!Memory::IsValidVirtualAddress(addr)) {
if (!dst) {
return SendReply("E00"); return SendReply("E00");
} }
GdbHexToMem(dst, len_pos + 1, len); std::vector<u8> data(len);
GdbHexToMem(data.data(), len_pos + 1, len);
Memory::WriteBlock(addr, data.data(), len);
SendReply("OK"); SendReply("OK");
} }

View File

@ -58,22 +58,21 @@ void Wrap() {
FuncReturn(retval); FuncReturn(retval);
} }
template <ResultCode func(s32*, u32*, s32, bool, s64)> template <ResultCode func(s32*, VAddr, s32, bool, s64)>
void Wrap() { void Wrap() {
s32 param_1 = 0; s32 param_1 = 0;
s32 retval = func(&param_1, (Kernel::Handle*)Memory::GetPointer(PARAM(1)), (s32)PARAM(2), s32 retval =
(PARAM(3) != 0), (((s64)PARAM(4) << 32) | PARAM(0))) func(&param_1, PARAM(1), (s32)PARAM(2), (PARAM(3) != 0), (((s64)PARAM(4) << 32) | PARAM(0)))
.raw; .raw;
Core::CPU().SetReg(1, (u32)param_1); Core::CPU().SetReg(1, (u32)param_1);
FuncReturn(retval); FuncReturn(retval);
} }
template <ResultCode func(s32*, u32*, s32, u32)> template <ResultCode func(s32*, VAddr, s32, u32)>
void Wrap() { void Wrap() {
s32 param_1 = 0; s32 param_1 = 0;
u32 retval = u32 retval = func(&param_1, PARAM(1), (s32)PARAM(2), PARAM(3)).raw;
func(&param_1, (Kernel::Handle*)Memory::GetPointer(PARAM(1)), (s32)PARAM(2), PARAM(3)).raw;
Core::CPU().SetReg(1, (u32)param_1); Core::CPU().SetReg(1, (u32)param_1);
FuncReturn(retval); FuncReturn(retval);
@ -152,21 +151,6 @@ void Wrap() {
FuncReturn(func(PARAM(0)).raw); FuncReturn(func(PARAM(0)).raw);
} }
template <ResultCode func(s64*, u32, u32*, u32)>
void Wrap() {
FuncReturn(func((s64*)Memory::GetPointer(PARAM(0)), PARAM(1),
(u32*)Memory::GetPointer(PARAM(2)), (s32)PARAM(3))
.raw);
}
template <ResultCode func(u32*, const char*)>
void Wrap() {
u32 param_1 = 0;
u32 retval = func(&param_1, (char*)Memory::GetPointer(PARAM(1))).raw;
Core::CPU().SetReg(1, param_1);
FuncReturn(retval);
}
template <ResultCode func(u32*, s32, s32)> template <ResultCode func(u32*, s32, s32)>
void Wrap() { void Wrap() {
u32 param_1 = 0; u32 param_1 = 0;
@ -222,13 +206,11 @@ void Wrap() {
FuncReturn(func(PARAM(0), PARAM(1)).raw); FuncReturn(func(PARAM(0), PARAM(1)).raw);
} }
template <ResultCode func(Kernel::Handle*, Kernel::Handle*, const char*, u32)> template <ResultCode func(Kernel::Handle*, Kernel::Handle*, VAddr, u32)>
void Wrap() { void Wrap() {
Kernel::Handle param_1 = 0; Kernel::Handle param_1 = 0;
Kernel::Handle param_2 = 0; Kernel::Handle param_2 = 0;
u32 retval = func(&param_1, &param_2, u32 retval = func(&param_1, &param_2, PARAM(2), PARAM(3)).raw;
reinterpret_cast<const char*>(Memory::GetPointer(PARAM(2))), PARAM(3))
.raw;
Core::CPU().SetReg(1, param_1); Core::CPU().SetReg(1, param_1);
Core::CPU().SetReg(2, param_2); Core::CPU().SetReg(2, param_2);
FuncReturn(retval); FuncReturn(retval);
@ -268,9 +250,9 @@ void Wrap() {
func(((s64)PARAM(1) << 32) | PARAM(0)); func(((s64)PARAM(1) << 32) | PARAM(0));
} }
template <void func(const char*, int len)> template <void func(VAddr, int len)>
void Wrap() { void Wrap() {
func((char*)Memory::GetPointer(PARAM(0)), PARAM(1)); func(PARAM(0), PARAM(1));
} }
template <void func(u8)> template <void func(u8)>

View File

@ -201,17 +201,21 @@ static ResultCode UnmapMemoryBlock(Kernel::Handle handle, u32 addr) {
} }
/// Connect to an OS service given the port name, returns the handle to the port to out /// Connect to an OS service given the port name, returns the handle to the port to out
static ResultCode ConnectToPort(Kernel::Handle* out_handle, const char* port_name) { static ResultCode ConnectToPort(Kernel::Handle* out_handle, VAddr port_name_address) {
if (port_name == nullptr) if (!Memory::IsValidVirtualAddress(port_name_address))
return Kernel::ERR_NOT_FOUND; return Kernel::ERR_NOT_FOUND;
if (std::strlen(port_name) > 11)
static constexpr std::size_t PortNameMaxLength = 11;
// Read 1 char beyond the max allowed port name to detect names that are too long.
std::string port_name = Memory::ReadCString(port_name_address, PortNameMaxLength + 1);
if (port_name.size() > PortNameMaxLength)
return Kernel::ERR_PORT_NAME_TOO_LONG; return Kernel::ERR_PORT_NAME_TOO_LONG;
LOG_TRACE(Kernel_SVC, "called port_name=%s", port_name); LOG_TRACE(Kernel_SVC, "called port_name=%s", port_name.c_str());
auto it = Service::g_kernel_named_ports.find(port_name); auto it = Service::g_kernel_named_ports.find(port_name);
if (it == Service::g_kernel_named_ports.end()) { if (it == Service::g_kernel_named_ports.end()) {
LOG_WARNING(Kernel_SVC, "tried to connect to unknown port: %s", port_name); LOG_WARNING(Kernel_SVC, "tried to connect to unknown port: %s", port_name.c_str());
return Kernel::ERR_NOT_FOUND; return Kernel::ERR_NOT_FOUND;
} }
@ -303,12 +307,11 @@ static ResultCode WaitSynchronization1(Kernel::Handle handle, s64 nano_seconds)
} }
/// Wait for the given handles to synchronize, timeout after the specified nanoseconds /// Wait for the given handles to synchronize, timeout after the specified nanoseconds
static ResultCode WaitSynchronizationN(s32* out, Kernel::Handle* handles, s32 handle_count, static ResultCode WaitSynchronizationN(s32* out, VAddr handles_address, s32 handle_count,
bool wait_all, s64 nano_seconds) { bool wait_all, s64 nano_seconds) {
Kernel::Thread* thread = Kernel::GetCurrentThread(); Kernel::Thread* thread = Kernel::GetCurrentThread();
// Check if 'handles' is invalid if (!Memory::IsValidVirtualAddress(handles_address))
if (handles == nullptr)
return Kernel::ERR_INVALID_POINTER; return Kernel::ERR_INVALID_POINTER;
// NOTE: on real hardware, there is no nullptr check for 'out' (tested with firmware 4.4). If // NOTE: on real hardware, there is no nullptr check for 'out' (tested with firmware 4.4). If
@ -323,7 +326,8 @@ static ResultCode WaitSynchronizationN(s32* out, Kernel::Handle* handles, s32 ha
std::vector<ObjectPtr> objects(handle_count); std::vector<ObjectPtr> objects(handle_count);
for (int i = 0; i < handle_count; ++i) { for (int i = 0; i < handle_count; ++i) {
auto object = Kernel::g_handle_table.Get<Kernel::WaitObject>(handles[i]); Kernel::Handle handle = Memory::Read32(handles_address + i * sizeof(Kernel::Handle));
auto object = Kernel::g_handle_table.Get<Kernel::WaitObject>(handle);
if (object == nullptr) if (object == nullptr)
return ERR_INVALID_HANDLE; return ERR_INVALID_HANDLE;
objects[i] = object; objects[i] = object;
@ -452,10 +456,9 @@ static ResultCode WaitSynchronizationN(s32* out, Kernel::Handle* handles, s32 ha
} }
/// In a single operation, sends a IPC reply and waits for a new request. /// In a single operation, sends a IPC reply and waits for a new request.
static ResultCode ReplyAndReceive(s32* index, Kernel::Handle* handles, s32 handle_count, static ResultCode ReplyAndReceive(s32* index, VAddr handles_address, s32 handle_count,
Kernel::Handle reply_target) { Kernel::Handle reply_target) {
// 'handles' has to be a valid pointer even if 'handle_count' is 0. if (!Memory::IsValidVirtualAddress(handles_address))
if (handles == nullptr)
return Kernel::ERR_INVALID_POINTER; return Kernel::ERR_INVALID_POINTER;
// Check if 'handle_count' is invalid // Check if 'handle_count' is invalid
@ -466,7 +469,8 @@ static ResultCode ReplyAndReceive(s32* index, Kernel::Handle* handles, s32 handl
std::vector<ObjectPtr> objects(handle_count); std::vector<ObjectPtr> objects(handle_count);
for (int i = 0; i < handle_count; ++i) { for (int i = 0; i < handle_count; ++i) {
auto object = Kernel::g_handle_table.Get<Kernel::WaitObject>(handles[i]); Kernel::Handle handle = Memory::Read32(handles_address + i * sizeof(Kernel::Handle));
auto object = Kernel::g_handle_table.Get<Kernel::WaitObject>(handle);
if (object == nullptr) if (object == nullptr)
return ERR_INVALID_HANDLE; return ERR_INVALID_HANDLE;
objects[i] = object; objects[i] = object;
@ -619,8 +623,10 @@ static void Break(u8 break_reason) {
} }
/// Used to output a message on a debug hardware unit - does nothing on a retail unit /// Used to output a message on a debug hardware unit - does nothing on a retail unit
static void OutputDebugString(const char* string, int len) { static void OutputDebugString(VAddr address, int len) {
LOG_DEBUG(Debug_Emulated, "%.*s", len, string); std::vector<char> string(len);
Memory::ReadBlock(address, string.data(), len);
LOG_DEBUG(Debug_Emulated, "%.*s", len, string.data());
} }
/// Get resource limit /// Get resource limit
@ -638,9 +644,9 @@ static ResultCode GetResourceLimit(Kernel::Handle* resource_limit, Kernel::Handl
} }
/// Get resource limit current values /// Get resource limit current values
static ResultCode GetResourceLimitCurrentValues(s64* values, Kernel::Handle resource_limit_handle, static ResultCode GetResourceLimitCurrentValues(VAddr values, Kernel::Handle resource_limit_handle,
u32* names, u32 name_count) { VAddr names, u32 name_count) {
LOG_TRACE(Kernel_SVC, "called resource_limit=%08X, names=%p, name_count=%d", LOG_TRACE(Kernel_SVC, "called resource_limit=%08X, names=%08X, name_count=%d",
resource_limit_handle, names, name_count); resource_limit_handle, names, name_count);
SharedPtr<Kernel::ResourceLimit> resource_limit = SharedPtr<Kernel::ResourceLimit> resource_limit =
@ -648,16 +654,19 @@ static ResultCode GetResourceLimitCurrentValues(s64* values, Kernel::Handle reso
if (resource_limit == nullptr) if (resource_limit == nullptr)
return ERR_INVALID_HANDLE; return ERR_INVALID_HANDLE;
for (unsigned int i = 0; i < name_count; ++i) for (unsigned int i = 0; i < name_count; ++i) {
values[i] = resource_limit->GetCurrentResourceValue(names[i]); u32 name = Memory::Read32(names + i * sizeof(u32));
s64 value = resource_limit->GetCurrentResourceValue(name);
Memory::Write64(values + i * sizeof(u64), value);
}
return RESULT_SUCCESS; return RESULT_SUCCESS;
} }
/// Get resource limit max values /// Get resource limit max values
static ResultCode GetResourceLimitLimitValues(s64* values, Kernel::Handle resource_limit_handle, static ResultCode GetResourceLimitLimitValues(VAddr values, Kernel::Handle resource_limit_handle,
u32* names, u32 name_count) { VAddr names, u32 name_count) {
LOG_TRACE(Kernel_SVC, "called resource_limit=%08X, names=%p, name_count=%d", LOG_TRACE(Kernel_SVC, "called resource_limit=%08X, names=%08X, name_count=%d",
resource_limit_handle, names, name_count); resource_limit_handle, names, name_count);
SharedPtr<Kernel::ResourceLimit> resource_limit = SharedPtr<Kernel::ResourceLimit> resource_limit =
@ -665,8 +674,11 @@ static ResultCode GetResourceLimitLimitValues(s64* values, Kernel::Handle resour
if (resource_limit == nullptr) if (resource_limit == nullptr)
return ERR_INVALID_HANDLE; return ERR_INVALID_HANDLE;
for (unsigned int i = 0; i < name_count; ++i) for (unsigned int i = 0; i < name_count; ++i) {
values[i] = resource_limit->GetMaxResourceValue(names[i]); u32 name = Memory::Read32(names + i * sizeof(u32));
s64 value = resource_limit->GetMaxResourceValue(names);
Memory::Write64(values + i * sizeof(u64), value);
}
return RESULT_SUCCESS; return RESULT_SUCCESS;
} }
@ -1098,9 +1110,9 @@ static ResultCode CreateMemoryBlock(Kernel::Handle* out_handle, u32 addr, u32 si
} }
static ResultCode CreatePort(Kernel::Handle* server_port, Kernel::Handle* client_port, static ResultCode CreatePort(Kernel::Handle* server_port, Kernel::Handle* client_port,
const char* name, u32 max_sessions) { VAddr name_address, u32 max_sessions) {
// TODO(Subv): Implement named ports. // TODO(Subv): Implement named ports.
ASSERT_MSG(name == nullptr, "Named ports are currently unimplemented"); ASSERT_MSG(name_address == 0, "Named ports are currently unimplemented");
using Kernel::ServerPort; using Kernel::ServerPort;
using Kernel::ClientPort; using Kernel::ClientPort;