Path: blob/main/contrib/llvm-project/lldb/source/Target/ABI.cpp
39587 views
//===-- ABI.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 "lldb/Target/ABI.h"9#include "lldb/Core/PluginManager.h"10#include "lldb/Core/Value.h"11#include "lldb/Core/ValueObjectConstResult.h"12#include "lldb/Expression/ExpressionVariable.h"13#include "lldb/Symbol/CompilerType.h"14#include "lldb/Symbol/TypeSystem.h"15#include "lldb/Target/Target.h"16#include "lldb/Target/Thread.h"17#include "lldb/Utility/LLDBLog.h"18#include "lldb/Utility/Log.h"19#include "llvm/MC/TargetRegistry.h"20#include <cctype>2122using namespace lldb;23using namespace lldb_private;2425ABISP26ABI::FindPlugin(lldb::ProcessSP process_sp, const ArchSpec &arch) {27ABISP abi_sp;28ABICreateInstance create_callback;2930for (uint32_t idx = 0;31(create_callback = PluginManager::GetABICreateCallbackAtIndex(idx)) !=32nullptr;33++idx) {34abi_sp = create_callback(process_sp, arch);3536if (abi_sp)37return abi_sp;38}39abi_sp.reset();40return abi_sp;41}4243ABI::~ABI() = default;4445bool RegInfoBasedABI::GetRegisterInfoByName(llvm::StringRef name,46RegisterInfo &info) {47uint32_t count = 0;48const RegisterInfo *register_info_array = GetRegisterInfoArray(count);49if (register_info_array) {50uint32_t i;51for (i = 0; i < count; ++i) {52const char *reg_name = register_info_array[i].name;53if (reg_name == name) {54info = register_info_array[i];55return true;56}57}58for (i = 0; i < count; ++i) {59const char *reg_alt_name = register_info_array[i].alt_name;60if (reg_alt_name == name) {61info = register_info_array[i];62return true;63}64}65}66return false;67}6869ValueObjectSP ABI::GetReturnValueObject(Thread &thread, CompilerType &ast_type,70bool persistent) const {71if (!ast_type.IsValid())72return ValueObjectSP();7374ValueObjectSP return_valobj_sp;7576return_valobj_sp = GetReturnValueObjectImpl(thread, ast_type);77if (!return_valobj_sp)78return return_valobj_sp;7980// Now turn this into a persistent variable.81// FIXME: This code is duplicated from Target::EvaluateExpression, and it is82// used in similar form in a couple83// of other places. Figure out the correct Create function to do all this84// work.8586if (persistent) {87Target &target = *thread.CalculateTarget();88PersistentExpressionState *persistent_expression_state =89target.GetPersistentExpressionStateForLanguage(90ast_type.GetMinimumLanguage());9192if (!persistent_expression_state)93return {};9495ConstString persistent_variable_name =96persistent_expression_state->GetNextPersistentVariableName();9798lldb::ValueObjectSP const_valobj_sp;99100// Check in case our value is already a constant value101if (return_valobj_sp->GetIsConstant()) {102const_valobj_sp = return_valobj_sp;103const_valobj_sp->SetName(persistent_variable_name);104} else105const_valobj_sp =106return_valobj_sp->CreateConstantValue(persistent_variable_name);107108lldb::ValueObjectSP live_valobj_sp = return_valobj_sp;109110return_valobj_sp = const_valobj_sp;111112ExpressionVariableSP expr_variable_sp(113persistent_expression_state->CreatePersistentVariable(114return_valobj_sp));115116assert(expr_variable_sp);117118// Set flags and live data as appropriate119120const Value &result_value = live_valobj_sp->GetValue();121122switch (result_value.GetValueType()) {123case Value::ValueType::Invalid:124return {};125case Value::ValueType::HostAddress:126case Value::ValueType::FileAddress:127// we odon't do anything with these for now128break;129case Value::ValueType::Scalar:130expr_variable_sp->m_flags |=131ExpressionVariable::EVIsFreezeDried;132expr_variable_sp->m_flags |=133ExpressionVariable::EVIsLLDBAllocated;134expr_variable_sp->m_flags |=135ExpressionVariable::EVNeedsAllocation;136break;137case Value::ValueType::LoadAddress:138expr_variable_sp->m_live_sp = live_valobj_sp;139expr_variable_sp->m_flags |=140ExpressionVariable::EVIsProgramReference;141break;142}143144return_valobj_sp = expr_variable_sp->GetValueObject();145}146return return_valobj_sp;147}148149addr_t ABI::FixCodeAddress(lldb::addr_t pc) {150ProcessSP process_sp(GetProcessSP());151152addr_t mask = process_sp->GetCodeAddressMask();153if (mask == LLDB_INVALID_ADDRESS_MASK)154return pc;155156// Assume the high bit is used for addressing, which157// may not be correct on all architectures e.g. AArch64158// where Top Byte Ignore mode is often used to store159// metadata in the top byte, and b55 is the bit used for160// differentiating between low- and high-memory addresses.161// That target's ABIs need to override this method.162bool is_highmem = pc & (1ULL << 63);163return is_highmem ? pc | mask : pc & (~mask);164}165166addr_t ABI::FixDataAddress(lldb::addr_t pc) {167ProcessSP process_sp(GetProcessSP());168addr_t mask = process_sp->GetDataAddressMask();169if (mask == LLDB_INVALID_ADDRESS_MASK)170return pc;171172// Assume the high bit is used for addressing, which173// may not be correct on all architectures e.g. AArch64174// where Top Byte Ignore mode is often used to store175// metadata in the top byte, and b55 is the bit used for176// differentiating between low- and high-memory addresses.177// That target's ABIs need to override this method.178bool is_highmem = pc & (1ULL << 63);179return is_highmem ? pc | mask : pc & (~mask);180}181182ValueObjectSP ABI::GetReturnValueObject(Thread &thread, llvm::Type &ast_type,183bool persistent) const {184ValueObjectSP return_valobj_sp;185return_valobj_sp = GetReturnValueObjectImpl(thread, ast_type);186return return_valobj_sp;187}188189// specialized to work with llvm IR types190//191// for now we will specify a default implementation so that we don't need to192// modify other ABIs193lldb::ValueObjectSP ABI::GetReturnValueObjectImpl(Thread &thread,194llvm::Type &ir_type) const {195ValueObjectSP return_valobj_sp;196197/* this is a dummy and will only be called if an ABI does not override this */198199return return_valobj_sp;200}201202bool ABI::PrepareTrivialCall(Thread &thread, lldb::addr_t sp,203lldb::addr_t functionAddress,204lldb::addr_t returnAddress, llvm::Type &returntype,205llvm::ArrayRef<ABI::CallArgument> args) const {206// dummy prepare trivial call207llvm_unreachable("Should never get here!");208}209210bool ABI::GetFallbackRegisterLocation(211const RegisterInfo *reg_info,212UnwindPlan::Row::RegisterLocation &unwind_regloc) {213// Did the UnwindPlan fail to give us the caller's stack pointer? The stack214// pointer is defined to be the same as THIS frame's CFA, so return the CFA215// value as the caller's stack pointer. This is true on x86-32/x86-64 at216// least.217if (reg_info->kinds[eRegisterKindGeneric] == LLDB_REGNUM_GENERIC_SP) {218unwind_regloc.SetIsCFAPlusOffset(0);219return true;220}221222// If a volatile register is being requested, we don't want to forward the223// next frame's register contents up the stack -- the register is not224// retrievable at this frame.225if (RegisterIsVolatile(reg_info)) {226unwind_regloc.SetUndefined();227return true;228}229230return false;231}232233std::unique_ptr<llvm::MCRegisterInfo> ABI::MakeMCRegisterInfo(const ArchSpec &arch) {234std::string triple = arch.GetTriple().getTriple();235std::string lookup_error;236const llvm::Target *target =237llvm::TargetRegistry::lookupTarget(triple, lookup_error);238if (!target) {239LLDB_LOG(GetLog(LLDBLog::Process),240"Failed to create an llvm target for {0}: {1}", triple,241lookup_error);242return nullptr;243}244std::unique_ptr<llvm::MCRegisterInfo> info_up(245target->createMCRegInfo(triple));246assert(info_up);247return info_up;248}249250void RegInfoBasedABI::AugmentRegisterInfo(251std::vector<DynamicRegisterInfo::Register> ®s) {252for (DynamicRegisterInfo::Register &info : regs) {253if (info.regnum_ehframe != LLDB_INVALID_REGNUM &&254info.regnum_dwarf != LLDB_INVALID_REGNUM)255continue;256257RegisterInfo abi_info;258if (!GetRegisterInfoByName(info.name.GetStringRef(), abi_info))259continue;260261if (info.regnum_ehframe == LLDB_INVALID_REGNUM)262info.regnum_ehframe = abi_info.kinds[eRegisterKindEHFrame];263if (info.regnum_dwarf == LLDB_INVALID_REGNUM)264info.regnum_dwarf = abi_info.kinds[eRegisterKindDWARF];265if (info.regnum_generic == LLDB_INVALID_REGNUM)266info.regnum_generic = abi_info.kinds[eRegisterKindGeneric];267}268}269270void MCBasedABI::AugmentRegisterInfo(271std::vector<DynamicRegisterInfo::Register> ®s) {272for (DynamicRegisterInfo::Register &info : regs) {273uint32_t eh, dwarf;274std::tie(eh, dwarf) = GetEHAndDWARFNums(info.name.GetStringRef());275276if (info.regnum_ehframe == LLDB_INVALID_REGNUM)277info.regnum_ehframe = eh;278if (info.regnum_dwarf == LLDB_INVALID_REGNUM)279info.regnum_dwarf = dwarf;280if (info.regnum_generic == LLDB_INVALID_REGNUM)281info.regnum_generic = GetGenericNum(info.name.GetStringRef());282}283}284285std::pair<uint32_t, uint32_t>286MCBasedABI::GetEHAndDWARFNums(llvm::StringRef name) {287std::string mc_name = GetMCName(name.str());288for (char &c : mc_name)289c = std::toupper(c);290int eh = -1;291int dwarf = -1;292for (unsigned reg = 0; reg < m_mc_register_info_up->getNumRegs(); ++reg) {293if (m_mc_register_info_up->getName(reg) == mc_name) {294eh = m_mc_register_info_up->getDwarfRegNum(reg, /*isEH=*/true);295dwarf = m_mc_register_info_up->getDwarfRegNum(reg, /*isEH=*/false);296break;297}298}299return std::pair<uint32_t, uint32_t>(eh == -1 ? LLDB_INVALID_REGNUM : eh,300dwarf == -1 ? LLDB_INVALID_REGNUM301: dwarf);302}303304void MCBasedABI::MapRegisterName(std::string &name, llvm::StringRef from_prefix,305llvm::StringRef to_prefix) {306llvm::StringRef name_ref = name;307if (!name_ref.consume_front(from_prefix))308return;309uint64_t _;310if (name_ref.empty() || to_integer(name_ref, _, 10))311name = (to_prefix + name_ref).str();312}313314315