15ffd83dbSDimitry Andric //===-- ABI.cpp -----------------------------------------------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andric #include "lldb/Target/ABI.h" 100b57cec5SDimitry Andric #include "lldb/Core/PluginManager.h" 110b57cec5SDimitry Andric #include "lldb/Core/Value.h" 120b57cec5SDimitry Andric #include "lldb/Core/ValueObjectConstResult.h" 130b57cec5SDimitry Andric #include "lldb/Expression/ExpressionVariable.h" 140b57cec5SDimitry Andric #include "lldb/Symbol/CompilerType.h" 150b57cec5SDimitry Andric #include "lldb/Symbol/TypeSystem.h" 160b57cec5SDimitry Andric #include "lldb/Target/Target.h" 170b57cec5SDimitry Andric #include "lldb/Target/Thread.h" 1881ad6265SDimitry Andric #include "lldb/Utility/LLDBLog.h" 199dba64beSDimitry Andric #include "lldb/Utility/Log.h" 20349cc55cSDimitry Andric #include "llvm/MC/TargetRegistry.h" 215ffd83dbSDimitry Andric #include <cctype> 220b57cec5SDimitry Andric 230b57cec5SDimitry Andric using namespace lldb; 240b57cec5SDimitry Andric using namespace lldb_private; 250b57cec5SDimitry Andric 260b57cec5SDimitry Andric ABISP 270b57cec5SDimitry Andric ABI::FindPlugin(lldb::ProcessSP process_sp, const ArchSpec &arch) { 280b57cec5SDimitry Andric ABISP abi_sp; 290b57cec5SDimitry Andric ABICreateInstance create_callback; 300b57cec5SDimitry Andric 310b57cec5SDimitry Andric for (uint32_t idx = 0; 320b57cec5SDimitry Andric (create_callback = PluginManager::GetABICreateCallbackAtIndex(idx)) != 330b57cec5SDimitry Andric nullptr; 340b57cec5SDimitry Andric ++idx) { 350b57cec5SDimitry Andric abi_sp = create_callback(process_sp, arch); 360b57cec5SDimitry Andric 370b57cec5SDimitry Andric if (abi_sp) 380b57cec5SDimitry Andric return abi_sp; 390b57cec5SDimitry Andric } 400b57cec5SDimitry Andric abi_sp.reset(); 410b57cec5SDimitry Andric return abi_sp; 420b57cec5SDimitry Andric } 430b57cec5SDimitry Andric 440b57cec5SDimitry Andric ABI::~ABI() = default; 450b57cec5SDimitry Andric 46e8d8bef9SDimitry Andric bool RegInfoBasedABI::GetRegisterInfoByName(llvm::StringRef name, 47e8d8bef9SDimitry Andric RegisterInfo &info) { 480b57cec5SDimitry Andric uint32_t count = 0; 490b57cec5SDimitry Andric const RegisterInfo *register_info_array = GetRegisterInfoArray(count); 500b57cec5SDimitry Andric if (register_info_array) { 510b57cec5SDimitry Andric uint32_t i; 520b57cec5SDimitry Andric for (i = 0; i < count; ++i) { 535ffd83dbSDimitry Andric const char *reg_name = register_info_array[i].name; 54e8d8bef9SDimitry Andric if (reg_name == name) { 550b57cec5SDimitry Andric info = register_info_array[i]; 560b57cec5SDimitry Andric return true; 570b57cec5SDimitry Andric } 580b57cec5SDimitry Andric } 590b57cec5SDimitry Andric for (i = 0; i < count; ++i) { 605ffd83dbSDimitry Andric const char *reg_alt_name = register_info_array[i].alt_name; 61e8d8bef9SDimitry Andric if (reg_alt_name == name) { 620b57cec5SDimitry Andric info = register_info_array[i]; 630b57cec5SDimitry Andric return true; 640b57cec5SDimitry Andric } 650b57cec5SDimitry Andric } 660b57cec5SDimitry Andric } 670b57cec5SDimitry Andric return false; 680b57cec5SDimitry Andric } 690b57cec5SDimitry Andric 700b57cec5SDimitry Andric ValueObjectSP ABI::GetReturnValueObject(Thread &thread, CompilerType &ast_type, 710b57cec5SDimitry Andric bool persistent) const { 720b57cec5SDimitry Andric if (!ast_type.IsValid()) 730b57cec5SDimitry Andric return ValueObjectSP(); 740b57cec5SDimitry Andric 750b57cec5SDimitry Andric ValueObjectSP return_valobj_sp; 760b57cec5SDimitry Andric 770b57cec5SDimitry Andric return_valobj_sp = GetReturnValueObjectImpl(thread, ast_type); 780b57cec5SDimitry Andric if (!return_valobj_sp) 790b57cec5SDimitry Andric return return_valobj_sp; 800b57cec5SDimitry Andric 810b57cec5SDimitry Andric // Now turn this into a persistent variable. 820b57cec5SDimitry Andric // FIXME: This code is duplicated from Target::EvaluateExpression, and it is 830b57cec5SDimitry Andric // used in similar form in a couple 840b57cec5SDimitry Andric // of other places. Figure out the correct Create function to do all this 850b57cec5SDimitry Andric // work. 860b57cec5SDimitry Andric 870b57cec5SDimitry Andric if (persistent) { 880b57cec5SDimitry Andric Target &target = *thread.CalculateTarget(); 890b57cec5SDimitry Andric PersistentExpressionState *persistent_expression_state = 900b57cec5SDimitry Andric target.GetPersistentExpressionStateForLanguage( 910b57cec5SDimitry Andric ast_type.GetMinimumLanguage()); 920b57cec5SDimitry Andric 930b57cec5SDimitry Andric if (!persistent_expression_state) 94480093f4SDimitry Andric return {}; 950b57cec5SDimitry Andric 960b57cec5SDimitry Andric ConstString persistent_variable_name = 975ffd83dbSDimitry Andric persistent_expression_state->GetNextPersistentVariableName(); 980b57cec5SDimitry Andric 990b57cec5SDimitry Andric lldb::ValueObjectSP const_valobj_sp; 1000b57cec5SDimitry Andric 1010b57cec5SDimitry Andric // Check in case our value is already a constant value 1020b57cec5SDimitry Andric if (return_valobj_sp->GetIsConstant()) { 1030b57cec5SDimitry Andric const_valobj_sp = return_valobj_sp; 1040b57cec5SDimitry Andric const_valobj_sp->SetName(persistent_variable_name); 1050b57cec5SDimitry Andric } else 1060b57cec5SDimitry Andric const_valobj_sp = 1070b57cec5SDimitry Andric return_valobj_sp->CreateConstantValue(persistent_variable_name); 1080b57cec5SDimitry Andric 1090b57cec5SDimitry Andric lldb::ValueObjectSP live_valobj_sp = return_valobj_sp; 1100b57cec5SDimitry Andric 1110b57cec5SDimitry Andric return_valobj_sp = const_valobj_sp; 1120b57cec5SDimitry Andric 1130b57cec5SDimitry Andric ExpressionVariableSP expr_variable_sp( 1140b57cec5SDimitry Andric persistent_expression_state->CreatePersistentVariable( 1150b57cec5SDimitry Andric return_valobj_sp)); 1160b57cec5SDimitry Andric 1170b57cec5SDimitry Andric assert(expr_variable_sp); 1180b57cec5SDimitry Andric 1190b57cec5SDimitry Andric // Set flags and live data as appropriate 1200b57cec5SDimitry Andric 1210b57cec5SDimitry Andric const Value &result_value = live_valobj_sp->GetValue(); 1220b57cec5SDimitry Andric 1230b57cec5SDimitry Andric switch (result_value.GetValueType()) { 124fe6060f1SDimitry Andric case Value::ValueType::Invalid: 125fe6060f1SDimitry Andric return {}; 126fe6060f1SDimitry Andric case Value::ValueType::HostAddress: 127fe6060f1SDimitry Andric case Value::ValueType::FileAddress: 128fe6060f1SDimitry Andric // we odon't do anything with these for now 1290b57cec5SDimitry Andric break; 130fe6060f1SDimitry Andric case Value::ValueType::Scalar: 1310b57cec5SDimitry Andric expr_variable_sp->m_flags |= 1320b57cec5SDimitry Andric ExpressionVariable::EVIsFreezeDried; 1330b57cec5SDimitry Andric expr_variable_sp->m_flags |= 1340b57cec5SDimitry Andric ExpressionVariable::EVIsLLDBAllocated; 1350b57cec5SDimitry Andric expr_variable_sp->m_flags |= 1360b57cec5SDimitry Andric ExpressionVariable::EVNeedsAllocation; 1370b57cec5SDimitry Andric break; 138fe6060f1SDimitry Andric case Value::ValueType::LoadAddress: 1390b57cec5SDimitry Andric expr_variable_sp->m_live_sp = live_valobj_sp; 1400b57cec5SDimitry Andric expr_variable_sp->m_flags |= 1410b57cec5SDimitry Andric ExpressionVariable::EVIsProgramReference; 1420b57cec5SDimitry Andric break; 1430b57cec5SDimitry Andric } 1440b57cec5SDimitry Andric 1450b57cec5SDimitry Andric return_valobj_sp = expr_variable_sp->GetValueObject(); 1460b57cec5SDimitry Andric } 1470b57cec5SDimitry Andric return return_valobj_sp; 1480b57cec5SDimitry Andric } 1490b57cec5SDimitry Andric 150*0fca6ea1SDimitry Andric addr_t ABI::FixCodeAddress(lldb::addr_t pc) { 151*0fca6ea1SDimitry Andric ProcessSP process_sp(GetProcessSP()); 152*0fca6ea1SDimitry Andric 153*0fca6ea1SDimitry Andric addr_t mask = process_sp->GetCodeAddressMask(); 154*0fca6ea1SDimitry Andric if (mask == LLDB_INVALID_ADDRESS_MASK) 155*0fca6ea1SDimitry Andric return pc; 156*0fca6ea1SDimitry Andric 157*0fca6ea1SDimitry Andric // Assume the high bit is used for addressing, which 158*0fca6ea1SDimitry Andric // may not be correct on all architectures e.g. AArch64 159*0fca6ea1SDimitry Andric // where Top Byte Ignore mode is often used to store 160*0fca6ea1SDimitry Andric // metadata in the top byte, and b55 is the bit used for 161*0fca6ea1SDimitry Andric // differentiating between low- and high-memory addresses. 162*0fca6ea1SDimitry Andric // That target's ABIs need to override this method. 163*0fca6ea1SDimitry Andric bool is_highmem = pc & (1ULL << 63); 164*0fca6ea1SDimitry Andric return is_highmem ? pc | mask : pc & (~mask); 165*0fca6ea1SDimitry Andric } 166*0fca6ea1SDimitry Andric 167*0fca6ea1SDimitry Andric addr_t ABI::FixDataAddress(lldb::addr_t pc) { 168*0fca6ea1SDimitry Andric ProcessSP process_sp(GetProcessSP()); 169*0fca6ea1SDimitry Andric addr_t mask = process_sp->GetDataAddressMask(); 170*0fca6ea1SDimitry Andric if (mask == LLDB_INVALID_ADDRESS_MASK) 171*0fca6ea1SDimitry Andric return pc; 172*0fca6ea1SDimitry Andric 173*0fca6ea1SDimitry Andric // Assume the high bit is used for addressing, which 174*0fca6ea1SDimitry Andric // may not be correct on all architectures e.g. AArch64 175*0fca6ea1SDimitry Andric // where Top Byte Ignore mode is often used to store 176*0fca6ea1SDimitry Andric // metadata in the top byte, and b55 is the bit used for 177*0fca6ea1SDimitry Andric // differentiating between low- and high-memory addresses. 178*0fca6ea1SDimitry Andric // That target's ABIs need to override this method. 179*0fca6ea1SDimitry Andric bool is_highmem = pc & (1ULL << 63); 180*0fca6ea1SDimitry Andric return is_highmem ? pc | mask : pc & (~mask); 181*0fca6ea1SDimitry Andric } 182*0fca6ea1SDimitry Andric 1830b57cec5SDimitry Andric ValueObjectSP ABI::GetReturnValueObject(Thread &thread, llvm::Type &ast_type, 1840b57cec5SDimitry Andric bool persistent) const { 1850b57cec5SDimitry Andric ValueObjectSP return_valobj_sp; 1860b57cec5SDimitry Andric return_valobj_sp = GetReturnValueObjectImpl(thread, ast_type); 1870b57cec5SDimitry Andric return return_valobj_sp; 1880b57cec5SDimitry Andric } 1890b57cec5SDimitry Andric 1900b57cec5SDimitry Andric // specialized to work with llvm IR types 1910b57cec5SDimitry Andric // 1920b57cec5SDimitry Andric // for now we will specify a default implementation so that we don't need to 1930b57cec5SDimitry Andric // modify other ABIs 1940b57cec5SDimitry Andric lldb::ValueObjectSP ABI::GetReturnValueObjectImpl(Thread &thread, 1950b57cec5SDimitry Andric llvm::Type &ir_type) const { 1960b57cec5SDimitry Andric ValueObjectSP return_valobj_sp; 1970b57cec5SDimitry Andric 1980b57cec5SDimitry Andric /* this is a dummy and will only be called if an ABI does not override this */ 1990b57cec5SDimitry Andric 2000b57cec5SDimitry Andric return return_valobj_sp; 2010b57cec5SDimitry Andric } 2020b57cec5SDimitry Andric 2030b57cec5SDimitry Andric bool ABI::PrepareTrivialCall(Thread &thread, lldb::addr_t sp, 2040b57cec5SDimitry Andric lldb::addr_t functionAddress, 2050b57cec5SDimitry Andric lldb::addr_t returnAddress, llvm::Type &returntype, 2060b57cec5SDimitry Andric llvm::ArrayRef<ABI::CallArgument> args) const { 2070b57cec5SDimitry Andric // dummy prepare trivial call 2080b57cec5SDimitry Andric llvm_unreachable("Should never get here!"); 2090b57cec5SDimitry Andric } 2100b57cec5SDimitry Andric 2110b57cec5SDimitry Andric bool ABI::GetFallbackRegisterLocation( 2120b57cec5SDimitry Andric const RegisterInfo *reg_info, 2130b57cec5SDimitry Andric UnwindPlan::Row::RegisterLocation &unwind_regloc) { 2140b57cec5SDimitry Andric // Did the UnwindPlan fail to give us the caller's stack pointer? The stack 2150b57cec5SDimitry Andric // pointer is defined to be the same as THIS frame's CFA, so return the CFA 2160b57cec5SDimitry Andric // value as the caller's stack pointer. This is true on x86-32/x86-64 at 2170b57cec5SDimitry Andric // least. 2180b57cec5SDimitry Andric if (reg_info->kinds[eRegisterKindGeneric] == LLDB_REGNUM_GENERIC_SP) { 2190b57cec5SDimitry Andric unwind_regloc.SetIsCFAPlusOffset(0); 2200b57cec5SDimitry Andric return true; 2210b57cec5SDimitry Andric } 2220b57cec5SDimitry Andric 2230b57cec5SDimitry Andric // If a volatile register is being requested, we don't want to forward the 2240b57cec5SDimitry Andric // next frame's register contents up the stack -- the register is not 2250b57cec5SDimitry Andric // retrievable at this frame. 2260b57cec5SDimitry Andric if (RegisterIsVolatile(reg_info)) { 2270b57cec5SDimitry Andric unwind_regloc.SetUndefined(); 2280b57cec5SDimitry Andric return true; 2290b57cec5SDimitry Andric } 2300b57cec5SDimitry Andric 2310b57cec5SDimitry Andric return false; 2320b57cec5SDimitry Andric } 2339dba64beSDimitry Andric 2349dba64beSDimitry Andric std::unique_ptr<llvm::MCRegisterInfo> ABI::MakeMCRegisterInfo(const ArchSpec &arch) { 2359dba64beSDimitry Andric std::string triple = arch.GetTriple().getTriple(); 2369dba64beSDimitry Andric std::string lookup_error; 2379dba64beSDimitry Andric const llvm::Target *target = 2389dba64beSDimitry Andric llvm::TargetRegistry::lookupTarget(triple, lookup_error); 2399dba64beSDimitry Andric if (!target) { 24081ad6265SDimitry Andric LLDB_LOG(GetLog(LLDBLog::Process), 2419dba64beSDimitry Andric "Failed to create an llvm target for {0}: {1}", triple, 2429dba64beSDimitry Andric lookup_error); 2439dba64beSDimitry Andric return nullptr; 2449dba64beSDimitry Andric } 2459dba64beSDimitry Andric std::unique_ptr<llvm::MCRegisterInfo> info_up( 2469dba64beSDimitry Andric target->createMCRegInfo(triple)); 2479dba64beSDimitry Andric assert(info_up); 2489dba64beSDimitry Andric return info_up; 2499dba64beSDimitry Andric } 250480093f4SDimitry Andric 251349cc55cSDimitry Andric void RegInfoBasedABI::AugmentRegisterInfo( 252349cc55cSDimitry Andric std::vector<DynamicRegisterInfo::Register> ®s) { 253349cc55cSDimitry Andric for (DynamicRegisterInfo::Register &info : regs) { 254349cc55cSDimitry Andric if (info.regnum_ehframe != LLDB_INVALID_REGNUM && 255349cc55cSDimitry Andric info.regnum_dwarf != LLDB_INVALID_REGNUM) 256349cc55cSDimitry Andric continue; 257480093f4SDimitry Andric 258480093f4SDimitry Andric RegisterInfo abi_info; 259349cc55cSDimitry Andric if (!GetRegisterInfoByName(info.name.GetStringRef(), abi_info)) 260349cc55cSDimitry Andric continue; 261480093f4SDimitry Andric 262349cc55cSDimitry Andric if (info.regnum_ehframe == LLDB_INVALID_REGNUM) 263349cc55cSDimitry Andric info.regnum_ehframe = abi_info.kinds[eRegisterKindEHFrame]; 264349cc55cSDimitry Andric if (info.regnum_dwarf == LLDB_INVALID_REGNUM) 265349cc55cSDimitry Andric info.regnum_dwarf = abi_info.kinds[eRegisterKindDWARF]; 266349cc55cSDimitry Andric if (info.regnum_generic == LLDB_INVALID_REGNUM) 267349cc55cSDimitry Andric info.regnum_generic = abi_info.kinds[eRegisterKindGeneric]; 268349cc55cSDimitry Andric } 269480093f4SDimitry Andric } 2705ffd83dbSDimitry Andric 271349cc55cSDimitry Andric void MCBasedABI::AugmentRegisterInfo( 272349cc55cSDimitry Andric std::vector<DynamicRegisterInfo::Register> ®s) { 273349cc55cSDimitry Andric for (DynamicRegisterInfo::Register &info : regs) { 2745ffd83dbSDimitry Andric uint32_t eh, dwarf; 275349cc55cSDimitry Andric std::tie(eh, dwarf) = GetEHAndDWARFNums(info.name.GetStringRef()); 2765ffd83dbSDimitry Andric 277349cc55cSDimitry Andric if (info.regnum_ehframe == LLDB_INVALID_REGNUM) 278349cc55cSDimitry Andric info.regnum_ehframe = eh; 279349cc55cSDimitry Andric if (info.regnum_dwarf == LLDB_INVALID_REGNUM) 280349cc55cSDimitry Andric info.regnum_dwarf = dwarf; 281349cc55cSDimitry Andric if (info.regnum_generic == LLDB_INVALID_REGNUM) 282349cc55cSDimitry Andric info.regnum_generic = GetGenericNum(info.name.GetStringRef()); 283349cc55cSDimitry Andric } 2845ffd83dbSDimitry Andric } 2855ffd83dbSDimitry Andric 2865ffd83dbSDimitry Andric std::pair<uint32_t, uint32_t> 2875ffd83dbSDimitry Andric MCBasedABI::GetEHAndDWARFNums(llvm::StringRef name) { 2885ffd83dbSDimitry Andric std::string mc_name = GetMCName(name.str()); 2895ffd83dbSDimitry Andric for (char &c : mc_name) 2905ffd83dbSDimitry Andric c = std::toupper(c); 2915ffd83dbSDimitry Andric int eh = -1; 2925ffd83dbSDimitry Andric int dwarf = -1; 2935ffd83dbSDimitry Andric for (unsigned reg = 0; reg < m_mc_register_info_up->getNumRegs(); ++reg) { 2945ffd83dbSDimitry Andric if (m_mc_register_info_up->getName(reg) == mc_name) { 2955ffd83dbSDimitry Andric eh = m_mc_register_info_up->getDwarfRegNum(reg, /*isEH=*/true); 2965ffd83dbSDimitry Andric dwarf = m_mc_register_info_up->getDwarfRegNum(reg, /*isEH=*/false); 2975ffd83dbSDimitry Andric break; 2985ffd83dbSDimitry Andric } 2995ffd83dbSDimitry Andric } 3005ffd83dbSDimitry Andric return std::pair<uint32_t, uint32_t>(eh == -1 ? LLDB_INVALID_REGNUM : eh, 3015ffd83dbSDimitry Andric dwarf == -1 ? LLDB_INVALID_REGNUM 3025ffd83dbSDimitry Andric : dwarf); 3035ffd83dbSDimitry Andric } 3045ffd83dbSDimitry Andric 3055ffd83dbSDimitry Andric void MCBasedABI::MapRegisterName(std::string &name, llvm::StringRef from_prefix, 3065ffd83dbSDimitry Andric llvm::StringRef to_prefix) { 3075ffd83dbSDimitry Andric llvm::StringRef name_ref = name; 3085ffd83dbSDimitry Andric if (!name_ref.consume_front(from_prefix)) 3095ffd83dbSDimitry Andric return; 3105ffd83dbSDimitry Andric uint64_t _; 3115ffd83dbSDimitry Andric if (name_ref.empty() || to_integer(name_ref, _, 10)) 3125ffd83dbSDimitry Andric name = (to_prefix + name_ref).str(); 3135ffd83dbSDimitry Andric } 314