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
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to