blob: fef6c57ba238ac4035046b899e7b6a0c3a91a4b2 [file] [log] [blame]
Sean Callanan3bfdaa22011-09-15 02:13:07 +00001//===-- IRInterpreter.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
Ted Woodward7071c5fd2016-03-01 21:53:26 +000010#include "lldb/Core/ConstString.h"
Sean Callananfefe43c2013-04-25 18:55:45 +000011#include "lldb/Core/DataExtractor.h"
12#include "lldb/Core/Error.h"
Sean Callanan3bfdaa22011-09-15 02:13:07 +000013#include "lldb/Core/Log.h"
Ewan Crawford90ff7912015-07-14 10:56:58 +000014#include "lldb/Core/ModuleSpec.h"
15#include "lldb/Core/Module.h"
Sean Callananfefe43c2013-04-25 18:55:45 +000016#include "lldb/Core/Scalar.h"
17#include "lldb/Core/StreamString.h"
Ewan Crawford90ff7912015-07-14 10:56:58 +000018#include "lldb/Core/ValueObject.h"
Ted Woodward7071c5fd2016-03-01 21:53:26 +000019#include "lldb/Expression/IRExecutionUnit.h"
Sean Callananfefe43c2013-04-25 18:55:45 +000020#include "lldb/Expression/IRMemoryMap.h"
Sean Callanan3bfdaa22011-09-15 02:13:07 +000021#include "lldb/Expression/IRInterpreter.h"
Sean Callanan46fc0062013-09-17 18:26:42 +000022#include "lldb/Host/Endian.h"
Sean Callanan3bfdaa22011-09-15 02:13:07 +000023
Ewan Crawford90ff7912015-07-14 10:56:58 +000024#include "lldb/Target/ABI.h"
25#include "lldb/Target/ExecutionContext.h"
26#include "lldb/Target/Target.h"
27#include "lldb/Target/Thread.h"
28#include "lldb/Target/ThreadPlan.h"
29#include "lldb/Target/ThreadPlanCallFunctionUsingABI.h"
30
Chandler Carruth1e157582013-01-02 12:20:07 +000031#include "llvm/IR/Constants.h"
Sean Callananfefe43c2013-04-25 18:55:45 +000032#include "llvm/IR/DataLayout.h"
Chandler Carruth1e157582013-01-02 12:20:07 +000033#include "llvm/IR/Function.h"
34#include "llvm/IR/Instructions.h"
Sean Callanan576a4372014-03-25 19:33:15 +000035#include "llvm/IR/Intrinsics.h"
Ewan Crawford90ff7912015-07-14 10:56:58 +000036#include "llvm/IR/LLVMContext.h"
Chandler Carruth1e157582013-01-02 12:20:07 +000037#include "llvm/IR/Module.h"
Eduard Burtescud05b8992016-01-22 03:43:23 +000038#include "llvm/IR/Operator.h"
Sean Callanan3bfdaa22011-09-15 02:13:07 +000039#include "llvm/Support/raw_ostream.h"
Sean Callanan3bfdaa22011-09-15 02:13:07 +000040
41#include <map>
42
43using namespace llvm;
44
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +000045static std::string
Sean Callanan3bfdaa22011-09-15 02:13:07 +000046PrintValue(const Value *value, bool truncate = false)
47{
48 std::string s;
49 raw_string_ostream rso(s);
50 value->print(rso);
51 rso.flush();
52 if (truncate)
53 s.resize(s.length() - 1);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +000054
Sean Callanan3bfdaa22011-09-15 02:13:07 +000055 size_t offset;
56 while ((offset = s.find('\n')) != s.npos)
57 s.erase(offset, 1);
58 while (s[0] == ' ' || s[0] == '\t')
59 s.erase(0, 1);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +000060
Sean Callanan3bfdaa22011-09-15 02:13:07 +000061 return s;
62}
63
64static std::string
65PrintType(const Type *type, bool truncate = false)
66{
67 std::string s;
68 raw_string_ostream rso(s);
69 type->print(rso);
70 rso.flush();
71 if (truncate)
72 s.resize(s.length() - 1);
73 return s;
74}
75
Sean Callanan576a4372014-03-25 19:33:15 +000076static bool
77CanIgnoreCall (const CallInst *call)
78{
79 const llvm::Function *called_function = call->getCalledFunction();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +000080
Sean Callanan576a4372014-03-25 19:33:15 +000081 if (!called_function)
82 return false;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +000083
Sean Callanan576a4372014-03-25 19:33:15 +000084 if (called_function->isIntrinsic())
85 {
86 switch (called_function->getIntrinsicID())
87 {
88 default:
89 break;
90 case llvm::Intrinsic::dbg_declare:
91 case llvm::Intrinsic::dbg_value:
92 return true;
93 }
94 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +000095
Sean Callanan576a4372014-03-25 19:33:15 +000096 return false;
97}
98
Sean Callanan3bfdaa22011-09-15 02:13:07 +000099class InterpreterStackFrame
100{
101public:
Sean Callanan08052af2013-04-17 07:50:58 +0000102 typedef std::map <const Value*, lldb::addr_t> ValueMap;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000103
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000104 ValueMap m_values;
Micah Villmow8468dbe2012-10-08 16:28:57 +0000105 DataLayout &m_target_data;
Ted Woodward7071c5fd2016-03-01 21:53:26 +0000106 lldb_private::IRExecutionUnit &m_execution_unit;
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000107 const BasicBlock *m_bb;
108 BasicBlock::const_iterator m_ii;
109 BasicBlock::const_iterator m_ie;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000110
Sean Callanan1582ee62013-04-18 22:06:33 +0000111 lldb::addr_t m_frame_process_address;
112 size_t m_frame_size;
113 lldb::addr_t m_stack_pointer;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000114
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000115 lldb::ByteOrder m_byte_order;
116 size_t m_addr_byte_size;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000117
Micah Villmow8468dbe2012-10-08 16:28:57 +0000118 InterpreterStackFrame (DataLayout &target_data,
Ted Woodward7071c5fd2016-03-01 21:53:26 +0000119 lldb_private::IRExecutionUnit &execution_unit,
Sean Callanandf565402013-04-27 02:19:33 +0000120 lldb::addr_t stack_frame_bottom,
121 lldb::addr_t stack_frame_top) :
Daniel Dunbara08823f2011-10-31 22:50:49 +0000122 m_target_data (target_data),
Ted Woodward7071c5fd2016-03-01 21:53:26 +0000123 m_execution_unit (execution_unit)
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000124 {
125 m_byte_order = (target_data.isLittleEndian() ? lldb::eByteOrderLittle : lldb::eByteOrderBig);
Sean Callanan95769bf2012-10-11 22:00:52 +0000126 m_addr_byte_size = (target_data.getPointerSize(0));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000127
Sean Callanandf565402013-04-27 02:19:33 +0000128 m_frame_process_address = stack_frame_bottom;
129 m_frame_size = stack_frame_top - stack_frame_bottom;
130 m_stack_pointer = stack_frame_top;
Sean Callanan1582ee62013-04-18 22:06:33 +0000131 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000132
Sean Callanan1582ee62013-04-18 22:06:33 +0000133 ~InterpreterStackFrame ()
134 {
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000135 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000136
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000137 void Jump (const BasicBlock *bb)
138 {
139 m_bb = bb;
140 m_ii = m_bb->begin();
141 m_ie = m_bb->end();
142 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000143
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000144 std::string SummarizeValue (const Value *value)
145 {
146 lldb_private::StreamString ss;
147
148 ss.Printf("%s", PrintValue(value).c_str());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000149
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000150 ValueMap::iterator i = m_values.find(value);
151
152 if (i != m_values.end())
153 {
Sean Callanan08052af2013-04-17 07:50:58 +0000154 lldb::addr_t addr = i->second;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000155
Sean Callanan08052af2013-04-17 07:50:58 +0000156 ss.Printf(" 0x%llx", (unsigned long long)addr);
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000157 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000158
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000159 return ss.GetString();
160 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000161
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000162 bool AssignToMatchType (lldb_private::Scalar &scalar, uint64_t u64value, Type *type)
163 {
164 size_t type_size = m_target_data.getTypeStoreSize(type);
165
166 switch (type_size)
167 {
168 case 1:
169 scalar = (uint8_t)u64value;
170 break;
171 case 2:
172 scalar = (uint16_t)u64value;
173 break;
174 case 4:
175 scalar = (uint32_t)u64value;
176 break;
177 case 8:
178 scalar = (uint64_t)u64value;
179 break;
180 default:
181 return false;
182 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000183
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000184 return true;
185 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000186
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000187 bool EvaluateValue (lldb_private::Scalar &scalar, const Value *value, Module &module)
188 {
189 const Constant *constant = dyn_cast<Constant>(value);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000190
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000191 if (constant)
192 {
Sean Callanan415422c2013-06-05 22:07:06 +0000193 APInt value_apint;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000194
Sean Callanan415422c2013-06-05 22:07:06 +0000195 if (!ResolveConstantValue(value_apint, constant))
196 return false;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000197
Sean Callanan415422c2013-06-05 22:07:06 +0000198 return AssignToMatchType(scalar, value_apint.getLimitedValue(), value->getType());
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000199 }
200 else
201 {
Sean Callanan08052af2013-04-17 07:50:58 +0000202 lldb::addr_t process_address = ResolveValue(value, module);
203 size_t value_size = m_target_data.getTypeStoreSize(value->getType());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000204
Sean Callanan08052af2013-04-17 07:50:58 +0000205 lldb_private::DataExtractor value_extractor;
206 lldb_private::Error extract_error;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000207
Ted Woodward7071c5fd2016-03-01 21:53:26 +0000208 m_execution_unit.GetMemoryData(value_extractor, process_address, value_size, extract_error);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000209
Sean Callanan08052af2013-04-17 07:50:58 +0000210 if (!extract_error.Success())
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000211 return false;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000212
Greg Claytonc7bece562013-01-25 18:06:21 +0000213 lldb::offset_t offset = 0;
Sean Callanan544053e2013-06-06 21:14:35 +0000214 if (value_size == 1 || value_size == 2 || value_size == 4 || value_size == 8)
Greg Clayton78e44bd2013-04-25 00:57:05 +0000215 {
216 uint64_t u64value = value_extractor.GetMaxU64(&offset, value_size);
217 return AssignToMatchType(scalar, u64value, value->getType());
218 }
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000219 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000220
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000221 return false;
222 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000223
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000224 bool AssignValue (const Value *value, lldb_private::Scalar &scalar, Module &module)
225 {
Sean Callanan08052af2013-04-17 07:50:58 +0000226 lldb::addr_t process_address = ResolveValue (value, module);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000227
Sean Callanan08052af2013-04-17 07:50:58 +0000228 if (process_address == LLDB_INVALID_ADDRESS)
229 return false;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000230
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000231 lldb_private::Scalar cast_scalar;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000232
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000233 if (!AssignToMatchType(cast_scalar, scalar.GetRawBits64(0), value->getType()))
234 return false;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000235
Sean Callanan08052af2013-04-17 07:50:58 +0000236 size_t value_byte_size = m_target_data.getTypeStoreSize(value->getType());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000237
Sean Callanan08052af2013-04-17 07:50:58 +0000238 lldb_private::DataBufferHeap buf(value_byte_size, 0);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000239
Sean Callanan08052af2013-04-17 07:50:58 +0000240 lldb_private::Error get_data_error;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000241
Sean Callanan08052af2013-04-17 07:50:58 +0000242 if (!cast_scalar.GetAsMemoryData(buf.GetBytes(), buf.GetByteSize(), m_byte_order, get_data_error))
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000243 return false;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000244
Sean Callanan08052af2013-04-17 07:50:58 +0000245 lldb_private::Error write_error;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000246
Ted Woodward7071c5fd2016-03-01 21:53:26 +0000247 m_execution_unit.WriteMemory(process_address, buf.GetBytes(), buf.GetByteSize(), write_error);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000248
Sean Callanan08052af2013-04-17 07:50:58 +0000249 return write_error.Success();
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000250 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000251
Sean Callanan94a9a392012-02-08 01:27:49 +0000252 bool ResolveConstantValue (APInt &value, const Constant *constant)
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000253 {
Sean Callanan1582ee62013-04-18 22:06:33 +0000254 switch (constant->getValueID())
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000255 {
Sean Callanan1582ee62013-04-18 22:06:33 +0000256 default:
257 break;
Ted Woodward7071c5fd2016-03-01 21:53:26 +0000258 case Value::FunctionVal:
259 if (const Function *constant_func = dyn_cast<Function>(constant))
260 {
261 lldb_private::ConstString name(constant_func->getName());
262 lldb::addr_t addr = m_execution_unit.FindSymbol(name);
263 if (addr == LLDB_INVALID_ADDRESS)
264 return false;
265 value = APInt(m_target_data.getPointerSizeInBits(), addr);
266 return true;
267 }
268 break;
Sean Callanan1582ee62013-04-18 22:06:33 +0000269 case Value::ConstantIntVal:
270 if (const ConstantInt *constant_int = dyn_cast<ConstantInt>(constant))
Sean Callanan80c48c12011-10-21 05:18:02 +0000271 {
Sean Callanan1582ee62013-04-18 22:06:33 +0000272 value = constant_int->getValue();
273 return true;
274 }
275 break;
276 case Value::ConstantFPVal:
277 if (const ConstantFP *constant_fp = dyn_cast<ConstantFP>(constant))
278 {
279 value = constant_fp->getValueAPF().bitcastToAPInt();
280 return true;
281 }
282 break;
283 case Value::ConstantExprVal:
284 if (const ConstantExpr *constant_expr = dyn_cast<ConstantExpr>(constant))
285 {
286 switch (constant_expr->getOpcode())
Sean Callanan94a9a392012-02-08 01:27:49 +0000287 {
Sean Callanan1582ee62013-04-18 22:06:33 +0000288 default:
Sean Callanan94a9a392012-02-08 01:27:49 +0000289 return false;
Sean Callanan1582ee62013-04-18 22:06:33 +0000290 case Instruction::IntToPtr:
291 case Instruction::PtrToInt:
292 case Instruction::BitCast:
293 return ResolveConstantValue(value, constant_expr->getOperand(0));
294 case Instruction::GetElementPtr:
295 {
296 ConstantExpr::const_op_iterator op_cursor = constant_expr->op_begin();
297 ConstantExpr::const_op_iterator op_end = constant_expr->op_end();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000298
Sean Callanan1582ee62013-04-18 22:06:33 +0000299 Constant *base = dyn_cast<Constant>(*op_cursor);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000300
Sean Callanan1582ee62013-04-18 22:06:33 +0000301 if (!base)
302 return false;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000303
Sean Callanan1582ee62013-04-18 22:06:33 +0000304 if (!ResolveConstantValue(value, base))
305 return false;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000306
Sean Callanan1582ee62013-04-18 22:06:33 +0000307 op_cursor++;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000308
Sean Callanan1582ee62013-04-18 22:06:33 +0000309 if (op_cursor == op_end)
310 return true; // no offset to apply!
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000311
Sean Callanan1582ee62013-04-18 22:06:33 +0000312 SmallVector <Value *, 8> indices (op_cursor, op_end);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000313
Eduard Burtescud05b8992016-01-22 03:43:23 +0000314 Type *src_elem_ty = cast<GEPOperator>(constant_expr)->getSourceElementType();
315 uint64_t offset = m_target_data.getIndexedOffsetInType(src_elem_ty, indices);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000316
Sean Callanan1582ee62013-04-18 22:06:33 +0000317 const bool is_signed = true;
318 value += APInt(value.getBitWidth(), offset, is_signed);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000319
Sean Callanan1582ee62013-04-18 22:06:33 +0000320 return true;
321 }
Sean Callanan94a9a392012-02-08 01:27:49 +0000322 }
Sean Callanan80c48c12011-10-21 05:18:02 +0000323 }
Sean Callanan1582ee62013-04-18 22:06:33 +0000324 break;
325 case Value::ConstantPointerNullVal:
326 if (isa<ConstantPointerNull>(constant))
327 {
328 value = APInt(m_target_data.getPointerSizeInBits(), 0);
329 return true;
330 }
331 break;
332 }
333 return false;
334 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000335
Sean Callanan1582ee62013-04-18 22:06:33 +0000336 bool MakeArgument(const Argument *value, uint64_t address)
337 {
338 lldb::addr_t data_address = Malloc(value->getType());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000339
Sean Callanan1582ee62013-04-18 22:06:33 +0000340 if (data_address == LLDB_INVALID_ADDRESS)
341 return false;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000342
Sean Callanan1582ee62013-04-18 22:06:33 +0000343 lldb_private::Error write_error;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000344
Ted Woodward7071c5fd2016-03-01 21:53:26 +0000345 m_execution_unit.WritePointerToMemory(data_address, address, write_error);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000346
Sean Callanan1582ee62013-04-18 22:06:33 +0000347 if (!write_error.Success())
348 {
349 lldb_private::Error free_error;
Ted Woodward7071c5fd2016-03-01 21:53:26 +0000350 m_execution_unit.Free(data_address, free_error);
Sean Callanan1582ee62013-04-18 22:06:33 +0000351 return false;
Sean Callanan80c48c12011-10-21 05:18:02 +0000352 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000353
Sean Callanan1582ee62013-04-18 22:06:33 +0000354 m_values[value] = data_address;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000355
Sean Callanan1582ee62013-04-18 22:06:33 +0000356 lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
357
358 if (log)
359 {
360 log->Printf("Made an allocation for argument %s", PrintValue(value).c_str());
361 log->Printf(" Data region : %llx", (unsigned long long)address);
362 log->Printf(" Ref region : %llx", (unsigned long long)data_address);
363 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000364
Sean Callanan1582ee62013-04-18 22:06:33 +0000365 return true;
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000366 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000367
Sean Callanan08052af2013-04-17 07:50:58 +0000368 bool ResolveConstant (lldb::addr_t process_address, const Constant *constant)
Sean Callanan94a9a392012-02-08 01:27:49 +0000369 {
370 APInt resolved_value;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000371
Sean Callanan94a9a392012-02-08 01:27:49 +0000372 if (!ResolveConstantValue(resolved_value, constant))
373 return false;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000374
Sean Callanan46fc0062013-09-17 18:26:42 +0000375 lldb_private::StreamString buffer (lldb_private::Stream::eBinary,
Ted Woodward7071c5fd2016-03-01 21:53:26 +0000376 m_execution_unit.GetAddressByteSize(),
377 m_execution_unit.GetByteOrder());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000378
Sean Callanan94a9a392012-02-08 01:27:49 +0000379 size_t constant_size = m_target_data.getTypeStoreSize(constant->getType());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000380
Sean Callanan46fc0062013-09-17 18:26:42 +0000381 const uint64_t *raw_data = resolved_value.getRawData();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000382
Bruce Mitchener9ccb9702015-11-07 04:40:13 +0000383 buffer.PutRawBytes(raw_data, constant_size, lldb_private::endian::InlHostByteOrder());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000384
Sean Callanan08052af2013-04-17 07:50:58 +0000385 lldb_private::Error write_error;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000386
Ted Woodward7071c5fd2016-03-01 21:53:26 +0000387 m_execution_unit.WriteMemory(process_address, (const uint8_t*)buffer.GetData(), constant_size, write_error);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000388
Sean Callanan08052af2013-04-17 07:50:58 +0000389 return write_error.Success();
390 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000391
Sean Callanan1582ee62013-04-18 22:06:33 +0000392 lldb::addr_t Malloc (size_t size, uint8_t byte_alignment)
393 {
394 lldb::addr_t ret = m_stack_pointer;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000395
Sean Callanan1582ee62013-04-18 22:06:33 +0000396 ret -= size;
397 ret -= (ret % byte_alignment);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000398
Sean Callanan1582ee62013-04-18 22:06:33 +0000399 if (ret < m_frame_process_address)
400 return LLDB_INVALID_ADDRESS;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000401
Sean Callanan1582ee62013-04-18 22:06:33 +0000402 m_stack_pointer = ret;
403 return ret;
404 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000405
Sean Callanan08052af2013-04-17 07:50:58 +0000406 lldb::addr_t MallocPointer ()
407 {
Sean Callanan1582ee62013-04-18 22:06:33 +0000408 return Malloc(m_target_data.getPointerSize(), m_target_data.getPointerPrefAlignment());
Sean Callanan08052af2013-04-17 07:50:58 +0000409 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000410
Sean Callanan1582ee62013-04-18 22:06:33 +0000411 lldb::addr_t Malloc (llvm::Type *type)
Sean Callanan08052af2013-04-17 07:50:58 +0000412 {
413 lldb_private::Error alloc_error;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000414
Sean Callanan1582ee62013-04-18 22:06:33 +0000415 return Malloc(m_target_data.getTypeAllocSize(type), m_target_data.getPrefTypeAlignment(type));
Sean Callanan08052af2013-04-17 07:50:58 +0000416 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000417
Sean Callanan08052af2013-04-17 07:50:58 +0000418 std::string PrintData (lldb::addr_t addr, llvm::Type *type)
419 {
420 size_t length = m_target_data.getTypeStoreSize(type);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000421
Sean Callanan08052af2013-04-17 07:50:58 +0000422 lldb_private::DataBufferHeap buf(length, 0);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000423
Sean Callanan08052af2013-04-17 07:50:58 +0000424 lldb_private::Error read_error;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000425
Ted Woodward7071c5fd2016-03-01 21:53:26 +0000426 m_execution_unit.ReadMemory(buf.GetBytes(), addr, length, read_error);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000427
Sean Callanan08052af2013-04-17 07:50:58 +0000428 if (!read_error.Success())
429 return std::string("<couldn't read data>");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000430
Sean Callanan08052af2013-04-17 07:50:58 +0000431 lldb_private::StreamString ss;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000432
Sean Callanan08052af2013-04-17 07:50:58 +0000433 for (size_t i = 0; i < length; i++)
434 {
435 if ((!(i & 0xf)) && i)
436 ss.Printf("%02hhx - ", buf.GetBytes()[i]);
437 else
438 ss.Printf("%02hhx ", buf.GetBytes()[i]);
439 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000440
Sean Callanan08052af2013-04-17 07:50:58 +0000441 return ss.GetString();
442 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000443
Sean Callanan08052af2013-04-17 07:50:58 +0000444 lldb::addr_t ResolveValue (const Value *value, Module &module)
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000445 {
446 ValueMap::iterator i = m_values.find(value);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000447
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000448 if (i != m_values.end())
449 return i->second;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000450
Sean Callanan1582ee62013-04-18 22:06:33 +0000451 // Fall back and allocate space [allocation type Alloca]
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000452
Sean Callanan1582ee62013-04-18 22:06:33 +0000453 lldb::addr_t data_address = Malloc(value->getType());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000454
Sean Callanan1582ee62013-04-18 22:06:33 +0000455 if (const Constant *constant = dyn_cast<Constant>(value))
456 {
457 if (!ResolveConstant (data_address, constant))
458 {
459 lldb_private::Error free_error;
Ted Woodward7071c5fd2016-03-01 21:53:26 +0000460 m_execution_unit.Free(data_address, free_error);
Sean Callanan1582ee62013-04-18 22:06:33 +0000461 return LLDB_INVALID_ADDRESS;
462 }
463 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000464
Sean Callanan1582ee62013-04-18 22:06:33 +0000465 m_values[value] = data_address;
466 return data_address;
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000467 }
468};
469
Sean Callanan175a0d02012-01-24 22:06:48 +0000470static const char *unsupported_opcode_error = "Interpreter doesn't handle one of the expression's opcodes";
Sean Callanan3fa3e652013-05-02 00:33:44 +0000471static const char *unsupported_operand_error = "Interpreter doesn't handle one of the expression's operands";
Greg Claytone01e07b2013-04-18 18:10:51 +0000472//static const char *interpreter_initialization_error = "Interpreter couldn't be initialized";
Sean Callanan175a0d02012-01-24 22:06:48 +0000473static const char *interpreter_internal_error = "Interpreter encountered an internal error";
474static const char *bad_value_error = "Interpreter couldn't resolve a value during execution";
475static const char *memory_allocation_error = "Interpreter couldn't allocate memory";
476static const char *memory_write_error = "Interpreter couldn't write to memory";
477static const char *memory_read_error = "Interpreter couldn't read from memory";
478static const char *infinite_loop_error = "Interpreter ran for too many cycles";
Sean Callanan44342732013-04-19 08:14:32 +0000479//static const char *bad_result_error = "Result of expression is in bad memory";
Sean Callanan175a0d02012-01-24 22:06:48 +0000480
Sean Callanan8c62daf2016-02-12 21:16:58 +0000481static bool
482CanResolveConstant (llvm::Constant *constant)
483{
484 switch (constant->getValueID())
485 {
486 default:
487 return false;
488 case Value::ConstantIntVal:
489 case Value::ConstantFPVal:
Ted Woodward7071c5fd2016-03-01 21:53:26 +0000490 case Value::FunctionVal:
Sean Callanan8c62daf2016-02-12 21:16:58 +0000491 return true;
492 case Value::ConstantExprVal:
493 if (const ConstantExpr *constant_expr = dyn_cast<ConstantExpr>(constant))
494 {
495 switch (constant_expr->getOpcode())
496 {
497 default:
498 return false;
499 case Instruction::IntToPtr:
500 case Instruction::PtrToInt:
501 case Instruction::BitCast:
502 return CanResolveConstant(constant_expr->getOperand(0));
503 case Instruction::GetElementPtr:
504 {
505 ConstantExpr::const_op_iterator op_cursor = constant_expr->op_begin();
506 Constant *base = dyn_cast<Constant>(*op_cursor);
507 if (!base)
508 return false;
509
510 return CanResolveConstant(base);
511 }
512 }
513 } else {
514 return false;
515 }
516 case Value::ConstantPointerNullVal:
517 return true;
518 }
519}
520
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000521bool
Sean Callanan44342732013-04-19 08:14:32 +0000522IRInterpreter::CanInterpret (llvm::Module &module,
523 llvm::Function &function,
Ewan Crawford90ff7912015-07-14 10:56:58 +0000524 lldb_private::Error &error,
525 const bool support_function_calls)
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000526{
Greg Clayton5160ce52013-03-27 23:08:40 +0000527 lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000528
Sean Callanan85fc8762013-06-27 01:59:51 +0000529 bool saw_function_with_body = false;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000530
Sean Callanan85fc8762013-06-27 01:59:51 +0000531 for (Module::iterator fi = module.begin(), fe = module.end();
532 fi != fe;
533 ++fi)
534 {
535 if (fi->begin() != fi->end())
536 {
537 if (saw_function_with_body)
538 return false;
539 saw_function_with_body = true;
540 }
541 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000542
Sean Callanan44342732013-04-19 08:14:32 +0000543 for (Function::iterator bbi = function.begin(), bbe = function.end();
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000544 bbi != bbe;
545 ++bbi)
546 {
547 for (BasicBlock::iterator ii = bbi->begin(), ie = bbi->end();
548 ii != ie;
549 ++ii)
550 {
551 switch (ii->getOpcode())
552 {
553 default:
554 {
555 if (log)
Duncan P. N. Exon Smith33e43ca2015-11-07 00:54:13 +0000556 log->Printf("Unsupported instruction: %s", PrintValue(&*ii).c_str());
Sean Callanan44342732013-04-19 08:14:32 +0000557 error.SetErrorToGenericError();
558 error.SetErrorString(unsupported_opcode_error);
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000559 return false;
560 }
561 case Instruction::Add:
562 case Instruction::Alloca:
563 case Instruction::BitCast:
564 case Instruction::Br:
Sean Callanan576a4372014-03-25 19:33:15 +0000565 break;
566 case Instruction::Call:
567 {
568 CallInst *call_inst = dyn_cast<CallInst>(ii);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000569
Sean Callanan576a4372014-03-25 19:33:15 +0000570 if (!call_inst)
571 {
572 error.SetErrorToGenericError();
573 error.SetErrorString(interpreter_internal_error);
574 return false;
575 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000576
Ewan Crawford90ff7912015-07-14 10:56:58 +0000577 if (!CanIgnoreCall(call_inst) && !support_function_calls)
Sean Callanan576a4372014-03-25 19:33:15 +0000578 {
579 if (log)
Duncan P. N. Exon Smith33e43ca2015-11-07 00:54:13 +0000580 log->Printf("Unsupported instruction: %s", PrintValue(&*ii).c_str());
Sean Callanan576a4372014-03-25 19:33:15 +0000581 error.SetErrorToGenericError();
582 error.SetErrorString(unsupported_opcode_error);
583 return false;
584 }
585 }
Sean Callanan92872892014-03-25 19:47:07 +0000586 break;
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000587 case Instruction::GetElementPtr:
588 break;
589 case Instruction::ICmp:
590 {
591 ICmpInst *icmp_inst = dyn_cast<ICmpInst>(ii);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000592
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000593 if (!icmp_inst)
Sean Callanan175a0d02012-01-24 22:06:48 +0000594 {
Sean Callanan44342732013-04-19 08:14:32 +0000595 error.SetErrorToGenericError();
596 error.SetErrorString(interpreter_internal_error);
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000597 return false;
Sean Callanan175a0d02012-01-24 22:06:48 +0000598 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000599
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000600 switch (icmp_inst->getPredicate())
601 {
602 default:
Sean Callanan44342732013-04-19 08:14:32 +0000603 {
604 if (log)
Duncan P. N. Exon Smith33e43ca2015-11-07 00:54:13 +0000605 log->Printf("Unsupported ICmp predicate: %s", PrintValue(&*ii).c_str());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000606
Sean Callanan44342732013-04-19 08:14:32 +0000607 error.SetErrorToGenericError();
608 error.SetErrorString(unsupported_opcode_error);
609 return false;
610 }
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000611 case CmpInst::ICMP_EQ:
612 case CmpInst::ICMP_NE:
613 case CmpInst::ICMP_UGT:
614 case CmpInst::ICMP_UGE:
615 case CmpInst::ICMP_ULT:
616 case CmpInst::ICMP_ULE:
617 case CmpInst::ICMP_SGT:
618 case CmpInst::ICMP_SGE:
619 case CmpInst::ICMP_SLT:
620 case CmpInst::ICMP_SLE:
621 break;
622 }
623 }
624 break;
Sean Callanan087f4372013-01-09 22:44:41 +0000625 case Instruction::And:
626 case Instruction::AShr:
Sean Callanan80c48c12011-10-21 05:18:02 +0000627 case Instruction::IntToPtr:
Sean Callanan2abffe02012-12-01 00:09:34 +0000628 case Instruction::PtrToInt:
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000629 case Instruction::Load:
Sean Callanan087f4372013-01-09 22:44:41 +0000630 case Instruction::LShr:
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000631 case Instruction::Mul:
Sean Callanan087f4372013-01-09 22:44:41 +0000632 case Instruction::Or:
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000633 case Instruction::Ret:
634 case Instruction::SDiv:
Sean Callanan415422c2013-06-05 22:07:06 +0000635 case Instruction::SExt:
Sean Callanan087f4372013-01-09 22:44:41 +0000636 case Instruction::Shl:
Sean Callananf466a6e2012-12-21 22:27:55 +0000637 case Instruction::SRem:
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000638 case Instruction::Store:
639 case Instruction::Sub:
Sean Callanan8c46bac2013-10-11 19:45:00 +0000640 case Instruction::Trunc:
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000641 case Instruction::UDiv:
Sean Callananf466a6e2012-12-21 22:27:55 +0000642 case Instruction::URem:
Sean Callanan087f4372013-01-09 22:44:41 +0000643 case Instruction::Xor:
Sean Callanan1ef77432012-04-23 17:25:38 +0000644 case Instruction::ZExt:
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000645 break;
646 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000647
Sean Callanan3fa3e652013-05-02 00:33:44 +0000648 for (int oi = 0, oe = ii->getNumOperands();
649 oi != oe;
650 ++oi)
651 {
652 Value *operand = ii->getOperand(oi);
653 Type *operand_type = operand->getType();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000654
Sean Callanan3fa3e652013-05-02 00:33:44 +0000655 switch (operand_type->getTypeID())
656 {
657 default:
658 break;
659 case Type::VectorTyID:
660 {
661 if (log)
662 log->Printf("Unsupported operand type: %s", PrintType(operand_type).c_str());
663 error.SetErrorString(unsupported_operand_error);
664 return false;
665 }
666 }
Sean Callanan8c62daf2016-02-12 21:16:58 +0000667
668 if (Constant *constant = llvm::dyn_cast<Constant>(operand))
669 {
670 if (!CanResolveConstant(constant))
671 {
672 if (log)
673 log->Printf("Unsupported constant: %s", PrintValue(constant).c_str());
674 error.SetErrorString(unsupported_operand_error);
675 return false;
676 }
677 }
Sean Callanan3fa3e652013-05-02 00:33:44 +0000678 }
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000679 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000680
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000681 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000682
Sean Callanan44342732013-04-19 08:14:32 +0000683 return true;}
Sean Callanan14cb2aa2013-04-17 18:35:47 +0000684
685bool
686IRInterpreter::Interpret (llvm::Module &module,
687 llvm::Function &function,
Sean Callanan1582ee62013-04-18 22:06:33 +0000688 llvm::ArrayRef<lldb::addr_t> args,
Ted Woodward7071c5fd2016-03-01 21:53:26 +0000689 lldb_private::IRExecutionUnit &execution_unit,
Sean Callanandf565402013-04-27 02:19:33 +0000690 lldb_private::Error &error,
691 lldb::addr_t stack_frame_bottom,
Ewan Crawford90ff7912015-07-14 10:56:58 +0000692 lldb::addr_t stack_frame_top,
693 lldb_private::ExecutionContext &exe_ctx)
Sean Callanan14cb2aa2013-04-17 18:35:47 +0000694{
695 lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000696
Sean Callanan1582ee62013-04-18 22:06:33 +0000697 if (log)
698 {
699 std::string s;
700 raw_string_ostream oss(s);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000701
Sean Callanan1582ee62013-04-18 22:06:33 +0000702 module.print(oss, NULL);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000703
Sean Callanan1582ee62013-04-18 22:06:33 +0000704 oss.flush();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000705
Sean Callanan1582ee62013-04-18 22:06:33 +0000706 log->Printf("Module as passed in to IRInterpreter::Interpret: \n\"%s\"", s.c_str());
707 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000708
Sean Callanan14cb2aa2013-04-17 18:35:47 +0000709 DataLayout data_layout(&module);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000710
Ted Woodward7071c5fd2016-03-01 21:53:26 +0000711 InterpreterStackFrame frame(data_layout, execution_unit, stack_frame_bottom, stack_frame_top);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000712
Sean Callanan1582ee62013-04-18 22:06:33 +0000713 if (frame.m_frame_process_address == LLDB_INVALID_ADDRESS)
714 {
715 error.SetErrorString("Couldn't allocate stack frame");
716 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000717
Sean Callanan1582ee62013-04-18 22:06:33 +0000718 int arg_index = 0;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000719
Sean Callanan1582ee62013-04-18 22:06:33 +0000720 for (llvm::Function::arg_iterator ai = function.arg_begin(), ae = function.arg_end();
721 ai != ae;
722 ++ai, ++arg_index)
723 {
Chaoren Lin3ca7a3e2015-09-16 01:20:34 +0000724 if (args.size() <= static_cast<size_t>(arg_index))
Sean Callanan1582ee62013-04-18 22:06:33 +0000725 {
726 error.SetErrorString ("Not enough arguments passed in to function");
727 return false;
728 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000729
Sean Callanan1582ee62013-04-18 22:06:33 +0000730 lldb::addr_t ptr = args[arg_index];
731
Duncan P. N. Exon Smith33e43ca2015-11-07 00:54:13 +0000732 frame.MakeArgument(&*ai, ptr);
Sean Callanan1582ee62013-04-18 22:06:33 +0000733 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000734
Sean Callanan14cb2aa2013-04-17 18:35:47 +0000735 uint32_t num_insts = 0;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000736
Duncan P. N. Exon Smith33e43ca2015-11-07 00:54:13 +0000737 frame.Jump(&function.front());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000738
Sean Callanan14cb2aa2013-04-17 18:35:47 +0000739 while (frame.m_ii != frame.m_ie && (++num_insts < 4096))
740 {
Duncan P. N. Exon Smith33e43ca2015-11-07 00:54:13 +0000741 const Instruction *inst = &*frame.m_ii;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000742
Sean Callanan14cb2aa2013-04-17 18:35:47 +0000743 if (log)
744 log->Printf("Interpreting %s", PrintValue(inst).c_str());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000745
Sean Callanan14cb2aa2013-04-17 18:35:47 +0000746 switch (inst->getOpcode())
747 {
748 default:
749 break;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000750
Sean Callanan14cb2aa2013-04-17 18:35:47 +0000751 case Instruction::Add:
752 case Instruction::Sub:
753 case Instruction::Mul:
754 case Instruction::SDiv:
755 case Instruction::UDiv:
756 case Instruction::SRem:
757 case Instruction::URem:
758 case Instruction::Shl:
759 case Instruction::LShr:
760 case Instruction::AShr:
761 case Instruction::And:
762 case Instruction::Or:
763 case Instruction::Xor:
764 {
765 const BinaryOperator *bin_op = dyn_cast<BinaryOperator>(inst);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000766
Sean Callanan14cb2aa2013-04-17 18:35:47 +0000767 if (!bin_op)
768 {
769 if (log)
770 log->Printf("getOpcode() returns %s, but instruction is not a BinaryOperator", inst->getOpcodeName());
771 error.SetErrorToGenericError();
772 error.SetErrorString(interpreter_internal_error);
773 return false;
774 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000775
Sean Callanan14cb2aa2013-04-17 18:35:47 +0000776 Value *lhs = inst->getOperand(0);
777 Value *rhs = inst->getOperand(1);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000778
Sean Callanan14cb2aa2013-04-17 18:35:47 +0000779 lldb_private::Scalar L;
780 lldb_private::Scalar R;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000781
Sean Callanan14cb2aa2013-04-17 18:35:47 +0000782 if (!frame.EvaluateValue(L, lhs, module))
783 {
784 if (log)
785 log->Printf("Couldn't evaluate %s", PrintValue(lhs).c_str());
786 error.SetErrorToGenericError();
787 error.SetErrorString(bad_value_error);
788 return false;
789 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000790
Sean Callanan14cb2aa2013-04-17 18:35:47 +0000791 if (!frame.EvaluateValue(R, rhs, module))
792 {
793 if (log)
794 log->Printf("Couldn't evaluate %s", PrintValue(rhs).c_str());
795 error.SetErrorToGenericError();
796 error.SetErrorString(bad_value_error);
797 return false;
798 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000799
Sean Callanan14cb2aa2013-04-17 18:35:47 +0000800 lldb_private::Scalar result;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000801
Sean Callanan14cb2aa2013-04-17 18:35:47 +0000802 switch (inst->getOpcode())
803 {
804 default:
805 break;
806 case Instruction::Add:
807 result = L + R;
808 break;
809 case Instruction::Mul:
810 result = L * R;
811 break;
812 case Instruction::Sub:
813 result = L - R;
814 break;
815 case Instruction::SDiv:
Sean Callanan0b342b62013-05-24 20:36:56 +0000816 L.MakeSigned();
817 R.MakeSigned();
Sean Callanan14cb2aa2013-04-17 18:35:47 +0000818 result = L / R;
819 break;
820 case Instruction::UDiv:
821 result = L.GetRawBits64(0) / R.GetRawBits64(1);
822 break;
823 case Instruction::SRem:
Sean Callanan0b342b62013-05-24 20:36:56 +0000824 L.MakeSigned();
825 R.MakeSigned();
Sean Callanan14cb2aa2013-04-17 18:35:47 +0000826 result = L % R;
827 break;
828 case Instruction::URem:
829 result = L.GetRawBits64(0) % R.GetRawBits64(1);
830 break;
831 case Instruction::Shl:
832 result = L << R;
833 break;
834 case Instruction::AShr:
835 result = L >> R;
836 break;
837 case Instruction::LShr:
838 result = L;
839 result.ShiftRightLogical(R);
840 break;
841 case Instruction::And:
842 result = L & R;
843 break;
844 case Instruction::Or:
845 result = L | R;
846 break;
847 case Instruction::Xor:
848 result = L ^ R;
849 break;
850 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000851
Sean Callanan14cb2aa2013-04-17 18:35:47 +0000852 frame.AssignValue(inst, result, module);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000853
Sean Callanan14cb2aa2013-04-17 18:35:47 +0000854 if (log)
855 {
856 log->Printf("Interpreted a %s", inst->getOpcodeName());
857 log->Printf(" L : %s", frame.SummarizeValue(lhs).c_str());
858 log->Printf(" R : %s", frame.SummarizeValue(rhs).c_str());
859 log->Printf(" = : %s", frame.SummarizeValue(inst).c_str());
860 }
861 }
862 break;
863 case Instruction::Alloca:
864 {
865 const AllocaInst *alloca_inst = dyn_cast<AllocaInst>(inst);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000866
Sean Callanan14cb2aa2013-04-17 18:35:47 +0000867 if (!alloca_inst)
868 {
869 if (log)
870 log->Printf("getOpcode() returns Alloca, but instruction is not an AllocaInst");
871 error.SetErrorToGenericError();
872 error.SetErrorString(interpreter_internal_error);
873 return false;
874 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000875
Sean Callanan14cb2aa2013-04-17 18:35:47 +0000876 if (alloca_inst->isArrayAllocation())
877 {
878 if (log)
879 log->Printf("AllocaInsts are not handled if isArrayAllocation() is true");
880 error.SetErrorToGenericError();
881 error.SetErrorString(unsupported_opcode_error);
882 return false;
883 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000884
Sean Callanan14cb2aa2013-04-17 18:35:47 +0000885 // The semantics of Alloca are:
886 // Create a region R of virtual memory of type T, backed by a data buffer
887 // Create a region P of virtual memory of type T*, backed by a data buffer
888 // Write the virtual address of R into P
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000889
Sean Callanan14cb2aa2013-04-17 18:35:47 +0000890 Type *T = alloca_inst->getAllocatedType();
891 Type *Tptr = alloca_inst->getType();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000892
Sean Callanan14cb2aa2013-04-17 18:35:47 +0000893 lldb::addr_t R = frame.Malloc(T);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000894
Sean Callanan14cb2aa2013-04-17 18:35:47 +0000895 if (R == LLDB_INVALID_ADDRESS)
896 {
897 if (log)
898 log->Printf("Couldn't allocate memory for an AllocaInst");
899 error.SetErrorToGenericError();
900 error.SetErrorString(memory_allocation_error);
901 return false;
902 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000903
Sean Callanan14cb2aa2013-04-17 18:35:47 +0000904 lldb::addr_t P = frame.Malloc(Tptr);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000905
Sean Callanan14cb2aa2013-04-17 18:35:47 +0000906 if (P == LLDB_INVALID_ADDRESS)
907 {
908 if (log)
909 log->Printf("Couldn't allocate the result pointer for an AllocaInst");
910 error.SetErrorToGenericError();
911 error.SetErrorString(memory_allocation_error);
912 return false;
913 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000914
Sean Callanan14cb2aa2013-04-17 18:35:47 +0000915 lldb_private::Error write_error;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000916
Ted Woodward7071c5fd2016-03-01 21:53:26 +0000917 execution_unit.WritePointerToMemory(P, R, write_error);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000918
Sean Callanan14cb2aa2013-04-17 18:35:47 +0000919 if (!write_error.Success())
920 {
921 if (log)
922 log->Printf("Couldn't write the result pointer for an AllocaInst");
923 error.SetErrorToGenericError();
924 error.SetErrorString(memory_write_error);
925 lldb_private::Error free_error;
Ted Woodward7071c5fd2016-03-01 21:53:26 +0000926 execution_unit.Free(P, free_error);
927 execution_unit.Free(R, free_error);
Sean Callanan14cb2aa2013-04-17 18:35:47 +0000928 return false;
929 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000930
Sean Callanan14cb2aa2013-04-17 18:35:47 +0000931 frame.m_values[alloca_inst] = P;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000932
Sean Callanan14cb2aa2013-04-17 18:35:47 +0000933 if (log)
934 {
935 log->Printf("Interpreted an AllocaInst");
Matt Kopecef143712013-06-03 18:00:07 +0000936 log->Printf(" R : 0x%" PRIx64, R);
937 log->Printf(" P : 0x%" PRIx64, P);
Sean Callanan14cb2aa2013-04-17 18:35:47 +0000938 }
939 }
940 break;
941 case Instruction::BitCast:
942 case Instruction::ZExt:
943 {
944 const CastInst *cast_inst = dyn_cast<CastInst>(inst);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000945
Sean Callanan14cb2aa2013-04-17 18:35:47 +0000946 if (!cast_inst)
947 {
948 if (log)
949 log->Printf("getOpcode() returns %s, but instruction is not a BitCastInst", cast_inst->getOpcodeName());
950 error.SetErrorToGenericError();
951 error.SetErrorString(interpreter_internal_error);
952 return false;
953 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000954
Sean Callanan14cb2aa2013-04-17 18:35:47 +0000955 Value *source = cast_inst->getOperand(0);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000956
Sean Callanan14cb2aa2013-04-17 18:35:47 +0000957 lldb_private::Scalar S;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000958
Sean Callanan14cb2aa2013-04-17 18:35:47 +0000959 if (!frame.EvaluateValue(S, source, module))
960 {
961 if (log)
962 log->Printf("Couldn't evaluate %s", PrintValue(source).c_str());
963 error.SetErrorToGenericError();
964 error.SetErrorString(bad_value_error);
965 return false;
966 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000967
Sean Callanan14cb2aa2013-04-17 18:35:47 +0000968 frame.AssignValue(inst, S, module);
969 }
970 break;
Sean Callanan415422c2013-06-05 22:07:06 +0000971 case Instruction::SExt:
972 {
973 const CastInst *cast_inst = dyn_cast<CastInst>(inst);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000974
Sean Callanan415422c2013-06-05 22:07:06 +0000975 if (!cast_inst)
976 {
977 if (log)
978 log->Printf("getOpcode() returns %s, but instruction is not a BitCastInst", cast_inst->getOpcodeName());
979 error.SetErrorToGenericError();
980 error.SetErrorString(interpreter_internal_error);
981 return false;
982 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000983
Sean Callanan415422c2013-06-05 22:07:06 +0000984 Value *source = cast_inst->getOperand(0);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000985
Sean Callanan415422c2013-06-05 22:07:06 +0000986 lldb_private::Scalar S;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000987
Sean Callanan415422c2013-06-05 22:07:06 +0000988 if (!frame.EvaluateValue(S, source, module))
989 {
990 if (log)
991 log->Printf("Couldn't evaluate %s", PrintValue(source).c_str());
992 error.SetErrorToGenericError();
993 error.SetErrorString(bad_value_error);
994 return false;
995 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000996
Sean Callanan415422c2013-06-05 22:07:06 +0000997 S.MakeSigned();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000998
Sean Callanan415422c2013-06-05 22:07:06 +0000999 lldb_private::Scalar S_signextend(S.SLongLong());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001000
Sean Callanan415422c2013-06-05 22:07:06 +00001001 frame.AssignValue(inst, S_signextend, module);
1002 }
1003 break;
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001004 case Instruction::Br:
1005 {
1006 const BranchInst *br_inst = dyn_cast<BranchInst>(inst);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001007
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001008 if (!br_inst)
1009 {
1010 if (log)
1011 log->Printf("getOpcode() returns Br, but instruction is not a BranchInst");
1012 error.SetErrorToGenericError();
1013 error.SetErrorString(interpreter_internal_error);
1014 return false;
1015 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001016
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001017 if (br_inst->isConditional())
1018 {
1019 Value *condition = br_inst->getCondition();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001020
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001021 lldb_private::Scalar C;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001022
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001023 if (!frame.EvaluateValue(C, condition, module))
1024 {
1025 if (log)
1026 log->Printf("Couldn't evaluate %s", PrintValue(condition).c_str());
1027 error.SetErrorToGenericError();
1028 error.SetErrorString(bad_value_error);
1029 return false;
1030 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001031
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001032 if (C.GetRawBits64(0))
1033 frame.Jump(br_inst->getSuccessor(0));
1034 else
1035 frame.Jump(br_inst->getSuccessor(1));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001036
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001037 if (log)
1038 {
1039 log->Printf("Interpreted a BrInst with a condition");
1040 log->Printf(" cond : %s", frame.SummarizeValue(condition).c_str());
1041 }
1042 }
1043 else
1044 {
1045 frame.Jump(br_inst->getSuccessor(0));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001046
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001047 if (log)
1048 {
1049 log->Printf("Interpreted a BrInst with no condition");
1050 }
1051 }
1052 }
1053 continue;
1054 case Instruction::GetElementPtr:
1055 {
1056 const GetElementPtrInst *gep_inst = dyn_cast<GetElementPtrInst>(inst);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001057
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001058 if (!gep_inst)
1059 {
1060 if (log)
1061 log->Printf("getOpcode() returns GetElementPtr, but instruction is not a GetElementPtrInst");
1062 error.SetErrorToGenericError();
1063 error.SetErrorString(interpreter_internal_error);
1064 return false;
1065 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001066
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001067 const Value *pointer_operand = gep_inst->getPointerOperand();
Eduard Burtescud05b8992016-01-22 03:43:23 +00001068 Type *src_elem_ty = gep_inst->getSourceElementType();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001069
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001070 lldb_private::Scalar P;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001071
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001072 if (!frame.EvaluateValue(P, pointer_operand, module))
1073 {
1074 if (log)
1075 log->Printf("Couldn't evaluate %s", PrintValue(pointer_operand).c_str());
1076 error.SetErrorToGenericError();
1077 error.SetErrorString(bad_value_error);
1078 return false;
1079 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001080
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001081 typedef SmallVector <Value *, 8> IndexVector;
1082 typedef IndexVector::iterator IndexIterator;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001083
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001084 SmallVector <Value *, 8> indices (gep_inst->idx_begin(),
1085 gep_inst->idx_end());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001086
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001087 SmallVector <Value *, 8> const_indices;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001088
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001089 for (IndexIterator ii = indices.begin(), ie = indices.end();
1090 ii != ie;
1091 ++ii)
1092 {
1093 ConstantInt *constant_index = dyn_cast<ConstantInt>(*ii);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001094
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001095 if (!constant_index)
1096 {
1097 lldb_private::Scalar I;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001098
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001099 if (!frame.EvaluateValue(I, *ii, module))
1100 {
1101 if (log)
1102 log->Printf("Couldn't evaluate %s", PrintValue(*ii).c_str());
1103 error.SetErrorToGenericError();
1104 error.SetErrorString(bad_value_error);
1105 return false;
1106 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001107
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001108 if (log)
1109 log->Printf("Evaluated constant index %s as %llu", PrintValue(*ii).c_str(), I.ULongLong(LLDB_INVALID_ADDRESS));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001110
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001111 constant_index = cast<ConstantInt>(ConstantInt::get((*ii)->getType(), I.ULongLong(LLDB_INVALID_ADDRESS)));
1112 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001113
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001114 const_indices.push_back(constant_index);
1115 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001116
Eduard Burtescud05b8992016-01-22 03:43:23 +00001117 uint64_t offset = data_layout.getIndexedOffsetInType(src_elem_ty, const_indices);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001118
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001119 lldb_private::Scalar Poffset = P + offset;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001120
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001121 frame.AssignValue(inst, Poffset, module);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001122
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001123 if (log)
1124 {
1125 log->Printf("Interpreted a GetElementPtrInst");
1126 log->Printf(" P : %s", frame.SummarizeValue(pointer_operand).c_str());
1127 log->Printf(" Poffset : %s", frame.SummarizeValue(inst).c_str());
1128 }
1129 }
1130 break;
1131 case Instruction::ICmp:
1132 {
1133 const ICmpInst *icmp_inst = dyn_cast<ICmpInst>(inst);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001134
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001135 if (!icmp_inst)
1136 {
1137 if (log)
1138 log->Printf("getOpcode() returns ICmp, but instruction is not an ICmpInst");
1139 error.SetErrorToGenericError();
1140 error.SetErrorString(interpreter_internal_error);
1141 return false;
1142 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001143
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001144 CmpInst::Predicate predicate = icmp_inst->getPredicate();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001145
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001146 Value *lhs = inst->getOperand(0);
1147 Value *rhs = inst->getOperand(1);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001148
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001149 lldb_private::Scalar L;
1150 lldb_private::Scalar R;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001151
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001152 if (!frame.EvaluateValue(L, lhs, module))
1153 {
1154 if (log)
1155 log->Printf("Couldn't evaluate %s", PrintValue(lhs).c_str());
1156 error.SetErrorToGenericError();
1157 error.SetErrorString(bad_value_error);
1158 return false;
1159 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001160
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001161 if (!frame.EvaluateValue(R, rhs, module))
1162 {
1163 if (log)
1164 log->Printf("Couldn't evaluate %s", PrintValue(rhs).c_str());
1165 error.SetErrorToGenericError();
1166 error.SetErrorString(bad_value_error);
1167 return false;
1168 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001169
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001170 lldb_private::Scalar result;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001171
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001172 switch (predicate)
1173 {
1174 default:
1175 return false;
1176 case CmpInst::ICMP_EQ:
1177 result = (L == R);
1178 break;
1179 case CmpInst::ICMP_NE:
1180 result = (L != R);
1181 break;
1182 case CmpInst::ICMP_UGT:
1183 result = (L.GetRawBits64(0) > R.GetRawBits64(0));
1184 break;
1185 case CmpInst::ICMP_UGE:
1186 result = (L.GetRawBits64(0) >= R.GetRawBits64(0));
1187 break;
1188 case CmpInst::ICMP_ULT:
1189 result = (L.GetRawBits64(0) < R.GetRawBits64(0));
1190 break;
1191 case CmpInst::ICMP_ULE:
1192 result = (L.GetRawBits64(0) <= R.GetRawBits64(0));
1193 break;
1194 case CmpInst::ICMP_SGT:
Sean Callanan0b342b62013-05-24 20:36:56 +00001195 L.MakeSigned();
1196 R.MakeSigned();
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001197 result = (L > R);
1198 break;
1199 case CmpInst::ICMP_SGE:
Sean Callanan0b342b62013-05-24 20:36:56 +00001200 L.MakeSigned();
1201 R.MakeSigned();
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001202 result = (L >= R);
1203 break;
1204 case CmpInst::ICMP_SLT:
Sean Callanan0b342b62013-05-24 20:36:56 +00001205 L.MakeSigned();
1206 R.MakeSigned();
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001207 result = (L < R);
1208 break;
1209 case CmpInst::ICMP_SLE:
Sean Callanan0b342b62013-05-24 20:36:56 +00001210 L.MakeSigned();
1211 R.MakeSigned();
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001212 result = (L <= R);
1213 break;
1214 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001215
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001216 frame.AssignValue(inst, result, module);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001217
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001218 if (log)
1219 {
1220 log->Printf("Interpreted an ICmpInst");
1221 log->Printf(" L : %s", frame.SummarizeValue(lhs).c_str());
1222 log->Printf(" R : %s", frame.SummarizeValue(rhs).c_str());
1223 log->Printf(" = : %s", frame.SummarizeValue(inst).c_str());
1224 }
1225 }
1226 break;
1227 case Instruction::IntToPtr:
1228 {
1229 const IntToPtrInst *int_to_ptr_inst = dyn_cast<IntToPtrInst>(inst);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001230
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001231 if (!int_to_ptr_inst)
1232 {
1233 if (log)
1234 log->Printf("getOpcode() returns IntToPtr, but instruction is not an IntToPtrInst");
1235 error.SetErrorToGenericError();
1236 error.SetErrorString(interpreter_internal_error);
1237 return false;
1238 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001239
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001240 Value *src_operand = int_to_ptr_inst->getOperand(0);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001241
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001242 lldb_private::Scalar I;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001243
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001244 if (!frame.EvaluateValue(I, src_operand, module))
1245 {
1246 if (log)
1247 log->Printf("Couldn't evaluate %s", PrintValue(src_operand).c_str());
1248 error.SetErrorToGenericError();
1249 error.SetErrorString(bad_value_error);
1250 return false;
1251 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001252
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001253 frame.AssignValue(inst, I, module);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001254
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001255 if (log)
1256 {
1257 log->Printf("Interpreted an IntToPtr");
1258 log->Printf(" Src : %s", frame.SummarizeValue(src_operand).c_str());
1259 log->Printf(" = : %s", frame.SummarizeValue(inst).c_str());
1260 }
1261 }
1262 break;
1263 case Instruction::PtrToInt:
1264 {
1265 const PtrToIntInst *ptr_to_int_inst = dyn_cast<PtrToIntInst>(inst);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001266
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001267 if (!ptr_to_int_inst)
1268 {
1269 if (log)
1270 log->Printf("getOpcode() returns PtrToInt, but instruction is not an PtrToIntInst");
1271 error.SetErrorToGenericError();
1272 error.SetErrorString(interpreter_internal_error);
1273 return false;
1274 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001275
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001276 Value *src_operand = ptr_to_int_inst->getOperand(0);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001277
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001278 lldb_private::Scalar I;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001279
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001280 if (!frame.EvaluateValue(I, src_operand, module))
1281 {
1282 if (log)
1283 log->Printf("Couldn't evaluate %s", PrintValue(src_operand).c_str());
1284 error.SetErrorToGenericError();
1285 error.SetErrorString(bad_value_error);
1286 return false;
1287 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001288
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001289 frame.AssignValue(inst, I, module);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001290
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001291 if (log)
1292 {
1293 log->Printf("Interpreted a PtrToInt");
1294 log->Printf(" Src : %s", frame.SummarizeValue(src_operand).c_str());
1295 log->Printf(" = : %s", frame.SummarizeValue(inst).c_str());
1296 }
1297 }
1298 break;
Sean Callanan8c46bac2013-10-11 19:45:00 +00001299 case Instruction::Trunc:
1300 {
1301 const TruncInst *trunc_inst = dyn_cast<TruncInst>(inst);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001302
Sean Callanan8c46bac2013-10-11 19:45:00 +00001303 if (!trunc_inst)
1304 {
1305 if (log)
1306 log->Printf("getOpcode() returns Trunc, but instruction is not a TruncInst");
1307 error.SetErrorToGenericError();
1308 error.SetErrorString(interpreter_internal_error);
1309 return false;
1310 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001311
Sean Callanan8c46bac2013-10-11 19:45:00 +00001312 Value *src_operand = trunc_inst->getOperand(0);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001313
Sean Callanan8c46bac2013-10-11 19:45:00 +00001314 lldb_private::Scalar I;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001315
Sean Callanan8c46bac2013-10-11 19:45:00 +00001316 if (!frame.EvaluateValue(I, src_operand, module))
1317 {
1318 if (log)
1319 log->Printf("Couldn't evaluate %s", PrintValue(src_operand).c_str());
1320 error.SetErrorToGenericError();
1321 error.SetErrorString(bad_value_error);
1322 return false;
1323 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001324
Sean Callanan8c46bac2013-10-11 19:45:00 +00001325 frame.AssignValue(inst, I, module);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001326
Sean Callanan8c46bac2013-10-11 19:45:00 +00001327 if (log)
1328 {
1329 log->Printf("Interpreted a Trunc");
1330 log->Printf(" Src : %s", frame.SummarizeValue(src_operand).c_str());
1331 log->Printf(" = : %s", frame.SummarizeValue(inst).c_str());
1332 }
1333 }
1334 break;
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001335 case Instruction::Load:
1336 {
1337 const LoadInst *load_inst = dyn_cast<LoadInst>(inst);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001338
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001339 if (!load_inst)
1340 {
1341 if (log)
1342 log->Printf("getOpcode() returns Load, but instruction is not a LoadInst");
1343 error.SetErrorToGenericError();
1344 error.SetErrorString(interpreter_internal_error);
1345 return false;
1346 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001347
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001348 // The semantics of Load are:
1349 // Create a region D that will contain the loaded data
1350 // Resolve the region P containing a pointer
1351 // Dereference P to get the region R that the data should be loaded from
1352 // Transfer a unit of type type(D) from R to D
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001353
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001354 const Value *pointer_operand = load_inst->getPointerOperand();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001355
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001356 Type *pointer_ty = pointer_operand->getType();
1357 PointerType *pointer_ptr_ty = dyn_cast<PointerType>(pointer_ty);
1358 if (!pointer_ptr_ty)
1359 {
1360 if (log)
1361 log->Printf("getPointerOperand()->getType() is not a PointerType");
1362 error.SetErrorToGenericError();
1363 error.SetErrorString(interpreter_internal_error);
1364 return false;
1365 }
1366 Type *target_ty = pointer_ptr_ty->getElementType();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001367
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001368 lldb::addr_t D = frame.ResolveValue(load_inst, module);
1369 lldb::addr_t P = frame.ResolveValue(pointer_operand, module);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001370
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001371 if (D == LLDB_INVALID_ADDRESS)
1372 {
1373 if (log)
1374 log->Printf("LoadInst's value doesn't resolve to anything");
1375 error.SetErrorToGenericError();
1376 error.SetErrorString(bad_value_error);
1377 return false;
1378 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001379
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001380 if (P == LLDB_INVALID_ADDRESS)
1381 {
1382 if (log)
1383 log->Printf("LoadInst's pointer doesn't resolve to anything");
1384 error.SetErrorToGenericError();
1385 error.SetErrorString(bad_value_error);
1386 return false;
1387 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001388
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001389 lldb::addr_t R;
1390 lldb_private::Error read_error;
Ted Woodward7071c5fd2016-03-01 21:53:26 +00001391 execution_unit.ReadPointerFromMemory(&R, P, read_error);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001392
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001393 if (!read_error.Success())
1394 {
1395 if (log)
1396 log->Printf("Couldn't read the address to be loaded for a LoadInst");
1397 error.SetErrorToGenericError();
1398 error.SetErrorString(memory_read_error);
1399 return false;
1400 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001401
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001402 size_t target_size = data_layout.getTypeStoreSize(target_ty);
1403 lldb_private::DataBufferHeap buffer(target_size, 0);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001404
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001405 read_error.Clear();
Ted Woodward7071c5fd2016-03-01 21:53:26 +00001406 execution_unit.ReadMemory(buffer.GetBytes(), R, buffer.GetByteSize(), read_error);
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001407 if (!read_error.Success())
1408 {
1409 if (log)
1410 log->Printf("Couldn't read from a region on behalf of a LoadInst");
1411 error.SetErrorToGenericError();
1412 error.SetErrorString(memory_read_error);
1413 return false;
1414 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001415
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001416 lldb_private::Error write_error;
Ted Woodward7071c5fd2016-03-01 21:53:26 +00001417 execution_unit.WriteMemory(D, buffer.GetBytes(), buffer.GetByteSize(), write_error);
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001418 if (!write_error.Success())
1419 {
1420 if (log)
1421 log->Printf("Couldn't write to a region on behalf of a LoadInst");
1422 error.SetErrorToGenericError();
1423 error.SetErrorString(memory_read_error);
1424 return false;
1425 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001426
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001427 if (log)
1428 {
1429 log->Printf("Interpreted a LoadInst");
Matt Kopecef143712013-06-03 18:00:07 +00001430 log->Printf(" P : 0x%" PRIx64, P);
1431 log->Printf(" R : 0x%" PRIx64, R);
1432 log->Printf(" D : 0x%" PRIx64, D);
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001433 }
1434 }
1435 break;
1436 case Instruction::Ret:
1437 {
1438 return true;
1439 }
1440 case Instruction::Store:
1441 {
1442 const StoreInst *store_inst = dyn_cast<StoreInst>(inst);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001443
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001444 if (!store_inst)
1445 {
1446 if (log)
1447 log->Printf("getOpcode() returns Store, but instruction is not a StoreInst");
1448 error.SetErrorToGenericError();
1449 error.SetErrorString(interpreter_internal_error);
1450 return false;
1451 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001452
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001453 // The semantics of Store are:
1454 // Resolve the region D containing the data to be stored
1455 // Resolve the region P containing a pointer
1456 // Dereference P to get the region R that the data should be stored in
1457 // Transfer a unit of type type(D) from D to R
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001458
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001459 const Value *value_operand = store_inst->getValueOperand();
1460 const Value *pointer_operand = store_inst->getPointerOperand();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001461
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001462 Type *pointer_ty = pointer_operand->getType();
1463 PointerType *pointer_ptr_ty = dyn_cast<PointerType>(pointer_ty);
1464 if (!pointer_ptr_ty)
1465 return false;
1466 Type *target_ty = pointer_ptr_ty->getElementType();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001467
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001468 lldb::addr_t D = frame.ResolveValue(value_operand, module);
1469 lldb::addr_t P = frame.ResolveValue(pointer_operand, module);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001470
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001471 if (D == LLDB_INVALID_ADDRESS)
1472 {
1473 if (log)
1474 log->Printf("StoreInst's value doesn't resolve to anything");
1475 error.SetErrorToGenericError();
1476 error.SetErrorString(bad_value_error);
1477 return false;
1478 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001479
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001480 if (P == LLDB_INVALID_ADDRESS)
1481 {
1482 if (log)
1483 log->Printf("StoreInst's pointer doesn't resolve to anything");
1484 error.SetErrorToGenericError();
1485 error.SetErrorString(bad_value_error);
1486 return false;
1487 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001488
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001489 lldb::addr_t R;
1490 lldb_private::Error read_error;
Ted Woodward7071c5fd2016-03-01 21:53:26 +00001491 execution_unit.ReadPointerFromMemory(&R, P, read_error);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001492
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001493 if (!read_error.Success())
1494 {
1495 if (log)
1496 log->Printf("Couldn't read the address to be loaded for a LoadInst");
1497 error.SetErrorToGenericError();
1498 error.SetErrorString(memory_read_error);
1499 return false;
1500 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001501
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001502 size_t target_size = data_layout.getTypeStoreSize(target_ty);
1503 lldb_private::DataBufferHeap buffer(target_size, 0);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001504
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001505 read_error.Clear();
Ted Woodward7071c5fd2016-03-01 21:53:26 +00001506 execution_unit.ReadMemory(buffer.GetBytes(), D, buffer.GetByteSize(), read_error);
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001507 if (!read_error.Success())
1508 {
1509 if (log)
1510 log->Printf("Couldn't read from a region on behalf of a StoreInst");
1511 error.SetErrorToGenericError();
1512 error.SetErrorString(memory_read_error);
1513 return false;
1514 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001515
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001516 lldb_private::Error write_error;
Ted Woodward7071c5fd2016-03-01 21:53:26 +00001517 execution_unit.WriteMemory(R, buffer.GetBytes(), buffer.GetByteSize(), write_error);
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001518 if (!write_error.Success())
1519 {
1520 if (log)
1521 log->Printf("Couldn't write to a region on behalf of a StoreInst");
1522 error.SetErrorToGenericError();
Sean Callanan49630e72013-04-20 02:39:24 +00001523 error.SetErrorString(memory_write_error);
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001524 return false;
1525 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001526
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001527 if (log)
1528 {
1529 log->Printf("Interpreted a StoreInst");
Matt Kopecef143712013-06-03 18:00:07 +00001530 log->Printf(" D : 0x%" PRIx64, D);
1531 log->Printf(" P : 0x%" PRIx64, P);
1532 log->Printf(" R : 0x%" PRIx64, R);
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001533 }
1534 }
1535 break;
Ewan Crawford90ff7912015-07-14 10:56:58 +00001536 case Instruction::Call:
1537 {
1538 const CallInst *call_inst = dyn_cast<CallInst>(inst);
1539
1540 if (!call_inst)
1541 {
1542 if (log)
1543 log->Printf("getOpcode() returns %s, but instruction is not a CallInst", inst->getOpcodeName());
1544 error.SetErrorToGenericError();
1545 error.SetErrorString(interpreter_internal_error);
1546 return false;
1547 }
1548
1549 if (CanIgnoreCall(call_inst))
1550 break;
1551
1552 // Get the return type
1553 llvm::Type *returnType = call_inst->getType();
1554 if (returnType == nullptr)
1555 {
1556 error.SetErrorToGenericError();
1557 error.SetErrorString("unable to access return type");
1558 return false;
1559 }
1560
1561 // Work with void, integer and pointer return types
1562 if (!returnType->isVoidTy() &&
1563 !returnType->isIntegerTy() &&
1564 !returnType->isPointerTy())
1565 {
1566 error.SetErrorToGenericError();
1567 error.SetErrorString("return type is not supported");
1568 return false;
1569 }
1570
1571 // Check we can actually get a thread
1572 if (exe_ctx.GetThreadPtr() == nullptr)
1573 {
1574 error.SetErrorToGenericError();
1575 error.SetErrorStringWithFormat("unable to acquire thread");
1576 return false;
1577 }
1578
1579 // Make sure we have a valid process
1580 if (!exe_ctx.GetProcessPtr())
1581 {
1582 error.SetErrorToGenericError();
1583 error.SetErrorStringWithFormat("unable to get the process");
1584 return false;
1585 }
1586
1587 // Find the address of the callee function
1588 lldb_private::Scalar I;
1589 const llvm::Value *val = call_inst->getCalledValue();
1590
1591 if (!frame.EvaluateValue(I, val, module))
1592 {
1593 error.SetErrorToGenericError();
1594 error.SetErrorString("unable to get address of function");
1595 return false;
1596 }
1597 lldb_private::Address funcAddr(I.ULongLong(LLDB_INVALID_ADDRESS));
1598
1599 lldb_private::StreamString error_stream;
1600 lldb_private::EvaluateExpressionOptions options;
1601
1602 // We generally receive a function pointer which we must dereference
1603 llvm::Type* prototype = val->getType();
1604 if (!prototype->isPointerTy())
1605 {
1606 error.SetErrorToGenericError();
1607 error.SetErrorString("call need function pointer");
1608 return false;
1609 }
1610
1611 // Dereference the function pointer
1612 prototype = prototype->getPointerElementType();
1613 if (!(prototype->isFunctionTy() || prototype->isFunctionVarArg()))
1614 {
1615 error.SetErrorToGenericError();
1616 error.SetErrorString("call need function pointer");
1617 return false;
1618 }
1619
1620 // Find number of arguments
1621 const int numArgs = call_inst->getNumArgOperands();
1622
1623 // We work with a fixed array of 16 arguments which is our upper limit
1624 static lldb_private::ABI::CallArgument rawArgs[16];
1625 if (numArgs >= 16)
1626 {
1627 error.SetErrorToGenericError();
1628 error.SetErrorStringWithFormat("function takes too many arguments");
1629 return false;
1630 }
1631
1632 // Push all function arguments to the argument list that will
1633 // be passed to the call function thread plan
1634 for (int i = 0; i < numArgs; i++)
1635 {
1636 // Get details of this argument
1637 llvm::Value *arg_op = call_inst->getArgOperand(i);
1638 llvm::Type *arg_ty = arg_op->getType();
1639
1640 // Ensure that this argument is an supported type
1641 if (!arg_ty->isIntegerTy() && !arg_ty->isPointerTy())
1642 {
1643 error.SetErrorToGenericError();
1644 error.SetErrorStringWithFormat("argument %d must be integer type", i);
1645 return false;
1646 }
1647
1648 // Extract the arguments value
1649 lldb_private::Scalar tmp_op = 0;
1650 if (!frame.EvaluateValue(tmp_op, arg_op, module))
1651 {
1652 error.SetErrorToGenericError();
1653 error.SetErrorStringWithFormat("unable to evaluate argument %d", i);
1654 return false;
1655 }
1656
1657 // Check if this is a string literal or constant string pointer
1658 if (arg_ty->isPointerTy())
1659 {
1660 // Pointer to just one type
1661 assert(arg_ty->getNumContainedTypes() == 1);
1662
1663 lldb::addr_t addr = tmp_op.ULongLong();
1664 size_t dataSize = 0;
1665
Ted Woodward7071c5fd2016-03-01 21:53:26 +00001666 if (execution_unit.GetAllocSize(addr, dataSize))
Ewan Crawford90ff7912015-07-14 10:56:58 +00001667 {
1668 // Create the required buffer
1669 rawArgs[i].size = dataSize;
1670 rawArgs[i].data_ap.reset(new uint8_t[dataSize + 1]);
1671
1672 // Read string from host memory
Ted Woodward7071c5fd2016-03-01 21:53:26 +00001673 execution_unit.ReadMemory(rawArgs[i].data_ap.get(), addr, dataSize, error);
Ewan Crawford90ff7912015-07-14 10:56:58 +00001674 if (error.Fail())
1675 {
1676 assert(!"we have failed to read the string from memory");
1677 return false;
1678 }
1679 // Add null terminator
1680 rawArgs[i].data_ap[dataSize] = '\0';
1681 rawArgs[i].type = lldb_private::ABI::CallArgument::HostPointer;
1682 }
1683 else
1684 {
1685 assert(!"unable to locate host data for transfer to device");
1686 return false;
1687 }
1688 }
1689 else /* if ( arg_ty->isPointerTy() ) */
1690 {
1691 rawArgs[i].type = lldb_private::ABI::CallArgument::TargetValue;
1692 // Get argument size in bytes
1693 rawArgs[i].size = arg_ty->getIntegerBitWidth() / 8;
1694 // Push value into argument list for thread plan
1695 rawArgs[i].value = tmp_op.ULongLong();
1696 }
1697
1698 }
1699
1700 // Pack the arguments into an llvm::array
1701 llvm::ArrayRef<lldb_private::ABI::CallArgument> args(rawArgs, numArgs);
1702
1703 // Setup a thread plan to call the target function
1704 lldb::ThreadPlanSP call_plan_sp
1705 (
1706 new lldb_private::ThreadPlanCallFunctionUsingABI
1707 (
1708 exe_ctx.GetThreadRef(),
1709 funcAddr,
1710 *prototype,
1711 *returnType,
1712 args,
1713 options
1714 )
1715 );
1716
1717 // Check if the plan is valid
1718 if (!call_plan_sp || !call_plan_sp->ValidatePlan(&error_stream))
1719 {
1720 error.SetErrorToGenericError();
1721 error.SetErrorStringWithFormat("unable to make ThreadPlanCallFunctionUsingABI for 0x%llx", I.ULongLong());
1722 return false;
1723 }
1724
1725 exe_ctx.GetProcessPtr()->SetRunningUserExpression(true);
1726
1727 // Execute the actual function call thread plan
1728 lldb::ExpressionResults res = exe_ctx.GetProcessRef().RunThreadPlan(exe_ctx, call_plan_sp, options, error_stream);
1729
1730 // Check that the thread plan completed successfully
1731 if (res != lldb::ExpressionResults::eExpressionCompleted)
1732 {
1733 error.SetErrorToGenericError();
1734 error.SetErrorStringWithFormat("ThreadPlanCallFunctionUsingABI failed");
1735 return false;
1736 }
1737
1738 exe_ctx.GetProcessPtr()->SetRunningUserExpression(false);
1739
1740 // Void return type
1741 if (returnType->isVoidTy())
1742 {
1743 // Cant assign to void types, so we leave the frame untouched
1744 }
1745 else
1746 // Integer or pointer return type
1747 if (returnType->isIntegerTy() || returnType->isPointerTy())
1748 {
1749 // Get the encapsulated return value
1750 lldb::ValueObjectSP retVal = call_plan_sp.get()->GetReturnValueObject();
1751
1752 lldb_private::Scalar returnVal = -1;
1753 lldb_private::ValueObject *vobj = retVal.get();
1754
1755 // Check if the return value is valid
1756 if (vobj == nullptr || retVal.empty())
1757 {
1758 error.SetErrorToGenericError();
1759 error.SetErrorStringWithFormat("unable to get the return value");
1760 return false;
1761 }
1762
1763 // Extract the return value as a integer
1764 lldb_private::Value & value = vobj->GetValue();
1765 returnVal = value.GetScalar();
1766
1767 // Push the return value as the result
1768 frame.AssignValue(inst, returnVal, module);
1769 }
1770 }
1771 break;
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001772 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001773
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001774 ++frame.m_ii;
1775 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001776
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001777 if (num_insts >= 4096)
1778 {
1779 error.SetErrorToGenericError();
1780 error.SetErrorString(infinite_loop_error);
1781 return false;
1782 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001783
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001784 return false;
1785}