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