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/Expression/ClangPersistentVariables.h"
15 #include "lldb/Symbol/CompilerType.h"
16 #include "lldb/Target/Target.h"
17 #include "lldb/Target/Thread.h"
18 
19 using namespace lldb;
20 using namespace lldb_private;
21 
22 ABISP
23 ABI::FindPlugin (const ArchSpec &arch)
24 {
25     ABISP abi_sp;
26     ABICreateInstance create_callback;
27 
28     for (uint32_t idx = 0;
29          (create_callback = PluginManager::GetABICreateCallbackAtIndex(idx)) != NULL;
30          ++idx)
31     {
32         abi_sp = create_callback(arch);
33 
34         if (abi_sp)
35             return abi_sp;
36     }
37     abi_sp.reset();
38     return abi_sp;
39 }
40 
41 //----------------------------------------------------------------------
42 // Constructor
43 //----------------------------------------------------------------------
44 ABI::ABI()
45 {
46 }
47 
48 //----------------------------------------------------------------------
49 // Destructor
50 //----------------------------------------------------------------------
51 ABI::~ABI()
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 < eRegisterKindEHFrame || 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                            CompilerType &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         ExpressionVariableSP 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 ValueObjectSP
176 ABI::GetReturnValueObject(Thread &thread, llvm::Type &ast_type, bool persistent) const
177 {
178     ValueObjectSP return_valobj_sp;
179     return_valobj_sp = GetReturnValueObjectImpl( thread, ast_type );
180     return return_valobj_sp;
181 }
182 
183 // specialized to work with llvm IR types
184 //
185 // for now we will specify a default implementation so that we don't need to
186 // modify other ABIs
187 lldb::ValueObjectSP
188 ABI::GetReturnValueObjectImpl( Thread &thread, llvm::Type &ir_type ) const
189 {
190     ValueObjectSP return_valobj_sp;
191 
192     /* this is a dummy and will only be called if an ABI does not override this */
193 
194     return return_valobj_sp;
195 }
196 
197 bool
198 ABI::PrepareTrivialCall (Thread &thread,
199                     lldb::addr_t sp,
200                     lldb::addr_t functionAddress,
201                     lldb::addr_t returnAddress,
202                     llvm::Type  &returntype,
203                     llvm::ArrayRef<ABI::CallArgument> args) const
204 {
205     // dummy prepare trivial call
206     assert( !"Should never get here!" );
207     return false;
208 }
209