Author: hhellyer
Date: Tue Jan  3 05:03:14 2017
New Revision: 290874

URL: http://llvm.org/viewvc/llvm-project?rev=290874&view=rev
Log:
Simplify reading of Linux notes to correctly handle endianess.

Summary:
This patch changes and simplifies the way notes are read from Linux Elf cores.
The current implementation copies the bytes from the notes directly over the 
lldb structure for 64 bit cores and reads field by field for 32 bit cores. 
Reading the bytes directly only works if the endianess of the core dump and the 
platform that lldb are running on matches. The case statements for s390x and 
x86_64 would would only work on big endian systems and little endian systems 
respectively. That meant that x86_64 generally worked but s390x didn't unless 
you were on s390x or another big endian platform.
This patch just reads field by field on all platform and updates the field by 
field version to allow for those fields which are word size instead of fixed 
size. It should also slightly simplify adding support for a new Linux platform.

This patch also re-enables the s390x test case in TestLinuxCore.py on all 
non-s390x platforms as it now passes.

Reviewers: uweigand, clayborg

Differential Revision: https://reviews.llvm.org/D27571

Modified:
    
lldb/trunk/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/TestLinuxCore.py
    lldb/trunk/source/Plugins/Process/elf-core/ThreadElfCore.cpp

Modified: 
lldb/trunk/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/TestLinuxCore.py
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/TestLinuxCore.py?rev=290874&r1=290873&r2=290874&view=diff
==============================================================================
--- 
lldb/trunk/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/TestLinuxCore.py
 (original)
+++ 
lldb/trunk/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/TestLinuxCore.py
 Tue Jan  3 05:03:14 2017
@@ -38,9 +38,7 @@ class LinuxCoreTestCase(TestBase):
         """Test that lldb can read the process information from an x86_64 
linux core file."""
         self.do_test("linux-x86_64", self._x86_64_pid, self._x86_64_regions)
 
-    # This seems to hang on non-s390x platforms for some reason.  Disabling
-    # for now.
-    @skipIf(archs=no_match(['s390x']))
+    @skipIf(oslist=['windows'])
     @skipIf(triple='^mips')
     def test_s390x(self):
         """Test that lldb can read the process information from an s390x linux 
core file."""

