]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Target/ABI.cpp
Import libucl 20170219
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Target / ABI.cpp
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 // C Includes
11 // C++ Includes
12 // Other libraries and framework includes
13 // Project includes
14 #include "lldb/Target/ABI.h"
15 #include "lldb/Core/PluginManager.h"
16 #include "lldb/Core/Value.h"
17 #include "lldb/Core/ValueObjectConstResult.h"
18 #include "Plugins/ExpressionParser/Clang/ClangPersistentVariables.h"
19 #include "lldb/Symbol/CompilerType.h"
20 #include "lldb/Symbol/TypeSystem.h"
21 #include "lldb/Target/Target.h"
22 #include "lldb/Target/Thread.h"
23
24 using namespace lldb;
25 using namespace lldb_private;
26
27 ABISP
28 ABI::FindPlugin (const ArchSpec &arch)
29 {
30     ABISP abi_sp;
31     ABICreateInstance create_callback;
32
33     for (uint32_t idx = 0;
34          (create_callback = PluginManager::GetABICreateCallbackAtIndex(idx)) != nullptr;
35          ++idx)
36     {
37         abi_sp = create_callback(arch);
38
39         if (abi_sp)
40             return abi_sp;
41     }
42     abi_sp.reset();
43     return abi_sp;
44 }
45
46 ABI::ABI() = default;
47
48 ABI::~ABI() = default;
49
50 bool
51 ABI::GetRegisterInfoByName (const ConstString &name, RegisterInfo &info)
52 {
53     uint32_t count = 0;
54     const RegisterInfo *register_info_array = GetRegisterInfoArray (count);
55     if (register_info_array)
56     {
57         const char *unique_name_cstr = name.GetCString();
58         uint32_t i;
59         for (i = 0; i < count; ++i)
60         {
61             if (register_info_array[i].name == unique_name_cstr)
62             {
63                 info = register_info_array[i];
64                 return true;
65             }
66         }
67         for (i = 0; i < count; ++i)
68         {
69             if (register_info_array[i].alt_name == unique_name_cstr)
70             {
71                 info = register_info_array[i];
72                 return true;
73             }
74         }
75     }
76     return false;
77 }
78
79 bool
80 ABI::GetRegisterInfoByKind (RegisterKind reg_kind, uint32_t reg_num, RegisterInfo &info)
81 {
82     if (reg_kind < eRegisterKindEHFrame || reg_kind >= kNumRegisterKinds)
83         return false;
84         
85     uint32_t count = 0;
86     const RegisterInfo *register_info_array = GetRegisterInfoArray (count);
87     if (register_info_array)
88     {
89         for (uint32_t i = 0; i < count; ++i)
90         {
91             if (register_info_array[i].kinds[reg_kind] == reg_num)
92             {
93                 info = register_info_array[i];
94                 return true;
95             }
96         }
97     }
98     return false;
99 }
100
101 ValueObjectSP
102 ABI::GetReturnValueObject (Thread &thread,
103                            CompilerType &ast_type,
104                            bool persistent) const
105 {
106     if (!ast_type.IsValid())
107         return ValueObjectSP();
108         
109     ValueObjectSP return_valobj_sp;
110         
111     return_valobj_sp = GetReturnValueObjectImpl(thread, ast_type);
112     if (!return_valobj_sp)
113         return return_valobj_sp;
114     
115     // Now turn this into a persistent variable.
116     // FIXME: This code is duplicated from Target::EvaluateExpression, and it is used in similar form in a couple
117     // of other places.  Figure out the correct Create function to do all this work.
118     
119     if (persistent)
120     {
121         PersistentExpressionState *persistent_expression_state = thread.CalculateTarget()->GetPersistentExpressionStateForLanguage(ast_type.GetMinimumLanguage());
122         
123         if (!persistent_expression_state)
124             return ValueObjectSP();
125         
126         ConstString persistent_variable_name (persistent_expression_state->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         ExpressionVariableSP clang_expr_variable_sp(persistent_expression_state->CreatePersistentVariable(return_valobj_sp));
144                
145         assert (clang_expr_variable_sp);
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
209 bool
210 ABI::GetFallbackRegisterLocation (const RegisterInfo *reg_info,
211                                   UnwindPlan::Row::RegisterLocation &unwind_regloc)
212 {
213     // Did the UnwindPlan fail to give us the caller's stack pointer?
214     // The stack pointer is defined to be the same as THIS frame's CFA, so return the CFA value as
215     // the caller's stack pointer.  This is true on x86-32/x86-64 at least.
216     if (reg_info->kinds[eRegisterKindGeneric] == LLDB_REGNUM_GENERIC_SP)
217     {
218         unwind_regloc.SetIsCFAPlusOffset(0);
219         return true;
220     }
221
222     // If a volatile register is being requested, we don't want to forward the next frame's register contents
223     // up the stack -- the register is not retrievable at this frame.
224     if (RegisterIsVolatile(reg_info))
225     {
226         unwind_regloc.SetUndefined();
227         return true;
228     }
229
230     return false;
231 }