Index: lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp =================================================================== --- lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp +++ lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp @@ -43,11 +43,16 @@ bool RegisterContextCorePOSIX_arm::ReadRegister(const RegisterInfo *reg_info, RegisterValue &value) { + if (!reg_info) + return false; + lldb::offset_t offset = reg_info->byte_offset; - uint64_t v = m_gpr.GetMaxU64(&offset, reg_info->byte_size); - if (offset == reg_info->byte_offset + reg_info->byte_size) { - value = v; - return true; + if (offset < GetGPRSize() && offset < m_gpr.GetByteSize()) { + uint64_t v = m_gpr.GetMaxU64(&offset, reg_info->byte_size); + if (offset == reg_info->byte_offset + reg_info->byte_size) { + value = v; + return true; + } } return false; } Index: lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h =================================================================== --- lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h +++ lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h @@ -48,6 +48,7 @@ private: lldb::DataBufferSP m_gpr_buffer; lldb_private::DataExtractor m_gpr; + lldb_private::DataExtractor m_fpregset; }; #endif // LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_REGISTERCONTEXTPOSIXCORE_ARM64_H Index: lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp =================================================================== --- lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp +++ lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp @@ -24,6 +24,9 @@ gpregset.GetByteSize()); m_gpr.SetData(m_gpr_buffer); m_gpr.SetByteOrder(gpregset.GetByteOrder()); + + m_fpregset = getRegset( + notes, register_info->GetTargetArchitecture().GetTriple(), FPR_Desc); } RegisterContextCorePOSIX_arm64::~RegisterContextCorePOSIX_arm64() {} @@ -44,12 +47,30 @@ bool RegisterContextCorePOSIX_arm64::ReadRegister(const RegisterInfo *reg_info, RegisterValue &value) { + if (!reg_info) + return false; + lldb::offset_t offset = reg_info->byte_offset; - uint64_t v = m_gpr.GetMaxU64(&offset, reg_info->byte_size); - if (offset == reg_info->byte_offset + reg_info->byte_size) { - value = v; - return true; + if (offset < GetGPRSize() && offset < m_gpr.GetByteSize()) { + uint64_t v = m_gpr.GetMaxU64(&offset, reg_info->byte_size); + if (offset == reg_info->byte_offset + reg_info->byte_size) { + value = v; + return true; + } + } + + const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB]; + if (reg == LLDB_INVALID_REGNUM) + return false; + + offset -= GetGPRSize(); + if (IsFPR(reg) && offset < m_fpregset.GetByteSize()) { + Status error; + value.SetFromMemoryData(reg_info, m_fpregset.GetDataStart() + offset, + reg_info->byte_size, lldb::eByteOrderLittle, error); + return error.Success(); } + return false; } Index: lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py =================================================================== --- lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py +++ lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py @@ -19,6 +19,7 @@ mydir = TestBase.compute_mydir(__file__) + _aarch64_pid = 37688 _i386_pid = 32306 _x86_64_pid = 32259 _s390x_pid = 1045 @@ -27,12 +28,20 @@ _mips_o32_pid = 3532 _ppc64le_pid = 28147 + _aarch64_regions = 4 _i386_regions = 4 _x86_64_regions = 5 _s390x_regions = 2 _mips_regions = 5 _ppc64le_regions = 2 + + @skipIf(triple='^mips') + @skipIfLLVMTargetMissing("AArch64") + def test_aarch64(self): + """Test that lldb can read the process information from an aarch64 linux core file.""" + self.do_test("linux-aarch64", self._aarch64_pid, self._aarch64_regions, "a.out") + @skipIf(triple='^mips') @skipIfLLVMTargetMissing("X86") def test_i386(self): @@ -209,6 +218,182 @@ self.dbg.DeleteTarget(target) + @skipIf(triple='^mips') + @skipIfLLVMTargetMissing("AArch64") + def test_aarch64_regs(self): + # check 64 bit ARM core files + target = self.dbg.CreateTarget(None) + self.assertTrue(target, VALID_TARGET) + process = target.LoadCore("linux-aarch64-neon.core") + + values = {} + values["x0"] = "0x000000000000000a" + values["x1"] = "0x0000000000000000" + values["x2"] = "0x0000000000000001" + values["x3"] = "0x0000000000000000" + values["x4"] = "0x000000000000000a" + values["x5"] = "0x5555555541154400" + values["x6"] = "0x0000000000413057" + values["x7"] = "0x7f7f7f7f7f7f7f7f" + values["x8"] = "0x0000000000000040" + values["x9"] = "0x0000000000000001" + values["x10"] = "0x000000000000000a" + values["x11"] = "0x0000000100000000" + values["x12"] = "0x0000000100000000" + values["x13"] = "0x0000000000000000" + values["x14"] = "0x0000000000000000" + values["x15"] = "0x0000007f93247000" + values["x16"] = "0x0000000000000000" + values["x17"] = "0x0000007f93120aa0" + values["x18"] = "0x0000000000000a03" + values["x19"] = "0x000000000040130c" + values["x20"] = "0x0000000000000000" + values["x21"] = "0x0000007fd1fb84a0" + values["x22"] = "0x0000007fd1fb849c" + values["x23"] = "0x0000000000000000" + values["x24"] = "0x0000000000000000" + values["x25"] = "0x0000000000000000" + values["x26"] = "0x0000000000000000" + values["x27"] = "0x0000000000000000" + values["x28"] = "0x0000000000000000" + values["fp"] = "0x0000007fd1fb8790" + values["lr"] = "0x0000000000401248" + values["sp"] = "0x0000007fd1fb8100" + values["pc"] = "0x0000000000401248" + values["cpsr"] = "0x60000000" + values["w0"] = "0x0000000a" + values["w1"] = "0x00000000" + values["w2"] = "0x00000001" + values["w3"] = "0x00000000" + values["w4"] = "0x0000000a" + values["w5"] = "0x41154400" + values["w6"] = "0x00413057" + values["w7"] = "0x7f7f7f7f" + values["w8"] = "0x00000040" + values["w9"] = "0x00000001" + values["w10"] = "0x0000000a" + values["w11"] = "0x00000000" + values["w12"] = "0x00000000" + values["w13"] = "0x00000000" + values["w14"] = "0x00000000" + values["w15"] = "0x93247000" + values["w16"] = "0x00000000" + values["w17"] = "0x93120aa0" + values["w18"] = "0x00000a03" + values["w19"] = "0x0040130c" + values["w20"] = "0x00000000" + values["w21"] = "0xd1fb84a0" + values["w22"] = "0xd1fb849c" + values["w23"] = "0x00000000" + values["w24"] = "0x00000000" + values["w25"] = "0x00000000" + values["w26"] = "0x00000000" + values["w27"] = "0x00000000" + values["w28"] = "0x00000000" + values["v0"] = "{0x25 0x25 0x25 0x25 0x25 0x25 0x25 0x25 0x25 0x25 0x25 0x25 0x25 0x25 0x25 0x25}" + values["v1"] = "{0xc0 0x03 0x5f 0xd6 0x01 0x00 0x02 0x00 0x00 0x00 0x00 0x30 0x25 0x66 0x20 0x00}" + values["v2"] = "{0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00}" + values["v3"] = "{0x00 0x00 0x00 0x00 0x00 0xff 0x00 0xff 0xff 0xff 0xff 0x00 0x00 0x00 0x00 0xff}" + values["v4"] = "{0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff}" + values["v5"] = "{0x00 0x00 0x00 0x00 0x00 0x04 0x00 0x40 0x01 0x04 0x10 0x00 0x01 0x00 0x00 0x40}" + values["v6"] = "{0x01 0x04 0x10 0x40 0x01 0x04 0x10 0x40 0x01 0x04 0x10 0x40 0x01 0x04 0x10 0x40}" + values["v7"] = "{0x01 0x04 0x10 0x40 0x01 0x04 0x10 0x40 0x01 0x04 0x10 0x40 0x01 0x04 0x10 0x40}" + values["v8"] = "{0x96 0x10 0x3d 0x3f 0x96 0x10 0x3d 0x3f 0x96 0x10 0x3d 0x3f 0x96 0x10 0x3d 0x3f}" + values["v9"] = "{0xde 0x45 0xb5 0x3e 0xde 0x45 0xb5 0x3e 0xde 0x45 0xb5 0x3e 0xde 0x45 0xb5 0x3e}" + values["v10"] = "{0x36 0xd2 0x5b 0x3f 0x36 0xd2 0x5b 0x3f 0x36 0xd2 0x5b 0x3f 0x36 0xd2 0x5b 0x3f}" + values["v11"] = "{0x49 0x89 0x6c 0x3f 0x49 0x89 0x6c 0x3f 0x49 0x89 0x6c 0x3f 0x49 0x89 0x6c 0x3f}" + values["v12"] = "{0x05 0xe7 0x8f 0x3e 0x05 0xe7 0x8f 0x3e 0x05 0xe7 0x8f 0x3e 0x05 0xe7 0x8f 0x3e}" + values["v13"] = "{0x43 0x31 0xc4 0x3e 0x43 0x31 0xc4 0x3e 0x43 0x31 0xc4 0x3e 0x43 0x31 0xc4 0x3e}" + values["v14"] = "{0x1e 0x6b 0x9d 0x3e 0x1e 0x6b 0x9d 0x3e 0x1e 0x6b 0x9d 0x3e 0x1e 0x6b 0x9d 0x3e}" + values["v15"] = "{0x6c 0x5c 0x6f 0x3f 0x6c 0x5c 0x6f 0x3f 0x6c 0x5c 0x6f 0x3f 0x6c 0x5c 0x6f 0x3f}" + values["v16"] = "{0x00 0x44 0x15 0x41 0x55 0x55 0x55 0x55 0x00 0x44 0x15 0x41 0x55 0x55 0x55 0x55}" + values["v17"] = "{0x3e 0xd6 0x2d 0x40 0x64 0xed 0x28 0x40 0xf3 0xf3 0x40 0x40 0xb5 0xf5 0x54 0x40}" + values["v18"] = "{0xf5 0xde 0x04 0x40 0xc4 0x4d 0x5e 0x40 0x17 0x16 0x02 0x40 0x02 0x58 0x46 0x40}" + values["v19"] = "{0x64 0xed 0x28 0x40 0x1c 0x6c 0x55 0x40 0x2e 0x5f 0x34 0x40 0x1c 0xc0 0x2a 0x40}" + values["v20"] = "{0xf3 0xf3 0x40 0x40 0xb0 0x2b 0x03 0x40 0x64 0xed 0x28 0x40 0x1c 0x6c 0x55 0x40}" + values["v21"] = "{0xbf 0x6b 0x07 0x40 0x74 0xf8 0x5a 0x40 0x63 0x47 0xc2 0x3f 0xec 0x2f 0x3d 0x40}" + values["v22"] = "{0x45 0x18 0x04 0x3f 0x04 0x94 0x63 0x3e 0xf5 0x1e 0x6c 0x3f 0xd4 0x93 0x28 0x3e}" + values["v23"] = "{0xa1 0xfb 0x38 0x3e 0xf4 0xa2 0x95 0x3e 0xa6 0x23 0x2e 0x3e 0x89 0xd4 0x48 0x3e}" + values["v24"] = "{0xc3 0x8b 0x6a 0x3f 0xc3 0x8b 0x6a 0x3f 0xc3 0x8b 0x6a 0x3f 0xc3 0x8b 0x6a 0x3f}" + values["v25"] = "{0xe8 0x8e 0x91 0x3e 0x14 0x45 0x28 0x3f 0xa7 0xd5 0x23 0x3f 0xff 0x0d 0xe1 0x3e}" + values["v26"] = "{0xbd 0x7e 0x5f 0x3e 0xbd 0x7e 0x5f 0x3e 0xbd 0x7e 0x5f 0x3e 0xbd 0x7e 0x5f 0x3e}" + values["v27"] = "{0x0f 0xd0 0x56 0x3f 0x0f 0xd0 0x56 0x3f 0x0f 0xd0 0x56 0x3f 0x0f 0xd0 0x56 0x3f}" + values["v28"] = "{0x6c 0x75 0xb4 0x3e 0x6c 0x75 0xb4 0x3e 0x6c 0x75 0xb4 0x3e 0x6c 0x75 0xb4 0x3e}" + values["v29"] = "{0x52 0x45 0x6b 0x3f 0x52 0x45 0x6b 0x3f 0x52 0x45 0x6b 0x3f 0x52 0x45 0x6b 0x3f}" + values["v30"] = "{0x7a 0x7b 0x78 0x3f 0x7a 0x7b 0x78 0x3f 0x7a 0x7b 0x78 0x3f 0x7a 0x7b 0x78 0x3f}" + values["v31"] = "{0xe1 0xd5 0x59 0x3f 0xe1 0xd5 0x59 0x3f 0xe1 0xd5 0x59 0x3f 0xe1 0xd5 0x59 0x3f}" + values["s0"] = "1.43241e-16" + values["s1"] = "-6.13018e+13" + values["s2"] = "0" + values["s3"] = "0" + values["s4"] = "-nan" + values["s5"] = "0" + values["s6"] = "2.25024" + values["s7"] = "2.25024" + values["s8"] = "0.738534" + values["s9"] = "0.354049" + values["s10"] = "0.858676" + values["s11"] = "0.92397" + values["s12"] = "0.281059" + values["s13"] = "0.383188" + values["s14"] = "0.307458" + values["s15"] = "0.935004" + values["s16"] = "9.3291" + values["s17"] = "2.7162" + values["s18"] = "2.07611" + values["s19"] = "2.63949" + values["s20"] = "3.01489" + values["s21"] = "2.11595" + values["s22"] = "0.515995" + values["s23"] = "0.180647" + values["s24"] = "0.916195" + values["s25"] = "0.284293" + values["s26"] = "0.218257" + values["s27"] = "0.839112" + values["s28"] = "0.352458" + values["s29"] = "0.919026" + values["s30"] = "0.970634" + values["s31"] = "0.85092" + values["d0"] = "9.53282412436824e-130" + values["d1"] = "2.78138131241535e-309" + values["d2"] = "0" + values["d3"] = "-5.82766743733431e+303" + values["d4"] = "-nan" + values["d5"] = "2.001953125" + values["d6"] = "4.00391101930381" + values["d7"] = "4.00391101930381" + values["d8"] = "0.000443493539240566" + values["d9"] = "1.26796498530303e-06" + values["d10"] = "0.00169806764227788" + values["d11"] = "0.00348343187523984" + values["d12"] = "2.37691579557495e-07" + values["d13"] = "2.40712551236567e-06" + values["d14"] = "4.38368771162803e-07" + values["d15"] = "0.0038282503332812" + values["d16"] = "1.19453046157665e+103" + values["d17"] = "12.4636554771379" + values["d18"] = "121.21510315395" + values["d19"] = "85.6892242812806" + values["d20"] = "2.39633226583691" + values["d21"] = "107.882095343825" + values["d22"] = "3.64672202453059e-08" + values["d23"] = "3.22409560580352e-07" + values["d24"] = "0.00324047216720788" + values["d25"] = "0.000185164185754087" + values["d26"] = "2.93320744567131e-08" + values["d27"] = "0.00139237870221809" + values["d28"] = "1.21943252901572e-06" + values["d29"] = "0.0033289533997524" + values["d30"] = "0.00597713234995367" + values["d31"] = "0.00157687184164722" + values["fpsr"] = "0x00000010" + values["fpcr"] = "0x00000000" + + for regname, value in values.items(): + self.expect("register read {}".format(regname), substrs=["{} = {}".format(regname, value)]) + + self.expect("register read --all") + @skipIf(triple='^mips') @skipIfLLVMTargetMissing("ARM") def test_arm_core(self): @@ -238,6 +423,8 @@ for regname, value in values.items(): self.expect("register read {}".format(regname), substrs=["{} = {}".format(regname, value)]) + self.expect("register read --all") + def check_memory_regions(self, process, region_count): region_list = process.GetMemoryRegions() self.assertEqual(region_list.GetSize(), region_count) Index: lldb/test/API/functionalities/postmortem/elf-core/aarch64-neon.c =================================================================== --- /dev/null +++ lldb/test/API/functionalities/postmortem/elf-core/aarch64-neon.c @@ -0,0 +1,57 @@ +// This is test program for generating core dump test file for aarch64-linux. +// Use following steps to generate a core dump that populates various registers: + +// Prerequisite (Linux): Make sure you can generate coredumps on your system. +// Step 0.1 - set ulimit) ulimit -c unlimited +// Step 0.2 - Set coredump target dir) sudo sysctl -w kernel.core_pattern=core +// Step 1 - Build exe) clang -O3 aarch64-neon.c -o linux-aarch64-neon.out +// Step 2 - Run exec and force a coredump) exec ./linux-aarch64-neon.out +// mv ./core linux-aarch64-neon.core + +#include +#include + +#define MATRIX_ROWS 8 +#define MATRIX_COLS 8 + +void matrix_multiply(float *matrix_a, float *matrix_b, float *matrix_r, + unsigned int rows, unsigned int cols) { + if (rows != cols) + return; + + for (int i = 0; i < rows; i++) { + for (int j = 0; j < cols; j++) { + matrix_r[cols * i + j] = 0.0; + for (int k = 0; k < cols; k++) { + matrix_r[cols * i + j] += + matrix_a[cols * i + k] * matrix_b[cols * k + j]; + } + } + } +} + +void matrix_print(float *matrix, unsigned int cols, unsigned int rows) { + for (int i = 0; i < rows; i++) { + for (int j = 0; j < cols; j++) { + printf("%f ", matrix[j * rows + i]); + } + printf("\n"); + } + printf("\n"); +} + +int main() { + float matrix_a[MATRIX_ROWS * MATRIX_COLS]; + float matrix_b[MATRIX_ROWS * MATRIX_COLS]; + float matrix_r[MATRIX_ROWS * MATRIX_COLS]; + + for (int i = 0; i < (MATRIX_ROWS * MATRIX_COLS); i++) { + matrix_a[i] = (float)rand() / (float)(RAND_MAX); + matrix_b[i] = (float)rand() / (float)(RAND_MAX); + matrix_r[i] = 0.0; + } + + matrix_multiply(matrix_a, matrix_b, matrix_r, MATRIX_ROWS, MATRIX_COLS); + matrix_print(matrix_r, MATRIX_COLS, MATRIX_ROWS); + asm volatile("brk #0\n\t"); +}