From 2507f1a819310220230e5a9f03c34f40f634098b Mon Sep 17 00:00:00 2001 From: Triang3l Date: Wed, 14 Aug 2019 10:31:11 +0300 Subject: [PATCH] [Memory] TranslateVirtual in shim and strings --- src/xenia/kernel/util/shim_utils.h | 59 +++++++++++++++---- src/xenia/kernel/xboxkrnl/xboxkrnl_io.cc | 9 ++- src/xenia/kernel/xboxkrnl/xboxkrnl_ob.cc | 13 ++-- src/xenia/kernel/xboxkrnl/xboxkrnl_rtl.cc | 2 +- .../kernel/xboxkrnl/xboxkrnl_threading.cc | 6 +- src/xenia/kernel/xobject.cc | 6 +- src/xenia/xbox.h | 45 -------------- 7 files changed, 67 insertions(+), 73 deletions(-) diff --git a/src/xenia/kernel/util/shim_utils.h b/src/xenia/kernel/util/shim_utils.h index 91ee8efe0..f4bf06a5f 100644 --- a/src/xenia/kernel/util/shim_utils.h +++ b/src/xenia/kernel/util/shim_utils.h @@ -81,6 +81,35 @@ inline uint64_t get_arg_64(PPCContext* ppc_context, uint8_t index) { uint32_t stack_address = get_arg_stack_ptr(ppc_context, index - 8); return SHIM_MEM_64(stack_address); } + +inline std::string TranslateAnsiString(const Memory* memory, + const X_ANSI_STRING* ansi_string) { + if (!ansi_string || !ansi_string->length) { + return ""; + } + return std::string( + memory->TranslateVirtual(ansi_string->pointer), + ansi_string->length); +} + +inline std::string TranslateAnsiStringAddress(const Memory* memory, + uint32_t guest_address) { + if (!guest_address) { + return ""; + } + return TranslateAnsiString( + memory, memory->TranslateVirtual(guest_address)); +} + +inline std::wstring TranslateUnicodeString( + const Memory* memory, const X_UNICODE_STRING* unicode_string) { + if (!unicode_string || !unicode_string->length) { + return L""; + } + return std::wstring( + memory->TranslateVirtual(unicode_string->pointer), + unicode_string->length); +} } // namespace util #define SHIM_GET_ARG_8(n) util::get_arg_8(ppc_context, n) @@ -117,8 +146,9 @@ class Param { } else { uint32_t stack_ptr = uint32_t(init.ppc_context->r[1]) + 0x54 + (ordinal_ - 8) * 8; - *out_value = - xe::load_and_swap(init.ppc_context->virtual_membase + stack_ptr); + *out_value = xe::load_and_swap( + init.ppc_context->kernel_state->memory()->TranslateVirtual( + stack_ptr)); } } @@ -153,7 +183,10 @@ class ParamBase : public Param { class PointerParam : public ParamBase { public: PointerParam(Init& init) : ParamBase(init) { - host_ptr_ = value_ ? init.ppc_context->virtual_membase + value_ : nullptr; + host_ptr_ = + value_ + ? init.ppc_context->kernel_state->memory()->TranslateVirtual(value_) + : nullptr; } PointerParam(void* host_ptr) : ParamBase(), host_ptr_(host_ptr) {} PointerParam& operator=(void*& other) { @@ -191,8 +224,8 @@ template class PrimitivePointerParam : public ParamBase { public: PrimitivePointerParam(Init& init) : ParamBase(init) { - host_ptr_ = value_ ? reinterpret_cast*>( - init.ppc_context->virtual_membase + value_) + host_ptr_ = value_ ? init.ppc_context->kernel_state->memory() + ->TranslateVirtual*>(value_) : nullptr; } PrimitivePointerParam(T* host_ptr) : ParamBase() { @@ -223,9 +256,11 @@ template class StringPointerParam : public ParamBase { public: StringPointerParam(Init& init) : ParamBase(init) { - host_ptr_ = value_ ? reinterpret_cast( - init.ppc_context->virtual_membase + value_) - : nullptr; + host_ptr_ = + value_ + ? init.ppc_context->kernel_state->memory()->TranslateVirtual( + value_) + : nullptr; } StringPointerParam(CHAR* host_ptr) : ParamBase(), host_ptr_(host_ptr) {} StringPointerParam& operator=(const CHAR*& other) { @@ -249,9 +284,9 @@ class TypedPointerParam : public ParamBase { public: TypedPointerParam(Init& init) : ParamBase(init) { host_ptr_ = - value_ - ? reinterpret_cast(init.ppc_context->virtual_membase + value_) - : nullptr; + value_ ? init.ppc_context->kernel_state->memory()->TranslateVirtual( + value_) + : nullptr; } TypedPointerParam(T* host_ptr) : ParamBase(), host_ptr_(host_ptr) {} TypedPointerParam& operator=(const T*& other) { @@ -391,7 +426,7 @@ inline void AppendParam(StringBuffer* string_buffer, std::string name = name_string == nullptr ? "(null)" - : name_string->to_string(kernel_memory()->virtual_membase()); + : util::TranslateAnsiString(kernel_memory(), name_string); string_buffer->AppendFormat("(%.8X,%s,%.8X)", uint32_t(record->root_directory), name.c_str(), uint32_t(record->attributes)); diff --git a/src/xenia/kernel/xboxkrnl/xboxkrnl_io.cc b/src/xenia/kernel/xboxkrnl/xboxkrnl_io.cc index 21fb050b6..cda1a9a48 100644 --- a/src/xenia/kernel/xboxkrnl/xboxkrnl_io.cc +++ b/src/xenia/kernel/xboxkrnl/xboxkrnl_io.cc @@ -91,7 +91,7 @@ dword_result_t NtCreateFile(lpdword_t handle_out, dword_t desired_access, // Compute path, possibly attrs relative. std::string target_path = - object_name->to_string(kernel_memory()->virtual_membase()); + util::TranslateAnsiString(kernel_memory(), object_name); if (object_attrs->root_directory != 0xFFFFFFFD && // ObDosDevices object_attrs->root_directory != 0) { auto root_file = kernel_state()->object_table()->LookupObject( @@ -571,7 +571,7 @@ dword_result_t NtQueryFullAttributesFile( // Resolve the file using the virtual file system. auto entry = kernel_state()->file_system()->ResolvePath( - object_name->to_string(kernel_memory()->virtual_membase())); + util::TranslateAnsiString(kernel_memory(), object_name)); if (entry) { // Found. file_info->creation_time = entry->create_timestamp(); @@ -678,8 +678,7 @@ dword_result_t NtQueryDirectoryFile( uint32_t info = 0; auto file = kernel_state()->object_table()->LookupObject(file_handle); - auto name = - file_name ? file_name->to_string(kernel_memory()->virtual_membase()) : ""; + auto name = util::TranslateAnsiString(kernel_memory(), file_name); if (file) { X_FILE_DIRECTORY_INFORMATION dir_info = {0}; result = file->QueryDirectory(file_info_ptr, length, @@ -732,7 +731,7 @@ dword_result_t NtOpenSymbolicLinkObject( kernel_memory()->TranslateVirtual(object_attrs->name_ptr); std::string target_path = - object_name->to_string(kernel_memory()->virtual_membase()); + util::TranslateAnsiString(kernel_memory(), object_name); if (object_attrs->root_directory != 0) { assert_always(); } diff --git a/src/xenia/kernel/xboxkrnl/xboxkrnl_ob.cc b/src/xenia/kernel/xboxkrnl/xboxkrnl_ob.cc index 18d518753..1593fe2f5 100644 --- a/src/xenia/kernel/xboxkrnl/xboxkrnl_ob.cc +++ b/src/xenia/kernel/xboxkrnl/xboxkrnl_ob.cc @@ -31,9 +31,10 @@ dword_result_t ObOpenObjectByName(lpunknown_t obj_attributes_ptr, // r5 = 0 // r6 = out_ptr (handle?) - auto name = - X_ANSI_STRING::to_string_indirect(kernel_memory()->virtual_membase(), - obj_attributes_ptr.guest_address() + 4); + auto name = util::TranslateAnsiStringAddress( + kernel_memory(), + xe::load_and_swap(kernel_memory()->TranslateVirtual( + obj_attributes_ptr.guest_address() + 4))); X_HANDLE handle = X_INVALID_HANDLE_VALUE; X_STATUS result = @@ -177,8 +178,8 @@ DECLARE_XBOXKRNL_EXPORT1(ObDereferenceObject, kNone, kImplemented); dword_result_t ObCreateSymbolicLink(pointer_t path, pointer_t target) { - auto path_str = path->to_string(kernel_memory()->virtual_membase()); - auto target_str = target->to_string(kernel_memory()->virtual_membase()); + auto path_str = util::TranslateAnsiString(kernel_memory(), path); + auto target_str = util::TranslateAnsiString(kernel_memory(), target); path_str = filesystem::CanonicalizePath(path_str); target_str = filesystem::CanonicalizePath(target_str); @@ -197,7 +198,7 @@ dword_result_t ObCreateSymbolicLink(pointer_t path, DECLARE_XBOXKRNL_EXPORT1(ObCreateSymbolicLink, kNone, kImplemented); dword_result_t ObDeleteSymbolicLink(pointer_t path) { - auto path_str = path->to_string(kernel_memory()->virtual_membase()); + auto path_str = util::TranslateAnsiString(kernel_memory(), path); if (!kernel_state()->file_system()->UnregisterSymbolicLink(path_str)) { return X_STATUS_UNSUCCESSFUL; } diff --git a/src/xenia/kernel/xboxkrnl/xboxkrnl_rtl.cc b/src/xenia/kernel/xboxkrnl/xboxkrnl_rtl.cc index 3182b510e..22170cb1f 100644 --- a/src/xenia/kernel/xboxkrnl/xboxkrnl_rtl.cc +++ b/src/xenia/kernel/xboxkrnl/xboxkrnl_rtl.cc @@ -230,7 +230,7 @@ dword_result_t RtlUnicodeStringToAnsiString( // _In_ BOOLEAN AllocateDestinationString std::wstring unicode_str = - source_ptr->to_string(kernel_memory()->virtual_membase()); + util::TranslateUnicodeString(kernel_memory(), source_ptr); std::string ansi_str = xe::to_string(unicode_str); if (ansi_str.size() > 0xFFFF - 1) { return X_STATUS_INVALID_PARAMETER_2; diff --git a/src/xenia/kernel/xboxkrnl/xboxkrnl_threading.cc b/src/xenia/kernel/xboxkrnl/xboxkrnl_threading.cc index d28ce1b42..c601b51da 100644 --- a/src/xenia/kernel/xboxkrnl/xboxkrnl_threading.cc +++ b/src/xenia/kernel/xboxkrnl/xboxkrnl_threading.cc @@ -74,8 +74,10 @@ object_ref LookupNamedObject(KernelState* kernel_state, if (!obj_attributes_ptr) { return nullptr; } - auto name = X_ANSI_STRING::to_string_indirect( - kernel_state->memory()->virtual_membase(), obj_attributes_ptr + 4); + auto name = util::TranslateAnsiStringAddress( + kernel_state->memory(), + xe::load_and_swap( + kernel_state->memory()->TranslateVirtual(obj_attributes_ptr + 4))); if (!name.empty()) { X_HANDLE handle = X_INVALID_HANDLE_VALUE; X_RESULT result = diff --git a/src/xenia/kernel/xobject.cc b/src/xenia/kernel/xobject.cc index 30a6436fa..7f615ef4b 100644 --- a/src/xenia/kernel/xobject.cc +++ b/src/xenia/kernel/xobject.cc @@ -14,6 +14,7 @@ #include "xenia/base/byte_stream.h" #include "xenia/base/clock.h" #include "xenia/kernel/kernel_state.h" +#include "xenia/kernel/util/shim_utils.h" #include "xenia/kernel/xboxkrnl/xboxkrnl_private.h" #include "xenia/kernel/xenumerator.h" #include "xenia/kernel/xevent.h" @@ -166,8 +167,9 @@ void XObject::SetAttributes(uint32_t obj_attributes_ptr) { return; } - auto name = X_ANSI_STRING::to_string_indirect(memory()->virtual_membase(), - obj_attributes_ptr + 4); + auto name = util::TranslateAnsiStringAddress( + memory(), xe::load_and_swap( + memory()->TranslateVirtual(obj_attributes_ptr + 4))); if (!name.empty()) { name_ = std::move(name); kernel_state_->object_table()->AddNameMapping(name_, handles_[0]); diff --git a/src/xenia/xbox.h b/src/xenia/xbox.h index 3fb8fb452..0b2cd3794 100644 --- a/src/xenia/xbox.h +++ b/src/xenia/xbox.h @@ -260,47 +260,11 @@ struct X_ANSI_STRING { xe::be maximum_length; xe::be pointer; - static X_ANSI_STRING* Translate(uint8_t* membase, uint32_t guest_address) { - if (!guest_address) { - return nullptr; - } - return reinterpret_cast(membase + guest_address); - } - - static X_ANSI_STRING* TranslateIndirect(uint8_t* membase, - uint32_t guest_address_ptr) { - if (!guest_address_ptr) { - return nullptr; - } - uint32_t guest_address = - xe::load_and_swap(membase + guest_address_ptr); - return Translate(membase, guest_address); - } - - static std::string to_string(uint8_t* membase, uint32_t guest_address) { - auto str = Translate(membase, guest_address); - return str ? str->to_string(membase) : ""; - } - - static std::string to_string_indirect(uint8_t* membase, - uint32_t guest_address_ptr) { - auto str = TranslateIndirect(membase, guest_address_ptr); - return str ? str->to_string(membase) : ""; - } - void reset() { length = 0; maximum_length = 0; pointer = 0; } - - std::string to_string(uint8_t* membase) const { - if (!length) { - return ""; - } - return std::string(reinterpret_cast(membase + pointer), - length); - } }; static_assert_size(X_ANSI_STRING, 8); @@ -314,15 +278,6 @@ struct X_UNICODE_STRING { maximum_length = 0; pointer = 0; } - - std::wstring to_string(uint8_t* membase) const { - if (!length) { - return L""; - } - - return std::wstring(reinterpret_cast(membase + pointer), - length); - } }; static_assert_size(X_UNICODE_STRING, 8);