dvlahovski updated this revision to Diff 77626.
dvlahovski marked an inline comment as done.
dvlahovski added a comment.

Use unique_ptr instead of shared_ptr


https://reviews.llvm.org/D26300

Files:
  
packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/TestLinuxCore.py
  
packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/fpr_sse.cpp
  
packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/linux-fpr_sse_i386.core
  
packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/linux-fpr_sse_x86_64.core
  source/Plugins/Process/Utility/RegisterContextLinux_i386.cpp
  source/Plugins/Process/Utility/RegisterContextLinux_i386.h
  source/Plugins/Process/Utility/RegisterContextLinux_x86_64.cpp
  source/Plugins/Process/Utility/RegisterContextLinux_x86_64.h
  source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp
  source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h
  source/Plugins/Process/Utility/RegisterInfoInterface.h
  source/Plugins/Process/elf-core/ProcessElfCore.cpp
  source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp
  source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.h

Index: source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.h
===================================================================
--- source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.h
+++ source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.h
@@ -24,8 +24,6 @@
       const lldb_private::DataExtractor &gpregset,
       const lldb_private::DataExtractor &fpregset);
 
-  ~RegisterContextCorePOSIX_x86_64() override;
-
   bool ReadRegister(const lldb_private::RegisterInfo *reg_info,
                     lldb_private::RegisterValue &value) override;
 
@@ -48,7 +46,8 @@
   bool WriteFPR() override;
 
 private:
-  uint8_t *m_gpregset;
+  std::unique_ptr<uint8_t[]> m_gpregset;
+  std::unique_ptr<uint8_t[]> m_fpregset;
 };
 
 #endif // liblldb_RegisterContextCorePOSIX_x86_64_h_
Index: source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp
===================================================================
--- source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp
+++ source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp
@@ -21,18 +21,27 @@
   size_t size, len;
 
   size = GetGPRSize();
-  m_gpregset = new uint8_t[size];
-  len = gpregset.ExtractBytes(0, size, lldb::eByteOrderLittle, m_gpregset);
-  assert(len == size);
-}
+  m_gpregset.reset(new uint8_t[size]);
+  len =
+      gpregset.ExtractBytes(0, size, lldb::eByteOrderLittle, m_gpregset.get());
+  if (len != size)
+    m_gpregset.reset();
 
-RegisterContextCorePOSIX_x86_64::~RegisterContextCorePOSIX_x86_64() {
-  delete[] m_gpregset;
+  size = sizeof(FXSAVE);
+  m_fpregset.reset(new uint8_t[size]);
+  len =
+      fpregset.ExtractBytes(0, size, lldb::eByteOrderLittle, m_fpregset.get());
+  if (len != size)
+    m_fpregset.reset();
 }
 
-bool RegisterContextCorePOSIX_x86_64::ReadGPR() { return m_gpregset != NULL; }
+bool RegisterContextCorePOSIX_x86_64::ReadGPR() {
+  return m_gpregset != nullptr;
+}
 
