| 1 | //===-- ABI.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-exception |
| 6 | // |
| 7 | //===----------------------------------------------------------------------===// |
| 8 | |
| 9 | #include "lldb/Target/ABI.h" |
| 10 | #include "lldb/Core/PluginManager.h" |
| 11 | #include "lldb/Core/Value.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 "lldb/ValueObject/ValueObjectConstResult.h" |
| 20 | #include "llvm/MC/TargetRegistry.h" |
| 21 | #include <cctype> |
| 22 | |
| 23 | using namespace lldb; |
| 24 | using namespace lldb_private; |
| 25 | |
| 26 | ABISP |
| 27 | ABI::FindPlugin(lldb::ProcessSP process_sp, const ArchSpec &arch) { |
| 28 | ABISP abi_sp; |
| 29 | ABICreateInstance create_callback; |
| 30 | |
| 31 | for (uint32_t idx = 0; |
| 32 | (create_callback = PluginManager::GetABICreateCallbackAtIndex(idx)) != |
| 33 | nullptr; |
| 34 | ++idx) { |
| 35 | abi_sp = create_callback(process_sp, arch); |
| 36 | |
| 37 | if (abi_sp) |
| 38 | return abi_sp; |
| 39 | } |
| 40 | abi_sp.reset(); |
| 41 | return abi_sp; |
| 42 | } |
| 43 | |
| 44 | ABI::~ABI() = default; |
| 45 | |
| 46 | bool RegInfoBasedABI::GetRegisterInfoByName(llvm::StringRef name, |
| 47 | RegisterInfo &info) { |
| 48 | uint32_t count = 0; |
| 49 | const RegisterInfo *register_info_array = GetRegisterInfoArray(count); |
| 50 | if (register_info_array) { |
| 51 | uint32_t i; |
| 52 | for (i = 0; i < count; ++i) { |
| 53 | const char *reg_name = register_info_array[i].name; |
| 54 | if (reg_name == name) { |
| 55 | info = register_info_array[i]; |
| 56 | return true; |
| 57 | } |
| 58 | } |
| 59 | for (i = 0; i < count; ++i) { |
| 60 | const char *reg_alt_name = register_info_array[i].alt_name; |
| 61 | if (reg_alt_name == name) { |
| 62 | info = register_info_array[i]; |
| 63 | return true; |
| 64 | } |
| 65 | } |
| 66 | } |
| 67 | return false; |
| 68 | } |
| 69 | |
| 70 | ValueObjectSP ABI::GetReturnValueObject(Thread &thread, CompilerType &ast_type, |
| 71 | bool persistent) const { |
| 72 | if (!ast_type.IsValid()) |
| 73 | return ValueObjectSP(); |
| 74 | |
| 75 | ValueObjectSP return_valobj_sp; |
| 76 | |
| 77 | return_valobj_sp = GetReturnValueObjectImpl(thread, ast_type); |
| 78 | if (!return_valobj_sp) |
| 79 | return return_valobj_sp; |
| 80 | |
| 81 | // Now turn this into a persistent variable. |
| 82 | // FIXME: This code is duplicated from Target::EvaluateExpression, and it is |
| 83 | // used in similar form in a couple |
| 84 | // of other places. Figure out the correct Create function to do all this |
| 85 | // work. |
| 86 | |
| 87 | if (persistent) { |
| 88 | Target &target = *thread.CalculateTarget(); |
| 89 | PersistentExpressionState *persistent_expression_state = |
| 90 | target.GetPersistentExpressionStateForLanguage( |
| 91 | language: ast_type.GetMinimumLanguage()); |
| 92 | |
| 93 | if (!persistent_expression_state) |
| 94 | return {}; |
| 95 | |
| 96 | ConstString persistent_variable_name = |
| 97 | persistent_expression_state->GetNextPersistentVariableName(); |
| 98 | |
| 99 | lldb::ValueObjectSP const_valobj_sp; |
| 100 | |
| 101 | // Check in case our value is already a constant value |
| 102 | if (return_valobj_sp->GetIsConstant()) { |
| 103 | const_valobj_sp = return_valobj_sp; |
| 104 | const_valobj_sp->SetName(persistent_variable_name); |
| 105 | } else |
| 106 | const_valobj_sp = |
| 107 | return_valobj_sp->CreateConstantValue(name: persistent_variable_name); |
| 108 | |
| 109 | lldb::ValueObjectSP live_valobj_sp = return_valobj_sp; |
| 110 | |
| 111 | return_valobj_sp = const_valobj_sp; |
| 112 | |
| 113 | ExpressionVariableSP expr_variable_sp( |
| 114 | persistent_expression_state->CreatePersistentVariable( |
| 115 | valobj_sp: return_valobj_sp)); |
| 116 | |
| 117 | assert(expr_variable_sp); |
| 118 | |
| 119 | // Set flags and live data as appropriate |
| 120 | |
| 121 | const Value &result_value = live_valobj_sp->GetValue(); |
| 122 | |
| 123 | switch (result_value.GetValueType()) { |
| 124 | case Value::ValueType::Invalid: |
| 125 | return {}; |
| 126 | case Value::ValueType::HostAddress: |
| 127 | case Value::ValueType::FileAddress: |
| 128 | // we odon't do anything with these for now |
| 129 | break; |
| 130 | case Value::ValueType::Scalar: |
| 131 | expr_variable_sp->m_flags |= |
| 132 | ExpressionVariable::EVIsFreezeDried; |
| 133 | expr_variable_sp->m_flags |= |
| 134 | ExpressionVariable::EVIsLLDBAllocated; |
| 135 | expr_variable_sp->m_flags |= |
| 136 | ExpressionVariable::EVNeedsAllocation; |
| 137 | break; |
| 138 | case Value::ValueType::LoadAddress: |
| 139 | expr_variable_sp->m_live_sp = live_valobj_sp; |
| 140 | expr_variable_sp->m_flags |= |
| 141 | ExpressionVariable::EVIsProgramReference; |
| 142 | break; |
| 143 | } |
| 144 | |
| 145 | return_valobj_sp = expr_variable_sp->GetValueObject(); |
| 146 | } |
| 147 | return return_valobj_sp; |
| 148 | } |
| 149 | |
| 150 | addr_t ABI::FixCodeAddress(lldb::addr_t pc) { |
| 151 | ProcessSP process_sp(GetProcessSP()); |
| 152 | |
| 153 | addr_t mask = process_sp->GetCodeAddressMask(); |
| 154 | if (mask == LLDB_INVALID_ADDRESS_MASK) |
| 155 | return pc; |
| 156 | |
| 157 | // Assume the high bit is used for addressing, which |
| 158 | // may not be correct on all architectures e.g. AArch64 |
| 159 | // where Top Byte Ignore mode is often used to store |
| 160 | // metadata in the top byte, and b55 is the bit used for |
| 161 | // differentiating between low- and high-memory addresses. |
| 162 | // That target's ABIs need to override this method. |
| 163 | bool is_highmem = pc & (1ULL << 63); |
| 164 | return is_highmem ? pc | mask : pc & (~mask); |
| 165 | } |
| 166 | |
| 167 | addr_t ABI::FixDataAddress(lldb::addr_t pc) { |
| 168 | ProcessSP process_sp(GetProcessSP()); |
| 169 | addr_t mask = process_sp->GetDataAddressMask(); |
| 170 | if (mask == LLDB_INVALID_ADDRESS_MASK) |
| 171 | return pc; |
| 172 | |
| 173 | // Assume the high bit is used for addressing, which |
| 174 | // may not be correct on all architectures e.g. AArch64 |
| 175 | // where Top Byte Ignore mode is often used to store |
| 176 | // metadata in the top byte, and b55 is the bit used for |
| 177 | // differentiating between low- and high-memory addresses. |
| 178 | // That target's ABIs need to override this method. |
| 179 | bool is_highmem = pc & (1ULL << 63); |
| 180 | return is_highmem ? pc | mask : pc & (~mask); |
| 181 | } |
| 182 | |
| 183 | ValueObjectSP ABI::GetReturnValueObject(Thread &thread, llvm::Type &ast_type, |
| 184 | bool persistent) const { |
| 185 | ValueObjectSP return_valobj_sp; |
| 186 | return_valobj_sp = GetReturnValueObjectImpl(thread, ir_type&: ast_type); |
| 187 | return return_valobj_sp; |
| 188 | } |
| 189 | |
| 190 | // specialized to work with llvm IR types |
| 191 | // |
| 192 | // for now we will specify a default implementation so that we don't need to |
| 193 | // modify other ABIs |
| 194 | lldb::ValueObjectSP ABI::GetReturnValueObjectImpl(Thread &thread, |
| 195 | llvm::Type &ir_type) const { |
| 196 | ValueObjectSP return_valobj_sp; |
| 197 | |
| 198 | /* this is a dummy and will only be called if an ABI does not override this */ |
| 199 | |
| 200 | return return_valobj_sp; |
| 201 | } |
| 202 | |
| 203 | bool ABI::PrepareTrivialCall(Thread &thread, lldb::addr_t sp, |
| 204 | lldb::addr_t functionAddress, |
| 205 | lldb::addr_t returnAddress, llvm::Type &returntype, |
| 206 | llvm::ArrayRef<ABI::CallArgument> args) const { |
| 207 | // dummy prepare trivial call |
| 208 | llvm_unreachable("Should never get here!" ); |
| 209 | } |
| 210 | |
| 211 | bool ABI::GetFallbackRegisterLocation( |
| 212 | const RegisterInfo *reg_info, |
| 213 | UnwindPlan::Row::AbstractRegisterLocation &unwind_regloc) { |
| 214 | // Did the UnwindPlan fail to give us the caller's stack pointer? The stack |
| 215 | // pointer is defined to be the same as THIS frame's CFA, so return the CFA |
| 216 | // value as the caller's stack pointer. This is true on x86-32/x86-64 at |
| 217 | // least. |
| 218 | if (reg_info->kinds[eRegisterKindGeneric] == LLDB_REGNUM_GENERIC_SP) { |
| 219 | unwind_regloc.SetIsCFAPlusOffset(0); |
| 220 | return true; |
| 221 | } |
| 222 | |
| 223 | // If a volatile register is being requested, we don't want to forward the |
| 224 | // next frame's register contents up the stack -- the register is not |
| 225 | // retrievable at this frame. |
| 226 | if (RegisterIsVolatile(reg_info)) { |
| 227 | unwind_regloc.SetUndefined(); |
| 228 | return true; |
| 229 | } |
| 230 | |
| 231 | return false; |
| 232 | } |
| 233 | |
| 234 | std::unique_ptr<llvm::MCRegisterInfo> ABI::MakeMCRegisterInfo(const ArchSpec &arch) { |
| 235 | std::string triple = arch.GetTriple().getTriple(); |
| 236 | std::string lookup_error; |
| 237 | const llvm::Target *target = |
| 238 | llvm::TargetRegistry::lookupTarget(TripleStr: triple, Error&: lookup_error); |
| 239 | if (!target) { |
| 240 | LLDB_LOG(GetLog(LLDBLog::Process), |
| 241 | "Failed to create an llvm target for {0}: {1}" , triple, |
| 242 | lookup_error); |
| 243 | return nullptr; |
| 244 | } |
| 245 | std::unique_ptr<llvm::MCRegisterInfo> info_up( |
| 246 | target->createMCRegInfo(TT: triple)); |
| 247 | assert(info_up); |
| 248 | return info_up; |
| 249 | } |
| 250 | |
| 251 | void RegInfoBasedABI::AugmentRegisterInfo( |
| 252 | std::vector<DynamicRegisterInfo::Register> ®s) { |
| 253 | for (DynamicRegisterInfo::Register &info : regs) { |
| 254 | if (info.regnum_ehframe != LLDB_INVALID_REGNUM && |
| 255 | info.regnum_dwarf != LLDB_INVALID_REGNUM) |
| 256 | continue; |
| 257 | |
| 258 | RegisterInfo abi_info; |
| 259 | if (!GetRegisterInfoByName(name: info.name.GetStringRef(), info&: abi_info)) |
| 260 | continue; |
| 261 | |
| 262 | if (info.regnum_ehframe == LLDB_INVALID_REGNUM) |
| 263 | info.regnum_ehframe = abi_info.kinds[eRegisterKindEHFrame]; |
| 264 | if (info.regnum_dwarf == LLDB_INVALID_REGNUM) |
| 265 | info.regnum_dwarf = abi_info.kinds[eRegisterKindDWARF]; |
| 266 | if (info.regnum_generic == LLDB_INVALID_REGNUM) |
| 267 | info.regnum_generic = abi_info.kinds[eRegisterKindGeneric]; |
| 268 | } |
| 269 | } |
| 270 | |
| 271 | void MCBasedABI::AugmentRegisterInfo( |
| 272 | std::vector<DynamicRegisterInfo::Register> ®s) { |
| 273 | for (DynamicRegisterInfo::Register &info : regs) { |
| 274 | uint32_t eh, dwarf; |
| 275 | std::tie(args&: eh, args&: dwarf) = GetEHAndDWARFNums(reg: info.name.GetStringRef()); |
| 276 | |
| 277 | if (info.regnum_ehframe == LLDB_INVALID_REGNUM) |
| 278 | info.regnum_ehframe = eh; |
| 279 | if (info.regnum_dwarf == LLDB_INVALID_REGNUM) |
| 280 | info.regnum_dwarf = dwarf; |
| 281 | if (info.regnum_generic == LLDB_INVALID_REGNUM) |
| 282 | info.regnum_generic = GetGenericNum(reg: info.name.GetStringRef()); |
| 283 | } |
| 284 | } |
| 285 | |
| 286 | std::pair<uint32_t, uint32_t> |
| 287 | MCBasedABI::GetEHAndDWARFNums(llvm::StringRef name) { |
| 288 | std::string mc_name = GetMCName(reg: name.str()); |
| 289 | for (char &c : mc_name) |
| 290 | c = std::toupper(c: c); |
| 291 | int eh = -1; |
| 292 | int dwarf = -1; |
| 293 | for (unsigned reg = 0; reg < m_mc_register_info_up->getNumRegs(); ++reg) { |
| 294 | if (m_mc_register_info_up->getName(RegNo: reg) == mc_name) { |
| 295 | eh = m_mc_register_info_up->getDwarfRegNum(RegNum: reg, /*isEH=*/true); |
| 296 | dwarf = m_mc_register_info_up->getDwarfRegNum(RegNum: reg, /*isEH=*/false); |
| 297 | break; |
| 298 | } |
| 299 | } |
| 300 | return std::pair<uint32_t, uint32_t>(eh == -1 ? LLDB_INVALID_REGNUM : eh, |
| 301 | dwarf == -1 ? LLDB_INVALID_REGNUM |
| 302 | : dwarf); |
| 303 | } |
| 304 | |
| 305 | void MCBasedABI::MapRegisterName(std::string &name, llvm::StringRef from_prefix, |
| 306 | llvm::StringRef to_prefix) { |
| 307 | llvm::StringRef name_ref = name; |
| 308 | if (!name_ref.consume_front(Prefix: from_prefix)) |
| 309 | return; |
| 310 | uint64_t _; |
| 311 | if (name_ref.empty() || to_integer(S: name_ref, Num&: _, Base: 10)) |
| 312 | name = (to_prefix + name_ref).str(); |
| 313 | } |
| 314 | |