mgorny created this revision.
mgorny added reviewers: krytarowski, emaste, JDevlieghere, labath, jasonmolenda.
mgorny requested review of this revision.
GDB uses normalized errno values for vFile errors. Implement
the translation between them and system errno values in the gdb-remote
plugin.
https://reviews.llvm.org/D108148
Files:
lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
lldb/test/API/functionalities/gdb_remote_client/TestGDBRemotePlatformFile.py
Index: lldb/test/API/functionalities/gdb_remote_client/TestGDBRemotePlatformFile.py
===================================================================
--- lldb/test/API/functionalities/gdb_remote_client/TestGDBRemotePlatformFile.py
+++ lldb/test/API/functionalities/gdb_remote_client/TestGDBRemotePlatformFile.py
@@ -15,7 +15,7 @@
return "Fa"
elif packet.startswith("vFile:close:"):
return "F0"
- return "F-1,16"
+ return "F-1,58"
self.server.responder = Responder()
@@ -47,7 +47,9 @@
class Responder(MockGDBServerResponder):
def vFile(self, packet):
- return "F-1,16"
+ # use ENOSYS as this constant differs between GDB Remote
+ # Protocol and Linux, so we can test the translation
+ return "F-1,58"
self.server.responder = Responder()
@@ -58,16 +60,16 @@
self.assertTrue(self.dbg.GetSelectedPlatform().IsConnected())
self.match("platform file open /some/file.txt -v 0755",
- [r"error: Invalid argument"],
+ [r"error: Function not implemented"],
error=True)
self.match("platform file read 16 -o 11 -c 13",
- [r"error: Invalid argument"],
+ [r"error: Function not implemented"],
error=True)
self.match("platform file write 16 -o 11 -d teststring",
- [r"error: Invalid argument"],
+ [r"error: Function not implemented"],
error=True)
self.match("platform file close 16",
- [r"error: Invalid argument"],
+ [r"error: Function not implemented"],
error=True)
self.assertPacketLogContains([
"vFile:open:2f736f6d652f66696c652e747874,00000202,000001ed",
Index: lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
===================================================================
--- lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
+++ lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
@@ -535,6 +535,55 @@
return SendErrorResponse(18);
}
+static GDBErrno system_errno_to_gdb(int err) {
+ switch (err) {
+ case EPERM:
+ return GDB_EPERM;
+ case ENOENT:
+ return GDB_ENOENT;
+ case EINTR:
+ return GDB_EINTR;
+ case EIO:
+ return GDB_EIO;
+ case EBADF:
+ return GDB_EBADF;
+ case EACCES:
+ return GDB_EACCES;
+ case EFAULT:
+ return GDB_EFAULT;
+ case EBUSY:
+ return GDB_EBUSY;
+ case EEXIST:
+ return GDB_EEXIST;
+ case ENODEV:
+ return GDB_ENODEV;
+ case ENOTDIR:
+ return GDB_ENOTDIR;
+ case EISDIR:
+ return GDB_EISDIR;
+ case EINVAL:
+ return GDB_EINVAL;
+ case ENFILE:
+ return GDB_ENFILE;
+ case EMFILE:
+ return GDB_EMFILE;
+ case EFBIG:
+ return GDB_EFBIG;
+ case ENOSPC:
+ return GDB_ENOSPC;
+ case ESPIPE:
+ return GDB_ESPIPE;
+ case EROFS:
+ return GDB_EROFS;
+ case ENOSYS:
+ return GDB_ENOSYS;
+ case ENAMETOOLONG:
+ return GDB_ENAMETOOLONG;
+ default:
+ return GDB_EUNKNOWN;
+ }
+}
+
GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerCommon::Handle_vFile_Close(
StringExtractorGDBRemote &packet) {
@@ -554,7 +603,7 @@
response.PutChar('F');
response.Printf("%x", err);
if (save_errno)
- response.Printf(",%x", save_errno);
+ response.Printf(",%x", system_errno_to_gdb(save_errno));
return SendPacketNoLock(response.GetString());
}
@@ -585,7 +634,7 @@
} else {
response.PutCString("-1");
if (save_errno)
- response.Printf(",%x", save_errno);
+ response.Printf(",%x", system_errno_to_gdb(save_errno));
}
return SendPacketNoLock(response.GetString());
}
@@ -617,7 +666,7 @@
else {
response.PutCString("-1");
if (save_errno)
- response.Printf(",%x", save_errno);
+ response.Printf(",%x", system_errno_to_gdb(save_errno));
}
} else {
response.Printf("-1,%x", EINVAL);
@@ -769,7 +818,7 @@
struct stat file_stats;
if (::fstat(fd, &file_stats) == -1) {
const int save_errno = errno;
- response.Printf("F-1,%x", save_errno);
+ response.Printf("F-1,%x", system_errno_to_gdb(save_errno));
return SendPacketNoLock(response.GetString());
}
Index: lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
===================================================================
--- lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -3046,6 +3046,55 @@
return Status(response.GetHexMaxU32(false, UINT32_MAX), eErrorTypePOSIX);
}
+static int gdb_errno_to_system(int err) {
+ switch (err) {
+ case GDB_EPERM:
+ return EPERM;
+ case GDB_ENOENT:
+ return ENOENT;
+ case GDB_EINTR:
+ return EINTR;
+ case GDB_EIO:
+ return EIO;
+ case GDB_EBADF:
+ return EBADF;
+ case GDB_EACCES:
+ return EACCES;
+ case GDB_EFAULT:
+ return EFAULT;
+ case GDB_EBUSY:
+ return EBUSY;
+ case GDB_EEXIST:
+ return EEXIST;
+ case GDB_ENODEV:
+ return ENODEV;
+ case GDB_ENOTDIR:
+ return ENOTDIR;
+ case GDB_EISDIR:
+ return EISDIR;
+ case GDB_EINVAL:
+ return EINVAL;
+ case GDB_ENFILE:
+ return ENFILE;
+ case GDB_EMFILE:
+ return EMFILE;
+ case GDB_EFBIG:
+ return EFBIG;
+ case GDB_ENOSPC:
+ return ENOSPC;
+ case GDB_ESPIPE:
+ return ESPIPE;
+ case GDB_EROFS:
+ return EROFS;
+ case GDB_ENOSYS:
+ return ENOSYS;
+ case GDB_ENAMETOOLONG:
+ return ENAMETOOLONG;
+ default:
+ return -1;
+ }
+}
+
static uint64_t ParseHostIOPacketResponse(StringExtractorGDBRemote &response,
uint64_t fail_result, Status &error) {
response.SetFilePos(0);
@@ -3055,8 +3104,8 @@
if (result == -2)
return fail_result;
if (response.GetChar() == ',') {
- int result_errno = response.GetS32(-2, 16);
- if (result_errno != -2)
+ int result_errno = gdb_errno_to_system(response.GetS32(-1, 16));
+ if (result_errno != -1)
error.SetError(result_errno, eErrorTypePOSIX);
else
error.SetError(-1, eErrorTypeGeneric);
@@ -3225,7 +3274,7 @@
const uint32_t mode = response.GetS32(-1, 16);
if (static_cast<int32_t>(mode) == -1) {
if (response.GetChar() == ',') {
- int response_errno = response.GetS32(-1, 16);
+ int response_errno = gdb_errno_to_system(response.GetS32(-1, 16));
if (response_errno > 0)
error.SetError(response_errno, lldb::eErrorTypePOSIX);
else
@@ -3267,7 +3316,7 @@
if (retcode == -1) {
error.SetErrorToGenericError();
if (response.GetChar() == ',') {
- int response_errno = response.GetS32(-1, 16);
+ int response_errno = gdb_errno_to_system(response.GetS32(-1, 16));
if (response_errno > 0)
error.SetError(response_errno, lldb::eErrorTypePOSIX);
}
@@ -3310,7 +3359,7 @@
if (bytes_written == -1) {
error.SetErrorToGenericError();
if (response.GetChar() == ',') {
- int response_errno = response.GetS32(-1, 16);
+ int response_errno = gdb_errno_to_system(response.GetS32(-1, 16));
if (response_errno > 0)
error.SetError(response_errno, lldb::eErrorTypePOSIX);
}
@@ -3342,7 +3391,7 @@
if (result != 0) {
error.SetErrorToGenericError();
if (response.GetChar() == ',') {
- int response_errno = response.GetS32(-1, 16);
+ int response_errno = gdb_errno_to_system(response.GetS32(-1, 16));
if (response_errno > 0)
error.SetError(response_errno, lldb::eErrorTypePOSIX);
}
@@ -3373,7 +3422,7 @@
if (result != 0) {
error.SetErrorToGenericError();
if (response.GetChar() == ',') {
- int response_errno = response.GetS32(-1, 16);
+ int response_errno = gdb_errno_to_system(response.GetS32(-1, 16));
if (response_errno > 0)
error.SetError(response_errno, lldb::eErrorTypePOSIX);
}
Index: lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
===================================================================
--- lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
+++ lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
@@ -69,6 +69,32 @@
uint32_t gdb_st_ctime;
};
+// from gdb's include/gdb/fileio.h
+enum GDBErrno {
+ GDB_EPERM = 1,
+ GDB_ENOENT = 2,
+ GDB_EINTR = 4,
+ GDB_EIO = 5,
+ GDB_EBADF = 9,
+ GDB_EACCES = 13,
+ GDB_EFAULT = 14,
+ GDB_EBUSY = 16,
+ GDB_EEXIST = 17,
+ GDB_ENODEV = 19,
+ GDB_ENOTDIR = 20,
+ GDB_EISDIR = 21,
+ GDB_EINVAL = 22,
+ GDB_ENFILE = 23,
+ GDB_EMFILE = 24,
+ GDB_EFBIG = 27,
+ GDB_ENOSPC = 28,
+ GDB_ESPIPE = 29,
+ GDB_EROFS = 30,
+ GDB_ENOSYS = 88,
+ GDB_ENAMETOOLONG = 91,
+ GDB_EUNKNOWN = 9999
+};
+
class ProcessGDBRemote;
class GDBRemoteCommunication : public Communication {
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits