blob: 71ef8d6457bc62bad1ad0697066a6e662e2b5038 [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
Sean Callananfefe43c2013-04-25 18:55:45 +000010#include "lldb/Core/DataExtractor.h"
11#include "lldb/Core/Error.h"
Sean Callanan3bfdaa22011-09-15 02:13:07 +000012#include "lldb/Core/Log.h"
Sean Callananfefe43c2013-04-25 18:55:45 +000013#include "lldb/Core/Scalar.h"
14#include "lldb/Core/StreamString.h"
15#include "lldb/Expression/IRMemoryMap.h"
Sean Callanan3bfdaa22011-09-15 02:13:07 +000016#include "lldb/Expression/IRInterpreter.h"
Sean Callanan46fc0062013-09-17 18:26:42 +000017#include "lldb/Host/Endian.h"
Sean Callanan3bfdaa22011-09-15 02:13:07 +000018
Chandler Carruth1e157582013-01-02 12:20:07 +000019#include "llvm/IR/Constants.h"
Sean Callananfefe43c2013-04-25 18:55:45 +000020#include "llvm/IR/DataLayout.h"
Chandler Carruth1e157582013-01-02 12:20:07 +000021#include "llvm/IR/Function.h"
22#include "llvm/IR/Instructions.h"
23#include "llvm/IR/Module.h"
Sean Callanan3bfdaa22011-09-15 02:13:07 +000024#include "llvm/Support/raw_ostream.h"
Sean Callanan3bfdaa22011-09-15 02:13:07 +000025
26#include <map>
27
28using namespace llvm;
29
Sean Callanan3bfdaa22011-09-15 02:13:07 +000030static std::string
31PrintValue(const Value *value, bool truncate = false)
32{
33 std::string s;
34 raw_string_ostream rso(s);
35 value->print(rso);
36 rso.flush();
37 if (truncate)
38 s.resize(s.length() - 1);
39
40 size_t offset;
41 while ((offset = s.find('\n')) != s.npos)
42 s.erase(offset, 1);
43 while (s[0] == ' ' || s[0] == '\t')
44 s.erase(0, 1);
45
46 return s;
47}
48
49static std::string
50PrintType(const Type *type, bool truncate = false)
51{
52 std::string s;
53 raw_string_ostream rso(s);
54 type->print(rso);
55 rso.flush();
56 if (truncate)
57 s.resize(s.length() - 1);
58 return s;
59}
60
Sean Callanan3bfdaa22011-09-15 02:13:07 +000061class InterpreterStackFrame
62{
63public:
Sean Callanan08052af2013-04-17 07:50:58 +000064 typedef std::map <const Value*, lldb::addr_t> ValueMap;
65
Sean Callanan3bfdaa22011-09-15 02:13:07 +000066 ValueMap m_values;
Micah Villmow8468dbe2012-10-08 16:28:57 +000067 DataLayout &m_target_data;
Sean Callanan179b5482013-04-16 23:49:09 +000068 lldb_private::IRMemoryMap &m_memory_map;
Sean Callanan3bfdaa22011-09-15 02:13:07 +000069 const BasicBlock *m_bb;
70 BasicBlock::const_iterator m_ii;
71 BasicBlock::const_iterator m_ie;
72
Sean Callanan1582ee62013-04-18 22:06:33 +000073 lldb::addr_t m_frame_process_address;
74 size_t m_frame_size;
75 lldb::addr_t m_stack_pointer;
76
Sean Callanan3bfdaa22011-09-15 02:13:07 +000077 lldb::ByteOrder m_byte_order;
78 size_t m_addr_byte_size;
79
Micah Villmow8468dbe2012-10-08 16:28:57 +000080 InterpreterStackFrame (DataLayout &target_data,
Sean Callanandf565402013-04-27 02:19:33 +000081 lldb_private::IRMemoryMap &memory_map,
82 lldb::addr_t stack_frame_bottom,
83 lldb::addr_t stack_frame_top) :
Daniel Dunbara08823f2011-10-31 22:50:49 +000084 m_target_data (target_data),
Sean Callanan179b5482013-04-16 23:49:09 +000085 m_memory_map (memory_map)
Sean Callanan3bfdaa22011-09-15 02:13:07 +000086 {
87 m_byte_order = (target_data.isLittleEndian() ? lldb::eByteOrderLittle : lldb::eByteOrderBig);
Sean Callanan95769bf2012-10-11 22:00:52 +000088 m_addr_byte_size = (target_data.getPointerSize(0));
Sean Callanandf565402013-04-27 02:19:33 +000089
90 m_frame_process_address = stack_frame_bottom;
91 m_frame_size = stack_frame_top - stack_frame_bottom;
92 m_stack_pointer = stack_frame_top;
Sean Callanan1582ee62013-04-18 22:06:33 +000093 }
94
95 ~InterpreterStackFrame ()
96 {
Sean Callanan3bfdaa22011-09-15 02:13:07 +000097 }
98
99 void Jump (const BasicBlock *bb)
100 {
101 m_bb = bb;
102 m_ii = m_bb->begin();
103 m_ie = m_bb->end();
104 }
105
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000106 std::string SummarizeValue (const Value *value)
107 {
108 lldb_private::StreamString ss;
109
110 ss.Printf("%s", PrintValue(value).c_str());
111
112 ValueMap::iterator i = m_values.find(value);
113
114 if (i != m_values.end())
115 {
Sean Callanan08052af2013-04-17 07:50:58 +0000116 lldb::addr_t addr = i->second;
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000117
Sean Callanan08052af2013-04-17 07:50:58 +0000118 ss.Printf(" 0x%llx", (unsigned long long)addr);
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000119 }
120
121 return ss.GetString();
122 }
123
124 bool AssignToMatchType (lldb_private::Scalar &scalar, uint64_t u64value, Type *type)
125 {
126 size_t type_size = m_target_data.getTypeStoreSize(type);
127
128 switch (type_size)
129 {
130 case 1:
131 scalar = (uint8_t)u64value;
132 break;
133 case 2:
134 scalar = (uint16_t)u64value;
135 break;
136 case 4:
137 scalar = (uint32_t)u64value;
138 break;
139 case 8:
140 scalar = (uint64_t)u64value;
141 break;
142 default:
143 return false;
144 }
145
146 return true;
147 }
148
149 bool EvaluateValue (lldb_private::Scalar &scalar, const Value *value, Module &module)
150 {
151 const Constant *constant = dyn_cast<Constant>(value);
152
153 if (constant)
154 {
Sean Callanan415422c2013-06-05 22:07:06 +0000155 APInt value_apint;
156
157 if (!ResolveConstantValue(value_apint, constant))
158 return false;
159
160 return AssignToMatchType(scalar, value_apint.getLimitedValue(), value->getType());
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000161 }
162 else
163 {
Sean Callanan08052af2013-04-17 07:50:58 +0000164 lldb::addr_t process_address = ResolveValue(value, module);
165 size_t value_size = m_target_data.getTypeStoreSize(value->getType());
166
167 lldb_private::DataExtractor value_extractor;
168 lldb_private::Error extract_error;
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000169
Sean Callanan08052af2013-04-17 07:50:58 +0000170 m_memory_map.GetMemoryData(value_extractor, process_address, value_size, extract_error);
171
172 if (!extract_error.Success())
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000173 return false;
174
Greg Claytonc7bece562013-01-25 18:06:21 +0000175 lldb::offset_t offset = 0;
Sean Callanan544053e2013-06-06 21:14:35 +0000176 if (value_size == 1 || value_size == 2 || value_size == 4 || value_size == 8)
Greg Clayton78e44bd2013-04-25 00:57:05 +0000177 {
178 uint64_t u64value = value_extractor.GetMaxU64(&offset, value_size);
179 return AssignToMatchType(scalar, u64value, value->getType());
180 }
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000181 }
182
183 return false;
184 }
185
186 bool AssignValue (const Value *value, lldb_private::Scalar &scalar, Module &module)
187 {
Sean Callanan08052af2013-04-17 07:50:58 +0000188 lldb::addr_t process_address = ResolveValue (value, module);
189
190 if (process_address == LLDB_INVALID_ADDRESS)
191 return false;
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000192
193 lldb_private::Scalar cast_scalar;
194
195 if (!AssignToMatchType(cast_scalar, scalar.GetRawBits64(0), value->getType()))
196 return false;
Sean Callanan08052af2013-04-17 07:50:58 +0000197
198 size_t value_byte_size = m_target_data.getTypeStoreSize(value->getType());
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000199
Sean Callanan08052af2013-04-17 07:50:58 +0000200 lldb_private::DataBufferHeap buf(value_byte_size, 0);
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000201
Sean Callanan08052af2013-04-17 07:50:58 +0000202 lldb_private::Error get_data_error;
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000203
Sean Callanan08052af2013-04-17 07:50:58 +0000204 if (!cast_scalar.GetAsMemoryData(buf.GetBytes(), buf.GetByteSize(), m_byte_order, get_data_error))
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000205 return false;
206
Sean Callanan08052af2013-04-17 07:50:58 +0000207 lldb_private::Error write_error;
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000208
Sean Callanan08052af2013-04-17 07:50:58 +0000209 m_memory_map.WriteMemory(process_address, buf.GetBytes(), buf.GetByteSize(), write_error);
Sean Callananc8675502013-02-15 23:07:52 +0000210
Sean Callanan08052af2013-04-17 07:50:58 +0000211 return write_error.Success();
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000212 }
213
Sean Callanan94a9a392012-02-08 01:27:49 +0000214 bool ResolveConstantValue (APInt &value, const Constant *constant)
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000215 {
Sean Callanan1582ee62013-04-18 22:06:33 +0000216 switch (constant->getValueID())
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000217 {
Sean Callanan1582ee62013-04-18 22:06:33 +0000218 default:
219 break;
220 case Value::ConstantIntVal:
221 if (const ConstantInt *constant_int = dyn_cast<ConstantInt>(constant))
Sean Callanan80c48c12011-10-21 05:18:02 +0000222 {
Sean Callanan1582ee62013-04-18 22:06:33 +0000223 value = constant_int->getValue();
224 return true;
225 }
226 break;
227 case Value::ConstantFPVal:
228 if (const ConstantFP *constant_fp = dyn_cast<ConstantFP>(constant))
229 {
230 value = constant_fp->getValueAPF().bitcastToAPInt();
231 return true;
232 }
233 break;
234 case Value::ConstantExprVal:
235 if (const ConstantExpr *constant_expr = dyn_cast<ConstantExpr>(constant))
236 {
237 switch (constant_expr->getOpcode())
Sean Callanan94a9a392012-02-08 01:27:49 +0000238 {
Sean Callanan1582ee62013-04-18 22:06:33 +0000239 default:
Sean Callanan94a9a392012-02-08 01:27:49 +0000240 return false;
Sean Callanan1582ee62013-04-18 22:06:33 +0000241 case Instruction::IntToPtr:
242 case Instruction::PtrToInt:
243 case Instruction::BitCast:
244 return ResolveConstantValue(value, constant_expr->getOperand(0));
245 case Instruction::GetElementPtr:
246 {
247 ConstantExpr::const_op_iterator op_cursor = constant_expr->op_begin();
248 ConstantExpr::const_op_iterator op_end = constant_expr->op_end();
249
250 Constant *base = dyn_cast<Constant>(*op_cursor);
251
252 if (!base)
253 return false;
254
255 if (!ResolveConstantValue(value, base))
256 return false;
257
258 op_cursor++;
259
260 if (op_cursor == op_end)
261 return true; // no offset to apply!
262
263 SmallVector <Value *, 8> indices (op_cursor, op_end);
264
265 uint64_t offset = m_target_data.getIndexedOffset(base->getType(), indices);
266
267 const bool is_signed = true;
268 value += APInt(value.getBitWidth(), offset, is_signed);
269
270 return true;
271 }
Sean Callanan94a9a392012-02-08 01:27:49 +0000272 }
Sean Callanan80c48c12011-10-21 05:18:02 +0000273 }
Sean Callanan1582ee62013-04-18 22:06:33 +0000274 break;
275 case Value::ConstantPointerNullVal:
276 if (isa<ConstantPointerNull>(constant))
277 {
278 value = APInt(m_target_data.getPointerSizeInBits(), 0);
279 return true;
280 }
281 break;
282 }
283 return false;
284 }
285
286 bool MakeArgument(const Argument *value, uint64_t address)
287 {
288 lldb::addr_t data_address = Malloc(value->getType());
289
290 if (data_address == LLDB_INVALID_ADDRESS)
291 return false;
292
293 lldb_private::Error write_error;
294
295 m_memory_map.WritePointerToMemory(data_address, address, write_error);
296
297 if (!write_error.Success())
298 {
299 lldb_private::Error free_error;
300 m_memory_map.Free(data_address, free_error);
301 return false;
Sean Callanan80c48c12011-10-21 05:18:02 +0000302 }
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000303
Sean Callanan1582ee62013-04-18 22:06:33 +0000304 m_values[value] = data_address;
305
306 lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
307
308 if (log)
309 {
310 log->Printf("Made an allocation for argument %s", PrintValue(value).c_str());
311 log->Printf(" Data region : %llx", (unsigned long long)address);
312 log->Printf(" Ref region : %llx", (unsigned long long)data_address);
313 }
314
315 return true;
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000316 }
317
Sean Callanan08052af2013-04-17 07:50:58 +0000318 bool ResolveConstant (lldb::addr_t process_address, const Constant *constant)
Sean Callanan94a9a392012-02-08 01:27:49 +0000319 {
320 APInt resolved_value;
321
322 if (!ResolveConstantValue(resolved_value, constant))
323 return false;
324
Sean Callanan46fc0062013-09-17 18:26:42 +0000325 lldb_private::StreamString buffer (lldb_private::Stream::eBinary,
326 m_memory_map.GetAddressByteSize(),
327 m_memory_map.GetByteOrder());
328
Sean Callanan94a9a392012-02-08 01:27:49 +0000329 size_t constant_size = m_target_data.getTypeStoreSize(constant->getType());
Sean Callanan94a9a392012-02-08 01:27:49 +0000330
Sean Callanan46fc0062013-09-17 18:26:42 +0000331 const uint64_t *raw_data = resolved_value.getRawData();
332
333 buffer.PutRawBytes(raw_data, constant_size, lldb::endian::InlHostByteOrder());
334
Sean Callanan08052af2013-04-17 07:50:58 +0000335 lldb_private::Error write_error;
336
Sean Callanan46fc0062013-09-17 18:26:42 +0000337 m_memory_map.WriteMemory(process_address, (const uint8_t*)buffer.GetData(), constant_size, write_error);
Sean Callanan08052af2013-04-17 07:50:58 +0000338
339 return write_error.Success();
340 }
341
Sean Callanan1582ee62013-04-18 22:06:33 +0000342 lldb::addr_t Malloc (size_t size, uint8_t byte_alignment)
343 {
344 lldb::addr_t ret = m_stack_pointer;
345
346 ret -= size;
347 ret -= (ret % byte_alignment);
348
349 if (ret < m_frame_process_address)
350 return LLDB_INVALID_ADDRESS;
351
352 m_stack_pointer = ret;
353 return ret;
354 }
355
Sean Callanan08052af2013-04-17 07:50:58 +0000356 lldb::addr_t MallocPointer ()
357 {
Sean Callanan1582ee62013-04-18 22:06:33 +0000358 return Malloc(m_target_data.getPointerSize(), m_target_data.getPointerPrefAlignment());
Sean Callanan08052af2013-04-17 07:50:58 +0000359 }
360
Sean Callanan1582ee62013-04-18 22:06:33 +0000361 lldb::addr_t Malloc (llvm::Type *type)
Sean Callanan08052af2013-04-17 07:50:58 +0000362 {
363 lldb_private::Error alloc_error;
364
Sean Callanan1582ee62013-04-18 22:06:33 +0000365 return Malloc(m_target_data.getTypeAllocSize(type), m_target_data.getPrefTypeAlignment(type));
Sean Callanan08052af2013-04-17 07:50:58 +0000366 }
367
Sean Callanan08052af2013-04-17 07:50:58 +0000368 std::string PrintData (lldb::addr_t addr, llvm::Type *type)
369 {
370 size_t length = m_target_data.getTypeStoreSize(type);
371
372 lldb_private::DataBufferHeap buf(length, 0);
373
374 lldb_private::Error read_error;
375
376 m_memory_map.ReadMemory(buf.GetBytes(), addr, length, read_error);
377
378 if (!read_error.Success())
379 return std::string("<couldn't read data>");
380
381 lldb_private::StreamString ss;
382
383 for (size_t i = 0; i < length; i++)
384 {
385 if ((!(i & 0xf)) && i)
386 ss.Printf("%02hhx - ", buf.GetBytes()[i]);
387 else
388 ss.Printf("%02hhx ", buf.GetBytes()[i]);
389 }
390
391 return ss.GetString();
392 }
393
394 lldb::addr_t ResolveValue (const Value *value, Module &module)
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000395 {
396 ValueMap::iterator i = m_values.find(value);
397
398 if (i != m_values.end())
399 return i->second;
400
Sean Callanan1582ee62013-04-18 22:06:33 +0000401 // Fall back and allocate space [allocation type Alloca]
402
403 lldb::addr_t data_address = Malloc(value->getType());
404
405 if (const Constant *constant = dyn_cast<Constant>(value))
406 {
407 if (!ResolveConstant (data_address, constant))
408 {
409 lldb_private::Error free_error;
410 m_memory_map.Free(data_address, free_error);
411 return LLDB_INVALID_ADDRESS;
412 }
413 }
414
415 m_values[value] = data_address;
416 return data_address;
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000417 }
418};
419
Sean Callanan175a0d02012-01-24 22:06:48 +0000420static const char *unsupported_opcode_error = "Interpreter doesn't handle one of the expression's opcodes";
Sean Callanan3fa3e652013-05-02 00:33:44 +0000421static const char *unsupported_operand_error = "Interpreter doesn't handle one of the expression's operands";
Greg Claytone01e07b2013-04-18 18:10:51 +0000422//static const char *interpreter_initialization_error = "Interpreter couldn't be initialized";
Sean Callanan175a0d02012-01-24 22:06:48 +0000423static const char *interpreter_internal_error = "Interpreter encountered an internal error";
424static const char *bad_value_error = "Interpreter couldn't resolve a value during execution";
425static const char *memory_allocation_error = "Interpreter couldn't allocate memory";
426static const char *memory_write_error = "Interpreter couldn't write to memory";
427static const char *memory_read_error = "Interpreter couldn't read from memory";
428static const char *infinite_loop_error = "Interpreter ran for too many cycles";
Sean Callanan44342732013-04-19 08:14:32 +0000429//static const char *bad_result_error = "Result of expression is in bad memory";
Sean Callanan175a0d02012-01-24 22:06:48 +0000430
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000431bool
Sean Callanan44342732013-04-19 08:14:32 +0000432IRInterpreter::CanInterpret (llvm::Module &module,
433 llvm::Function &function,
434 lldb_private::Error &error)
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000435{
Greg Clayton5160ce52013-03-27 23:08:40 +0000436 lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000437
Sean Callanan85fc8762013-06-27 01:59:51 +0000438 bool saw_function_with_body = false;
439
440 for (Module::iterator fi = module.begin(), fe = module.end();
441 fi != fe;
442 ++fi)
443 {
444 if (fi->begin() != fi->end())
445 {
446 if (saw_function_with_body)
447 return false;
448 saw_function_with_body = true;
449 }
450 }
451
Sean Callanan44342732013-04-19 08:14:32 +0000452 for (Function::iterator bbi = function.begin(), bbe = function.end();
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000453 bbi != bbe;
454 ++bbi)
455 {
456 for (BasicBlock::iterator ii = bbi->begin(), ie = bbi->end();
457 ii != ie;
458 ++ii)
459 {
460 switch (ii->getOpcode())
461 {
462 default:
463 {
464 if (log)
465 log->Printf("Unsupported instruction: %s", PrintValue(ii).c_str());
Sean Callanan44342732013-04-19 08:14:32 +0000466 error.SetErrorToGenericError();
467 error.SetErrorString(unsupported_opcode_error);
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000468 return false;
469 }
470 case Instruction::Add:
471 case Instruction::Alloca:
472 case Instruction::BitCast:
473 case Instruction::Br:
474 case Instruction::GetElementPtr:
475 break;
476 case Instruction::ICmp:
477 {
478 ICmpInst *icmp_inst = dyn_cast<ICmpInst>(ii);
479
480 if (!icmp_inst)
Sean Callanan175a0d02012-01-24 22:06:48 +0000481 {
Sean Callanan44342732013-04-19 08:14:32 +0000482 error.SetErrorToGenericError();
483 error.SetErrorString(interpreter_internal_error);
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000484 return false;
Sean Callanan175a0d02012-01-24 22:06:48 +0000485 }
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000486
487 switch (icmp_inst->getPredicate())
488 {
489 default:
Sean Callanan44342732013-04-19 08:14:32 +0000490 {
491 if (log)
492 log->Printf("Unsupported ICmp predicate: %s", PrintValue(ii).c_str());
493
494 error.SetErrorToGenericError();
495 error.SetErrorString(unsupported_opcode_error);
496 return false;
497 }
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000498 case CmpInst::ICMP_EQ:
499 case CmpInst::ICMP_NE:
500 case CmpInst::ICMP_UGT:
501 case CmpInst::ICMP_UGE:
502 case CmpInst::ICMP_ULT:
503 case CmpInst::ICMP_ULE:
504 case CmpInst::ICMP_SGT:
505 case CmpInst::ICMP_SGE:
506 case CmpInst::ICMP_SLT:
507 case CmpInst::ICMP_SLE:
508 break;
509 }
510 }
511 break;
Sean Callanan087f4372013-01-09 22:44:41 +0000512 case Instruction::And:
513 case Instruction::AShr:
Sean Callanan80c48c12011-10-21 05:18:02 +0000514 case Instruction::IntToPtr:
Sean Callanan2abffe02012-12-01 00:09:34 +0000515 case Instruction::PtrToInt:
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000516 case Instruction::Load:
Sean Callanan087f4372013-01-09 22:44:41 +0000517 case Instruction::LShr:
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000518 case Instruction::Mul:
Sean Callanan087f4372013-01-09 22:44:41 +0000519 case Instruction::Or:
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000520 case Instruction::Ret:
521 case Instruction::SDiv:
Sean Callanan415422c2013-06-05 22:07:06 +0000522 case Instruction::SExt:
Sean Callanan087f4372013-01-09 22:44:41 +0000523 case Instruction::Shl:
Sean Callananf466a6e2012-12-21 22:27:55 +0000524 case Instruction::SRem:
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000525 case Instruction::Store:
526 case Instruction::Sub:
Sean Callanan8c46bac2013-10-11 19:45:00 +0000527 case Instruction::Trunc:
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000528 case Instruction::UDiv:
Sean Callananf466a6e2012-12-21 22:27:55 +0000529 case Instruction::URem:
Sean Callanan087f4372013-01-09 22:44:41 +0000530 case Instruction::Xor:
Sean Callanan1ef77432012-04-23 17:25:38 +0000531 case Instruction::ZExt:
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000532 break;
533 }
Sean Callanan3fa3e652013-05-02 00:33:44 +0000534
535 for (int oi = 0, oe = ii->getNumOperands();
536 oi != oe;
537 ++oi)
538 {
539 Value *operand = ii->getOperand(oi);
540 Type *operand_type = operand->getType();
541
542 switch (operand_type->getTypeID())
543 {
544 default:
545 break;
546 case Type::VectorTyID:
547 {
548 if (log)
549 log->Printf("Unsupported operand type: %s", PrintType(operand_type).c_str());
550 error.SetErrorString(unsupported_operand_error);
551 return false;
552 }
553 }
554 }
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000555 }
Sean Callanan3fa3e652013-05-02 00:33:44 +0000556
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000557 }
558
Sean Callanan44342732013-04-19 08:14:32 +0000559 return true;}
Sean Callanan14cb2aa2013-04-17 18:35:47 +0000560
561bool
562IRInterpreter::Interpret (llvm::Module &module,
563 llvm::Function &function,
Sean Callanan1582ee62013-04-18 22:06:33 +0000564 llvm::ArrayRef<lldb::addr_t> args,
Sean Callanan14cb2aa2013-04-17 18:35:47 +0000565 lldb_private::IRMemoryMap &memory_map,
Sean Callanandf565402013-04-27 02:19:33 +0000566 lldb_private::Error &error,
567 lldb::addr_t stack_frame_bottom,
568 lldb::addr_t stack_frame_top)
Sean Callanan14cb2aa2013-04-17 18:35:47 +0000569{
570 lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
571
Sean Callanan1582ee62013-04-18 22:06:33 +0000572 if (log)
573 {
574 std::string s;
575 raw_string_ostream oss(s);
576
577 module.print(oss, NULL);
578
579 oss.flush();
580
581 log->Printf("Module as passed in to IRInterpreter::Interpret: \n\"%s\"", s.c_str());
582 }
583
Sean Callanan14cb2aa2013-04-17 18:35:47 +0000584 DataLayout data_layout(&module);
585
Sean Callanandf565402013-04-27 02:19:33 +0000586 InterpreterStackFrame frame(data_layout, memory_map, stack_frame_bottom, stack_frame_top);
Sean Callanan14cb2aa2013-04-17 18:35:47 +0000587
Sean Callanan1582ee62013-04-18 22:06:33 +0000588 if (frame.m_frame_process_address == LLDB_INVALID_ADDRESS)
589 {
590 error.SetErrorString("Couldn't allocate stack frame");
591 }
592
593 int arg_index = 0;
594
595 for (llvm::Function::arg_iterator ai = function.arg_begin(), ae = function.arg_end();
596 ai != ae;
597 ++ai, ++arg_index)
598 {
599 if (args.size() < arg_index)
600 {
601 error.SetErrorString ("Not enough arguments passed in to function");
602 return false;
603 }
604
605 lldb::addr_t ptr = args[arg_index];
606
607 frame.MakeArgument(ai, ptr);
608 }
609
Sean Callanan14cb2aa2013-04-17 18:35:47 +0000610 uint32_t num_insts = 0;
611
612 frame.Jump(function.begin());
613
614 while (frame.m_ii != frame.m_ie && (++num_insts < 4096))
615 {
616 const Instruction *inst = frame.m_ii;
617
618 if (log)
619 log->Printf("Interpreting %s", PrintValue(inst).c_str());
620
621 switch (inst->getOpcode())
622 {
623 default:
624 break;
625 case Instruction::Add:
626 case Instruction::Sub:
627 case Instruction::Mul:
628 case Instruction::SDiv:
629 case Instruction::UDiv:
630 case Instruction::SRem:
631 case Instruction::URem:
632 case Instruction::Shl:
633 case Instruction::LShr:
634 case Instruction::AShr:
635 case Instruction::And:
636 case Instruction::Or:
637 case Instruction::Xor:
638 {
639 const BinaryOperator *bin_op = dyn_cast<BinaryOperator>(inst);
640
641 if (!bin_op)
642 {
643 if (log)
644 log->Printf("getOpcode() returns %s, but instruction is not a BinaryOperator", inst->getOpcodeName());
645 error.SetErrorToGenericError();
646 error.SetErrorString(interpreter_internal_error);
647 return false;
648 }
649
650 Value *lhs = inst->getOperand(0);
651 Value *rhs = inst->getOperand(1);
652
653 lldb_private::Scalar L;
654 lldb_private::Scalar R;
655
656 if (!frame.EvaluateValue(L, lhs, module))
657 {
658 if (log)
659 log->Printf("Couldn't evaluate %s", PrintValue(lhs).c_str());
660 error.SetErrorToGenericError();
661 error.SetErrorString(bad_value_error);
662 return false;
663 }
664
665 if (!frame.EvaluateValue(R, rhs, module))
666 {
667 if (log)
668 log->Printf("Couldn't evaluate %s", PrintValue(rhs).c_str());
669 error.SetErrorToGenericError();
670 error.SetErrorString(bad_value_error);
671 return false;
672 }
673
674 lldb_private::Scalar result;
675
676 switch (inst->getOpcode())
677 {
678 default:
679 break;
680 case Instruction::Add:
681 result = L + R;
682 break;
683 case Instruction::Mul:
684 result = L * R;
685 break;
686 case Instruction::Sub:
687 result = L - R;
688 break;
689 case Instruction::SDiv:
Sean Callanan0b342b62013-05-24 20:36:56 +0000690 L.MakeSigned();
691 R.MakeSigned();
Sean Callanan14cb2aa2013-04-17 18:35:47 +0000692 result = L / R;
693 break;
694 case Instruction::UDiv:
695 result = L.GetRawBits64(0) / R.GetRawBits64(1);
696 break;
697 case Instruction::SRem:
Sean Callanan0b342b62013-05-24 20:36:56 +0000698 L.MakeSigned();
699 R.MakeSigned();
Sean Callanan14cb2aa2013-04-17 18:35:47 +0000700 result = L % R;
701 break;
702 case Instruction::URem:
703 result = L.GetRawBits64(0) % R.GetRawBits64(1);
704 break;
705 case Instruction::Shl:
706 result = L << R;
707 break;
708 case Instruction::AShr:
709 result = L >> R;
710 break;
711 case Instruction::LShr:
712 result = L;
713 result.ShiftRightLogical(R);
714 break;
715 case Instruction::And:
716 result = L & R;
717 break;
718 case Instruction::Or:
719 result = L | R;
720 break;
721 case Instruction::Xor:
722 result = L ^ R;
723 break;
724 }
725
726 frame.AssignValue(inst, result, module);
727
728 if (log)
729 {
730 log->Printf("Interpreted a %s", inst->getOpcodeName());
731 log->Printf(" L : %s", frame.SummarizeValue(lhs).c_str());
732 log->Printf(" R : %s", frame.SummarizeValue(rhs).c_str());
733 log->Printf(" = : %s", frame.SummarizeValue(inst).c_str());
734 }
735 }
736 break;
737 case Instruction::Alloca:
738 {
739 const AllocaInst *alloca_inst = dyn_cast<AllocaInst>(inst);
740
741 if (!alloca_inst)
742 {
743 if (log)
744 log->Printf("getOpcode() returns Alloca, but instruction is not an AllocaInst");
745 error.SetErrorToGenericError();
746 error.SetErrorString(interpreter_internal_error);
747 return false;
748 }
749
750 if (alloca_inst->isArrayAllocation())
751 {
752 if (log)
753 log->Printf("AllocaInsts are not handled if isArrayAllocation() is true");
754 error.SetErrorToGenericError();
755 error.SetErrorString(unsupported_opcode_error);
756 return false;
757 }
758
759 // The semantics of Alloca are:
760 // Create a region R of virtual memory of type T, backed by a data buffer
761 // Create a region P of virtual memory of type T*, backed by a data buffer
762 // Write the virtual address of R into P
763
764 Type *T = alloca_inst->getAllocatedType();
765 Type *Tptr = alloca_inst->getType();
766
767 lldb::addr_t R = frame.Malloc(T);
768
769 if (R == LLDB_INVALID_ADDRESS)
770 {
771 if (log)
772 log->Printf("Couldn't allocate memory for an AllocaInst");
773 error.SetErrorToGenericError();
774 error.SetErrorString(memory_allocation_error);
775 return false;
776 }
777
778 lldb::addr_t P = frame.Malloc(Tptr);
779
780 if (P == LLDB_INVALID_ADDRESS)
781 {
782 if (log)
783 log->Printf("Couldn't allocate the result pointer for an AllocaInst");
784 error.SetErrorToGenericError();
785 error.SetErrorString(memory_allocation_error);
786 return false;
787 }
788
789 lldb_private::Error write_error;
790
791 memory_map.WritePointerToMemory(P, R, write_error);
792
793 if (!write_error.Success())
794 {
795 if (log)
796 log->Printf("Couldn't write the result pointer for an AllocaInst");
797 error.SetErrorToGenericError();
798 error.SetErrorString(memory_write_error);
799 lldb_private::Error free_error;
800 memory_map.Free(P, free_error);
801 memory_map.Free(R, free_error);
802 return false;
803 }
804
805 frame.m_values[alloca_inst] = P;
806
807 if (log)
808 {
809 log->Printf("Interpreted an AllocaInst");
Matt Kopecef143712013-06-03 18:00:07 +0000810 log->Printf(" R : 0x%" PRIx64, R);
811 log->Printf(" P : 0x%" PRIx64, P);
Sean Callanan14cb2aa2013-04-17 18:35:47 +0000812 }
813 }
814 break;
815 case Instruction::BitCast:
816 case Instruction::ZExt:
817 {
818 const CastInst *cast_inst = dyn_cast<CastInst>(inst);
819
820 if (!cast_inst)
821 {
822 if (log)
823 log->Printf("getOpcode() returns %s, but instruction is not a BitCastInst", cast_inst->getOpcodeName());
824 error.SetErrorToGenericError();
825 error.SetErrorString(interpreter_internal_error);
826 return false;
827 }
828
829 Value *source = cast_inst->getOperand(0);
830
831 lldb_private::Scalar S;
832
833 if (!frame.EvaluateValue(S, source, module))
834 {
835 if (log)
836 log->Printf("Couldn't evaluate %s", PrintValue(source).c_str());
837 error.SetErrorToGenericError();
838 error.SetErrorString(bad_value_error);
839 return false;
840 }
841
842 frame.AssignValue(inst, S, module);
843 }
844 break;
Sean Callanan415422c2013-06-05 22:07:06 +0000845 case Instruction::SExt:
846 {
847 const CastInst *cast_inst = dyn_cast<CastInst>(inst);
848
849 if (!cast_inst)
850 {
851 if (log)
852 log->Printf("getOpcode() returns %s, but instruction is not a BitCastInst", cast_inst->getOpcodeName());
853 error.SetErrorToGenericError();
854 error.SetErrorString(interpreter_internal_error);
855 return false;
856 }
857
858 Value *source = cast_inst->getOperand(0);
859
860 lldb_private::Scalar S;
861
862 if (!frame.EvaluateValue(S, source, module))
863 {
864 if (log)
865 log->Printf("Couldn't evaluate %s", PrintValue(source).c_str());
866 error.SetErrorToGenericError();
867 error.SetErrorString(bad_value_error);
868 return false;
869 }
870
871 S.MakeSigned();
872
873 lldb_private::Scalar S_signextend(S.SLongLong());
874
875 frame.AssignValue(inst, S_signextend, module);
876 }
877 break;
Sean Callanan14cb2aa2013-04-17 18:35:47 +0000878 case Instruction::Br:
879 {
880 const BranchInst *br_inst = dyn_cast<BranchInst>(inst);
881
882 if (!br_inst)
883 {
884 if (log)
885 log->Printf("getOpcode() returns Br, but instruction is not a BranchInst");
886 error.SetErrorToGenericError();
887 error.SetErrorString(interpreter_internal_error);
888 return false;
889 }
890
891 if (br_inst->isConditional())
892 {
893 Value *condition = br_inst->getCondition();
894
895 lldb_private::Scalar C;
896
897 if (!frame.EvaluateValue(C, condition, module))
898 {
899 if (log)
900 log->Printf("Couldn't evaluate %s", PrintValue(condition).c_str());
901 error.SetErrorToGenericError();
902 error.SetErrorString(bad_value_error);
903 return false;
904 }
905
906 if (C.GetRawBits64(0))
907 frame.Jump(br_inst->getSuccessor(0));
908 else
909 frame.Jump(br_inst->getSuccessor(1));
910
911 if (log)
912 {
913 log->Printf("Interpreted a BrInst with a condition");
914 log->Printf(" cond : %s", frame.SummarizeValue(condition).c_str());
915 }
916 }
917 else
918 {
919 frame.Jump(br_inst->getSuccessor(0));
920
921 if (log)
922 {
923 log->Printf("Interpreted a BrInst with no condition");
924 }
925 }
926 }
927 continue;
928 case Instruction::GetElementPtr:
929 {
930 const GetElementPtrInst *gep_inst = dyn_cast<GetElementPtrInst>(inst);
931
932 if (!gep_inst)
933 {
934 if (log)
935 log->Printf("getOpcode() returns GetElementPtr, but instruction is not a GetElementPtrInst");
936 error.SetErrorToGenericError();
937 error.SetErrorString(interpreter_internal_error);
938 return false;
939 }
940
941 const Value *pointer_operand = gep_inst->getPointerOperand();
942 Type *pointer_type = pointer_operand->getType();
943
944 lldb_private::Scalar P;
945
946 if (!frame.EvaluateValue(P, pointer_operand, module))
947 {
948 if (log)
949 log->Printf("Couldn't evaluate %s", PrintValue(pointer_operand).c_str());
950 error.SetErrorToGenericError();
951 error.SetErrorString(bad_value_error);
952 return false;
953 }
954
955 typedef SmallVector <Value *, 8> IndexVector;
956 typedef IndexVector::iterator IndexIterator;
957
958 SmallVector <Value *, 8> indices (gep_inst->idx_begin(),
959 gep_inst->idx_end());
960
961 SmallVector <Value *, 8> const_indices;
962
963 for (IndexIterator ii = indices.begin(), ie = indices.end();
964 ii != ie;
965 ++ii)
966 {
967 ConstantInt *constant_index = dyn_cast<ConstantInt>(*ii);
968
969 if (!constant_index)
970 {
971 lldb_private::Scalar I;
972
973 if (!frame.EvaluateValue(I, *ii, module))
974 {
975 if (log)
976 log->Printf("Couldn't evaluate %s", PrintValue(*ii).c_str());
977 error.SetErrorToGenericError();
978 error.SetErrorString(bad_value_error);
979 return false;
980 }
981
982 if (log)
983 log->Printf("Evaluated constant index %s as %llu", PrintValue(*ii).c_str(), I.ULongLong(LLDB_INVALID_ADDRESS));
984
985 constant_index = cast<ConstantInt>(ConstantInt::get((*ii)->getType(), I.ULongLong(LLDB_INVALID_ADDRESS)));
986 }
987
988 const_indices.push_back(constant_index);
989 }
990
991 uint64_t offset = data_layout.getIndexedOffset(pointer_type, const_indices);
992
993 lldb_private::Scalar Poffset = P + offset;
994
995 frame.AssignValue(inst, Poffset, module);
996
997 if (log)
998 {
999 log->Printf("Interpreted a GetElementPtrInst");
1000 log->Printf(" P : %s", frame.SummarizeValue(pointer_operand).c_str());
1001 log->Printf(" Poffset : %s", frame.SummarizeValue(inst).c_str());
1002 }
1003 }
1004 break;
1005 case Instruction::ICmp:
1006 {
1007 const ICmpInst *icmp_inst = dyn_cast<ICmpInst>(inst);
1008
1009 if (!icmp_inst)
1010 {
1011 if (log)
1012 log->Printf("getOpcode() returns ICmp, but instruction is not an ICmpInst");
1013 error.SetErrorToGenericError();
1014 error.SetErrorString(interpreter_internal_error);
1015 return false;
1016 }
1017
1018 CmpInst::Predicate predicate = icmp_inst->getPredicate();
1019
1020 Value *lhs = inst->getOperand(0);
1021 Value *rhs = inst->getOperand(1);
1022
1023 lldb_private::Scalar L;
1024 lldb_private::Scalar R;
1025
1026 if (!frame.EvaluateValue(L, lhs, module))
1027 {
1028 if (log)
1029 log->Printf("Couldn't evaluate %s", PrintValue(lhs).c_str());
1030 error.SetErrorToGenericError();
1031 error.SetErrorString(bad_value_error);
1032 return false;
1033 }
1034
1035 if (!frame.EvaluateValue(R, rhs, module))
1036 {
1037 if (log)
1038 log->Printf("Couldn't evaluate %s", PrintValue(rhs).c_str());
1039 error.SetErrorToGenericError();
1040 error.SetErrorString(bad_value_error);
1041 return false;
1042 }
1043
1044 lldb_private::Scalar result;
1045
1046 switch (predicate)
1047 {
1048 default:
1049 return false;
1050 case CmpInst::ICMP_EQ:
1051 result = (L == R);
1052 break;
1053 case CmpInst::ICMP_NE:
1054 result = (L != R);
1055 break;
1056 case CmpInst::ICMP_UGT:
1057 result = (L.GetRawBits64(0) > R.GetRawBits64(0));
1058 break;
1059 case CmpInst::ICMP_UGE:
1060 result = (L.GetRawBits64(0) >= R.GetRawBits64(0));
1061 break;
1062 case CmpInst::ICMP_ULT:
1063 result = (L.GetRawBits64(0) < R.GetRawBits64(0));
1064 break;
1065 case CmpInst::ICMP_ULE:
1066 result = (L.GetRawBits64(0) <= R.GetRawBits64(0));
1067 break;
1068 case CmpInst::ICMP_SGT:
Sean Callanan0b342b62013-05-24 20:36:56 +00001069 L.MakeSigned();
1070 R.MakeSigned();
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001071 result = (L > R);
1072 break;
1073 case CmpInst::ICMP_SGE:
Sean Callanan0b342b62013-05-24 20:36:56 +00001074 L.MakeSigned();
1075 R.MakeSigned();
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001076 result = (L >= R);
1077 break;
1078 case CmpInst::ICMP_SLT:
Sean Callanan0b342b62013-05-24 20:36:56 +00001079 L.MakeSigned();
1080 R.MakeSigned();
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001081 result = (L < R);
1082 break;
1083 case CmpInst::ICMP_SLE:
Sean Callanan0b342b62013-05-24 20:36:56 +00001084 L.MakeSigned();
1085 R.MakeSigned();
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001086 result = (L <= R);
1087 break;
1088 }
1089
1090 frame.AssignValue(inst, result, module);
1091
1092 if (log)
1093 {
1094 log->Printf("Interpreted an ICmpInst");
1095 log->Printf(" L : %s", frame.SummarizeValue(lhs).c_str());
1096 log->Printf(" R : %s", frame.SummarizeValue(rhs).c_str());
1097 log->Printf(" = : %s", frame.SummarizeValue(inst).c_str());
1098 }
1099 }
1100 break;
1101 case Instruction::IntToPtr:
1102 {
1103 const IntToPtrInst *int_to_ptr_inst = dyn_cast<IntToPtrInst>(inst);
1104
1105 if (!int_to_ptr_inst)
1106 {
1107 if (log)
1108 log->Printf("getOpcode() returns IntToPtr, but instruction is not an IntToPtrInst");
1109 error.SetErrorToGenericError();
1110 error.SetErrorString(interpreter_internal_error);
1111 return false;
1112 }
1113
1114 Value *src_operand = int_to_ptr_inst->getOperand(0);
1115
1116 lldb_private::Scalar I;
1117
1118 if (!frame.EvaluateValue(I, src_operand, module))
1119 {
1120 if (log)
1121 log->Printf("Couldn't evaluate %s", PrintValue(src_operand).c_str());
1122 error.SetErrorToGenericError();
1123 error.SetErrorString(bad_value_error);
1124 return false;
1125 }
1126
1127 frame.AssignValue(inst, I, module);
1128
1129 if (log)
1130 {
1131 log->Printf("Interpreted an IntToPtr");
1132 log->Printf(" Src : %s", frame.SummarizeValue(src_operand).c_str());
1133 log->Printf(" = : %s", frame.SummarizeValue(inst).c_str());
1134 }
1135 }
1136 break;
1137 case Instruction::PtrToInt:
1138 {
1139 const PtrToIntInst *ptr_to_int_inst = dyn_cast<PtrToIntInst>(inst);
1140
1141 if (!ptr_to_int_inst)
1142 {
1143 if (log)
1144 log->Printf("getOpcode() returns PtrToInt, but instruction is not an PtrToIntInst");
1145 error.SetErrorToGenericError();
1146 error.SetErrorString(interpreter_internal_error);
1147 return false;
1148 }
1149
1150 Value *src_operand = ptr_to_int_inst->getOperand(0);
1151
1152 lldb_private::Scalar I;
1153
1154 if (!frame.EvaluateValue(I, src_operand, module))
1155 {
1156 if (log)
1157 log->Printf("Couldn't evaluate %s", PrintValue(src_operand).c_str());
1158 error.SetErrorToGenericError();
1159 error.SetErrorString(bad_value_error);
1160 return false;
1161 }
1162
1163 frame.AssignValue(inst, I, module);
1164
1165 if (log)
1166 {
1167 log->Printf("Interpreted a PtrToInt");
1168 log->Printf(" Src : %s", frame.SummarizeValue(src_operand).c_str());
1169 log->Printf(" = : %s", frame.SummarizeValue(inst).c_str());
1170 }
1171 }
1172 break;
Sean Callanan8c46bac2013-10-11 19:45:00 +00001173 case Instruction::Trunc:
1174 {
1175 const TruncInst *trunc_inst = dyn_cast<TruncInst>(inst);
1176
1177 if (!trunc_inst)
1178 {
1179 if (log)
1180 log->Printf("getOpcode() returns Trunc, but instruction is not a TruncInst");
1181 error.SetErrorToGenericError();
1182 error.SetErrorString(interpreter_internal_error);
1183 return false;
1184 }
1185
1186 Value *src_operand = trunc_inst->getOperand(0);
1187
1188 lldb_private::Scalar I;
1189
1190 if (!frame.EvaluateValue(I, src_operand, module))
1191 {
1192 if (log)
1193 log->Printf("Couldn't evaluate %s", PrintValue(src_operand).c_str());
1194 error.SetErrorToGenericError();
1195 error.SetErrorString(bad_value_error);
1196 return false;
1197 }
1198
1199 frame.AssignValue(inst, I, module);
1200
1201 if (log)
1202 {
1203 log->Printf("Interpreted a Trunc");
1204 log->Printf(" Src : %s", frame.SummarizeValue(src_operand).c_str());
1205 log->Printf(" = : %s", frame.SummarizeValue(inst).c_str());
1206 }
1207 }
1208 break;
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001209 case Instruction::Load:
1210 {
1211 const LoadInst *load_inst = dyn_cast<LoadInst>(inst);
1212
1213 if (!load_inst)
1214 {
1215 if (log)
1216 log->Printf("getOpcode() returns Load, but instruction is not a LoadInst");
1217 error.SetErrorToGenericError();
1218 error.SetErrorString(interpreter_internal_error);
1219 return false;
1220 }
1221
1222 // The semantics of Load are:
1223 // Create a region D that will contain the loaded data
1224 // Resolve the region P containing a pointer
1225 // Dereference P to get the region R that the data should be loaded from
1226 // Transfer a unit of type type(D) from R to D
1227
1228 const Value *pointer_operand = load_inst->getPointerOperand();
1229
1230 Type *pointer_ty = pointer_operand->getType();
1231 PointerType *pointer_ptr_ty = dyn_cast<PointerType>(pointer_ty);
1232 if (!pointer_ptr_ty)
1233 {
1234 if (log)
1235 log->Printf("getPointerOperand()->getType() is not a PointerType");
1236 error.SetErrorToGenericError();
1237 error.SetErrorString(interpreter_internal_error);
1238 return false;
1239 }
1240 Type *target_ty = pointer_ptr_ty->getElementType();
1241
1242 lldb::addr_t D = frame.ResolveValue(load_inst, module);
1243 lldb::addr_t P = frame.ResolveValue(pointer_operand, module);
1244
1245 if (D == LLDB_INVALID_ADDRESS)
1246 {
1247 if (log)
1248 log->Printf("LoadInst's value doesn't resolve to anything");
1249 error.SetErrorToGenericError();
1250 error.SetErrorString(bad_value_error);
1251 return false;
1252 }
1253
1254 if (P == LLDB_INVALID_ADDRESS)
1255 {
1256 if (log)
1257 log->Printf("LoadInst's pointer doesn't resolve to anything");
1258 error.SetErrorToGenericError();
1259 error.SetErrorString(bad_value_error);
1260 return false;
1261 }
1262
1263 lldb::addr_t R;
1264 lldb_private::Error read_error;
1265 memory_map.ReadPointerFromMemory(&R, P, read_error);
1266
1267 if (!read_error.Success())
1268 {
1269 if (log)
1270 log->Printf("Couldn't read the address to be loaded for a LoadInst");
1271 error.SetErrorToGenericError();
1272 error.SetErrorString(memory_read_error);
1273 return false;
1274 }
1275
1276 size_t target_size = data_layout.getTypeStoreSize(target_ty);
1277 lldb_private::DataBufferHeap buffer(target_size, 0);
1278
1279 read_error.Clear();
1280 memory_map.ReadMemory(buffer.GetBytes(), R, buffer.GetByteSize(), read_error);
1281 if (!read_error.Success())
1282 {
1283 if (log)
1284 log->Printf("Couldn't read from a region on behalf of a LoadInst");
1285 error.SetErrorToGenericError();
1286 error.SetErrorString(memory_read_error);
1287 return false;
1288 }
1289
1290 lldb_private::Error write_error;
1291 memory_map.WriteMemory(D, buffer.GetBytes(), buffer.GetByteSize(), write_error);
1292 if (!write_error.Success())
1293 {
1294 if (log)
1295 log->Printf("Couldn't write to a region on behalf of a LoadInst");
1296 error.SetErrorToGenericError();
1297 error.SetErrorString(memory_read_error);
1298 return false;
1299 }
1300
1301 if (log)
1302 {
1303 log->Printf("Interpreted a LoadInst");
Matt Kopecef143712013-06-03 18:00:07 +00001304 log->Printf(" P : 0x%" PRIx64, P);
1305 log->Printf(" R : 0x%" PRIx64, R);
1306 log->Printf(" D : 0x%" PRIx64, D);
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001307 }
1308 }
1309 break;
1310 case Instruction::Ret:
1311 {
1312 return true;
1313 }
1314 case Instruction::Store:
1315 {
1316 const StoreInst *store_inst = dyn_cast<StoreInst>(inst);
1317
1318 if (!store_inst)
1319 {
1320 if (log)
1321 log->Printf("getOpcode() returns Store, but instruction is not a StoreInst");
1322 error.SetErrorToGenericError();
1323 error.SetErrorString(interpreter_internal_error);
1324 return false;
1325 }
1326
1327 // The semantics of Store are:
1328 // Resolve the region D containing the data to be stored
1329 // Resolve the region P containing a pointer
1330 // Dereference P to get the region R that the data should be stored in
1331 // Transfer a unit of type type(D) from D to R
1332
1333 const Value *value_operand = store_inst->getValueOperand();
1334 const Value *pointer_operand = store_inst->getPointerOperand();
1335
1336 Type *pointer_ty = pointer_operand->getType();
1337 PointerType *pointer_ptr_ty = dyn_cast<PointerType>(pointer_ty);
1338 if (!pointer_ptr_ty)
1339 return false;
1340 Type *target_ty = pointer_ptr_ty->getElementType();
1341
1342 lldb::addr_t D = frame.ResolveValue(value_operand, module);
1343 lldb::addr_t P = frame.ResolveValue(pointer_operand, module);
1344
1345 if (D == LLDB_INVALID_ADDRESS)
1346 {
1347 if (log)
1348 log->Printf("StoreInst's value doesn't resolve to anything");
1349 error.SetErrorToGenericError();
1350 error.SetErrorString(bad_value_error);
1351 return false;
1352 }
1353
1354 if (P == LLDB_INVALID_ADDRESS)
1355 {
1356 if (log)
1357 log->Printf("StoreInst's pointer doesn't resolve to anything");
1358 error.SetErrorToGenericError();
1359 error.SetErrorString(bad_value_error);
1360 return false;
1361 }
1362
1363 lldb::addr_t R;
1364 lldb_private::Error read_error;
1365 memory_map.ReadPointerFromMemory(&R, P, read_error);
1366
1367 if (!read_error.Success())
1368 {
1369 if (log)
1370 log->Printf("Couldn't read the address to be loaded for a LoadInst");
1371 error.SetErrorToGenericError();
1372 error.SetErrorString(memory_read_error);
1373 return false;
1374 }
1375
1376 size_t target_size = data_layout.getTypeStoreSize(target_ty);
1377 lldb_private::DataBufferHeap buffer(target_size, 0);
1378
1379 read_error.Clear();
1380 memory_map.ReadMemory(buffer.GetBytes(), D, buffer.GetByteSize(), read_error);
1381 if (!read_error.Success())
1382 {
1383 if (log)
1384 log->Printf("Couldn't read from a region on behalf of a StoreInst");
1385 error.SetErrorToGenericError();
1386 error.SetErrorString(memory_read_error);
1387 return false;
1388 }
1389
1390 lldb_private::Error write_error;
1391 memory_map.WriteMemory(R, buffer.GetBytes(), buffer.GetByteSize(), write_error);
1392 if (!write_error.Success())
1393 {
1394 if (log)
1395 log->Printf("Couldn't write to a region on behalf of a StoreInst");
1396 error.SetErrorToGenericError();
Sean Callanan49630e72013-04-20 02:39:24 +00001397 error.SetErrorString(memory_write_error);
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001398 return false;
1399 }
1400
1401 if (log)
1402 {
1403 log->Printf("Interpreted a StoreInst");
Matt Kopecef143712013-06-03 18:00:07 +00001404 log->Printf(" D : 0x%" PRIx64, D);
1405 log->Printf(" P : 0x%" PRIx64, P);
1406 log->Printf(" R : 0x%" PRIx64, R);
Sean Callanan14cb2aa2013-04-17 18:35:47 +00001407 }
1408 }
1409 break;
1410 }
1411
1412 ++frame.m_ii;
1413 }
1414
1415 if (num_insts >= 4096)
1416 {
1417 error.SetErrorToGenericError();
1418 error.SetErrorString(infinite_loop_error);
1419 return false;
1420 }
1421
1422 return false;
1423}