Home | History | Annotate | Download | only in Target
      1 //===-- ABI.cpp -------------------------------------------------*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 #include "lldb/Target/ABI.h"
     11 #include "lldb/Core/PluginManager.h"
     12 #include "lldb/Core/Value.h"
     13 #include "lldb/Core/ValueObjectConstResult.h"
     14 #include "lldb/Symbol/ClangASTType.h"
     15 #include "lldb/Target/Target.h"
     16 #include "lldb/Target/Thread.h"
     17 
     18 using namespace lldb;
     19 using namespace lldb_private;
     20 
     21 ABISP
     22 ABI::FindPlugin (const ArchSpec &arch)
     23 {
     24     ABISP abi_sp;
     25     ABICreateInstance create_callback;
     26 
     27     for (uint32_t idx = 0;
     28          (create_callback = PluginManager::GetABICreateCallbackAtIndex(idx)) != NULL;
     29          ++idx)
     30     {
     31         abi_sp = create_callback(arch);
     32 
     33         if (abi_sp)
     34             return abi_sp;
     35     }
     36     abi_sp.reset();
     37     return abi_sp;
     38 }
     39 
     40 //----------------------------------------------------------------------
     41 // Constructor
     42 //----------------------------------------------------------------------
     43 ABI::ABI()
     44 {
     45 }
     46 
     47 //----------------------------------------------------------------------
     48 // Destructor
     49 //----------------------------------------------------------------------
     50 ABI::~ABI()
     51 {
     52 }
     53 
     54 
     55 bool
     56 ABI::GetRegisterInfoByName (const ConstString &name, RegisterInfo &info)
     57 {
     58     uint32_t count = 0;
     59     const RegisterInfo *register_info_array = GetRegisterInfoArray (count);
     60     if (register_info_array)
     61     {
     62         const char *unique_name_cstr = name.GetCString();
     63         uint32_t i;
     64         for (i=0; i<count; ++i)
     65         {
     66             if (register_info_array[i].name == unique_name_cstr)
     67             {
     68                 info = register_info_array[i];
     69                 return true;
     70             }
     71         }
     72         for (i=0; i<count; ++i)
     73         {
     74             if (register_info_array[i].alt_name == unique_name_cstr)
     75             {
     76                 info = register_info_array[i];
     77                 return true;
     78             }
     79         }
     80     }
     81     return false;
     82 }
     83 
     84 bool
     85 ABI::GetRegisterInfoByKind (RegisterKind reg_kind, uint32_t reg_num, RegisterInfo &info)
     86 {
     87     if (reg_kind < eRegisterKindGCC || reg_kind >= kNumRegisterKinds)
     88         return false;
     89 
     90     uint32_t count = 0;
     91     const RegisterInfo *register_info_array = GetRegisterInfoArray (count);
     92     if (register_info_array)
     93     {
     94         for (uint32_t i=0; i<count; ++i)
     95         {
     96             if (register_info_array[i].kinds[reg_kind] == reg_num)
     97             {
     98                 info = register_info_array[i];
     99                 return true;
    100             }
    101         }
    102     }
    103     return false;
    104 }
    105 
    106 ValueObjectSP
    107 ABI::GetReturnValueObject (Thread &thread,
    108                            ClangASTType &ast_type,
    109                            bool persistent) const
    110 {
    111     if (!ast_type.IsValid())
    112         return ValueObjectSP();
    113 
    114     ValueObjectSP return_valobj_sp;
    115 
    116     return_valobj_sp = GetReturnValueObjectImpl(thread, ast_type);
    117     if (!return_valobj_sp)
    118         return return_valobj_sp;
    119 
    120     // Now turn this into a persistent variable.
    121     // FIXME: This code is duplicated from Target::EvaluateExpression, and it is used in similar form in a couple
    122     // of other places.  Figure out the correct Create function to do all this work.
    123 
    124     if (persistent)
    125     {
    126         ClangPersistentVariables& persistent_variables = thread.CalculateTarget()->GetPersistentVariables();
    127         ConstString persistent_variable_name (persistent_variables.GetNextPersistentVariableName());
    128 
    129         lldb::ValueObjectSP const_valobj_sp;
    130 
    131         // Check in case our value is already a constant value
    132         if (return_valobj_sp->GetIsConstant())
    133         {
    134             const_valobj_sp = return_valobj_sp;
    135             const_valobj_sp->SetName (persistent_variable_name);
    136         }
    137         else
    138             const_valobj_sp = return_valobj_sp->CreateConstantValue (persistent_variable_name);
    139 
    140         lldb::ValueObjectSP live_valobj_sp = return_valobj_sp;
    141 
    142         return_valobj_sp = const_valobj_sp;
    143 
    144         ClangExpressionVariableSP clang_expr_variable_sp(persistent_variables.CreatePersistentVariable(return_valobj_sp));
    145 
    146         assert (clang_expr_variable_sp.get());
    147 
    148         // Set flags and live data as appropriate
    149 
    150         const Value &result_value = live_valobj_sp->GetValue();
    151 
    152         switch (result_value.GetValueType())
    153         {
    154         case Value::eValueTypeHostAddress:
    155         case Value::eValueTypeFileAddress:
    156             // we don't do anything with these for now
    157             break;
    158         case Value::eValueTypeScalar:
    159         case Value::eValueTypeVector:
    160             clang_expr_variable_sp->m_flags |= ClangExpressionVariable::EVIsFreezeDried;
    161             clang_expr_variable_sp->m_flags |= ClangExpressionVariable::EVIsLLDBAllocated;
    162             clang_expr_variable_sp->m_flags |= ClangExpressionVariable::EVNeedsAllocation;
    163             break;
    164         case Value::eValueTypeLoadAddress:
    165             clang_expr_variable_sp->m_live_sp = live_valobj_sp;
    166             clang_expr_variable_sp->m_flags |= ClangExpressionVariable::EVIsProgramReference;
    167             break;
    168         }
    169 
    170         return_valobj_sp = clang_expr_variable_sp->GetValueObject();
    171     }
    172     return return_valobj_sp;
    173 }
    174 
    175 
    176