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 "Plugins/ExpressionParser/Clang/ClangPersistentVariables.h" 15 #include "lldb/Symbol/CompilerType.h" 16 #include "lldb/Symbol/TypeSystem.h" 17 #include "lldb/Target/Target.h" 18 #include "lldb/Target/Thread.h" 19 20 using namespace lldb; 21 using namespace lldb_private; 22 23 ABISP 24 ABI::FindPlugin (const ArchSpec &arch) 25 { 26 ABISP abi_sp; 27 ABICreateInstance create_callback; 28 29 for (uint32_t idx = 0; 30 (create_callback = PluginManager::GetABICreateCallbackAtIndex(idx)) != NULL; 31 ++idx) 32 { 33 abi_sp = create_callback(arch); 34 35 if (abi_sp) 36 return abi_sp; 37 } 38 abi_sp.reset(); 39 return abi_sp; 40 } 41 42 //---------------------------------------------------------------------- 43 // Constructor 44 //---------------------------------------------------------------------- 45 ABI::ABI() 46 { 47 } 48 49 //---------------------------------------------------------------------- 50 // Destructor 51 //---------------------------------------------------------------------- 52 ABI::~ABI() 53 { 54 } 55 56 bool 57 ABI::GetRegisterInfoByName (const ConstString &name, RegisterInfo &info) 58 { 59 uint32_t count = 0; 60 const RegisterInfo *register_info_array = GetRegisterInfoArray (count); 61 if (register_info_array) 62 { 63 const char *unique_name_cstr = name.GetCString(); 64 uint32_t i; 65 for (i=0; i<count; ++i) 66 { 67 if (register_info_array[i].name == unique_name_cstr) 68 { 69 info = register_info_array[i]; 70 return true; 71 } 72 } 73 for (i=0; i<count; ++i) 74 { 75 if (register_info_array[i].alt_name == unique_name_cstr) 76 { 77 info = register_info_array[i]; 78 return true; 79 } 80 } 81 } 82 return false; 83 } 84 85 bool 86 ABI::GetRegisterInfoByKind (RegisterKind reg_kind, uint32_t reg_num, RegisterInfo &info) 87 { 88 if (reg_kind < eRegisterKindEHFrame || reg_kind >= kNumRegisterKinds) 89 return false; 90 91 uint32_t count = 0; 92 const RegisterInfo *register_info_array = GetRegisterInfoArray (count); 93 if (register_info_array) 94 { 95 for (uint32_t i=0; i<count; ++i) 96 { 97 if (register_info_array[i].kinds[reg_kind] == reg_num) 98 { 99 info = register_info_array[i]; 100 return true; 101 } 102 } 103 } 104 return false; 105 } 106 107 ValueObjectSP 108 ABI::GetReturnValueObject (Thread &thread, 109 CompilerType &ast_type, 110 bool persistent) const 111 { 112 if (!ast_type.IsValid()) 113 return ValueObjectSP(); 114 115 ValueObjectSP return_valobj_sp; 116 117 return_valobj_sp = GetReturnValueObjectImpl(thread, ast_type); 118 if (!return_valobj_sp) 119 return return_valobj_sp; 120 121 // Now turn this into a persistent variable. 122 // FIXME: This code is duplicated from Target::EvaluateExpression, and it is used in similar form in a couple 123 // of other places. Figure out the correct Create function to do all this work. 124 125 if (persistent) 126 { 127 PersistentExpressionState *persistent_expression_state = thread.CalculateTarget()->GetScratchTypeSystemForLanguage(ast_type.GetMinimumLanguage())->GetPersistentExpressionState(); 128 ConstString persistent_variable_name (persistent_expression_state->GetNextPersistentVariableName()); 129 130 lldb::ValueObjectSP const_valobj_sp; 131 132 // Check in case our value is already a constant value 133 if (return_valobj_sp->GetIsConstant()) 134 { 135 const_valobj_sp = return_valobj_sp; 136 const_valobj_sp->SetName (persistent_variable_name); 137 } 138 else 139 const_valobj_sp = return_valobj_sp->CreateConstantValue (persistent_variable_name); 140 141 lldb::ValueObjectSP live_valobj_sp = return_valobj_sp; 142 143 return_valobj_sp = const_valobj_sp; 144 145 ExpressionVariableSP clang_expr_variable_sp(ClangExpressionVariable::CreateVariableInList(*persistent_expression_state, return_valobj_sp)->shared_from_this()); 146 147 assert (clang_expr_variable_sp.get()); 148 149 // Set flags and live data as appropriate 150 151 const Value &result_value = live_valobj_sp->GetValue(); 152 153 switch (result_value.GetValueType()) 154 { 155 case Value::eValueTypeHostAddress: 156 case Value::eValueTypeFileAddress: 157 // we don't do anything with these for now 158 break; 159 case Value::eValueTypeScalar: 160 case Value::eValueTypeVector: 161 clang_expr_variable_sp->m_flags |= ClangExpressionVariable::EVIsFreezeDried; 162 clang_expr_variable_sp->m_flags |= ClangExpressionVariable::EVIsLLDBAllocated; 163 clang_expr_variable_sp->m_flags |= ClangExpressionVariable::EVNeedsAllocation; 164 break; 165 case Value::eValueTypeLoadAddress: 166 clang_expr_variable_sp->m_live_sp = live_valobj_sp; 167 clang_expr_variable_sp->m_flags |= ClangExpressionVariable::EVIsProgramReference; 168 break; 169 } 170 171 return_valobj_sp = clang_expr_variable_sp->GetValueObject(); 172 } 173 return return_valobj_sp; 174 } 175 176 ValueObjectSP 177 ABI::GetReturnValueObject(Thread &thread, llvm::Type &ast_type, bool persistent) const 178 { 179 ValueObjectSP return_valobj_sp; 180 return_valobj_sp = GetReturnValueObjectImpl( thread, ast_type ); 181 return return_valobj_sp; 182 } 183 184 // specialized to work with llvm IR types 185 // 186 // for now we will specify a default implementation so that we don't need to 187 // modify other ABIs 188 lldb::ValueObjectSP 189 ABI::GetReturnValueObjectImpl( Thread &thread, llvm::Type &ir_type ) const 190 { 191 ValueObjectSP return_valobj_sp; 192 193 /* this is a dummy and will only be called if an ABI does not override this */ 194 195 return return_valobj_sp; 196 } 197 198 bool 199 ABI::PrepareTrivialCall (Thread &thread, 200 lldb::addr_t sp, 201 lldb::addr_t functionAddress, 202 lldb::addr_t returnAddress, 203 llvm::Type &returntype, 204 llvm::ArrayRef<ABI::CallArgument> args) const 205 { 206 // dummy prepare trivial call 207 assert( !"Should never get here!" ); 208 return false; 209 } 210