brintos

brintos / llvm-project-archived public Read only

0
0
Text · 10.4 KiB · 3c51074 Raw
314 lines · cpp
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-exception6//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 23using namespace lldb;24using namespace lldb_private;25 26ABISP27ABI::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 44ABI::~ABI() = default;45 46bool 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 70ValueObjectSP 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 is83  // used in similar form in a couple84  // of other places.  Figure out the correct Create function to do all this85  // work.86 87  if (persistent) {88    Target &target = *thread.CalculateTarget();89    PersistentExpressionState *persistent_expression_state =90        target.GetPersistentExpressionStateForLanguage(91            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 value102    if (return_valobj_sp->GetIsConstant()) {103      const_valobj_sp = return_valobj_sp;104      const_valobj_sp->SetName(persistent_variable_name);105    } else106      const_valobj_sp =107          return_valobj_sp->CreateConstantValue(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            return_valobj_sp));116 117    assert(expr_variable_sp);118 119    // Set flags and live data as appropriate120 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 now129      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 150addr_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, which158  // may not be correct on all architectures e.g. AArch64159  // where Top Byte Ignore mode is often used to store160  // metadata in the top byte, and b55 is the bit used for161  // 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 167addr_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, which174  // may not be correct on all architectures e.g. AArch64175  // where Top Byte Ignore mode is often used to store176  // metadata in the top byte, and b55 is the bit used for177  // 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 183ValueObjectSP ABI::GetReturnValueObject(Thread &thread, llvm::Type &ast_type,184                                        bool persistent) const {185  ValueObjectSP return_valobj_sp;186  return_valobj_sp = GetReturnValueObjectImpl(thread, ast_type);187  return return_valobj_sp;188}189 190// specialized to work with llvm IR types191//192// for now we will specify a default implementation so that we don't need to193// modify other ABIs194lldb::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 203bool 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 call208  llvm_unreachable("Should never get here!");209}210 211bool 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 stack215  // pointer is defined to be the same as THIS frame's CFA, so return the CFA216  // value as the caller's stack pointer.  This is true on x86-32/x86-64 at217  // 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 the224  // next frame's register contents up the stack -- the register is not225  // retrievable at this frame.226  if (RegisterIsVolatile(reg_info)) {227    unwind_regloc.SetUndefined();228    return true;229  }230 231  return false;232}233 234std::unique_ptr<llvm::MCRegisterInfo> ABI::MakeMCRegisterInfo(const ArchSpec &arch) {235  const llvm::Triple &triple = arch.GetTriple();236  std::string lookup_error;237  const llvm::Target *target =238      llvm::TargetRegistry::lookupTarget(triple, lookup_error);239  if (!target) {240    LLDB_LOG(GetLog(LLDBLog::Process),241             "Failed to create an llvm target for {0}: {1}", triple.str(),242             lookup_error);243    return nullptr;244  }245  std::unique_ptr<llvm::MCRegisterInfo> info_up(246      target->createMCRegInfo(triple));247  assert(info_up);248  return info_up;249}250 251void RegInfoBasedABI::AugmentRegisterInfo(252    std::vector<DynamicRegisterInfo::Register> &regs) {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(info.name.GetStringRef(), 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 271void MCBasedABI::AugmentRegisterInfo(272    std::vector<DynamicRegisterInfo::Register> &regs) {273  for (DynamicRegisterInfo::Register &info : regs) {274    uint32_t eh, dwarf;275    std::tie(eh, dwarf) = GetEHAndDWARFNums(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(info.name.GetStringRef());283  }284}285 286std::pair<uint32_t, uint32_t>287MCBasedABI::GetEHAndDWARFNums(llvm::StringRef name) {288  std::string mc_name = GetMCName(name.str());289  for (char &c : mc_name)290    c = std::toupper(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(reg) == mc_name) {295      eh = m_mc_register_info_up->getDwarfRegNum(reg, /*isEH=*/true);296      dwarf = m_mc_register_info_up->getDwarfRegNum(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_REGNUM302                                                   : dwarf);303}304 305void 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(from_prefix))309    return;310  uint64_t _;311  if (name_ref.empty() || to_integer(name_ref, _, 10))312    name = (to_prefix + name_ref).str();313}314