Merging r284001:
------------------------------------------------------------------------
r284001 | nitesh.jain | 2016-10-12 15:51:09 +0530 (Wed, 12 Oct 2016) | 7 lines

[LLDB][MIPS] Fix qProcessInfo to return correct pointer size based on ELF ABI

Reviewers: clayborg, labath

Subscribers: jaydeep, bhushan, slthakur, lldb-commits

Differential Revision: https://reviews.llvm.org/D25021
------------------------------------------------------------------------


git-svn-id: https://llvm.org/svn/llvm-project/lldb/branches/release_39@287747 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/lldb/Core/ArchSpec.h b/include/lldb/Core/ArchSpec.h
index be76063..b2d5f2d 100644
--- a/include/lldb/Core/ArchSpec.h
+++ b/include/lldb/Core/ArchSpec.h
@@ -382,6 +382,14 @@
         return m_core >= eCore_arm_generic && m_core < kNumCores;
     }
 
+    //------------------------------------------------------------------
+    /// Return a string representing target application ABI.
+    ///
+    /// @return A string representing target application ABI.
+    //------------------------------------------------------------------
+    std::string GetTargetABI() const;
+
+
     bool
     TripleVendorWasSpecified() const
     {
@@ -677,6 +685,8 @@
         m_flags = flags;
     }
 
+  void SetFlags(std::string elf_abi);
+
 protected:
     bool
     IsEqualTo (const ArchSpec& rhs, bool exact_match) const;
diff --git a/source/Core/ArchSpec.cpp b/source/Core/ArchSpec.cpp
index 24aba81..efdbf11 100644
--- a/source/Core/ArchSpec.cpp
+++ b/source/Core/ArchSpec.cpp
@@ -519,11 +519,46 @@
     return false;
 }
 
-std::string
-ArchSpec::GetClangTargetCPU ()
-{
-    std::string cpu;
-    const llvm::Triple::ArchType machine = GetMachine();
+
+std::string ArchSpec::GetTargetABI() const {
+
+  std::string abi;
+
+  if (IsMIPS()) {
+    switch (GetFlags() & ArchSpec::eMIPSABI_mask) {
+    case ArchSpec::eMIPSABI_N64:
+      abi = "n64";
+      return abi;
+    case ArchSpec::eMIPSABI_N32:
+      abi = "n32";
+      return abi;
+    case ArchSpec::eMIPSABI_O32:
+      abi = "o32";
+      return abi;
+    default:
+      return abi;
+    }
+  }
+  return abi;
+}
+
+void ArchSpec::SetFlags(std::string elf_abi) {
+
+  uint32_t flag = GetFlags();
+  if (IsMIPS()) {
+    if (elf_abi == "n64")
+      flag |= ArchSpec::eMIPSABI_N64;
+    else if (elf_abi == "n32")
+      flag |= ArchSpec::eMIPSABI_N32;
+    else if (elf_abi == "o32")
+      flag |= ArchSpec::eMIPSABI_O32;
+  }
+  SetFlags(flag);
+}
+
+std::string ArchSpec::GetClangTargetCPU() {
+  std::string cpu;
+  const llvm::Triple::ArchType machine = GetMachine();
 
     if (machine == llvm::Triple::mips ||
         machine == llvm::Triple::mipsel ||
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
index c90706a..a792bbb 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -2856,6 +2856,7 @@
             std::string os_name;
             std::string vendor_name;
             std::string triple;
+            std::string elf_abi;
             uint32_t pointer_byte_size = 0;
             StringExtractor extractor;
             ByteOrder byte_order = eByteOrderInvalid;
@@ -2917,6 +2918,11 @@
                     if (pid != LLDB_INVALID_PROCESS_ID)
                         ++num_keys_decoded;
                 }
+                else if (name.compare("elf_abi") == 0)
+                {
+                    elf_abi = value;
+                    ++num_keys_decoded;
+                }
             }
             if (num_keys_decoded > 0)
                 m_qProcessInfo_is_valid = eLazyBoolYes;
@@ -2930,6 +2936,7 @@
             if (!triple.empty ())
             {
                 m_process_arch.SetTriple (triple.c_str ());
+                m_process_arch.SetFlags(elf_abi);
                 if (pointer_byte_size)
                 {
                     assert (pointer_byte_size == m_process_arch.GetAddressByteSize());
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
index 7f876fb..26a2e69 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
@@ -1235,12 +1235,12 @@
                 break;
         }
 
-        if (proc_triple.isArch64Bit ())
-            response.PutCString ("ptrsize:8;");
-        else if (proc_triple.isArch32Bit ())
-            response.PutCString ("ptrsize:4;");
-        else if (proc_triple.isArch16Bit ())
-            response.PutCString ("ptrsize:2;");
+        // In case of MIPS64, pointer size is depend on ELF ABI
+        // For N32 the pointer size is 4 and for N64 it is 8
+        std::string abi = proc_arch.GetTargetABI();
+        if (!abi.empty())
+            response.Printf("elf_abi:%s;", abi.c_str());
+        response.Printf("ptrsize:%d;", proc_arch.GetAddressByteSize());
     }
 }