Path: blob/main/contrib/llvm-project/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.cpp
96383 views
//===-- RegisterContextMinidump_ARM64.cpp ---------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "RegisterContextMinidump_ARM64.h"910#include "Utility/ARM64_DWARF_Registers.h"11#include "lldb/Utility/RegisterValue.h"12#include "lldb/Utility/DataExtractor.h"13#include "lldb/lldb-enumerations.h"1415// C includes16#include <cassert>1718// C++ includes1920using namespace lldb;21using namespace lldb_private;22using namespace minidump;2324#define INV LLDB_INVALID_REGNUM25#define OFFSET(r) (offsetof(RegisterContextMinidump_ARM64::Context, r))2627#define DEF_X(i) \28{ \29"x" #i, nullptr, 8, OFFSET(x) + i * 8, eEncodingUint, eFormatHex, \30{arm64_dwarf::x##i, arm64_dwarf::x##i, INV, INV, reg_x##i}, \31nullptr, nullptr, nullptr, \32}3334#define DEF_W(i) \35{ \36"w" #i, nullptr, 4, OFFSET(x) + i * 8, eEncodingUint, eFormatHex, \37{INV, INV, INV, INV, reg_w##i}, nullptr, nullptr, nullptr, \38}3940#define DEF_X_ARG(i, n) \41{ \42"x" #i, "arg" #n, 8, OFFSET(x) + i * 8, eEncodingUint, eFormatHex, \43{arm64_dwarf::x##i, arm64_dwarf::x##i, LLDB_REGNUM_GENERIC_ARG1 + i, \44INV, reg_x##i}, nullptr, nullptr, nullptr, \45}4647#define DEF_V(i) \48{ \49"v" #i, nullptr, 16, OFFSET(v) + i * 16, eEncodingVector, \50eFormatVectorOfUInt8, {arm64_dwarf::v##i, arm64_dwarf::v##i, INV, INV, \51reg_v##i}, nullptr, nullptr, nullptr, \52}5354#define DEF_D(i) \55{ \56"d" #i, nullptr, 8, OFFSET(v) + i * 16, eEncodingVector, \57eFormatVectorOfUInt8, {INV, INV, INV, INV, reg_d##i}, nullptr, \58nullptr, nullptr, \59}6061#define DEF_S(i) \62{ \63"s" #i, nullptr, 4, OFFSET(v) + i * 16, eEncodingVector, \64eFormatVectorOfUInt8, {INV, INV, INV, INV, reg_s##i}, nullptr, \65nullptr, nullptr, \66}6768#define DEF_H(i) \69{ \70"h" #i, nullptr, 2, OFFSET(v) + i * 16, eEncodingVector, \71eFormatVectorOfUInt8, {INV, INV, INV, INV, reg_h##i}, nullptr, \72nullptr, nullptr, \73}7475// Zero based LLDB register numbers for this register context76enum {77// General Purpose Registers78reg_x0 = 0,79reg_x1,80reg_x2,81reg_x3,82reg_x4,83reg_x5,84reg_x6,85reg_x7,86reg_x8,87reg_x9,88reg_x10,89reg_x11,90reg_x12,91reg_x13,92reg_x14,93reg_x15,94reg_x16,95reg_x17,96reg_x18,97reg_x19,98reg_x20,99reg_x21,100reg_x22,101reg_x23,102reg_x24,103reg_x25,104reg_x26,105reg_x27,106reg_x28,107reg_fp,108reg_lr,109reg_sp,110reg_pc,111reg_w0,112reg_w1,113reg_w2,114reg_w3,115reg_w4,116reg_w5,117reg_w6,118reg_w7,119reg_w8,120reg_w9,121reg_w10,122reg_w11,123reg_w12,124reg_w13,125reg_w14,126reg_w15,127reg_w16,128reg_w17,129reg_w18,130reg_w19,131reg_w20,132reg_w21,133reg_w22,134reg_w23,135reg_w24,136reg_w25,137reg_w26,138reg_w27,139reg_w28,140reg_w29,141reg_w30,142reg_w31,143reg_cpsr,144// Floating Point Registers145reg_fpsr,146reg_fpcr,147reg_v0,148reg_v1,149reg_v2,150reg_v3,151reg_v4,152reg_v5,153reg_v6,154reg_v7,155reg_v8,156reg_v9,157reg_v10,158reg_v11,159reg_v12,160reg_v13,161reg_v14,162reg_v15,163reg_v16,164reg_v17,165reg_v18,166reg_v19,167reg_v20,168reg_v21,169reg_v22,170reg_v23,171reg_v24,172reg_v25,173reg_v26,174reg_v27,175reg_v28,176reg_v29,177reg_v30,178reg_v31,179reg_d0,180reg_d1,181reg_d2,182reg_d3,183reg_d4,184reg_d5,185reg_d6,186reg_d7,187reg_d8,188reg_d9,189reg_d10,190reg_d11,191reg_d12,192reg_d13,193reg_d14,194reg_d15,195reg_d16,196reg_d17,197reg_d18,198reg_d19,199reg_d20,200reg_d21,201reg_d22,202reg_d23,203reg_d24,204reg_d25,205reg_d26,206reg_d27,207reg_d28,208reg_d29,209reg_d30,210reg_d31,211reg_s0,212reg_s1,213reg_s2,214reg_s3,215reg_s4,216reg_s5,217reg_s6,218reg_s7,219reg_s8,220reg_s9,221reg_s10,222reg_s11,223reg_s12,224reg_s13,225reg_s14,226reg_s15,227reg_s16,228reg_s17,229reg_s18,230reg_s19,231reg_s20,232reg_s21,233reg_s22,234reg_s23,235reg_s24,236reg_s25,237reg_s26,238reg_s27,239reg_s28,240reg_s29,241reg_s30,242reg_s31,243reg_h0,244reg_h1,245reg_h2,246reg_h3,247reg_h4,248reg_h5,249reg_h6,250reg_h7,251reg_h8,252reg_h9,253reg_h10,254reg_h11,255reg_h12,256reg_h13,257reg_h14,258reg_h15,259reg_h16,260reg_h17,261reg_h18,262reg_h19,263reg_h20,264reg_h21,265reg_h22,266reg_h23,267reg_h24,268reg_h25,269reg_h26,270reg_h27,271reg_h28,272reg_h29,273reg_h30,274reg_h31,275k_num_regs276};277278// Register info definitions for this register context279static RegisterInfo g_reg_infos[] = {280DEF_X_ARG(0, 1),281DEF_X_ARG(1, 2),282DEF_X_ARG(2, 3),283DEF_X_ARG(3, 4),284DEF_X_ARG(4, 5),285DEF_X_ARG(5, 6),286DEF_X_ARG(6, 7),287DEF_X_ARG(7, 8),288DEF_X(8),289DEF_X(9),290DEF_X(10),291DEF_X(11),292DEF_X(12),293DEF_X(13),294DEF_X(14),295DEF_X(15),296DEF_X(16),297DEF_X(17),298DEF_X(18),299DEF_X(19),300DEF_X(20),301DEF_X(21),302DEF_X(22),303DEF_X(23),304DEF_X(24),305DEF_X(25),306DEF_X(26),307DEF_X(27),308DEF_X(28),309{"fp",310"x29",3118,312OFFSET(x) + 29 * 8,313eEncodingUint,314eFormatHex,315{arm64_dwarf::x29, arm64_dwarf::x29, LLDB_REGNUM_GENERIC_FP, INV, reg_fp},316nullptr,317nullptr,318nullptr,319},320{"lr",321"x30",3228,323OFFSET(x) + 30 * 8,324eEncodingUint,325eFormatHex,326{arm64_dwarf::x30, arm64_dwarf::x30, LLDB_REGNUM_GENERIC_RA, INV, reg_lr},327nullptr,328nullptr,329nullptr,330},331{"sp",332"x31",3338,334OFFSET(x) + 31 * 8,335eEncodingUint,336eFormatHex,337{arm64_dwarf::x31, arm64_dwarf::x31, LLDB_REGNUM_GENERIC_SP, INV, reg_sp},338nullptr,339nullptr,340nullptr,341},342{"pc",343nullptr,3448,345OFFSET(pc),346eEncodingUint,347eFormatHex,348{arm64_dwarf::pc, arm64_dwarf::pc, LLDB_REGNUM_GENERIC_PC, INV, reg_pc},349nullptr,350nullptr,351nullptr,352},353// w0 - w31354DEF_W(0),355DEF_W(1),356DEF_W(2),357DEF_W(3),358DEF_W(4),359DEF_W(5),360DEF_W(6),361DEF_W(7),362DEF_W(8),363DEF_W(9),364DEF_W(10),365DEF_W(11),366DEF_W(12),367DEF_W(13),368DEF_W(14),369DEF_W(15),370DEF_W(16),371DEF_W(17),372DEF_W(18),373DEF_W(19),374DEF_W(20),375DEF_W(21),376DEF_W(22),377DEF_W(23),378DEF_W(24),379DEF_W(25),380DEF_W(26),381DEF_W(27),382DEF_W(28),383DEF_W(29),384DEF_W(30),385DEF_W(31),386{"cpsr",387"psr",3884,389OFFSET(cpsr),390eEncodingUint,391eFormatHex,392{INV, arm64_dwarf::cpsr, LLDB_REGNUM_GENERIC_FLAGS, INV, reg_cpsr},393nullptr,394nullptr,395nullptr,396},397{"fpsr",398nullptr,3994,400OFFSET(fpsr),401eEncodingUint,402eFormatHex,403{INV, INV, INV, INV, reg_fpsr},404nullptr,405nullptr,406nullptr,407},408{"fpcr",409nullptr,4104,411OFFSET(fpcr),412eEncodingUint,413eFormatHex,414{INV, INV, INV, INV, reg_fpcr},415nullptr,416nullptr,417nullptr,418},419// v0 - v31420DEF_V(0),421DEF_V(1),422DEF_V(2),423DEF_V(3),424DEF_V(4),425DEF_V(5),426DEF_V(6),427DEF_V(7),428DEF_V(8),429DEF_V(9),430DEF_V(10),431DEF_V(11),432DEF_V(12),433DEF_V(13),434DEF_V(14),435DEF_V(15),436DEF_V(16),437DEF_V(17),438DEF_V(18),439DEF_V(19),440DEF_V(20),441DEF_V(21),442DEF_V(22),443DEF_V(23),444DEF_V(24),445DEF_V(25),446DEF_V(26),447DEF_V(27),448DEF_V(28),449DEF_V(29),450DEF_V(30),451DEF_V(31),452// d0 - d31453DEF_D(0),454DEF_D(1),455DEF_D(2),456DEF_D(3),457DEF_D(4),458DEF_D(5),459DEF_D(6),460DEF_D(7),461DEF_D(8),462DEF_D(9),463DEF_D(10),464DEF_D(11),465DEF_D(12),466DEF_D(13),467DEF_D(14),468DEF_D(15),469DEF_D(16),470DEF_D(17),471DEF_D(18),472DEF_D(19),473DEF_D(20),474DEF_D(21),475DEF_D(22),476DEF_D(23),477DEF_D(24),478DEF_D(25),479DEF_D(26),480DEF_D(27),481DEF_D(28),482DEF_D(29),483DEF_D(30),484DEF_D(31),485// s0 - s31486DEF_S(0),487DEF_S(1),488DEF_S(2),489DEF_S(3),490DEF_S(4),491DEF_S(5),492DEF_S(6),493DEF_S(7),494DEF_S(8),495DEF_S(9),496DEF_S(10),497DEF_S(11),498DEF_S(12),499DEF_S(13),500DEF_S(14),501DEF_S(15),502DEF_S(16),503DEF_S(17),504DEF_S(18),505DEF_S(19),506DEF_S(20),507DEF_S(21),508DEF_S(22),509DEF_S(23),510DEF_S(24),511DEF_S(25),512DEF_S(26),513DEF_S(27),514DEF_S(28),515DEF_S(29),516DEF_S(30),517DEF_S(31),518// h0 - h31519DEF_H(0),520DEF_H(1),521DEF_H(2),522DEF_H(3),523DEF_H(4),524DEF_H(5),525DEF_H(6),526DEF_H(7),527DEF_H(8),528DEF_H(9),529DEF_H(10),530DEF_H(11),531DEF_H(12),532DEF_H(13),533DEF_H(14),534DEF_H(15),535DEF_H(16),536DEF_H(17),537DEF_H(18),538DEF_H(19),539DEF_H(20),540DEF_H(21),541DEF_H(22),542DEF_H(23),543DEF_H(24),544DEF_H(25),545DEF_H(26),546DEF_H(27),547DEF_H(28),548DEF_H(29),549DEF_H(30),550DEF_H(31),551};552553constexpr size_t k_num_reg_infos = std::size(g_reg_infos);554555// ARM64 general purpose registers.556const uint32_t g_gpr_regnums[] = {557reg_x0,558reg_x1,559reg_x2,560reg_x3,561reg_x4,562reg_x5,563reg_x6,564reg_x7,565reg_x8,566reg_x9,567reg_x10,568reg_x11,569reg_x12,570reg_x13,571reg_x14,572reg_x15,573reg_x16,574reg_x17,575reg_x18,576reg_x19,577reg_x20,578reg_x21,579reg_x22,580reg_x23,581reg_x24,582reg_x25,583reg_x26,584reg_x27,585reg_x28,586reg_fp,587reg_lr,588reg_sp,589reg_w0,590reg_w1,591reg_w2,592reg_w3,593reg_w4,594reg_w5,595reg_w6,596reg_w7,597reg_w8,598reg_w9,599reg_w10,600reg_w11,601reg_w12,602reg_w13,603reg_w14,604reg_w15,605reg_w16,606reg_w17,607reg_w18,608reg_w19,609reg_w20,610reg_w21,611reg_w22,612reg_w23,613reg_w24,614reg_w25,615reg_w26,616reg_w27,617reg_w28,618reg_w29,619reg_w30,620reg_w31,621reg_pc,622reg_cpsr,623LLDB_INVALID_REGNUM // register sets need to end with this flag624};625const uint32_t g_fpu_regnums[] = {626reg_v0,627reg_v1,628reg_v2,629reg_v3,630reg_v4,631reg_v5,632reg_v6,633reg_v7,634reg_v8,635reg_v9,636reg_v10,637reg_v11,638reg_v12,639reg_v13,640reg_v14,641reg_v15,642reg_v16,643reg_v17,644reg_v18,645reg_v19,646reg_v20,647reg_v21,648reg_v22,649reg_v23,650reg_v24,651reg_v25,652reg_v26,653reg_v27,654reg_v28,655reg_v29,656reg_v30,657reg_v31,658reg_d0,659reg_d1,660reg_d2,661reg_d3,662reg_d4,663reg_d5,664reg_d6,665reg_d7,666reg_d8,667reg_d9,668reg_d10,669reg_d11,670reg_d12,671reg_d13,672reg_d14,673reg_d15,674reg_d16,675reg_d17,676reg_d18,677reg_d19,678reg_d20,679reg_d21,680reg_d22,681reg_d23,682reg_d24,683reg_d25,684reg_d26,685reg_d27,686reg_d28,687reg_d29,688reg_d30,689reg_d31,690reg_s0,691reg_s1,692reg_s2,693reg_s3,694reg_s4,695reg_s5,696reg_s6,697reg_s7,698reg_s8,699reg_s9,700reg_s10,701reg_s11,702reg_s12,703reg_s13,704reg_s14,705reg_s15,706reg_s16,707reg_s17,708reg_s18,709reg_s19,710reg_s20,711reg_s21,712reg_s22,713reg_s23,714reg_s24,715reg_s25,716reg_s26,717reg_s27,718reg_s28,719reg_s29,720reg_s30,721reg_s31,722reg_h0,723reg_h1,724reg_h2,725reg_h3,726reg_h4,727reg_h5,728reg_h6,729reg_h7,730reg_h8,731reg_h9,732reg_h10,733reg_h11,734reg_h12,735reg_h13,736reg_h14,737reg_h15,738reg_h16,739reg_h17,740reg_h18,741reg_h19,742reg_h20,743reg_h21,744reg_h22,745reg_h23,746reg_h24,747reg_h25,748reg_h26,749reg_h27,750reg_h28,751reg_h29,752reg_h30,753reg_h31,754reg_fpsr,755reg_fpcr,756LLDB_INVALID_REGNUM // register sets need to end with this flag757};758759// Skip the last LLDB_INVALID_REGNUM in each count below by subtracting 1760constexpr size_t k_num_gpr_regs = std::size(g_gpr_regnums) - 1;761constexpr size_t k_num_fpu_regs = std::size(g_fpu_regnums) - 1;762763static RegisterSet g_reg_sets[] = {764{"General Purpose Registers", "gpr", k_num_gpr_regs, g_gpr_regnums},765{"Floating Point Registers", "fpu", k_num_fpu_regs, g_fpu_regnums},766};767768constexpr size_t k_num_reg_sets = std::size(g_reg_sets);769770RegisterContextMinidump_ARM64::RegisterContextMinidump_ARM64(771lldb_private::Thread &thread, const DataExtractor &data)772: RegisterContext(thread, 0) {773lldb::offset_t offset = 0;774m_regs.context_flags = data.GetU64(&offset);775for (unsigned i = 0; i < 32; ++i)776m_regs.x[i] = data.GetU64(&offset);777m_regs.pc = data.GetU64(&offset);778m_regs.cpsr = data.GetU32(&offset);779m_regs.fpsr = data.GetU32(&offset);780m_regs.fpcr = data.GetU32(&offset);781auto regs_data = data.GetData(&offset, sizeof(m_regs.v));782if (regs_data)783memcpy(m_regs.v, regs_data, sizeof(m_regs.v));784static_assert(k_num_regs == k_num_reg_infos);785}786size_t RegisterContextMinidump_ARM64::GetRegisterCount() { return k_num_regs; }787788const RegisterInfo *789RegisterContextMinidump_ARM64::GetRegisterInfoAtIndex(size_t reg) {790if (reg < k_num_reg_infos)791return &g_reg_infos[reg];792return nullptr;793}794795size_t RegisterContextMinidump_ARM64::GetRegisterSetCount() {796return k_num_reg_sets;797}798799const RegisterSet *RegisterContextMinidump_ARM64::GetRegisterSet(size_t set) {800if (set < k_num_reg_sets)801return &g_reg_sets[set];802return nullptr;803}804805const char *RegisterContextMinidump_ARM64::GetRegisterName(unsigned reg) {806if (reg < k_num_reg_infos)807return g_reg_infos[reg].name;808return nullptr;809}810811bool RegisterContextMinidump_ARM64::ReadRegister(const RegisterInfo *reg_info,812RegisterValue ®_value) {813Status error;814reg_value.SetFromMemoryData(815*reg_info, (const uint8_t *)&m_regs + reg_info->byte_offset,816reg_info->byte_size, lldb::eByteOrderLittle, error);817return error.Success();818}819820bool RegisterContextMinidump_ARM64::WriteRegister(const RegisterInfo *,821const RegisterValue &) {822return false;823}824825uint32_t RegisterContextMinidump_ARM64::ConvertRegisterKindToRegisterNumber(826lldb::RegisterKind kind, uint32_t num) {827for (size_t i = 0; i < k_num_regs; ++i) {828if (g_reg_infos[i].kinds[kind] == num)829return i;830}831return LLDB_INVALID_REGNUM;832}833834835