[Lldb-commits] [lldb] r290874 - Simplify reading of Linux notes to correctly handle endianess.

Howard Hellyer via lldb-commits lldb-commits at lists.llvm.org
Tue Jan 3 03:03:15 PST 2017


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;
 }




More information about the lldb-commits mailing list