Modified: lldb/trunk/source/Plugins/Process/elf-core/ThreadElfCore.cpp
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/elf-core/ThreadElfCore.cpp?rev=290874&r1=290873&r2=290874&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/elf-core/ThreadElfCore.cpp (original)
+++ lldb/trunk/source/Plugins/Process/elf-core/ThreadElfCore.cpp Tue Jan  3 
05:03:14 2017
@@ -202,7 +202,6 @@ ELFLinuxPrStatus::ELFLinuxPrStatus() {
 
 Error ELFLinuxPrStatus::Parse(DataExtractor &data, ArchSpec &arch) {
   Error error;
-  ByteOrder byteorder = data.GetByteOrder();
   if (GetSize(arch) > data.GetByteSize()) {
     error.SetErrorStringWithFormat(
         "NT_PRSTATUS size should be %zu, but the remaining bytes are: %" 
PRIu64,
@@ -210,50 +209,36 @@ Error ELFLinuxPrStatus::Parse(DataExtrac
     return error;
   }
 
-  switch (arch.GetCore()) {
-  case ArchSpec::eCore_s390x_generic:
-  case ArchSpec::eCore_x86_64_x86_64:
-    data.ExtractBytes(0, sizeof(ELFLinuxPrStatus), byteorder, this);
-    break;
-  case ArchSpec::eCore_x86_32_i386:
-  case ArchSpec::eCore_x86_32_i486: {
-    // Parsing from a 32 bit ELF core file, and populating/reusing the 
structure
-    // properly, because the struct is for the 64 bit version
-    offset_t offset = 0;
-    si_signo = data.GetU32(&offset);
-    si_code = data.GetU32(&offset);
-    si_errno = data.GetU32(&offset);
-
-    pr_cursig = data.GetU16(&offset);
-    offset += 2; // pad
-
-    pr_sigpend = data.GetU32(&offset);
-    pr_sighold = data.GetU32(&offset);
-
-    pr_pid = data.GetU32(&offset);
-    pr_ppid = data.GetU32(&offset);
-    pr_pgrp = data.GetU32(&offset);
-    pr_sid = data.GetU32(&offset);
-
-    pr_utime.tv_sec = data.GetU32(&offset);
-    pr_utime.tv_usec = data.GetU32(&offset);
-
-    pr_stime.tv_sec = data.GetU32(&offset);
-    pr_stime.tv_usec = data.GetU32(&offset);
+  // Read field by field to correctly account for endianess
+  // of both the core dump and the platform running lldb.
+  offset_t offset = 0;
+  si_signo = data.GetU32(&offset);
+  si_code = data.GetU32(&offset);
+  si_errno = data.GetU32(&offset);
+
+  pr_cursig = data.GetU16(&offset);
+  offset += 2; // pad
+
+  pr_sigpend = data.GetPointer(&offset);
+  pr_sighold = data.GetPointer(&offset);
+
+  pr_pid = data.GetU32(&offset);
+  pr_ppid = data.GetU32(&offset);
+  pr_pgrp = data.GetU32(&offset);
+  pr_sid = data.GetU32(&offset);
+
+  pr_utime.tv_sec = data.GetPointer(&offset);
+  pr_utime.tv_usec = data.GetPointer(&offset);
 
-    pr_cutime.tv_sec = data.GetU32(&offset);
-    pr_cutime.tv_usec = data.GetU32(&offset);
+  pr_stime.tv_sec = data.GetPointer(&offset);
+  pr_stime.tv_usec = data.GetPointer(&offset);
 
-    pr_cstime.tv_sec = data.GetU32(&offset);
-    pr_cstime.tv_usec = data.GetU32(&offset);
+  pr_cutime.tv_sec = data.GetPointer(&offset);
+  pr_cutime.tv_usec = data.GetPointer(&offset);
+
+  pr_cstime.tv_sec = data.GetPointer(&offset);
+  pr_cstime.tv_usec = data.GetPointer(&offset);
 
-    break;
-  }
-  default:
-    error.SetErrorStringWithFormat("ELFLinuxPrStatus::%s Unknown architecture",
-                                   __FUNCTION__);
-    break;
-  }
 
   return error;
 }
@@ -274,48 +259,36 @@ Error ELFLinuxPrPsInfo::Parse(DataExtrac
         GetSize(arch), data.GetByteSize());
     return error;
   }
+  size_t size = 0;
+  offset_t offset = 0;
 
-  switch (arch.GetCore()) {
-  case ArchSpec::eCore_s390x_generic:
-  case ArchSpec::eCore_x86_64_x86_64:
-    data.ExtractBytes(0, sizeof(ELFLinuxPrPsInfo), byteorder, this);
-    break;
-  case ArchSpec::eCore_x86_32_i386:
-  case ArchSpec::eCore_x86_32_i486: {
-    // Parsing from a 32 bit ELF core file, and populating/reusing the 
structure
-    // properly, because the struct is for the 64 bit version
-    size_t size = 0;
-    offset_t offset = 0;
-
-    pr_state = data.GetU8(&offset);
-    pr_sname = data.GetU8(&offset);
-    pr_zomb = data.GetU8(&offset);
-    pr_nice = data.GetU8(&offset);
-
-    pr_flag = data.GetU32(&offset);
-    pr_uid = data.GetU16(&offset);
-    pr_gid = data.GetU16(&offset);
-
-    pr_pid = data.GetU32(&offset);
-    pr_ppid = data.GetU32(&offset);
-    pr_pgrp = data.GetU32(&offset);
-    pr_sid = data.GetU32(&offset);
-
-    size = 16;
-    data.ExtractBytes(offset, size, byteorder, pr_fname);
-    offset += size;
-
-    size = 80;
-    data.ExtractBytes(offset, size, byteorder, pr_psargs);
-    offset += size;
-
-    break;
-  }
-  default:
-    error.SetErrorStringWithFormat("ELFLinuxPrPsInfo::%s Unknown architecture",
-                                   __FUNCTION__);
-    break;
-  }
+  pr_state = data.GetU8(&offset);
+  pr_sname = data.GetU8(&offset);
+  pr_zomb = data.GetU8(&offset);
+  pr_nice = data.GetU8(&offset);
+  if (data.GetAddressByteSize() == 8) {
+    // Word align the next field on 64 bit.
+    offset += 4;
+  }
+
+  pr_flag = data.GetPointer(&offset);
+
+  // 16 bit on 32 bit platforms, 32 bit on 64 bit platforms
+  pr_uid = data.GetMaxU64(&offset, data.GetAddressByteSize() >> 1);
+  pr_gid = data.GetMaxU64(&offset, data.GetAddressByteSize() >> 1);
+
+  pr_pid = data.GetU32(&offset);
+  pr_ppid = data.GetU32(&offset);
+  pr_pgrp = data.GetU32(&offset);
+  pr_sid = data.GetU32(&offset);
+
+  size = 16;
+  data.ExtractBytes(offset, size, byteorder, pr_fname);
+  offset += size;
+
+  size = 80;
+  data.ExtractBytes(offset, size, byteorder, pr_psargs);
+  offset += size;
 
   return error;
 }
@@ -329,7 +302,6 @@ ELFLinuxSigInfo::ELFLinuxSigInfo() {
 
 Error ELFLinuxSigInfo::Parse(DataExtractor &data, const ArchSpec &arch) {
   Error error;
-  ByteOrder byteorder = data.GetByteOrder();
   if (GetSize(arch) > data.GetByteSize()) {
     error.SetErrorStringWithFormat(
         "NT_SIGINFO size should be %zu, but the remaining bytes are: %" PRIu64,
@@ -337,27 +309,12 @@ Error ELFLinuxSigInfo::Parse(DataExtract
     return error;
   }
 
-  switch (arch.GetCore()) {
-  case ArchSpec::eCore_x86_64_x86_64:
-    data.ExtractBytes(0, sizeof(ELFLinuxPrStatus), byteorder, this);
-    break;
-  case ArchSpec::eCore_s390x_generic:
-  case ArchSpec::eCore_x86_32_i386:
-  case ArchSpec::eCore_x86_32_i486: {
-    // Parsing from a 32 bit ELF core file, and populating/reusing the 
structure
-    // properly, because the struct is for the 64 bit version
-    offset_t offset = 0;
-    si_signo = data.GetU32(&offset);
-    si_code = data.GetU32(&offset);
-    si_errno = data.GetU32(&offset);
-
-    break;
-  }
-  default:
-    error.SetErrorStringWithFormat("ELFLinuxSigInfo::%s Unknown architecture",
-                                   __FUNCTION__);
-    break;
-  }
+  // Parsing from a 32 bit ELF core file, and populating/reusing the structure
+  // properly, because the struct is for the 64 bit version
+  offset_t offset = 0;
+  si_signo = data.GetU32(&offset);
+  si_code = data.GetU32(&offset);
+  si_errno = data.GetU32(&offset);
 
   return error;
 }


_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to