#include "RegisterContextMinidump_ARM.h"
#include "Utility/ARM_DWARF_Registers.h"
+#include "Utility/ARM_ehframe_Registers.h"
#include "lldb/Utility/RegisterValue.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/LLDBAssert.h"
#define DEF_R(i) \
{ \
"r" #i, nullptr, 4, OFFSET(r) + i * 4, eEncodingUint, eFormatHex, \
- {dwarf_r##i, dwarf_r##i, INV, INV, reg_r##i}, \
+ {ehframe_r##i, dwarf_r##i, INV, INV, reg_r##i}, \
nullptr, nullptr, nullptr, 0 \
}
#define DEF_R_ARG(i, n) \
{ \
"r" #i, "arg" #n, 4, OFFSET(r) + i * 4, eEncodingUint, eFormatHex, \
- {dwarf_r##i, dwarf_r##i, LLDB_REGNUM_GENERIC_ARG1 + i, INV, reg_r##i}, \
+ {ehframe_r##i, dwarf_r##i, LLDB_REGNUM_GENERIC_ARG1 + i, INV, reg_r##i}, \
nullptr, nullptr, nullptr, 0 \
}
OFFSET(r) + 7 * 4,
eEncodingUint,
eFormatHex,
- {INV, dwarf_r7, LLDB_REGNUM_GENERIC_FP, INV, reg_r7},
+ {ehframe_r7, dwarf_r7, LLDB_REGNUM_GENERIC_FP, INV, reg_r7},
nullptr,
nullptr,
nullptr,
OFFSET(r) + 11 * 4,
eEncodingUint,
eFormatHex,
- {INV, dwarf_r11, LLDB_REGNUM_GENERIC_FP, INV, reg_r11},
+ {ehframe_r11, dwarf_r11, LLDB_REGNUM_GENERIC_FP, INV, reg_r11},
nullptr,
nullptr,
nullptr,
OFFSET(r) + 13 * 4,
eEncodingUint,
eFormatHex,
- {INV, dwarf_sp, LLDB_REGNUM_GENERIC_SP, INV, reg_sp},
+ {ehframe_sp, dwarf_sp, LLDB_REGNUM_GENERIC_SP, INV, reg_sp},
nullptr,
nullptr,
nullptr,
OFFSET(r) + 14 * 4,
eEncodingUint,
eFormatHex,
- {INV, dwarf_lr, LLDB_REGNUM_GENERIC_RA, INV, reg_lr},
+ {ehframe_lr, dwarf_lr, LLDB_REGNUM_GENERIC_RA, INV, reg_lr},
nullptr,
nullptr,
nullptr,
OFFSET(r) + 15 * 4,
eEncodingUint,
eFormatHex,
- {INV, dwarf_pc, LLDB_REGNUM_GENERIC_PC, INV, reg_pc},
+ {ehframe_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, INV, reg_pc},
nullptr,
nullptr,
nullptr,
OFFSET(cpsr),
eEncodingUint,
eFormatHex,
- {INV, dwarf_cpsr, LLDB_REGNUM_GENERIC_FLAGS, INV, reg_cpsr},
+ {ehframe_cpsr, dwarf_cpsr, LLDB_REGNUM_GENERIC_FLAGS, INV, reg_cpsr},
nullptr,
nullptr,
nullptr,
lldbassert(k_num_regs == k_num_reg_infos);
}
-size_t RegisterContextMinidump_ARM::GetRegisterCount() { return k_num_regs; }
+size_t RegisterContextMinidump_ARM::GetRegisterCountStatic() {
+ return k_num_regs;
+}
+
+// Used for unit testing so we can verify register info is filled in for
+// all register flavors (DWARF, EH Frame, generic, etc).
+size_t RegisterContextMinidump_ARM::GetRegisterCount() {
+ return GetRegisterCountStatic();
+}
+// Used for unit testing so we can verify register info is filled in.
const RegisterInfo *
-RegisterContextMinidump_ARM::GetRegisterInfoAtIndex(size_t reg) {
+RegisterContextMinidump_ARM::GetRegisterInfoAtIndexStatic(size_t reg,
+ bool apple) {
if (reg < k_num_reg_infos) {
- if (m_apple) {
+ if (apple) {
if (reg == reg_r7)
return &g_reg_info_apple_fp;
} else {
return nullptr;
}
+const RegisterInfo *
+RegisterContextMinidump_ARM::GetRegisterInfoAtIndex(size_t reg) {
+ return GetRegisterInfoAtIndexStatic(reg, m_apple);
+}
+
size_t RegisterContextMinidump_ARM::GetRegisterSetCount() {
return k_num_reg_sets;
}
#include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h"
#include "Plugins/Process/minidump/RegisterContextMinidump_x86_32.h"
#include "Plugins/Process/minidump/RegisterContextMinidump_x86_64.h"
+#include "Plugins/Process/minidump/RegisterContextMinidump_ARM.h"
#include "lldb/Utility/DataBuffer.h"
+#include "llvm/ADT/StringRef.h"
#include "gtest/gtest.h"
using namespace lldb_private;
EXPECT_EQ(Context.ds, reg64(*Buf, Info[lldb_ds_x86_64]));
EXPECT_EQ(Context.es, reg64(*Buf, Info[lldb_es_x86_64]));
}
+
+static void TestARMRegInfo(const lldb_private::RegisterInfo *info) {
+ // Make sure we have valid register numbers for eRegisterKindEHFrame and
+ // eRegisterKindDWARF for GPR registers r0-r15 so that we can unwind
+ // correctly when using this information.
+ llvm::StringRef name(info->name);
+ llvm::StringRef alt_name(info->alt_name);
+ if (name.startswith("r") || alt_name.startswith("r")) {
+ EXPECT_NE(info->kinds[lldb::eRegisterKindEHFrame], LLDB_INVALID_REGNUM);
+ EXPECT_NE(info->kinds[lldb::eRegisterKindDWARF], LLDB_INVALID_REGNUM);
+ }
+ // Verify generic register are set correctly
+ if (name == "r0")
+ EXPECT_EQ(info->kinds[lldb::eRegisterKindGeneric],
+ (uint32_t)LLDB_REGNUM_GENERIC_ARG1);
+ else if (name == "r1")
+ EXPECT_EQ(info->kinds[lldb::eRegisterKindGeneric],
+ (uint32_t)LLDB_REGNUM_GENERIC_ARG2);
+ else if (name == "r2")
+ EXPECT_EQ(info->kinds[lldb::eRegisterKindGeneric],
+ (uint32_t)LLDB_REGNUM_GENERIC_ARG3);
+ else if (name == "r3")
+ EXPECT_EQ(info->kinds[lldb::eRegisterKindGeneric],
+ (uint32_t)LLDB_REGNUM_GENERIC_ARG4);
+ else if (name == "sp")
+ EXPECT_EQ(info->kinds[lldb::eRegisterKindGeneric],
+ (uint32_t)LLDB_REGNUM_GENERIC_SP);
+ else if (name == "fp")
+ EXPECT_EQ(info->kinds[lldb::eRegisterKindGeneric],
+ (uint32_t)LLDB_REGNUM_GENERIC_FP);
+ else if (name == "lr")
+ EXPECT_EQ(info->kinds[lldb::eRegisterKindGeneric],
+ (uint32_t)LLDB_REGNUM_GENERIC_RA);
+ else if (name == "pc")
+ EXPECT_EQ(info->kinds[lldb::eRegisterKindGeneric],
+ (uint32_t)LLDB_REGNUM_GENERIC_PC);
+ else if (name == "cpsr")
+ EXPECT_EQ(info->kinds[lldb::eRegisterKindGeneric],
+ (uint32_t)LLDB_REGNUM_GENERIC_FLAGS);
+}
+
+TEST(RegisterContextMinidump, CheckRegisterContextMinidump_ARM) {
+ size_t num_regs = RegisterContextMinidump_ARM::GetRegisterCountStatic();
+ const lldb_private::RegisterInfo *reg_info;
+ for (size_t reg=0; reg<num_regs; ++reg) {
+ reg_info = RegisterContextMinidump_ARM::GetRegisterInfoAtIndexStatic(reg,
+ true);
+ TestARMRegInfo(reg_info);
+ reg_info = RegisterContextMinidump_ARM::GetRegisterInfoAtIndexStatic(reg,
+ false);
+ TestARMRegInfo(reg_info);
+ }
+}