diff options
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/debugger/gdbstub.cpp | 17 | ||||
-rw-r--r-- | src/core/hle/service/sockets/sockets.h | 2 | ||||
-rw-r--r-- | src/core/hle/service/sockets/sockets_translate.cpp | 4 | ||||
-rw-r--r-- | src/core/internal_network/network.cpp | 43 | ||||
-rw-r--r-- | src/core/internal_network/network.h | 2 | ||||
-rw-r--r-- | src/core/internal_network/network_interface.cpp | 9 |
6 files changed, 68 insertions, 9 deletions
diff --git a/src/core/debugger/gdbstub.cpp b/src/core/debugger/gdbstub.cpp index 0f839d5b4..e55831f27 100644 --- a/src/core/debugger/gdbstub.cpp +++ b/src/core/debugger/gdbstub.cpp @@ -263,6 +263,23 @@ void GDBStub::ExecuteCommand(std::string_view packet, std::vector<DebuggerAction std::vector<u8> mem(size); if (system.ApplicationMemory().ReadBlock(addr, mem.data(), size)) { + // Restore any bytes belonging to replaced instructions. + auto it = replaced_instructions.lower_bound(addr); + for (; it != replaced_instructions.end() && it->first < addr + size; it++) { + // Get the bytes of the instruction we previously replaced. + const u32 original_bytes = it->second; + + // Calculate where to start writing to the output buffer. + const size_t output_offset = it->first - addr; + + // Calculate how many bytes to write. + // The loop condition ensures output_offset < size. + const size_t n = std::min<size_t>(size - output_offset, sizeof(u32)); + + // Write the bytes to the output buffer. + std::memcpy(mem.data() + output_offset, &original_bytes, n); + } + SendReply(Common::HexToString(mem)); } else { SendReply(GDB_STUB_REPLY_ERR); diff --git a/src/core/hle/service/sockets/sockets.h b/src/core/hle/service/sockets/sockets.h index 77426c46e..f86af01a4 100644 --- a/src/core/hle/service/sockets/sockets.h +++ b/src/core/hle/service/sockets/sockets.h @@ -18,7 +18,9 @@ enum class Errno : u32 { AGAIN = 11, INVAL = 22, MFILE = 24, + PIPE = 32, MSGSIZE = 90, + CONNABORTED = 103, CONNRESET = 104, NOTCONN = 107, TIMEDOUT = 110, diff --git a/src/core/hle/service/sockets/sockets_translate.cpp b/src/core/hle/service/sockets/sockets_translate.cpp index c1187209f..aed05250c 100644 --- a/src/core/hle/service/sockets/sockets_translate.cpp +++ b/src/core/hle/service/sockets/sockets_translate.cpp @@ -23,10 +23,14 @@ Errno Translate(Network::Errno value) { return Errno::INVAL; case Network::Errno::MFILE: return Errno::MFILE; + case Network::Errno::PIPE: + return Errno::PIPE; case Network::Errno::NOTCONN: return Errno::NOTCONN; case Network::Errno::TIMEDOUT: return Errno::TIMEDOUT; + case Network::Errno::CONNABORTED: + return Errno::CONNABORTED; case Network::Errno::CONNRESET: return Errno::CONNRESET; case Network::Errno::INPROGRESS: diff --git a/src/core/internal_network/network.cpp b/src/core/internal_network/network.cpp index 28f89c599..5d28300e6 100644 --- a/src/core/internal_network/network.cpp +++ b/src/core/internal_network/network.cpp @@ -39,6 +39,11 @@ namespace Network { namespace { +enum class CallType { + Send, + Other, +}; + #ifdef _WIN32 using socklen_t = int; @@ -96,7 +101,7 @@ bool EnableNonBlock(SOCKET fd, bool enable) { return ioctlsocket(fd, FIONBIO, &value) != SOCKET_ERROR; } -Errno TranslateNativeError(int e) { +Errno TranslateNativeError(int e, CallType call_type = CallType::Other) { switch (e) { case 0: return Errno::SUCCESS; @@ -112,6 +117,14 @@ Errno TranslateNativeError(int e) { return Errno::AGAIN; case WSAECONNREFUSED: return Errno::CONNREFUSED; + case WSAECONNABORTED: + if (call_type == CallType::Send) { + // Winsock yields WSAECONNABORTED from `send` in situations where Unix + // systems, and actual Switches, yield EPIPE. + return Errno::PIPE; + } else { + return Errno::CONNABORTED; + } case WSAECONNRESET: return Errno::CONNRESET; case WSAEHOSTUNREACH: @@ -198,7 +211,7 @@ bool EnableNonBlock(int fd, bool enable) { return fcntl(fd, F_SETFL, flags) == 0; } -Errno TranslateNativeError(int e) { +Errno TranslateNativeError(int e, CallType call_type = CallType::Other) { switch (e) { case 0: return Errno::SUCCESS; @@ -208,6 +221,10 @@ Errno TranslateNativeError(int e) { return Errno::INVAL; case EMFILE: return Errno::MFILE; + case EPIPE: + return Errno::PIPE; + case ECONNABORTED: + return Errno::CONNABORTED; case ENOTCONN: return Errno::NOTCONN; case EAGAIN: @@ -236,13 +253,13 @@ Errno TranslateNativeError(int e) { #endif -Errno GetAndLogLastError() { +Errno GetAndLogLastError(CallType call_type = CallType::Other) { #ifdef _WIN32 int e = WSAGetLastError(); #else int e = errno; #endif - const Errno err = TranslateNativeError(e); + const Errno err = TranslateNativeError(e, call_type); if (err == Errno::AGAIN || err == Errno::TIMEDOUT || err == Errno::INPROGRESS) { // These happen during normal operation, so only log them at debug level. LOG_DEBUG(Network, "Socket operation error: {}", Common::NativeErrorToString(e)); @@ -476,7 +493,13 @@ NetworkInstance::~NetworkInstance() { std::optional<IPv4Address> GetHostIPv4Address() { const auto network_interface = Network::GetSelectedNetworkInterface(); if (!network_interface.has_value()) { - LOG_DEBUG(Network, "GetSelectedNetworkInterface returned no interface"); + // Only print the error once to avoid log spam + static bool print_error = true; + if (print_error) { + LOG_ERROR(Network, "GetSelectedNetworkInterface returned no interface"); + print_error = false; + } + return {}; } @@ -725,13 +748,17 @@ std::pair<s32, Errno> Socket::Send(std::span<const u8> message, int flags) { ASSERT(message.size() < static_cast<size_t>(std::numeric_limits<int>::max())); ASSERT(flags == 0); + int native_flags = 0; +#if YUZU_UNIX + native_flags |= MSG_NOSIGNAL; // do not send us SIGPIPE +#endif const auto result = send(fd, reinterpret_cast<const char*>(message.data()), - static_cast<int>(message.size()), 0); + static_cast<int>(message.size()), native_flags); if (result != SOCKET_ERROR) { return {static_cast<s32>(result), Errno::SUCCESS}; } - return {-1, GetAndLogLastError()}; + return {-1, GetAndLogLastError(CallType::Send)}; } std::pair<s32, Errno> Socket::SendTo(u32 flags, std::span<const u8> message, @@ -753,7 +780,7 @@ std::pair<s32, Errno> Socket::SendTo(u32 flags, std::span<const u8> message, return {static_cast<s32>(result), Errno::SUCCESS}; } - return {-1, GetAndLogLastError()}; + return {-1, GetAndLogLastError(CallType::Send)}; } Errno Socket::Close() { diff --git a/src/core/internal_network/network.h b/src/core/internal_network/network.h index badcb8369..c7e20ae34 100644 --- a/src/core/internal_network/network.h +++ b/src/core/internal_network/network.h @@ -33,10 +33,12 @@ enum class Errno { BADF, INVAL, MFILE, + PIPE, NOTCONN, AGAIN, CONNREFUSED, CONNRESET, + CONNABORTED, HOSTUNREACH, NETDOWN, NETUNREACH, diff --git a/src/core/internal_network/network_interface.cpp b/src/core/internal_network/network_interface.cpp index 4c909a6d3..7c37f660b 100644 --- a/src/core/internal_network/network_interface.cpp +++ b/src/core/internal_network/network_interface.cpp @@ -200,7 +200,14 @@ std::optional<NetworkInterface> GetSelectedNetworkInterface() { }); if (res == network_interfaces.end()) { - LOG_DEBUG(Network, "Couldn't find selected interface \"{}\"", selected_network_interface); + // Only print the error once to avoid log spam + static bool print_error = true; + if (print_error) { + LOG_ERROR(Network, "Couldn't find selected interface \"{}\"", + selected_network_interface); + print_error = false; + } + return std::nullopt; } |