From adc41bff70d975038e1cd3ae9873f4281c768b34 Mon Sep 17 00:00:00 2001 From: JPikachu Date: Fri, 12 Dec 2025 04:06:33 +0100 Subject: [PATCH] [bsd, am, fermi] Replace assertions with warnings and update stubs (#3160) - Return error logs instead of asserts for BSD sockets - Warn about source depth != 1 in blits instead of assert in Fermi2D - Update AM 210 - GetLaunchRequiredVersionUpgrade Credit: liberodark. Fixes Marvel Cosmic Invasion loading screen crash. Co-authored-by: JPikachu Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3160 Reviewed-by: crueter Reviewed-by: Caio Oliveira Co-authored-by: JPikachu Co-committed-by: JPikachu --- shell.nix | 2 +- .../am/service/application_functions.cpp | 9 +-- .../am/service/application_functions.h | 2 +- src/core/hle/service/sockets/bsd.cpp | 69 +++++++++++++++---- src/video_core/engines/fermi_2d.cpp | 4 +- 5 files changed, 64 insertions(+), 22 deletions(-) diff --git a/shell.nix b/shell.nix index 3c91286738..403f594852 100644 --- a/shell.nix +++ b/shell.nix @@ -1,5 +1,5 @@ let - nixpkgs = fetchTarball "https://github.com/NixOS/nixpkgs/tarball/nixos-24.05"; + nixpkgs = fetchTarball "https://github.com/NixOS/nixpkgs/tarball/nixos-25.11"; pkgs = import nixpkgs { config = {}; overlays = []; }; in pkgs.mkShellNoCC { diff --git a/src/core/hle/service/am/service/application_functions.cpp b/src/core/hle/service/am/service/application_functions.cpp index e70ed2cccd..49e4cfcd23 100644 --- a/src/core/hle/service/am/service/application_functions.cpp +++ b/src/core/hle/service/am/service/application_functions.cpp @@ -88,7 +88,8 @@ IApplicationFunctions::IApplicationFunctions(Core::System& system_, std::shared_ {181, nullptr, "UpgradeLaunchRequiredVersion"}, {190, nullptr, "SendServerMaintenanceOverlayNotification"}, {200, nullptr, "GetLastApplicationExitReason"}, - {210, D<&IApplicationFunctions::GetUnknownEvent210>, "Unknown210"}, + {210, D<&IApplicationFunctions::GetLaunchRequiredVersionUpgrade>, "GetLaunchRequiredVersionUpgrade"}, // [20.0.0+] + {211, nullptr, "GetLaunchRequiredVersionUpgradeStatus"}, // [20.0.0+] {220, nullptr, "Unknown220"}, // [20.0.0+] {300, nullptr, "Unknown300"}, // [20.0.0+] {310, nullptr, "Unknown310"}, // [20.0.0+] @@ -496,10 +497,10 @@ Result IApplicationFunctions::GetHealthWarningDisappearedSystemEvent( R_SUCCEED(); } -Result IApplicationFunctions::GetUnknownEvent210( +Result IApplicationFunctions::GetLaunchRequiredVersionUpgrade( OutCopyHandle out_event) { - LOG_DEBUG(Service_AM, "called"); - *out_event = m_applet->unknown_event.GetHandle(); + LOG_WARNING(Service_AM, "(STUBBED) called"); + *out_event = m_applet->state_changed_event.GetHandle(); R_SUCCEED(); } diff --git a/src/core/hle/service/am/service/application_functions.h b/src/core/hle/service/am/service/application_functions.h index 35b3e9505d..894684ca64 100644 --- a/src/core/hle/service/am/service/application_functions.h +++ b/src/core/hle/service/am/service/application_functions.h @@ -79,7 +79,7 @@ private: Result TryPopFromFriendInvitationStorageChannel(Out> out_storage); Result GetNotificationStorageChannelEvent(OutCopyHandle out_event); Result GetHealthWarningDisappearedSystemEvent(OutCopyHandle out_event); - Result GetUnknownEvent210(OutCopyHandle out_event); + Result GetLaunchRequiredVersionUpgrade(OutCopyHandle out_event); Result PrepareForJit(); const std::shared_ptr m_applet; diff --git a/src/core/hle/service/sockets/bsd.cpp b/src/core/hle/service/sockets/bsd.cpp index a31bf45238..d6c06bb9b4 100644 --- a/src/core/hle/service/sockets/bsd.cpp +++ b/src/core/hle/service/sockets/bsd.cpp @@ -312,7 +312,7 @@ void BSD::Listen(HLERequestContext& ctx) { void BSD::Fcntl(HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const s32 fd = rp.Pop(); - const s32 cmd = rp.Pop(); + const u32 cmd = rp.Pop(); const s32 arg = rp.Pop(); LOG_DEBUG(Service, "called. fd={} cmd={} arg={}", fd, cmd, arg); @@ -627,23 +627,41 @@ std::pair BSD::AcceptImpl(s32 fd, std::vector& write_buffer) { Errno BSD::BindImpl(s32 fd, std::span addr) { if (!IsFileDescriptorValid(fd)) { + LOG_ERROR(Service, "Bind failed: Invalid fd={}", fd); return Errno::BADF; } ASSERT(addr.size() == sizeof(SockAddrIn)); auto addr_in = GetValue(addr); - return Translate(file_descriptors[fd]->socket->Bind(Translate(addr_in))); + LOG_INFO(Service, "Bind fd={} to {}:{}", fd, Network::IPv4AddressToString(addr_in.ip), + addr_in.portno); + + const auto result = Translate(file_descriptors[fd]->socket->Bind(Translate(addr_in))); + if (result != Errno::SUCCESS) { + LOG_ERROR(Service, "Bind fd={} failed with errno={}", fd, static_cast(result)); + } + return result; } Errno BSD::ConnectImpl(s32 fd, std::span addr) { if (!IsFileDescriptorValid(fd)) { + LOG_ERROR(Service, "Connect failed: Invalid fd={}", fd); return Errno::BADF; } UNIMPLEMENTED_IF(addr.size() != sizeof(SockAddrIn)); auto addr_in = GetValue(addr); - return Translate(file_descriptors[fd]->socket->Connect(Translate(addr_in))); + LOG_INFO(Service, "Connect fd={} to {}:{}", fd, Network::IPv4AddressToString(addr_in.ip), + addr_in.portno); + + const auto result = Translate(file_descriptors[fd]->socket->Connect(Translate(addr_in))); + if (result != Errno::SUCCESS) { + LOG_ERROR(Service, "Connect fd={} failed with errno={}", fd, static_cast(result)); + } else { + LOG_INFO(Service, "Connect fd={} succeeded", fd); + } + return result; } Errno BSD::GetPeerNameImpl(s32 fd, std::vector& write_buffer) { @@ -719,8 +737,8 @@ Errno BSD::GetSockOptImpl(s32 fd, u32 level, OptName optname, std::vector& o } if (level != static_cast(SocketLevel::SOCKET)) { - UNIMPLEMENTED_MSG("Unknown getsockopt level"); - return Errno::SUCCESS; + LOG_WARNING(Service, "(STUBBED) Unknown getsockopt level={}, returning INVAL", level); + return Errno::INVAL; } Network::SocketBase* const socket = file_descriptors[fd]->socket.get(); @@ -750,32 +768,52 @@ Errno BSD::SetSockOptImpl(s32 fd, u32 level, OptName optname, std::span(SocketLevel::SOCKET)) { - UNIMPLEMENTED_MSG("Unknown setsockopt level"); - return Errno::SUCCESS; + LOG_WARNING(Service, "(STUBBED) Unknown setsockopt level={}, returning INVAL", level); + return Errno::INVAL; } Network::SocketBase* const socket = file_descriptors[fd]->socket.get(); if (optname == OptName::LINGER) { - ASSERT(optval.size() == sizeof(Linger)); + if (optval.size() != sizeof(Linger)) { + LOG_WARNING(Service, "LINGER optval size mismatch: expected {}, got {}", sizeof(Linger), + optval.size()); + return Errno::INVAL; + } auto linger = GetValue(optval); - ASSERT(linger.onoff == 0 || linger.onoff == 1); + if (linger.onoff != 0 && linger.onoff != 1) { + LOG_WARNING(Service, "Invalid LINGER onoff value: {}", linger.onoff); + return Errno::INVAL; + } return Translate(socket->SetLinger(linger.onoff != 0, linger.linger)); } - ASSERT(optval.size() == sizeof(u32)); + if (optval.size() != sizeof(u32)) { + LOG_WARNING(Service, "optval size mismatch: expected {}, got {} for optname={}", sizeof(u32), + optval.size(), static_cast(optname)); + return Errno::INVAL; + } auto value = GetValue(optval); switch (optname) { case OptName::REUSEADDR: - ASSERT(value == 0 || value == 1); + if (value != 0 && value != 1) { + LOG_WARNING(Service, "Invalid REUSEADDR value: {}", value); + return Errno::INVAL; + } return Translate(socket->SetReuseAddr(value != 0)); case OptName::KEEPALIVE: - ASSERT(value == 0 || value == 1); + if (value != 0 && value != 1) { + LOG_WARNING(Service, "Invalid KEEPALIVE value: {}", value); + return Errno::INVAL; + } return Translate(socket->SetKeepAlive(value != 0)); case OptName::BROADCAST: - ASSERT(value == 0 || value == 1); + if (value != 0 && value != 1) { + LOG_WARNING(Service, "Invalid BROADCAST value: {}", value); + return Errno::INVAL; + } return Translate(socket->SetBroadcast(value != 0)); case OptName::SNDBUF: return Translate(socket->SetSndBuf(value)); @@ -789,8 +827,9 @@ Errno BSD::SetSockOptImpl(s32 fd, u32 level, OptName optname, std::span(optname), static_cast(optname)); + return Errno::INVAL; } } diff --git a/src/video_core/engines/fermi_2d.cpp b/src/video_core/engines/fermi_2d.cpp index 17fbe9961c..afb5c95da2 100644 --- a/src/video_core/engines/fermi_2d.cpp +++ b/src/video_core/engines/fermi_2d.cpp @@ -66,7 +66,9 @@ void Fermi2D::Blit() { UNIMPLEMENTED_IF_MSG(regs.operation != Operation::SrcCopy, "Operation is not copy"); UNIMPLEMENTED_IF_MSG(regs.src.layer != 0, "Source layer is not zero"); UNIMPLEMENTED_IF_MSG(regs.dst.layer != 0, "Destination layer is not zero"); - UNIMPLEMENTED_IF_MSG(regs.src.depth != 1, "Source depth is not one"); + if (regs.src.depth != 1) { + LOG_DEBUG(HW_GPU, "Source depth is {}, expected 1 - using first layer", regs.src.depth); + } UNIMPLEMENTED_IF_MSG(regs.clip_enable != 0, "Clipped blit enabled"); const auto& args = regs.pixels_from_memory;