-bool RegisterContextCorePOSIX_x86_64::ReadFPR() { return false; }
+bool RegisterContextCorePOSIX_x86_64::ReadFPR() {
+  return m_fpregset != nullptr;
+}
 
 bool RegisterContextCorePOSIX_x86_64::WriteGPR() {
   assert(0);
@@ -46,15 +55,27 @@
 
 bool RegisterContextCorePOSIX_x86_64::ReadRegister(const RegisterInfo *reg_info,
                                                    RegisterValue &value) {
-  switch (reg_info->byte_size) {
-  case 4:
-    value = *(uint32_t *)(m_gpregset + reg_info->byte_offset);
-    return true;
-  case 8:
-    value = *(uint64_t *)(m_gpregset + reg_info->byte_offset);
-    return true;
+  const uint8_t *src;
+  size_t offset;
+  const size_t fxsave_offset = reg_info->byte_offset - GetFXSAVEOffset();
+  // make the offset relative to the beginning of the FXSAVE structure
+  // because this is the data that we have (not the entire UserArea)
+
+  if (m_gpregset && reg_info->byte_offset < GetGPRSize()) {
+    src = m_gpregset.get();
+    offset = reg_info->byte_offset;
+  } else if (m_fpregset && fxsave_offset < sizeof(FXSAVE)) {
+    src = m_fpregset.get();
+    offset = fxsave_offset;
+  } else {
+    return false;
   }
-  return false;
+
+  Error error;
+  value.SetFromMemoryData(reg_info, src + offset, reg_info->byte_size,
+                          lldb::eByteOrderLittle, error);
+
+  return error.Success();
 }
 
 bool RegisterContextCorePOSIX_x86_64::ReadAllRegisterValues(
Index: source/Plugins/Process/elf-core/ProcessElfCore.cpp
===================================================================
--- source/Plugins/Process/elf-core/ProcessElfCore.cpp
+++ source/Plugins/Process/elf-core/ProcessElfCore.cpp
@@ -400,7 +400,8 @@
   NT_TASKSTRUCT,
   NT_PLATFORM,
   NT_AUXV,
-  NT_FILE = 0x46494c45
+  NT_FILE = 0x46494c45,
+  NT_PRXFPREG = 0x46e62b7f,
 };
 
 namespace FREEBSD {
@@ -552,7 +553,11 @@
         thread_data->gpregset = DataExtractor(note_data, header_size, len);
         break;
       case NT_FPREGSET:
-        thread_data->fpregset = note_data;
+        // In a i386 core file NT_FPREGSET is present, but it's not the result
+        // of the FXSAVE instruction like in 64 bit files.
+        // The result from FXSAVE is in NT_PRXFPREG for i386 core files
+        if (arch.GetCore() == ArchSpec::eCore_x86_64_x86_64)
+          thread_data->fpregset = note_data;
         break;
       case NT_PRPSINFO:
         have_prpsinfo = true;
@@ -586,6 +591,11 @@
       default:
         break;
       }
+    } else if (note.n_name == "LINUX") {
+      switch (note.n_type) {
+      case NT_PRXFPREG:
+        thread_data->fpregset = note_data;
+      }
     }
 
     offset += note_size;
Index: source/Plugins/Process/Utility/RegisterInfoInterface.h
===================================================================
--- source/Plugins/Process/Utility/RegisterInfoInterface.h
+++ source/Plugins/Process/Utility/RegisterInfoInterface.h
@@ -29,6 +29,8 @@
 
   virtual size_t GetGPRSize() const = 0;
 
+  virtual size_t GetFXSAVEOffset() const { return 0; }
+
   virtual const lldb_private::RegisterInfo *GetRegisterInfo() const = 0;
 
   // Returns the number of registers including the user registers and the
Index: source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h
===================================================================
--- source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h
+++ source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h
@@ -38,6 +38,8 @@
 
   virtual size_t GetGPRSize();
 
+  virtual size_t GetFXSAVEOffset();
+
   virtual unsigned GetRegisterSize(unsigned reg);
 
   virtual unsigned GetRegisterOffset(unsigned reg);
Index: source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp
===================================================================
--- source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp
+++ source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp
@@ -419,6 +419,10 @@
   return m_register_info_ap->GetGPRSize();
 }
 
