From a228c46c2a1ec209ec1cc67ba2a58f8df4150668 Mon Sep 17 00:00:00 2001 From: Dimitar Vlahovski Date: Sun, 20 Nov 2016 21:24:49 +0000 Subject: ELF core: Adding parsing of the floating-point and SSE registers on x86 32/64 bit elf core files Summary: The floating-point and SSE registers could be present in the elf-core file in the note NT_FPREGSET for 64 bit ones, and in the note NT_PRXFPREG for 32 bit ones. The entire note is a binary blob matching the layout of the x87 save area that gets generated by the FXSAVE instruction (see Intel developers manual for more information). This CL mainly modifies the RegisterRead function in RegisterContextPOSIXCore_x86_64 for it to return the correct data both for GPR and FPR/SSE registers, and return false (meaning "this register is not available") for other registers. I added a test to TestElfCore.py that tests reading FPR/SSE registers both from a 32 and 64 bit elf-core file and I have inluded the source which I used to generate the core files. I tried to also add support for the AVX registers, because this info could also be present in the elf-core file (note NT_X86_XSTATE - that is the result of the newer XSAVE instruction). Parsing the contents from the file is easy. The problem is that the ymm registers are split into two halves and they are in different places in the note. For making this work one would either make a "hacky" approach, because there won't be any other way with the current state of the register contexts - they assume that "this register is of size N and at offset M" and don't have the notion of discontinuos registers. Reviewers: labath Subscribers: emaste, lldb-commits Differential Revision: https://reviews.llvm.org/D26300 llvm-svn: 287506 --- .../postmortem/elf-core/TestLinuxCore.py | 50 +++++++++++++++++++++ .../postmortem/elf-core/fpr_sse.cpp | 38 ++++++++++++++++ .../postmortem/elf-core/linux-fpr_sse_i386.core | Bin 0 -> 32768 bytes .../postmortem/elf-core/linux-fpr_sse_x86_64.core | Bin 0 -> 40960 bytes 4 files changed, 88 insertions(+) create mode 100644 lldb/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/fpr_sse.cpp create mode 100644 lldb/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/linux-fpr_sse_i386.core create mode 100644 lldb/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/linux-fpr_sse_x86_64.core (limited to 'lldb/packages/Python/lldbsuite/test/functionalities') diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/TestLinuxCore.py b/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/TestLinuxCore.py index 42542099b9f..ed46ef1c847 100644 --- a/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/TestLinuxCore.py +++ b/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/TestLinuxCore.py @@ -104,6 +104,56 @@ class LinuxCoreTestCase(TestBase): # same pid self.do_test("linux-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) diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/fpr_sse.cpp b/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/fpr_sse.cpp new file mode 100644 index 00000000000..e6826fc7a09 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/elf-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; +} diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/linux-fpr_sse_i386.core b/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/linux-fpr_sse_i386.core new file mode 100644 index 00000000000..b0fdaf67ca4 Binary files /dev/null and b/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/linux-fpr_sse_i386.core differ diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/linux-fpr_sse_x86_64.core b/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/linux-fpr_sse_x86_64.core new file mode 100644 index 00000000000..5fb39ee115b Binary files /dev/null and b/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/linux-fpr_sse_x86_64.core differ -- cgit v1.2.3