diff options
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/arm/symbols.cpp | 85 | ||||
-rw-r--r-- | src/core/debugger/debugger.cpp | 21 | ||||
-rw-r--r-- | src/core/debugger/gdbstub.cpp | 199 | ||||
-rw-r--r-- | src/core/debugger/gdbstub.h | 1 | ||||
-rw-r--r-- | src/core/hle/kernel/k_thread.cpp | 4 | ||||
-rw-r--r-- | src/core/hle/kernel/k_thread.h | 10 | ||||
-rw-r--r-- | src/core/hle/service/hid/controllers/gesture.cpp | 4 | ||||
-rw-r--r-- | src/core/hle/service/hid/controllers/gesture.h | 3 | ||||
-rw-r--r-- | src/core/hle/service/hid/irs.cpp | 249 | ||||
-rw-r--r-- | src/core/hle/service/hid/irs.h | 232 | ||||
-rw-r--r-- | src/core/hle/service/jit/jit_context.cpp | 32 | ||||
-rw-r--r-- | src/core/hle/service/nvflinger/buffer_queue_consumer.cpp | 29 | ||||
-rw-r--r-- | src/core/hle/service/nvflinger/buffer_queue_core.cpp | 4 | ||||
-rw-r--r-- | src/core/hle/service/nvflinger/buffer_slot.h | 1 | ||||
-rw-r--r-- | src/core/loader/elf.cpp | 183 |
15 files changed, 703 insertions, 354 deletions
diff --git a/src/core/arm/symbols.cpp b/src/core/arm/symbols.cpp index 4aa1a1ee1..0259c7ea2 100644 --- a/src/core/arm/symbols.cpp +++ b/src/core/arm/symbols.cpp @@ -3,73 +3,14 @@ #include "common/bit_field.h" #include "common/common_funcs.h" +#include "common/elf.h" #include "core/arm/symbols.h" #include "core/core.h" #include "core/memory.h" -namespace Core { -namespace { - -constexpr u64 ELF_DYNAMIC_TAG_NULL = 0; -constexpr u64 ELF_DYNAMIC_TAG_STRTAB = 5; -constexpr u64 ELF_DYNAMIC_TAG_SYMTAB = 6; -constexpr u64 ELF_DYNAMIC_TAG_SYMENT = 11; - -enum class ELFSymbolType : u8 { - None = 0, - Object = 1, - Function = 2, - Section = 3, - File = 4, - Common = 5, - TLS = 6, -}; - -enum class ELFSymbolBinding : u8 { - Local = 0, - Global = 1, - Weak = 2, -}; - -enum class ELFSymbolVisibility : u8 { - Default = 0, - Internal = 1, - Hidden = 2, - Protected = 3, -}; - -struct ELF64Symbol { - u32 name_index; - union { - u8 info; - - BitField<0, 4, ELFSymbolType> type; - BitField<4, 4, ELFSymbolBinding> binding; - }; - ELFSymbolVisibility visibility; - u16 sh_index; - u64 value; - u64 size; -}; -static_assert(sizeof(ELF64Symbol) == 0x18, "ELF64Symbol has incorrect size."); - -struct ELF32Symbol { - u32 name_index; - u32 value; - u32 size; - union { - u8 info; - - BitField<0, 4, ELFSymbolType> type; - BitField<4, 4, ELFSymbolBinding> binding; - }; - ELFSymbolVisibility visibility; - u16 sh_index; -}; -static_assert(sizeof(ELF32Symbol) == 0x10, "ELF32Symbol has incorrect size."); - -} // Anonymous namespace +using namespace Common::ELF; +namespace Core { namespace Symbols { template <typename Word, typename ELFSymbol, typename ByteReader> @@ -110,15 +51,15 @@ static Symbols GetSymbols(ByteReader ReadBytes) { const Word value = ReadWord(dynamic_index + sizeof(Word)); dynamic_index += 2 * sizeof(Word); - if (tag == ELF_DYNAMIC_TAG_NULL) { + if (tag == ElfDtNull) { break; } - if (tag == ELF_DYNAMIC_TAG_STRTAB) { + if (tag == ElfDtStrtab) { string_table_offset = value; - } else if (tag == ELF_DYNAMIC_TAG_SYMTAB) { + } else if (tag == ElfDtSymtab) { symbol_table_offset = value; - } else if (tag == ELF_DYNAMIC_TAG_SYMENT) { + } else if (tag == ElfDtSyment) { symbol_entry_size = value; } } @@ -134,14 +75,14 @@ static Symbols GetSymbols(ByteReader ReadBytes) { ELFSymbol symbol{}; ReadBytes(&symbol, symbol_index, sizeof(ELFSymbol)); - VAddr string_offset = string_table_offset + symbol.name_index; + VAddr string_offset = string_table_offset + symbol.st_name; std::string name; for (u8 c = Read8(string_offset); c != 0; c = Read8(++string_offset)) { name += static_cast<char>(c); } symbol_index += symbol_entry_size; - out[name] = std::make_pair(symbol.value, symbol.size); + out[name] = std::make_pair(symbol.st_value, symbol.st_size); } return out; @@ -152,9 +93,9 @@ Symbols GetSymbols(VAddr base, Core::Memory::Memory& memory, bool is_64) { [&](void* ptr, size_t offset, size_t size) { memory.ReadBlock(base + offset, ptr, size); }}; if (is_64) { - return GetSymbols<u64, ELF64Symbol>(ReadBytes); + return GetSymbols<u64, Elf64_Sym>(ReadBytes); } else { - return GetSymbols<u32, ELF32Symbol>(ReadBytes); + return GetSymbols<u32, Elf32_Sym>(ReadBytes); } } @@ -164,9 +105,9 @@ Symbols GetSymbols(std::span<const u8> data, bool is_64) { }}; if (is_64) { - return GetSymbols<u64, ELF64Symbol>(ReadBytes); + return GetSymbols<u64, Elf64_Sym>(ReadBytes); } else { - return GetSymbols<u32, ELF32Symbol>(ReadBytes); + return GetSymbols<u32, Elf32_Sym>(ReadBytes); } } diff --git a/src/core/debugger/debugger.cpp b/src/core/debugger/debugger.cpp index 68ab33e46..8d64990ed 100644 --- a/src/core/debugger/debugger.cpp +++ b/src/core/debugger/debugger.cpp @@ -20,15 +20,16 @@ template <typename Readable, typename Buffer, typename Callback> static void AsyncReceiveInto(Readable& r, Buffer& buffer, Callback&& c) { static_assert(std::is_trivial_v<Buffer>); auto boost_buffer{boost::asio::buffer(&buffer, sizeof(Buffer))}; - r.async_read_some(boost_buffer, [&](const boost::system::error_code& error, size_t bytes_read) { - if (!error.failed()) { - const u8* buffer_start = reinterpret_cast<const u8*>(&buffer); - std::span<const u8> received_data{buffer_start, buffer_start + bytes_read}; - c(received_data); - } + r.async_read_some( + boost_buffer, [&, c](const boost::system::error_code& error, size_t bytes_read) { + if (!error.failed()) { + const u8* buffer_start = reinterpret_cast<const u8*>(&buffer); + std::span<const u8> received_data{buffer_start, buffer_start + bytes_read}; + c(received_data); + } - AsyncReceiveInto(r, buffer, c); - }); + AsyncReceiveInto(r, buffer, c); + }); } template <typename Readable, typename Buffer> @@ -65,7 +66,7 @@ public: } stopped = true; - signal_pipe.write_some(boost::asio::buffer(&thread, sizeof(thread))); + boost::asio::write(signal_pipe, boost::asio::buffer(&thread, sizeof(thread))); return true; } @@ -74,7 +75,7 @@ public: } void WriteToClient(std::span<const u8> data) override { - client_socket.write_some(boost::asio::buffer(data.data(), data.size_bytes())); + boost::asio::write(client_socket, boost::asio::buffer(data.data(), data.size_bytes())); } void SetActiveThread(Kernel::KThread* thread) override { diff --git a/src/core/debugger/gdbstub.cpp b/src/core/debugger/gdbstub.cpp index 0c36069a6..f52d78829 100644 --- a/src/core/debugger/gdbstub.cpp +++ b/src/core/debugger/gdbstub.cpp @@ -34,6 +34,65 @@ constexpr char GDB_STUB_REPLY_ERR[] = "E01"; constexpr char GDB_STUB_REPLY_OK[] = "OK"; constexpr char GDB_STUB_REPLY_EMPTY[] = ""; +static u8 CalculateChecksum(std::string_view data) { + return std::accumulate(data.begin(), data.end(), u8{0}, + [](u8 lhs, u8 rhs) { return static_cast<u8>(lhs + rhs); }); +} + +static std::string EscapeGDB(std::string_view data) { + std::string escaped; + escaped.reserve(data.size()); + + for (char c : data) { + switch (c) { + case '#': + escaped += "}\x03"; + break; + case '$': + escaped += "}\x04"; + break; + case '*': + escaped += "}\x0a"; + break; + case '}': + escaped += "}\x5d"; + break; + default: + escaped += c; + break; + } + } + + return escaped; +} + +static std::string EscapeXML(std::string_view data) { + std::string escaped; + escaped.reserve(data.size()); + + for (char c : data) { + switch (c) { + case '&': + escaped += "&"; + break; + case '"': + escaped += """; + break; + case '<': + escaped += "<"; + break; + case '>': + escaped += ">"; + break; + default: + escaped += c; + break; + } + } + + return escaped; +} + GDBStub::GDBStub(DebuggerBackend& backend_, Core::System& system_) : DebuggerFrontend(backend_), system{system_} { if (system.CurrentProcess()->Is64BitProcess()) { @@ -255,6 +314,80 @@ void GDBStub::ExecuteCommand(std::string_view packet, std::vector<DebuggerAction } } +// Structure offsets are from Atmosphere +// See osdbg_thread_local_region.os.horizon.hpp and osdbg_thread_type.os.horizon.hpp + +static std::optional<std::string> GetNameFromThreadType32(Core::Memory::Memory& memory, + const Kernel::KThread* thread) { + // Read thread type from TLS + const VAddr tls_thread_type{memory.Read32(thread->GetTLSAddress() + 0x1fc)}; + const VAddr argument_thread_type{thread->GetArgument()}; + + if (argument_thread_type && tls_thread_type != argument_thread_type) { + // Probably not created by nnsdk, no name available. + return std::nullopt; + } + + if (!tls_thread_type) { + return std::nullopt; + } + + const u16 version{memory.Read16(tls_thread_type + 0x26)}; + VAddr name_pointer{}; + if (version == 1) { + name_pointer = memory.Read32(tls_thread_type + 0xe4); + } else { + name_pointer = memory.Read32(tls_thread_type + 0xe8); + } + + if (!name_pointer) { + // No name provided. + return std::nullopt; + } + + return memory.ReadCString(name_pointer, 256); +} + +static std::optional<std::string> GetNameFromThreadType64(Core::Memory::Memory& memory, + const Kernel::KThread* thread) { + // Read thread type from TLS + const VAddr tls_thread_type{memory.Read64(thread->GetTLSAddress() + 0x1f8)}; + const VAddr argument_thread_type{thread->GetArgument()}; + + if (argument_thread_type && tls_thread_type != argument_thread_type) { + // Probably not created by nnsdk, no name available. + return std::nullopt; + } + + if (!tls_thread_type) { + return std::nullopt; + } + + const u16 version{memory.Read16(tls_thread_type + 0x46)}; + VAddr name_pointer{}; + if (version == 1) { + name_pointer = memory.Read64(tls_thread_type + 0x1a0); + } else { + name_pointer = memory.Read64(tls_thread_type + 0x1a8); + } + + if (!name_pointer) { + // No name provided. + return std::nullopt; + } + + return memory.ReadCString(name_pointer, 256); +} + +static std::optional<std::string> GetThreadName(Core::System& system, + const Kernel::KThread* thread) { + if (system.CurrentProcess()->Is64BitProcess()) { + return GetNameFromThreadType64(system.Memory(), thread); + } else { + return GetNameFromThreadType32(system.Memory(), thread); + } +} + static std::string_view GetThreadWaitReason(const Kernel::KThread* thread) { switch (thread->GetWaitReasonForDebugging()) { case Kernel::ThreadWaitReasonForDebugging::Sleep: @@ -289,6 +422,18 @@ static std::string GetThreadState(const Kernel::KThread* thread) { } } +static std::string PaginateBuffer(std::string_view buffer, std::string_view request) { + const auto amount{request.substr(request.find(',') + 1)}; + const auto offset_val{static_cast<u64>(strtoll(request.data(), nullptr, 16))}; + const auto amount_val{static_cast<u64>(strtoll(amount.data(), nullptr, 16))}; + + if (offset_val + amount_val > buffer.size()) { + return fmt::format("l{}", buffer.substr(offset_val)); + } else { + return fmt::format("m{}", buffer.substr(offset_val, amount_val)); + } +} + void GDBStub::HandleQuery(std::string_view command) { if (command.starts_with("TStatus")) { // no tracepoint support @@ -297,18 +442,8 @@ void GDBStub::HandleQuery(std::string_view command) { SendReply("PacketSize=4000;qXfer:features:read+;qXfer:threads:read+;qXfer:libraries:read+;" "vContSupported+;QStartNoAckMode+"); } else if (command.starts_with("Xfer:features:read:target.xml:")) { - const auto offset{command.substr(30)}; - const auto amount{command.substr(command.find(',') + 1)}; - - const auto offset_val{static_cast<u64>(strtoll(offset.data(), nullptr, 16))}; - const auto amount_val{static_cast<u64>(strtoll(amount.data(), nullptr, 16))}; const auto target_xml{arch->GetTargetXML()}; - - if (offset_val + amount_val > target_xml.size()) { - SendReply("l" + target_xml.substr(offset_val)); - } else { - SendReply("m" + target_xml.substr(offset_val, amount_val)); - } + SendReply(PaginateBuffer(target_xml, command.substr(30))); } else if (command.starts_with("Offsets")) { Loader::AppLoader::Modules modules; system.GetAppLoader().ReadNSOModules(modules); @@ -321,6 +456,20 @@ void GDBStub::HandleQuery(std::string_view command) { SendReply(fmt::format("TextSeg={:x}", system.CurrentProcess()->PageTable().GetCodeRegionStart())); } + } else if (command.starts_with("Xfer:libraries:read::")) { + Loader::AppLoader::Modules modules; + system.GetAppLoader().ReadNSOModules(modules); + + std::string buffer; + buffer += R"(<?xml version="1.0"?>)"; + buffer += "<library-list>"; + for (const auto& [base, name] : modules) { + buffer += fmt::format(R"(<library name="{}"><segment address="{:#x}"/></library>)", + EscapeXML(name), base); + } + buffer += "</library-list>"; + + SendReply(PaginateBuffer(buffer, command.substr(21))); } else if (command.starts_with("fThreadInfo")) { // beginning of list const auto& threads = system.GlobalSchedulerContext().GetThreadList(); @@ -332,20 +481,26 @@ void GDBStub::HandleQuery(std::string_view command) { } else if (command.starts_with("sThreadInfo")) { // end of list SendReply("l"); - } else if (command.starts_with("Xfer:threads:read")) { + } else if (command.starts_with("Xfer:threads:read::")) { std::string buffer; - buffer += R"(l<?xml version="1.0"?>)"; + buffer += R"(<?xml version="1.0"?>)"; buffer += "<threads>"; const auto& threads = system.GlobalSchedulerContext().GetThreadList(); - for (const auto& thread : threads) { - buffer += fmt::format(R"(<thread id="{:x}" core="{:d}" name="Thread {:d}">{}</thread>)", + for (const auto* thread : threads) { + auto thread_name{GetThreadName(system, thread)}; + if (!thread_name) { + thread_name = fmt::format("Thread {:d}", thread->GetThreadID()); + } + + buffer += fmt::format(R"(<thread id="{:x}" core="{:d}" name="{}">{}</thread>)", thread->GetThreadID(), thread->GetActiveCore(), - thread->GetThreadID(), GetThreadState(thread)); + EscapeXML(*thread_name), GetThreadState(thread)); } buffer += "</threads>"; - SendReply(buffer); + + SendReply(PaginateBuffer(buffer, command.substr(19))); } else if (command.starts_with("Attached")) { SendReply("0"); } else if (command.starts_with("StartNoAckMode")) { @@ -438,14 +593,10 @@ std::optional<std::string> GDBStub::DetachCommand() { return data.substr(1, data.size() - 4); } -u8 GDBStub::CalculateChecksum(std::string_view data) { - return std::accumulate(data.begin(), data.end(), u8{0}, - [](u8 lhs, u8 rhs) { return static_cast<u8>(lhs + rhs); }); -} - void GDBStub::SendReply(std::string_view data) { - const auto output{ - fmt::format("{}{}{}{:02x}", GDB_STUB_START, data, GDB_STUB_END, CalculateChecksum(data))}; + const auto escaped{EscapeGDB(data)}; + const auto output{fmt::format("{}{}{}{:02x}", GDB_STUB_START, escaped, GDB_STUB_END, + CalculateChecksum(escaped))}; LOG_TRACE(Debug_GDBStub, "Writing reply: {}", output); // C++ string support is complete rubbish diff --git a/src/core/debugger/gdbstub.h b/src/core/debugger/gdbstub.h index aa1f7de6c..1bb638187 100644 --- a/src/core/debugger/gdbstub.h +++ b/src/core/debugger/gdbstub.h @@ -34,7 +34,6 @@ private: std::optional<std::string> DetachCommand(); Kernel::KThread* GetThreadByID(u64 thread_id); - static u8 CalculateChecksum(std::string_view data); void SendReply(std::string_view data); void SendStatus(char status); diff --git a/src/core/hle/kernel/k_thread.cpp b/src/core/hle/kernel/k_thread.cpp index ab9ce6a86..940334f59 100644 --- a/src/core/hle/kernel/k_thread.cpp +++ b/src/core/hle/kernel/k_thread.cpp @@ -198,6 +198,10 @@ ResultCode KThread::Initialize(KThreadFunction func, uintptr_t arg, VAddr user_s resource_limit_release_hint = false; cpu_time = 0; + // Set debug context. + stack_top = user_stack_top; + argument = arg; + // Clear our stack parameters. std::memset(static_cast<void*>(std::addressof(GetStackParameters())), 0, sizeof(StackParameters)); diff --git a/src/core/hle/kernel/k_thread.h b/src/core/hle/kernel/k_thread.h index 60ae0da78..f4d83f99a 100644 --- a/src/core/hle/kernel/k_thread.h +++ b/src/core/hle/kernel/k_thread.h @@ -660,6 +660,14 @@ public: void IfDummyThreadTryWait(); void IfDummyThreadEndWait(); + [[nodiscard]] uintptr_t GetArgument() const { + return argument; + } + + [[nodiscard]] VAddr GetUserStackTop() const { + return stack_top; + } + private: static constexpr size_t PriorityInheritanceCountMax = 10; union SyncObjectBuffer { @@ -791,6 +799,8 @@ private: std::vector<KSynchronizationObject*> wait_objects_for_debugging; VAddr mutex_wait_address_for_debugging{}; ThreadWaitReasonForDebugging wait_reason_for_debugging{}; + uintptr_t argument; + VAddr stack_top; public: using ConditionVariableThreadTreeType = ConditionVariableThreadTree; diff --git a/src/core/hle/service/hid/controllers/gesture.cpp b/src/core/hle/service/hid/controllers/gesture.cpp index 3eae1ae35..32e0708ba 100644 --- a/src/core/hle/service/hid/controllers/gesture.cpp +++ b/src/core/hle/service/hid/controllers/gesture.cpp @@ -61,6 +61,7 @@ void Controller_Gesture::OnUpdate(const Core::Timing::CoreTiming& core_timing) { } last_update_timestamp = shared_memory->gesture_lifo.timestamp; + UpdateGestureSharedMemory(gesture, time_difference); } void Controller_Gesture::ReadTouchInput() { @@ -94,8 +95,7 @@ bool Controller_Gesture::ShouldUpdateGesture(const GestureProperties& gesture, return false; } -void Controller_Gesture::UpdateGestureSharedMemory(u8* data, std::size_t size, - GestureProperties& gesture, +void Controller_Gesture::UpdateGestureSharedMemory(GestureProperties& gesture, f32 time_difference) { GestureType type = GestureType::Idle; GestureAttribute attributes{}; diff --git a/src/core/hle/service/hid/controllers/gesture.h b/src/core/hle/service/hid/controllers/gesture.h index c62a341bf..0d6099ea0 100644 --- a/src/core/hle/service/hid/controllers/gesture.h +++ b/src/core/hle/service/hid/controllers/gesture.h @@ -107,8 +107,7 @@ private: bool ShouldUpdateGesture(const GestureProperties& gesture, f32 time_difference); // Updates the shared memory to the next state - void UpdateGestureSharedMemory(u8* data, std::size_t size, GestureProperties& gesture, - f32 time_difference); + void UpdateGestureSharedMemory(GestureProperties& gesture, f32 time_difference); // Initializes new gesture void NewGesture(GestureProperties& gesture, GestureType& type, GestureAttribute& attributes); diff --git a/src/core/hle/service/hid/irs.cpp b/src/core/hle/service/hid/irs.cpp index 9e32f3e60..d2a91d913 100644 --- a/src/core/hle/service/hid/irs.cpp +++ b/src/core/hle/service/hid/irs.cpp @@ -5,7 +5,9 @@ #include "core/core_timing.h" #include "core/hle/ipc_helpers.h" #include "core/hle/kernel/k_shared_memory.h" +#include "core/hle/kernel/k_transfer_memory.h" #include "core/hle/kernel/kernel.h" +#include "core/hle/service/hid/errors.h" #include "core/hle/service/hid/irs.h" namespace Service::HID { @@ -38,21 +40,32 @@ IRS::IRS(Core::System& system_) : ServiceFramework{system_, "irs"} { } void IRS::ActivateIrsensor(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_IRS, "(STUBBED) called"); + IPC::RequestParser rp{ctx}; + const auto applet_resource_user_id{rp.Pop<u64>()}; + + LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}", + applet_resource_user_id); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); } void IRS::DeactivateIrsensor(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_IRS, "(STUBBED) called"); + IPC::RequestParser rp{ctx}; + const auto applet_resource_user_id{rp.Pop<u64>()}; + + LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}", + applet_resource_user_id); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); } void IRS::GetIrsensorSharedMemoryHandle(Kernel::HLERequestContext& ctx) { - LOG_DEBUG(Service_IRS, "called"); + IPC::RequestParser rp{ctx}; + const auto applet_resource_user_id{rp.Pop<u64>()}; + + LOG_DEBUG(Service_IRS, "called, applet_resource_user_id={}", applet_resource_user_id); IPC::ResponseBuilder rb{ctx, 2, 1}; rb.Push(ResultSuccess); @@ -60,35 +73,109 @@ void IRS::GetIrsensorSharedMemoryHandle(Kernel::HLERequestContext& ctx) { } void IRS::StopImageProcessor(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_IRS, "(STUBBED) called"); + IPC::RequestParser rp{ctx}; + struct Parameters { + IrCameraHandle camera_handle; + INSERT_PADDING_WORDS_NOINIT(1); + u64 applet_resource_user_id; + }; + static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); + + const auto parameters{rp.PopRaw<Parameters>()}; + + LOG_WARNING(Service_IRS, + "(STUBBED) called, npad_type={}, npad_id={}, applet_resource_user_id={}", + parameters.camera_handle.npad_type, parameters.camera_handle.npad_id, + parameters.applet_resource_user_id); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); } void IRS::RunMomentProcessor(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_IRS, "(STUBBED) called"); + IPC::RequestParser rp{ctx}; + struct Parameters { + IrCameraHandle camera_handle; + INSERT_PADDING_WORDS_NOINIT(1); + u64 applet_resource_user_id; + PackedMomentProcessorConfig processor_config; + }; + static_assert(sizeof(Parameters) == 0x30, "Parameters has incorrect size."); + + const auto parameters{rp.PopRaw<Parameters>()}; + + LOG_WARNING(Service_IRS, + "(STUBBED) called, npad_type={}, npad_id={}, applet_resource_user_id={}", + parameters.camera_handle.npad_type, parameters.camera_handle.npad_id, + parameters.applet_resource_user_id); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); } void IRS::RunClusteringProcessor(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_IRS, "(STUBBED) called"); + IPC::RequestParser rp{ctx}; + struct Parameters { + IrCameraHandle camera_handle; + INSERT_PADDING_WORDS_NOINIT(1); + u64 applet_resource_user_id; + PackedClusteringProcessorConfig processor_config; + }; + static_assert(sizeof(Parameters) == 0x40, "Parameters has incorrect size."); + + const auto parameters{rp.PopRaw<Parameters>()}; + + LOG_WARNING(Service_IRS, + "(STUBBED) called, npad_type={}, npad_id={}, applet_resource_user_id={}", + parameters.camera_handle.npad_type, parameters.camera_handle.npad_id, + parameters.applet_resource_user_id); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); } void IRS::RunImageTransferProcessor(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_IRS, "(STUBBED) called"); + IPC::RequestParser rp{ctx}; + struct Parameters { + IrCameraHandle camera_handle; + INSERT_PADDING_WORDS_NOINIT(1); + u64 applet_resource_user_id; + PackedImageTransferProcessorConfig processor_config; + u32 transfer_memory_size; + }; + static_assert(sizeof(Parameters) == 0x30, "Parameters has incorrect size."); + + const auto parameters{rp.PopRaw<Parameters>()}; + const auto t_mem_handle{ctx.GetCopyHandle(0)}; + + auto t_mem = + system.CurrentProcess()->GetHandleTable().GetObject<Kernel::KTransferMemory>(t_mem_handle); + + LOG_WARNING(Service_IRS, + "(STUBBED) called, npad_type={}, npad_id={}, transfer_memory_size={}, " + "applet_resource_user_id={}", + parameters.camera_handle.npad_type, parameters.camera_handle.npad_id, + parameters.transfer_memory_size, parameters.applet_resource_user_id); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); } void IRS::GetImageTransferProcessorState(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_IRS, "(STUBBED) called"); + IPC::RequestParser rp{ctx}; + struct Parameters { + IrCameraHandle camera_handle; + INSERT_PADDING_WORDS_NOINIT(1); + u64 applet_resource_user_id; + }; + static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); + + const auto parameters{rp.PopRaw<Parameters>()}; + + LOG_WARNING(Service_IRS, + "(STUBBED) called, npad_type={}, npad_id={}, applet_resource_user_id={}", + parameters.camera_handle.npad_type, parameters.camera_handle.npad_id, + parameters.applet_resource_user_id); IPC::ResponseBuilder rb{ctx, 5}; rb.Push(ResultSuccess); @@ -97,71 +184,195 @@ void IRS::GetImageTransferProcessorState(Kernel::HLERequestContext& ctx) { } void IRS::RunTeraPluginProcessor(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_IRS, "(STUBBED) called"); + IPC::RequestParser rp{ctx}; + const auto camera_handle{rp.PopRaw<IrCameraHandle>()}; + const auto processor_config{rp.PopRaw<PackedTeraPluginProcessorConfig>()}; + const auto applet_resource_user_id{rp.Pop<u64>()}; + + LOG_WARNING(Service_IRS, + "(STUBBED) called, npad_type={}, npad_id={}, mode={}, mcu_version={}.{}, " + "applet_resource_user_id={}", + camera_handle.npad_type, camera_handle.npad_id, processor_config.mode, + processor_config.required_mcu_version.major, + processor_config.required_mcu_version.minor, applet_resource_user_id); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); } void IRS::GetNpadIrCameraHandle(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_IRS, "(STUBBED) called"); + IPC::RequestParser rp{ctx}; + const auto npad_id{rp.PopEnum<Core::HID::NpadIdType>()}; + + if (npad_id > Core::HID::NpadIdType::Player8 && npad_id != Core::HID::NpadIdType::Invalid && + npad_id != Core::HID::NpadIdType::Handheld) { + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(InvalidNpadId); + return; + } + + IrCameraHandle camera_handle{ + .npad_id = static_cast<u8>(NpadIdTypeToIndex(npad_id)), + .npad_type = Core::HID::NpadStyleIndex::None, + }; + + LOG_WARNING(Service_IRS, "(STUBBED) called, npad_id={}, camera_npad_id={}, camera_npad_type={}", + npad_id, camera_handle.npad_id, camera_handle.npad_type); IPC::ResponseBuilder rb{ctx, 3}; rb.Push(ResultSuccess); - rb.PushRaw<u32>(device_handle); + rb.PushRaw(camera_handle); } void IRS::RunPointingProcessor(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_IRS, "(STUBBED) called"); + IPC::RequestParser rp{ctx}; + const auto camera_handle{rp.PopRaw<IrCameraHandle>()}; + const auto processor_config{rp.PopRaw<PackedPointingProcessorConfig>()}; + const auto applet_resource_user_id{rp.Pop<u64>()}; + + LOG_WARNING( + Service_IRS, + "(STUBBED) called, npad_type={}, npad_id={}, mcu_version={}.{}, applet_resource_user_id={}", + camera_handle.npad_type, camera_handle.npad_id, processor_config.required_mcu_version.major, + processor_config.required_mcu_version.minor, applet_resource_user_id); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); } void IRS::SuspendImageProcessor(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_IRS, "(STUBBED) called"); + IPC::RequestParser rp{ctx}; + struct Parameters { + IrCameraHandle camera_handle; + INSERT_PADDING_WORDS_NOINIT(1); + u64 applet_resource_user_id; + }; + static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); + + const auto parameters{rp.PopRaw<Parameters>()}; + + LOG_WARNING(Service_IRS, + "(STUBBED) called, npad_type={}, npad_id={}, applet_resource_user_id={}", + parameters.camera_handle.npad_type, parameters.camera_handle.npad_id, + parameters.applet_resource_user_id); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); } void IRS::CheckFirmwareVersion(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_IRS, "(STUBBED) called"); + IPC::RequestParser rp{ctx}; + const auto camera_handle{rp.PopRaw<IrCameraHandle>()}; + const auto mcu_version{rp.PopRaw<PackedMcuVersion>()}; + const auto applet_resource_user_id{rp.Pop<u64>()}; + + LOG_WARNING( + Service_IRS, + "(STUBBED) called, npad_type={}, npad_id={}, applet_resource_user_id={}, mcu_version={}.{}", + camera_handle.npad_type, camera_handle.npad_id, applet_resource_user_id, mcu_version.major, + mcu_version.minor); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); } void IRS::SetFunctionLevel(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_IRS, "(STUBBED) called"); + IPC::RequestParser rp{ctx}; + struct Parameters { + IrCameraHandle camera_handle; + PackedFunctionLevel function_level; + u64 applet_resource_user_id; + }; + static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); + + const auto parameters{rp.PopRaw<Parameters>()}; + + LOG_WARNING(Service_IRS, + "(STUBBED) called, npad_type={}, npad_id={}, applet_resource_user_id={}", + parameters.camera_handle.npad_type, parameters.camera_handle.npad_id, + parameters.applet_resource_user_id); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); } void IRS::RunImageTransferExProcessor(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_IRS, "(STUBBED) called"); + IPC::RequestParser rp{ctx}; + struct Parameters { + IrCameraHandle camera_handle; + INSERT_PADDING_WORDS_NOINIT(1); + u64 applet_resource_user_id; + PackedImageTransferProcessorExConfig processor_config; + u64 transfer_memory_size; + }; + static_assert(sizeof(Parameters) == 0x38, "Parameters has incorrect size."); + + const auto parameters{rp.PopRaw<Parameters>()}; + const auto t_mem_handle{ctx.GetCopyHandle(0)}; + + auto t_mem = + system.CurrentProcess()->GetHandleTable().GetObject<Kernel::KTransferMemory>(t_mem_handle); + + LOG_WARNING(Service_IRS, + "(STUBBED) called, npad_type={}, npad_id={}, transfer_memory_size={}, " + "applet_resource_user_id={}", + parameters.camera_handle.npad_type, parameters.camera_handle.npad_id, + parameters.transfer_memory_size, parameters.applet_resource_user_id); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); } void IRS::RunIrLedProcessor(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_IRS, "(STUBBED) called"); + IPC::RequestParser rp{ctx}; + const auto camera_handle{rp.PopRaw<IrCameraHandle>()}; + const auto processor_config{rp.PopRaw<PackedIrLedProcessorConfig>()}; + const auto applet_resource_user_id{rp.Pop<u64>()}; + + LOG_WARNING(Service_IRS, + "(STUBBED) called, npad_type={}, npad_id={}, light_target={}, mcu_version={}.{} " + "applet_resource_user_id={}", + camera_handle.npad_type, camera_handle.npad_id, processor_config.light_target, + processor_config.required_mcu_version.major, + processor_config.required_mcu_version.minor, applet_resource_user_id); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); } void IRS::StopImageProcessorAsync(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_IRS, "(STUBBED) called"); + IPC::RequestParser rp{ctx}; + struct Parameters { + IrCameraHandle camera_handle; + INSERT_PADDING_WORDS_NOINIT(1); + u64 applet_resource_user_id; + }; + static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); + + const auto parameters{rp.PopRaw<Parameters>()}; + + LOG_WARNING(Service_IRS, + "(STUBBED) called, npad_type={}, npad_id={}, applet_resource_user_id={}", + parameters.camera_handle.npad_type, parameters.camera_handle.npad_id, + parameters.applet_resource_user_id); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); } void IRS::ActivateIrsensorWithFunctionLevel(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_IRS, "(STUBBED) called"); + IPC::RequestParser rp{ctx}; + struct Parameters { + PackedFunctionLevel function_level; + INSERT_PADDING_WORDS_NOINIT(1); + u64 applet_resource_user_id; + }; + static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); + + const auto parameters{rp.PopRaw<Parameters>()}; + + LOG_WARNING(Service_IRS, "(STUBBED) called, function_level={}, applet_resource_user_id={}", + parameters.function_level.function_level, parameters.applet_resource_user_id); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); diff --git a/src/core/hle/service/hid/irs.h b/src/core/hle/service/hid/irs.h index efb29d3fd..361dc2213 100644 --- a/src/core/hle/service/hid/irs.h +++ b/src/core/hle/service/hid/irs.h @@ -3,6 +3,7 @@ #pragma once +#include "core/hid/hid_types.h" #include "core/hle/service/service.h" namespace Core { @@ -17,6 +18,235 @@ public: ~IRS() override; private: + // This is nn::irsensor::IrCameraStatus + enum IrCameraStatus : u32 { + Available, + Unsupported, + Unconnected, + }; + + // This is nn::irsensor::IrCameraInternalStatus + enum IrCameraInternalStatus : u32 { + Stopped, + FirmwareUpdateNeeded, + Unkown2, + Unkown3, + Unkown4, + FirmwareVersionRequested, + FirmwareVersionIsInvalid, + Ready, + Setting, + }; + + // This is nn::irsensor::detail::StatusManager::IrSensorMode + enum IrSensorMode : u64 { + None, + MomentProcessor, + ClusteringProcessor, + ImageTransferProcessor, + PointingProcessorMarker, + TeraPluginProcessor, + IrLedProcessor, + }; + + // This is nn::irsensor::ImageProcessorStatus + enum ImageProcessorStatus : u8 { + stopped, + running, + }; + + // This is nn::irsensor::ImageTransferProcessorFormat + enum ImageTransferProcessorFormat : u8 { + Size320x240, + Size160x120, + Size80x60, + Size40x30, + Size20x15, + }; + + // This is nn::irsensor::AdaptiveClusteringMode + enum AdaptiveClusteringMode : u8 { + StaticFov, + DynamicFov, + }; + + // This is nn::irsensor::AdaptiveClusteringTargetDistance + enum AdaptiveClusteringTargetDistance : u8 { + Near, + Middle, + Far, + }; + + // This is nn::irsensor::IrsHandAnalysisMode + enum IrsHandAnalysisMode : u8 { + Silhouette, + Image, + SilhoueteAndImage, + SilhuetteOnly, + }; + + // This is nn::irsensor::IrSensorFunctionLevel + enum IrSensorFunctionLevel : u8 { + unknown0, + unknown1, + unknown2, + unknown3, + unknown4, + }; + + // This is nn::irsensor::IrCameraHandle + struct IrCameraHandle { + u8 npad_id{}; + Core::HID::NpadStyleIndex npad_type{Core::HID::NpadStyleIndex::None}; + INSERT_PADDING_BYTES(2); + }; + static_assert(sizeof(IrCameraHandle) == 4, "IrCameraHandle is an invalid size"); + + struct IrsRect { + s16 x; + s16 y; + s16 width; + s16 height; + }; + + // This is nn::irsensor::PackedMcuVersion + struct PackedMcuVersion { + u16 major; + u16 minor; + }; + static_assert(sizeof(PackedMcuVersion) == 4, "PackedMcuVersion is an invalid size"); + + // This is nn::irsensor::MomentProcessorConfig + struct MomentProcessorConfig { + u64 exposire_time; + u8 light_target; + u8 gain; + u8 is_negative_used; + INSERT_PADDING_BYTES(7); + IrsRect window_of_interest; + u8 preprocess; + u8 preprocess_intensity_threshold; + INSERT_PADDING_BYTES(5); + }; + static_assert(sizeof(MomentProcessorConfig) == 0x28, + "MomentProcessorConfig is an invalid size"); + + // This is nn::irsensor::PackedMomentProcessorConfig + struct PackedMomentProcessorConfig { + u64 exposire_time; + u8 light_target; + u8 gain; + u8 is_negative_used; + INSERT_PADDING_BYTES(5); + IrsRect window_of_interest; + PackedMcuVersion required_mcu_version; + u8 preprocess; + u8 preprocess_intensity_threshold; + INSERT_PADDING_BYTES(2); + }; + static_assert(sizeof(PackedMomentProcessorConfig) == 0x20, + "PackedMomentProcessorConfig is an invalid size"); + + // This is nn::irsensor::ClusteringProcessorConfig + struct ClusteringProcessorConfig { + u64 exposire_time; + u32 light_target; + u32 gain; + u8 is_negative_used; + INSERT_PADDING_BYTES(7); + IrsRect window_of_interest; + u32 pixel_count_min; + u32 pixel_count_max; + u32 object_intensity_min; + u8 is_external_light_filter_enabled; + INSERT_PADDING_BYTES(3); + }; + static_assert(sizeof(ClusteringProcessorConfig) == 0x30, + "ClusteringProcessorConfig is an invalid size"); + + // This is nn::irsensor::PackedClusteringProcessorConfig + struct PackedClusteringProcessorConfig { + u64 exposire_time; + u8 light_target; + u8 gain; + u8 is_negative_used; + INSERT_PADDING_BYTES(5); + IrsRect window_of_interest; + PackedMcuVersion required_mcu_version; + u32 pixel_count_min; + u32 pixel_count_max; + u32 object_intensity_min; + u8 is_external_light_filter_enabled; + INSERT_PADDING_BYTES(2); + }; + static_assert(sizeof(PackedClusteringProcessorConfig) == 0x30, + "PackedClusteringProcessorConfig is an invalid size"); + + // This is nn::irsensor::PackedImageTransferProcessorConfig + struct PackedImageTransferProcessorConfig { + u64 exposire_time; + u8 light_target; + u8 gain; + u8 is_negative_used; + INSERT_PADDING_BYTES(5); + PackedMcuVersion required_mcu_version; + u8 format; + INSERT_PADDING_BYTES(3); + }; + static_assert(sizeof(PackedImageTransferProcessorConfig) == 0x18, + "PackedImageTransferProcessorConfig is an invalid size"); + + // This is nn::irsensor::PackedTeraPluginProcessorConfig + struct PackedTeraPluginProcessorConfig { + PackedMcuVersion required_mcu_version; + u8 mode; + INSERT_PADDING_BYTES(3); + }; + static_assert(sizeof(PackedTeraPluginProcessorConfig) == 0x8, + "PackedTeraPluginProcessorConfig is an invalid size"); + + // This is nn::irsensor::PackedPointingProcessorConfig + struct PackedPointingProcessorConfig { + IrsRect window_of_interest; + PackedMcuVersion required_mcu_version; + }; + static_assert(sizeof(PackedPointingProcessorConfig) == 0xC, + "PackedPointingProcessorConfig is an invalid size"); + + // This is nn::irsensor::PackedFunctionLevel + struct PackedFunctionLevel { + IrSensorFunctionLevel function_level; + INSERT_PADDING_BYTES(3); + }; + static_assert(sizeof(PackedFunctionLevel) == 0x4, "PackedFunctionLevel is an invalid size"); + + // This is nn::irsensor::PackedImageTransferProcessorExConfig + struct PackedImageTransferProcessorExConfig { + u64 exposire_time; + u8 light_target; + u8 gain; + u8 is_negative_used; + INSERT_PADDING_BYTES(5); + PackedMcuVersion required_mcu_version; + ImageTransferProcessorFormat origin_format; + ImageTransferProcessorFormat trimming_format; + u16 trimming_start_x; + u16 trimming_start_y; + u8 is_external_light_filter_enabled; + INSERT_PADDING_BYTES(3); + }; + static_assert(sizeof(PackedImageTransferProcessorExConfig) == 0x20, + "PackedImageTransferProcessorExConfig is an invalid size"); + + // This is nn::irsensor::PackedIrLedProcessorConfig + struct PackedIrLedProcessorConfig { + PackedMcuVersion required_mcu_version; + u8 light_target; + INSERT_PADDING_BYTES(3); + }; + static_assert(sizeof(PackedIrLedProcessorConfig) == 0x8, + "PackedIrLedProcessorConfig is an invalid size"); + void ActivateIrsensor(Kernel::HLERequestContext& ctx); void DeactivateIrsensor(Kernel::HLERequestContext& ctx); void GetIrsensorSharedMemoryHandle(Kernel::HLERequestContext& ctx); @@ -35,8 +265,6 @@ private: void RunIrLedProcessor(Kernel::HLERequestContext& ctx); void StopImageProcessorAsync(Kernel::HLERequestContext& ctx); void ActivateIrsensorWithFunctionLevel(Kernel::HLERequestContext& ctx); - - const u32 device_handle{0xABCD}; }; class IRS_SYS final : public ServiceFramework<IRS_SYS> { diff --git a/src/core/hle/service/jit/jit_context.cpp b/src/core/hle/service/jit/jit_context.cpp index 19bd85b6c..4ed3f02e2 100644 --- a/src/core/hle/service/jit/jit_context.cpp +++ b/src/core/hle/service/jit/jit_context.cpp @@ -11,10 +11,13 @@ #include "common/alignment.h" #include "common/common_funcs.h" #include "common/div_ceil.h" +#include "common/elf.h" #include "common/logging/log.h" #include "core/hle/service/jit/jit_context.h" #include "core/memory.h" +using namespace Common::ELF; + namespace Service::JIT { constexpr std::array<u8, 8> SVC0_ARM64 = { @@ -26,25 +29,6 @@ constexpr std::array HELPER_FUNCTIONS{ "_stop", "_resolve", "_panic", "memcpy", "memmove", "memset", }; -struct Elf64_Dyn { - u64 d_tag; - u64 d_un; -}; - -struct Elf64_Rela { - u64 r_offset; - u64 r_info; - s64 r_addend; -}; - -static constexpr u32 Elf64_RelaType(const Elf64_Rela* rela) { - return static_cast<u32>(rela->r_info); -} - -constexpr int DT_RELA = 7; /* Address of Rela relocs */ -constexpr int DT_RELASZ = 8; /* Total size of Rela relocs */ -constexpr int R_AARCH64_RELATIVE = 1027; /* Adjust by program base. */ - constexpr size_t STACK_ALIGN = 16; class JITContextImpl; @@ -206,17 +190,17 @@ public: if (!dyn.d_tag) { break; } - if (dyn.d_tag == DT_RELA) { - rela_dyn = dyn.d_un; + if (dyn.d_tag == ElfDtRela) { + rela_dyn = dyn.d_un.d_ptr; } - if (dyn.d_tag == DT_RELASZ) { - num_rela = dyn.d_un / sizeof(Elf64_Rela); + if (dyn.d_tag == ElfDtRelasz) { + num_rela = dyn.d_un.d_val / sizeof(Elf64_Rela); } } for (size_t i = 0; i < num_rela; i++) { const auto rela{callbacks->ReadMemory<Elf64_Rela>(rela_dyn + i * sizeof(Elf64_Rela))}; - if (Elf64_RelaType(&rela) != R_AARCH64_RELATIVE) { + if (Elf64RelType(rela.r_info) != ElfAArch64Relative) { continue; } const VAddr contents{callbacks->MemoryRead64(rela.r_offset)}; diff --git a/src/core/hle/service/nvflinger/buffer_queue_consumer.cpp b/src/core/hle/service/nvflinger/buffer_queue_consumer.cpp index d7db77aff..4b3d5efd6 100644 --- a/src/core/hle/service/nvflinger/buffer_queue_consumer.cpp +++ b/src/core/hle/service/nvflinger/buffer_queue_consumer.cpp @@ -89,14 +89,6 @@ Status BufferQueueConsumer::AcquireBuffer(BufferItem* out_buffer, LOG_DEBUG(Service_NVFlinger, "acquiring slot={}", slot); - // If the front buffer is still being tracked, update its slot state - if (core->StillTracking(*front)) { - slots[slot].acquire_called = true; - slots[slot].needs_cleanup_on_release = false; - slots[slot].buffer_state = BufferState::Acquired; - slots[slot].fence = Fence::NoFence(); - } - // If the buffer has previously been acquired by the consumer, set graphic_buffer to nullptr to // avoid unnecessarily remapping this buffer on the consumer side. if (out_buffer->acquire_called) { @@ -139,26 +131,11 @@ Status BufferQueueConsumer::ReleaseBuffer(s32 slot, u64 frame_number, const Fenc ++current; } - if (slots[slot].buffer_state == BufferState::Acquired) { - slots[slot].fence = release_fence; - slots[slot].buffer_state = BufferState::Free; - - listener = core->connected_producer_listener; - - LOG_DEBUG(Service_NVFlinger, "releasing slot {}", slot); - } else if (slots[slot].needs_cleanup_on_release) { - LOG_DEBUG(Service_NVFlinger, "releasing a stale buffer slot {} (state = {})", slot, - slots[slot].buffer_state); + slots[slot].buffer_state = BufferState::Free; - slots[slot].needs_cleanup_on_release = false; + listener = core->connected_producer_listener; - return Status::StaleBufferSlot; - } else { - LOG_ERROR(Service_NVFlinger, "attempted to release buffer slot {} but its state was {}", - slot, slots[slot].buffer_state); - - return Status::BadValue; - } + LOG_DEBUG(Service_NVFlinger, "releasing slot {}", slot); core->SignalDequeueCondition(); } diff --git a/src/core/hle/service/nvflinger/buffer_queue_core.cpp b/src/core/hle/service/nvflinger/buffer_queue_core.cpp index d4e8b44d0..ea4a14ea4 100644 --- a/src/core/hle/service/nvflinger/buffer_queue_core.cpp +++ b/src/core/hle/service/nvflinger/buffer_queue_core.cpp @@ -84,10 +84,6 @@ void BufferQueueCore::FreeBufferLocked(s32 slot) { slots[slot].graphic_buffer.reset(); - if (slots[slot].buffer_state == BufferState::Acquired) { - slots[slot].needs_cleanup_on_release = true; - } - slots[slot].buffer_state = BufferState::Free; slots[slot].frame_number = UINT32_MAX; slots[slot].acquire_called = false; diff --git a/src/core/hle/service/nvflinger/buffer_slot.h b/src/core/hle/service/nvflinger/buffer_slot.h index 6b3e87446..0cd0e9964 100644 --- a/src/core/hle/service/nvflinger/buffer_slot.h +++ b/src/core/hle/service/nvflinger/buffer_slot.h @@ -31,7 +31,6 @@ struct BufferSlot final { u64 frame_number{}; Fence fence; bool acquire_called{}; - bool needs_cleanup_on_release{}; bool attached_by_consumer{}; bool is_preallocated{}; }; diff --git a/src/core/loader/elf.cpp b/src/core/loader/elf.cpp index cf5933699..dfb10c34f 100644 --- a/src/core/loader/elf.cpp +++ b/src/core/loader/elf.cpp @@ -6,6 +6,7 @@ #include <memory> #include "common/common_funcs.h" #include "common/common_types.h" +#include "common/elf.h" #include "common/logging/log.h" #include "core/hle/kernel/code_set.h" #include "core/hle/kernel/k_page_table.h" @@ -13,159 +14,7 @@ #include "core/loader/elf.h" #include "core/memory.h" -//////////////////////////////////////////////////////////////////////////////////////////////////// -// ELF Header Constants - -// File type -enum ElfType { - ET_NONE = 0, - ET_REL = 1, - ET_EXEC = 2, - ET_DYN = 3, - ET_CORE = 4, - ET_LOPROC = 0xFF00, - ET_HIPROC = 0xFFFF, -}; - -// Machine/Architecture -enum ElfMachine { - EM_NONE = 0, - EM_M32 = 1, - EM_SPARC = 2, - EM_386 = 3, - EM_68K = 4, - EM_88K = 5, - EM_860 = 7, - EM_MIPS = 8 -}; - -// File version -#define EV_NONE 0 -#define EV_CURRENT 1 - -// Identification index -#define EI_MAG0 0 -#define EI_MAG1 1 -#define EI_MAG2 2 -#define EI_MAG3 3 -#define EI_CLASS 4 -#define EI_DATA 5 -#define EI_VERSION 6 -#define EI_PAD 7 -#define EI_NIDENT 16 - -// Sections constants - -// Section types -#define SHT_NULL 0 -#define SHT_PROGBITS 1 -#define SHT_SYMTAB 2 -#define SHT_STRTAB 3 -#define SHT_RELA 4 -#define SHT_HASH 5 -#define SHT_DYNAMIC 6 -#define SHT_NOTE 7 -#define SHT_NOBITS 8 -#define SHT_REL 9 -#define SHT_SHLIB 10 -#define SHT_DYNSYM 11 -#define SHT_LOPROC 0x70000000 -#define SHT_HIPROC 0x7FFFFFFF -#define SHT_LOUSER 0x80000000 -#define SHT_HIUSER 0xFFFFFFFF - -// Section flags -enum ElfSectionFlags { - SHF_WRITE = 0x1, - SHF_ALLOC = 0x2, - SHF_EXECINSTR = 0x4, - SHF_MASKPROC = 0xF0000000, -}; - -// Segment types -#define PT_NULL 0 -#define PT_LOAD 1 -#define PT_DYNAMIC 2 -#define PT_INTERP 3 -#define PT_NOTE 4 -#define PT_SHLIB 5 -#define PT_PHDR 6 -#define PT_LOPROC 0x70000000 -#define PT_HIPROC 0x7FFFFFFF - -// Segment flags -#define PF_X 0x1 -#define PF_W 0x2 -#define PF_R 0x4 -#define PF_MASKPROC 0xF0000000 - -typedef unsigned int Elf32_Addr; -typedef unsigned short Elf32_Half; -typedef unsigned int Elf32_Off; -typedef signed int Elf32_Sword; -typedef unsigned int Elf32_Word; - -//////////////////////////////////////////////////////////////////////////////////////////////////// -// ELF file header - -struct Elf32_Ehdr { - unsigned char e_ident[EI_NIDENT]; - Elf32_Half e_type; - Elf32_Half e_machine; - Elf32_Word e_version; - Elf32_Addr e_entry; - Elf32_Off e_phoff; - Elf32_Off e_shoff; - Elf32_Word e_flags; - Elf32_Half e_ehsize; - Elf32_Half e_phentsize; - Elf32_Half e_phnum; - Elf32_Half e_shentsize; - Elf32_Half e_shnum; - Elf32_Half e_shstrndx; -}; - -// Section header -struct Elf32_Shdr { - Elf32_Word sh_name; - Elf32_Word sh_type; - Elf32_Word sh_flags; - Elf32_Addr sh_addr; - Elf32_Off sh_offset; - Elf32_Word sh_size; - Elf32_Word sh_link; - Elf32_Word sh_info; - Elf32_Word sh_addralign; - Elf32_Word sh_entsize; -}; - -// Segment header -struct Elf32_Phdr { - Elf32_Word p_type; - Elf32_Off p_offset; - Elf32_Addr p_vaddr; - Elf32_Addr p_paddr; - Elf32_Word p_filesz; - Elf32_Word p_memsz; - Elf32_Word p_flags; - Elf32_Word p_align; -}; - -// Symbol table entry -struct Elf32_Sym { - Elf32_Word st_name; - Elf32_Addr st_value; - Elf32_Word st_size; - unsigned char st_info; - unsigned char st_other; - Elf32_Half st_shndx; -}; - -// Relocation entries -struct Elf32_Rel { - Elf32_Addr r_offset; - Elf32_Word r_info; -}; +using namespace Common::ELF; //////////////////////////////////////////////////////////////////////////////////////////////////// // ElfReader class @@ -193,11 +42,11 @@ public: } // Quick accessors - ElfType GetType() const { - return (ElfType)(header->e_type); + u16 GetType() const { + return header->e_type; } - ElfMachine GetMachine() const { - return (ElfMachine)(header->e_machine); + u16 GetMachine() const { + return header->e_machine; } VAddr GetEntryPoint() const { return entryPoint; @@ -220,13 +69,13 @@ public: const u8* GetSectionDataPtr(int section) const { if (section < 0 || section >= header->e_shnum) return nullptr; - if (sections[section].sh_type != SHT_NOBITS) + if (sections[section].sh_type != ElfShtNobits) return GetPtr(sections[section].sh_offset); else return nullptr; } bool IsCodeSection(int section) const { - return sections[section].sh_type == SHT_PROGBITS; + return sections[section].sh_type == ElfShtProgBits; } const u8* GetSegmentPtr(int segment) { return GetPtr(segments[segment].p_offset); @@ -256,7 +105,7 @@ ElfReader::ElfReader(void* ptr) { } const char* ElfReader::GetSectionName(int section) const { - if (sections[section].sh_type == SHT_NULL) + if (sections[section].sh_type == ElfShtNull) return nullptr; int name_offset = sections[section].sh_name; @@ -272,7 +121,7 @@ Kernel::CodeSet ElfReader::LoadInto(VAddr vaddr) { LOG_DEBUG(Loader, "String section: {}", header->e_shstrndx); // Should we relocate? - relocate = (header->e_type != ET_EXEC); + relocate = (header->e_type != ElfTypeExec); if (relocate) { LOG_DEBUG(Loader, "Relocatable module"); @@ -288,7 +137,7 @@ Kernel::CodeSet ElfReader::LoadInto(VAddr vaddr) { u64 total_image_size = 0; for (unsigned int i = 0; i < header->e_phnum; ++i) { const Elf32_Phdr* p = &segments[i]; - if (p->p_type == PT_LOAD) { + if (p->p_type == ElfPtLoad) { total_image_size += (p->p_memsz + 0xFFF) & ~0xFFF; } } @@ -303,14 +152,14 @@ Kernel::CodeSet ElfReader::LoadInto(VAddr vaddr) { LOG_DEBUG(Loader, "Type: {} Vaddr: {:08X} Filesz: {:08X} Memsz: {:08X} ", p->p_type, p->p_vaddr, p->p_filesz, p->p_memsz); - if (p->p_type == PT_LOAD) { + if (p->p_type == ElfPtLoad) { Kernel::CodeSet::Segment* codeset_segment; - u32 permission_flags = p->p_flags & (PF_R | PF_W | PF_X); - if (permission_flags == (PF_R | PF_X)) { + u32 permission_flags = p->p_flags & (ElfPfRead | ElfPfWrite | ElfPfExec); + if (permission_flags == (ElfPfRead | ElfPfExec)) { codeset_segment = &codeset.CodeSegment(); - } else if (permission_flags == (PF_R)) { + } else if (permission_flags == (ElfPfRead)) { codeset_segment = &codeset.RODataSegment(); - } else if (permission_flags == (PF_R | PF_W)) { + } else if (permission_flags == (ElfPfRead | ElfPfWrite)) { codeset_segment = &codeset.DataSegment(); } else { LOG_ERROR(Loader, "Unexpected ELF PT_LOAD segment id {} with flags {:X}", i, |