+size_t RegisterContextPOSIX_x86::GetFXSAVEOffset() {
+  return m_register_info_ap->GetFXSAVEOffset();
+}
+
 const RegisterInfo *RegisterContextPOSIX_x86::GetRegisterInfo() {
   // Commonly, this method is overridden and g_register_infos is copied and
   // specialized.
Index: source/Plugins/Process/Utility/RegisterContextLinux_x86_64.h
===================================================================
--- source/Plugins/Process/Utility/RegisterContextLinux_x86_64.h
+++ source/Plugins/Process/Utility/RegisterContextLinux_x86_64.h
@@ -18,6 +18,8 @@
 
   size_t GetGPRSize() const override;
 
+  size_t GetFXSAVEOffset() const override;
+
   const lldb_private::RegisterInfo *GetRegisterInfo() const override;
 
   uint32_t GetRegisterCount() const override;
Index: source/Plugins/Process/Utility/RegisterContextLinux_x86_64.cpp
===================================================================
--- source/Plugins/Process/Utility/RegisterContextLinux_x86_64.cpp
+++ source/Plugins/Process/Utility/RegisterContextLinux_x86_64.cpp
@@ -179,6 +179,11 @@
 
 size_t RegisterContextLinux_x86_64::GetGPRSize() const { return sizeof(GPR); }
 
+size_t RegisterContextLinux_x86_64::GetFXSAVEOffset() const {
+  return (LLVM_EXTENSION offsetof(UserArea, fpr) +
+          LLVM_EXTENSION offsetof(FPR, xstate));
+}
+
 const std::vector<lldb_private::RegisterInfo> *
 RegisterContextLinux_x86_64::GetDynamicRegisterInfoP() const {
   return &d_register_infos;
Index: source/Plugins/Process/Utility/RegisterContextLinux_i386.h
===================================================================
--- source/Plugins/Process/Utility/RegisterContextLinux_i386.h
+++ source/Plugins/Process/Utility/RegisterContextLinux_i386.h
@@ -18,6 +18,8 @@
 
   size_t GetGPRSize() const override;
 
+  size_t GetFXSAVEOffset() const override;
+
   const lldb_private::RegisterInfo *GetRegisterInfo() const override;
 
   uint32_t GetRegisterCount() const override;
Index: source/Plugins/Process/Utility/RegisterContextLinux_i386.cpp
===================================================================
--- source/Plugins/Process/Utility/RegisterContextLinux_i386.cpp
+++ source/Plugins/Process/Utility/RegisterContextLinux_i386.cpp
@@ -111,6 +111,10 @@
 
 size_t RegisterContextLinux_i386::GetGPRSize() const { return sizeof(GPR); }
 
+size_t RegisterContextLinux_i386::GetFXSAVEOffset() const {
+  return (LLVM_EXTENSION offsetof(UserArea, i387));
+}
+
 const RegisterInfo *RegisterContextLinux_i386::GetRegisterInfo() const {
   switch (m_target_arch.GetMachine()) {
   case llvm::Triple::x86:
Index: packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/fpr_sse.cpp
===================================================================
--- /dev/null
+++ packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/fpr_sse.cpp
@@ -0,0 +1,38 @@
+// fpr_sse_x86_64.core was generated with:
+// ./make-core.sh fpr_sse.cpp
+//
+// fpr_sse_i386.core was generated with:
+//   export CFLAGS=-m32
+//   ./make-core.sh fpr_sse.cpp
+
+void _start(void) {
+  __asm__("fldpi;"
+          "fldz;"
+          "fld1;"
+          "fldl2e;"
+          "fldln2;"
+          "fldl2t;"
+          "fld1;"
+          "fldlg2;");
+
+  unsigned int values[8] = {
+      0x46643129, 0x6486ed9c, 0xd71fc207, 0x254820a2,
+      0xc4a85aeb, 0x0b204149, 0x4f8bf1f8, 0xcd30f113,
+  };
+
+  __asm__("vbroadcastss %0, %%xmm0;"
+          "vbroadcastss %1, %%xmm1;"
+          "vbroadcastss %2, %%xmm2;"
+          "vbroadcastss %3, %%xmm3;"
+          "vbroadcastss %4, %%xmm4;"
+          "vbroadcastss %5, %%xmm5;"
+          "vbroadcastss %6, %%xmm6;"
+          "vbroadcastss %7, %%xmm7;"
+
+          ::"m"(values[0]),
+          "m"(values[1]), "m"(values[2]), "m"(values[3]), "m"(values[4]),
+          "m"(values[5]), "m"(values[6]), "m"(values[7]));
+
+  volatile int *a = 0;
+  *a = 0;
+}
Index: packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/TestLinuxCore.py
===================================================================
--- packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/TestLinuxCore.py
+++ packages/Python/lldbsuite/test/functionalities/postmortem/linux-core/TestLinuxCore.py
@@ -104,6 +104,56 @@
         # same pid
         self.do_test("x86_64", self._x86_64_pid, self._x86_64_regions)
 
+    @skipIf(oslist=['windows'])
+    @skipIf(triple='^mips')
+    def test_FPR_SSE(self):
+        # check x86_64 core file
+        target = self.dbg.CreateTarget(None)
+        self.assertTrue(target, VALID_TARGET)
+        process = target.LoadCore("linux-fpr_sse_x86_64.core")
+
+        values = {}
+        values["fctrl"] = "0x037f"
+        values["fstat"] = "0x0000"
+        values["ftag"] = "0xff"
+        values["fop"] = "0x0000"
+        values["fiseg"] = "0x00000000"
+        values["fioff"] = "0x0040011e"
+        values["foseg"] = "0x00000000"
+        values["fooff"] = "0x00000000"
+        values["mxcsr"] = "0x00001f80"
+        values["mxcsrmask"] = "0x0000ffff"
+        values["st0"] = "{0x99 0xf7 0xcf 0xfb 0x84 0x9a 0x20 0x9a 0xfd 0x3f}"
+        values["st1"] = "{0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x80 0xff 0x3f}"
+        values["st2"] = "{0xfe 0x8a 0x1b 0xcd 0x4b 0x78 0x9a 0xd4 0x00 0x40}"
+        values["st3"] = "{0xac 0x79 0xcf 0xd1 0xf7 0x17 0x72 0xb1 0xfe 0x3f}"
+        values["st4"] = "{0xbc 0xf0 0x17 0x5c 0x29 0x3b 0xaa 0xb8 0xff 0x3f}"
+        values["st5"] = "{0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x80 0xff 0x3f}"
+        values["st6"] = "{0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00}"
+        values["st7"] = "{0x35 0xc2 0x68 0x21 0xa2 0xda 0x0f 0xc9 0x00 0x40}"
+        values["xmm0"] = "{0x29 0x31 0x64 0x46 0x29 0x31 0x64 0x46 0x29 0x31 0x64 0x46 0x29 0x31 0x64 0x46}"
+        values["xmm1"] = "{0x9c 0xed 0x86 0x64 0x9c 0xed 0x86 0x64 0x9c 0xed 0x86 0x64 0x9c 0xed 0x86 0x64}"
+        values["xmm2"] = "{0x07 0xc2 0x1f 0xd7 0x07 0xc2 0x1f 0xd7 0x07 0xc2 0x1f 0xd7 0x07 0xc2 0x1f 0xd7}"
+        values["xmm3"] = "{0xa2 0x20 0x48 0x25 0xa2 0x20 0x48 0x25 0xa2 0x20 0x48 0x25 0xa2 0x20 0x48 0x25}"
+        values["xmm4"] = "{0xeb 0x5a 0xa8 0xc4 0xeb 0x5a 0xa8 0xc4 0xeb 0x5a 0xa8 0xc4 0xeb 0x5a 0xa8 0xc4}"
+        values["xmm5"] = "{0x49 0x41 0x20 0x0b 0x49 0x41 0x20 0x0b 0x49 0x41 0x20 0x0b 0x49 0x41 0x20 0x0b}"
+        values["xmm6"] = "{0xf8 0xf1 0x8b 0x4f 0xf8 0xf1 0x8b 0x4f 0xf8 0xf1 0x8b 0x4f 0xf8 0xf1 0x8b 0x4f}"
+        values["xmm7"] = "{0x13 0xf1 0x30 0xcd 0x13 0xf1 0x30 0xcd 0x13 0xf1 0x30 0xcd 0x13 0xf1 0x30 0xcd}"
+
+        for regname, value in values.iteritems():
+            self.expect("register read {}".format(regname), substrs=["{} = {}".format(regname, value)])
+
+
+        # now check i386 core file
+        target = self.dbg.CreateTarget(None)
+        self.assertTrue(target, VALID_TARGET)
+        process = target.LoadCore("linux-fpr_sse_i386.core")
+
+        values["fioff"] = "0x080480cc"
+
+        for regname, value in values.iteritems():
+            self.expect("register read {}".format(regname), substrs=["{} = {}".format(regname, value)])
+
     def check_memory_regions(self, process, region_count):
         region_list = process.GetMemoryRegions()
         self.assertEqual(region_list.GetSize(), region_count)
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to