Path: blob/main/contrib/llvm-project/lldb/source/Plugins/Architecture/AArch64/ArchitectureAArch64.cpp
39645 views
//===-- ArchitectureAArch64.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 "Plugins/Architecture/AArch64/ArchitectureAArch64.h"9#include "lldb/Core/PluginManager.h"10#include "lldb/Target/RegisterContext.h"11#include "lldb/Utility/ArchSpec.h"12#include "lldb/Utility/DataBufferHeap.h"13#include "lldb/Utility/DataExtractor.h"1415using namespace lldb_private;16using namespace lldb;1718LLDB_PLUGIN_DEFINE(ArchitectureAArch64)1920void ArchitectureAArch64::Initialize() {21PluginManager::RegisterPlugin(GetPluginNameStatic(),22"AArch64-specific algorithms",23&ArchitectureAArch64::Create);24}2526void ArchitectureAArch64::Terminate() {27PluginManager::UnregisterPlugin(&ArchitectureAArch64::Create);28}2930std::unique_ptr<Architecture>31ArchitectureAArch64::Create(const ArchSpec &arch) {32auto machine = arch.GetMachine();33if (machine != llvm::Triple::aarch64 && machine != llvm::Triple::aarch64_be &&34machine != llvm::Triple::aarch64_32) {35return nullptr;36}37return std::unique_ptr<Architecture>(new ArchitectureAArch64());38}3940static void41UpdateARM64SVERegistersInfos(DynamicRegisterInfo::reg_collection_range regs,42uint64_t vg) {43// SVE Z register size is vg x 8 bytes.44uint32_t z_reg_byte_size = vg * 8;4546// SVE vector length has changed, accordingly set size of Z, P and FFR47// registers. Also invalidate register offsets it will be recalculated48// after SVE register size update.49for (auto ® : regs) {50if (reg.value_regs == nullptr) {51if (reg.name[0] == 'z' && isdigit(reg.name[1]))52reg.byte_size = z_reg_byte_size;53else if (reg.name[0] == 'p' && isdigit(reg.name[1]))54reg.byte_size = vg;55else if (strcmp(reg.name, "ffr") == 0)56reg.byte_size = vg;57}58reg.byte_offset = LLDB_INVALID_INDEX32;59}60}6162static void63UpdateARM64SMERegistersInfos(DynamicRegisterInfo::reg_collection_range regs,64uint64_t svg) {65for (auto ® : regs) {66if (strcmp(reg.name, "za") == 0) {67// ZA is a register with size (svg*8) * (svg*8). A square essentially.68reg.byte_size = (svg * 8) * (svg * 8);69}70reg.byte_offset = LLDB_INVALID_INDEX32;71}72}7374bool ArchitectureAArch64::ReconfigureRegisterInfo(DynamicRegisterInfo ®_info,75DataExtractor ®_data,76RegisterContext ®_context7778) const {79// Once we start to reconfigure registers, we cannot read any of them.80// So we must read VG and SVG up front.8182const uint64_t fail_value = LLDB_INVALID_ADDRESS;83std::optional<uint64_t> vg_reg_value;84const RegisterInfo *vg_reg_info = reg_info.GetRegisterInfo("vg");85if (vg_reg_info) {86uint32_t vg_reg_num = vg_reg_info->kinds[eRegisterKindLLDB];87uint64_t reg_value =88reg_context.ReadRegisterAsUnsigned(vg_reg_num, fail_value);89if (reg_value != fail_value && reg_value <= 32)90vg_reg_value = reg_value;91}9293std::optional<uint64_t> svg_reg_value;94const RegisterInfo *svg_reg_info = reg_info.GetRegisterInfo("svg");95if (svg_reg_info) {96uint32_t svg_reg_num = svg_reg_info->kinds[eRegisterKindLLDB];97uint64_t reg_value =98reg_context.ReadRegisterAsUnsigned(svg_reg_num, fail_value);99if (reg_value != fail_value && reg_value <= 32)100svg_reg_value = reg_value;101}102103if (!vg_reg_value && !svg_reg_value)104return false;105106auto regs = reg_info.registers<DynamicRegisterInfo::reg_collection_range>();107if (vg_reg_value)108UpdateARM64SVERegistersInfos(regs, *vg_reg_value);109if (svg_reg_value)110UpdateARM64SMERegistersInfos(regs, *svg_reg_value);111112// At this point if we have updated any registers, their offsets will all be113// invalid. If we did, we need to update them all.114reg_info.ConfigureOffsets();115// From here we are able to read registers again.116117// Make a heap based buffer that is big enough to store all registers118reg_data.SetData(119std::make_shared<DataBufferHeap>(reg_info.GetRegisterDataByteSize(), 0));120reg_data.SetByteOrder(reg_context.GetByteOrder());121122return true;123}124125126