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