blob: b2334d6abb8bcd2bc3795093eb6f1256644ca6a3 [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- 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"
Jim Ingham73ca05a2011-12-17 01:35:57 +000012#include "lldb/Core/Value.h"
13#include "lldb/Core/ValueObjectConstResult.h"
Sean Callanan4dbb2712015-09-25 20:35:58 +000014#include "Plugins/ExpressionParser/Clang/ClangPersistentVariables.h"
Greg Claytona1e5dc82015-08-11 22:53:00 +000015#include "lldb/Symbol/CompilerType.h"
Sean Callanan8f1f9a12015-09-30 19:57:57 +000016#include "lldb/Symbol/TypeSystem.h"
Jim Inghamef651602011-12-22 19:12:40 +000017#include "lldb/Target/Target.h"
Jim Ingham73ca05a2011-12-17 01:35:57 +000018#include "lldb/Target/Thread.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000019
20using namespace lldb;
21using namespace lldb_private;
22
Greg Clayton31f1d2f2011-05-11 18:39:18 +000023ABISP
Greg Clayton514487e2011-02-15 21:59:32 +000024ABI::FindPlugin (const ArchSpec &arch)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000025{
Greg Clayton31f1d2f2011-05-11 18:39:18 +000026 ABISP abi_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000027 ABICreateInstance create_callback;
28
29 for (uint32_t idx = 0;
30 (create_callback = PluginManager::GetABICreateCallbackAtIndex(idx)) != NULL;
31 ++idx)
32 {
Greg Clayton31f1d2f2011-05-11 18:39:18 +000033 abi_sp = create_callback(arch);
Chris Lattner30fdc8d2010-06-08 16:52:24 +000034
Greg Clayton31f1d2f2011-05-11 18:39:18 +000035 if (abi_sp)
36 return abi_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000037 }
Greg Clayton31f1d2f2011-05-11 18:39:18 +000038 abi_sp.reset();
39 return abi_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000040}
41
42//----------------------------------------------------------------------
43// Constructor
44//----------------------------------------------------------------------
45ABI::ABI()
46{
47}
48
49//----------------------------------------------------------------------
50// Destructor
51//----------------------------------------------------------------------
52ABI::~ABI()
53{
54}
Greg Clayton56d9a1b2011-08-22 02:49:39 +000055
Greg Clayton56d9a1b2011-08-22 02:49:39 +000056bool
57ABI::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
85bool
86ABI::GetRegisterInfoByKind (RegisterKind reg_kind, uint32_t reg_num, RegisterInfo &info)
87{
Jason Molendaa18f7072015-08-15 01:21:01 +000088 if (reg_kind < eRegisterKindEHFrame || reg_kind >= kNumRegisterKinds)
Greg Clayton56d9a1b2011-08-22 02:49:39 +000089 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}
Jim Ingham73ca05a2011-12-17 01:35:57 +0000106
107ValueObjectSP
108ABI::GetReturnValueObject (Thread &thread,
Greg Claytona1e5dc82015-08-11 22:53:00 +0000109 CompilerType &ast_type,
Greg Clayton1ac04c32012-02-21 00:09:25 +0000110 bool persistent) const
Jim Ingham73ca05a2011-12-17 01:35:57 +0000111{
112 if (!ast_type.IsValid())
113 return ValueObjectSP();
114
Jim Inghamef651602011-12-22 19:12:40 +0000115 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)
Jim Ingham73ca05a2011-12-17 01:35:57 +0000126 {
Sean Callananb92bd752015-10-01 16:28:02 +0000127 PersistentExpressionState *persistent_expression_state = thread.CalculateTarget()->GetPersistentExpressionStateForLanguage(ast_type.GetMinimumLanguage());
128
129 if (!persistent_expression_state)
130 return ValueObjectSP();
131
Sean Callanan8f1f9a12015-09-30 19:57:57 +0000132 ConstString persistent_variable_name (persistent_expression_state->GetNextPersistentVariableName());
Jim Inghamef651602011-12-22 19:12:40 +0000133
134 lldb::ValueObjectSP const_valobj_sp;
135
136 // Check in case our value is already a constant value
137 if (return_valobj_sp->GetIsConstant())
138 {
139 const_valobj_sp = return_valobj_sp;
140 const_valobj_sp->SetName (persistent_variable_name);
141 }
142 else
143 const_valobj_sp = return_valobj_sp->CreateConstantValue (persistent_variable_name);
144
145 lldb::ValueObjectSP live_valobj_sp = return_valobj_sp;
146
147 return_valobj_sp = const_valobj_sp;
148
Sean Callanan8f1f9a12015-09-30 19:57:57 +0000149 ExpressionVariableSP clang_expr_variable_sp(ClangExpressionVariable::CreateVariableInList(*persistent_expression_state, return_valobj_sp)->shared_from_this());
Jim Inghamef651602011-12-22 19:12:40 +0000150
151 assert (clang_expr_variable_sp.get());
152
153 // Set flags and live data as appropriate
154
155 const Value &result_value = live_valobj_sp->GetValue();
156
157 switch (result_value.GetValueType())
158 {
159 case Value::eValueTypeHostAddress:
160 case Value::eValueTypeFileAddress:
161 // we don't do anything with these for now
162 break;
163 case Value::eValueTypeScalar:
Greg Clayton2fb45d02012-10-30 23:56:14 +0000164 case Value::eValueTypeVector:
Sean Callanan31a8d052012-01-05 01:11:09 +0000165 clang_expr_variable_sp->m_flags |= ClangExpressionVariable::EVIsFreezeDried;
Jim Inghamef651602011-12-22 19:12:40 +0000166 clang_expr_variable_sp->m_flags |= ClangExpressionVariable::EVIsLLDBAllocated;
167 clang_expr_variable_sp->m_flags |= ClangExpressionVariable::EVNeedsAllocation;
168 break;
169 case Value::eValueTypeLoadAddress:
170 clang_expr_variable_sp->m_live_sp = live_valobj_sp;
171 clang_expr_variable_sp->m_flags |= ClangExpressionVariable::EVIsProgramReference;
172 break;
173 }
Sean Callanan31a8d052012-01-05 01:11:09 +0000174
Jim Inghamef651602011-12-22 19:12:40 +0000175 return_valobj_sp = clang_expr_variable_sp->GetValueObject();
Jim Ingham73ca05a2011-12-17 01:35:57 +0000176 }
Jim Inghamef651602011-12-22 19:12:40 +0000177 return return_valobj_sp;
Jim Ingham73ca05a2011-12-17 01:35:57 +0000178}
179
Deepak Panickal2526ee52014-07-21 17:21:01 +0000180ValueObjectSP
181ABI::GetReturnValueObject(Thread &thread, llvm::Type &ast_type, bool persistent) const
182{
183 ValueObjectSP return_valobj_sp;
184 return_valobj_sp = GetReturnValueObjectImpl( thread, ast_type );
185 return return_valobj_sp;
186}
Jim Ingham73ca05a2011-12-17 01:35:57 +0000187
Deepak Panickal2526ee52014-07-21 17:21:01 +0000188// specialized to work with llvm IR types
189//
190// for now we will specify a default implementation so that we don't need to
191// modify other ABIs
192lldb::ValueObjectSP
193ABI::GetReturnValueObjectImpl( Thread &thread, llvm::Type &ir_type ) const
194{
195 ValueObjectSP return_valobj_sp;
196
197 /* this is a dummy and will only be called if an ABI does not override this */
198
199 return return_valobj_sp;
200}
201
202bool
203ABI::PrepareTrivialCall (Thread &thread,
204 lldb::addr_t sp,
205 lldb::addr_t functionAddress,
206 lldb::addr_t returnAddress,
207 llvm::Type &returntype,
208 llvm::ArrayRef<ABI::CallArgument> args) const
209{
210 // dummy prepare trivial call
211 assert( !"Should never get here!" );
212 return false;
213}