brintos

brintos / llvm-project-archived public Read only

0
0
Text · 11.5 KiB · 0004d5d Raw
551 lines · cpp
1//===-- RegisterContextMinidump_ARM.cpp -----------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "RegisterContextMinidump_ARM.h"10 11#include "Utility/ARM_DWARF_Registers.h"12#include "Utility/ARM_ehframe_Registers.h"13#include "lldb/Utility/RegisterValue.h"14#include "lldb/Utility/DataExtractor.h"15#include "lldb/Utility/LLDBAssert.h"16#include "lldb/lldb-enumerations.h"17 18// C includes19#include <cassert>20 21// C++ includes22 23using namespace lldb;24using namespace lldb_private;25using namespace minidump;26 27#define INV LLDB_INVALID_REGNUM28#define OFFSET(r) (offsetof(RegisterContextMinidump_ARM::Context, r))29 30#define DEF_R(i)                                                               \31  {                                                                            \32    "r" #i, nullptr, 4, OFFSET(r) + i * 4, eEncodingUint, eFormatHex,          \33        {ehframe_r##i, dwarf_r##i, INV, INV, reg_r##i}, nullptr, nullptr,      \34        nullptr,                                                               \35  }36 37#define DEF_R_ARG(i, n)                                                        \38  {                                                                            \39    "r" #i, "arg" #n, 4, OFFSET(r) + i * 4, eEncodingUint, eFormatHex,         \40        {ehframe_r##i, dwarf_r##i, LLDB_REGNUM_GENERIC_ARG1 + i, INV,          \41         reg_r##i},                                                            \42        nullptr, nullptr, nullptr,                                             \43  }44 45#define DEF_D(i)                                                               \46  {                                                                            \47    "d" #i, nullptr, 8, OFFSET(d) + i * 8, eEncodingVector,                    \48        eFormatVectorOfUInt8, {dwarf_d##i, dwarf_d##i, INV, INV, reg_d##i},    \49        nullptr, nullptr, nullptr,                                             \50  }51 52#define DEF_S(i)                                                               \53  {                                                                            \54    "s" #i, nullptr, 4, OFFSET(s) + i * 4, eEncodingIEEE754, eFormatFloat,     \55        {dwarf_s##i, dwarf_s##i, INV, INV, reg_s##i}, nullptr, nullptr,        \56        nullptr,                                                               \57  }58 59#define DEF_Q(i)                                                               \60  {                                                                            \61    "q" #i, nullptr, 16, OFFSET(q) + i * 16, eEncodingVector,                  \62        eFormatVectorOfUInt8, {dwarf_q##i, dwarf_q##i, INV, INV, reg_q##i},    \63        nullptr, nullptr, nullptr,                                             \64  }65 66// Zero based LLDB register numbers for this register context67enum {68  // General Purpose Registers69  reg_r0,70  reg_r1,71  reg_r2,72  reg_r3,73  reg_r4,74  reg_r5,75  reg_r6,76  reg_r7,77  reg_r8,78  reg_r9,79  reg_r10,80  reg_r11,81  reg_r12,82  reg_sp,83  reg_lr,84  reg_pc,85  reg_cpsr,86  // Floating Point Registers87  reg_fpscr,88  reg_d0,89  reg_d1,90  reg_d2,91  reg_d3,92  reg_d4,93  reg_d5,94  reg_d6,95  reg_d7,96  reg_d8,97  reg_d9,98  reg_d10,99  reg_d11,100  reg_d12,101  reg_d13,102  reg_d14,103  reg_d15,104  reg_d16,105  reg_d17,106  reg_d18,107  reg_d19,108  reg_d20,109  reg_d21,110  reg_d22,111  reg_d23,112  reg_d24,113  reg_d25,114  reg_d26,115  reg_d27,116  reg_d28,117  reg_d29,118  reg_d30,119  reg_d31,120  reg_s0,121  reg_s1,122  reg_s2,123  reg_s3,124  reg_s4,125  reg_s5,126  reg_s6,127  reg_s7,128  reg_s8,129  reg_s9,130  reg_s10,131  reg_s11,132  reg_s12,133  reg_s13,134  reg_s14,135  reg_s15,136  reg_s16,137  reg_s17,138  reg_s18,139  reg_s19,140  reg_s20,141  reg_s21,142  reg_s22,143  reg_s23,144  reg_s24,145  reg_s25,146  reg_s26,147  reg_s27,148  reg_s28,149  reg_s29,150  reg_s30,151  reg_s31,152  reg_q0,153  reg_q1,154  reg_q2,155  reg_q3,156  reg_q4,157  reg_q5,158  reg_q6,159  reg_q7,160  reg_q8,161  reg_q9,162  reg_q10,163  reg_q11,164  reg_q12,165  reg_q13,166  reg_q14,167  reg_q15,168  k_num_regs169};170 171static RegisterInfo g_reg_info_apple_fp = {172    "fp",173    "r7",174    4,175    OFFSET(r) + 7 * 4,176    eEncodingUint,177    eFormatHex,178    {ehframe_r7, dwarf_r7, LLDB_REGNUM_GENERIC_FP, INV, reg_r7},179    nullptr,180    nullptr,181    nullptr,182};183 184static RegisterInfo g_reg_info_fp = {185    "fp",186    "r11",187    4,188    OFFSET(r) + 11 * 4,189    eEncodingUint,190    eFormatHex,191    {ehframe_r11, dwarf_r11, LLDB_REGNUM_GENERIC_FP, INV, reg_r11},192    nullptr,193    nullptr,194    nullptr,195};196 197// Register info definitions for this register context198static RegisterInfo g_reg_infos[] = {199    DEF_R_ARG(0, 1),200    DEF_R_ARG(1, 2),201    DEF_R_ARG(2, 3),202    DEF_R_ARG(3, 4),203    DEF_R(4),204    DEF_R(5),205    DEF_R(6),206    DEF_R(7),207    DEF_R(8),208    DEF_R(9),209    DEF_R(10),210    DEF_R(11),211    DEF_R(12),212    {"sp",213     "r13",214     4,215     OFFSET(r) + 13 * 4,216     eEncodingUint,217     eFormatHex,218     {ehframe_sp, dwarf_sp, LLDB_REGNUM_GENERIC_SP, INV, reg_sp},219     nullptr,220     nullptr,221     nullptr,222    },223    {"lr",224     "r14",225     4,226     OFFSET(r) + 14 * 4,227     eEncodingUint,228     eFormatHex,229     {ehframe_lr, dwarf_lr, LLDB_REGNUM_GENERIC_RA, INV, reg_lr},230     nullptr,231     nullptr,232     nullptr,233    },234    {"pc",235     "r15",236     4,237     OFFSET(r) + 15 * 4,238     eEncodingUint,239     eFormatHex,240     {ehframe_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, INV, reg_pc},241     nullptr,242     nullptr,243     nullptr,244    },245    {"cpsr",246     "psr",247     4,248     OFFSET(cpsr),249     eEncodingUint,250     eFormatHex,251     {ehframe_cpsr, dwarf_cpsr, LLDB_REGNUM_GENERIC_FLAGS, INV, reg_cpsr},252     nullptr,253     nullptr,254     nullptr,255    },256    {"fpscr",257     nullptr,258     8,259     OFFSET(fpscr),260     eEncodingUint,261     eFormatHex,262     {INV, INV, INV, INV, reg_fpscr},263     nullptr,264     nullptr,265     nullptr,266    },267    DEF_D(0),268    DEF_D(1),269    DEF_D(2),270    DEF_D(3),271    DEF_D(4),272    DEF_D(5),273    DEF_D(6),274    DEF_D(7),275    DEF_D(8),276    DEF_D(9),277    DEF_D(10),278    DEF_D(11),279    DEF_D(12),280    DEF_D(13),281    DEF_D(14),282    DEF_D(15),283    DEF_D(16),284    DEF_D(17),285    DEF_D(18),286    DEF_D(19),287    DEF_D(20),288    DEF_D(21),289    DEF_D(22),290    DEF_D(23),291    DEF_D(24),292    DEF_D(25),293    DEF_D(26),294    DEF_D(27),295    DEF_D(28),296    DEF_D(29),297    DEF_D(30),298    DEF_D(31),299    DEF_S(0),300    DEF_S(1),301    DEF_S(2),302    DEF_S(3),303    DEF_S(4),304    DEF_S(5),305    DEF_S(6),306    DEF_S(7),307    DEF_S(8),308    DEF_S(9),309    DEF_S(10),310    DEF_S(11),311    DEF_S(12),312    DEF_S(13),313    DEF_S(14),314    DEF_S(15),315    DEF_S(16),316    DEF_S(17),317    DEF_S(18),318    DEF_S(19),319    DEF_S(20),320    DEF_S(21),321    DEF_S(22),322    DEF_S(23),323    DEF_S(24),324    DEF_S(25),325    DEF_S(26),326    DEF_S(27),327    DEF_S(28),328    DEF_S(29),329    DEF_S(30),330    DEF_S(31),331    DEF_Q(0),332    DEF_Q(1),333    DEF_Q(2),334    DEF_Q(3),335    DEF_Q(4),336    DEF_Q(5),337    DEF_Q(6),338    DEF_Q(7),339    DEF_Q(8),340    DEF_Q(9),341    DEF_Q(10),342    DEF_Q(11),343    DEF_Q(12),344    DEF_Q(13),345    DEF_Q(14),346    DEF_Q(15)};347 348constexpr size_t k_num_reg_infos = std::size(g_reg_infos);349 350// ARM general purpose registers.351const uint32_t g_gpr_regnums[] = {352    reg_r0,353    reg_r1,354    reg_r2,355    reg_r3,356    reg_r4,357    reg_r5,358    reg_r6,359    reg_r7,360    reg_r8,361    reg_r9,362    reg_r10,363    reg_r11,364    reg_r12,365    reg_sp,366    reg_lr,367    reg_pc,368    reg_cpsr,369    LLDB_INVALID_REGNUM // register sets need to end with this flag370};371const uint32_t g_fpu_regnums[] = {372    reg_fpscr,373    reg_d0,374    reg_d1,375    reg_d2,376    reg_d3,377    reg_d4,378    reg_d5,379    reg_d6,380    reg_d7,381    reg_d8,382    reg_d9,383    reg_d10,384    reg_d11,385    reg_d12,386    reg_d13,387    reg_d14,388    reg_d15,389    reg_d16,390    reg_d17,391    reg_d18,392    reg_d19,393    reg_d20,394    reg_d21,395    reg_d22,396    reg_d23,397    reg_d24,398    reg_d25,399    reg_d26,400    reg_d27,401    reg_d28,402    reg_d29,403    reg_d30,404    reg_d31,405    reg_s0,406    reg_s1,407    reg_s2,408    reg_s3,409    reg_s4,410    reg_s5,411    reg_s6,412    reg_s7,413    reg_s8,414    reg_s9,415    reg_s10,416    reg_s11,417    reg_s12,418    reg_s13,419    reg_s14,420    reg_s15,421    reg_s16,422    reg_s17,423    reg_s18,424    reg_s19,425    reg_s20,426    reg_s21,427    reg_s22,428    reg_s23,429    reg_s24,430    reg_s25,431    reg_s26,432    reg_s27,433    reg_s28,434    reg_s29,435    reg_s30,436    reg_s31,437    reg_q0,438    reg_q1,439    reg_q2,440    reg_q3,441    reg_q4,442    reg_q5,443    reg_q6,444    reg_q7,445    reg_q8,446    reg_q9,447    reg_q10,448    reg_q11,449    reg_q12,450    reg_q13,451    reg_q14,452    reg_q15,453    LLDB_INVALID_REGNUM // register sets need to end with this flag454};455 456// Skip the last LLDB_INVALID_REGNUM in each count below by subtracting 1457constexpr size_t k_num_gpr_regs = std::size(g_gpr_regnums) - 1;458constexpr size_t k_num_fpu_regs = std::size(g_fpu_regnums) - 1;459 460static RegisterSet g_reg_sets[] = {461    {"General Purpose Registers", "gpr", k_num_gpr_regs, g_gpr_regnums},462    {"Floating Point Registers", "fpu", k_num_fpu_regs, g_fpu_regnums},463};464 465constexpr size_t k_num_reg_sets = std::size(g_reg_sets);466 467RegisterContextMinidump_ARM::RegisterContextMinidump_ARM(468    lldb_private::Thread &thread, const DataExtractor &data, bool apple)469    : RegisterContext(thread, 0), m_apple(apple) {470  lldb::offset_t offset = 0;471  m_regs.context_flags = data.GetU32(&offset);472  for (unsigned i = 0; i < std::size(m_regs.r); ++i)473    m_regs.r[i] = data.GetU32(&offset);474  m_regs.cpsr = data.GetU32(&offset);475  m_regs.fpscr = data.GetU64(&offset);476  for (unsigned i = 0; i < std::size(m_regs.d); ++i)477    m_regs.d[i] = data.GetU64(&offset);478  lldbassert(k_num_regs == k_num_reg_infos);479}480 481size_t RegisterContextMinidump_ARM::GetRegisterCountStatic() {482  return k_num_regs;483}484 485// Used for unit testing so we can verify register info is filled in for486// all register flavors (DWARF, EH Frame, generic, etc).487size_t RegisterContextMinidump_ARM::GetRegisterCount() {488  return GetRegisterCountStatic();489}490 491// Used for unit testing so we can verify register info is filled in.492const RegisterInfo *493RegisterContextMinidump_ARM::GetRegisterInfoAtIndexStatic(size_t reg,494                                                          bool apple) {495  if (reg < k_num_reg_infos) {496    if (apple) {497      if (reg == reg_r7)498        return &g_reg_info_apple_fp;499    } else {500      if (reg == reg_r11)501        return &g_reg_info_fp;502    }503    return &g_reg_infos[reg];504  }505  return nullptr;506}507 508const RegisterInfo *509RegisterContextMinidump_ARM::GetRegisterInfoAtIndex(size_t reg) {510  return GetRegisterInfoAtIndexStatic(reg, m_apple);511}512 513size_t RegisterContextMinidump_ARM::GetRegisterSetCount() {514  return k_num_reg_sets;515}516 517const RegisterSet *RegisterContextMinidump_ARM::GetRegisterSet(size_t set) {518  if (set < k_num_reg_sets)519    return &g_reg_sets[set];520  return nullptr;521}522 523const char *RegisterContextMinidump_ARM::GetRegisterName(unsigned reg) {524  if (reg < k_num_reg_infos)525    return g_reg_infos[reg].name;526  return nullptr;527}528 529bool RegisterContextMinidump_ARM::ReadRegister(const RegisterInfo *reg_info,530                                               RegisterValue &reg_value) {531  Status error;532  reg_value.SetFromMemoryData(533      *reg_info, (const uint8_t *)&m_regs + reg_info->byte_offset,534      reg_info->byte_size, lldb::eByteOrderLittle, error);535  return error.Success();536}537 538bool RegisterContextMinidump_ARM::WriteRegister(const RegisterInfo *,539                                                const RegisterValue &) {540  return false;541}542 543uint32_t RegisterContextMinidump_ARM::ConvertRegisterKindToRegisterNumber(544    lldb::RegisterKind kind, uint32_t num) {545  for (size_t i = 0; i < k_num_regs; ++i) {546    if (g_reg_infos[i].kinds[kind] == num)547      return i;548  }549  return LLDB_INVALID_REGNUM;550}551