180814287SRaphael Isemann //===-- IRInterpreter.cpp -------------------------------------------------===// 23bfdaa2aSSean Callanan // 32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 63bfdaa2aSSean Callanan // 73bfdaa2aSSean Callanan //===----------------------------------------------------------------------===// 83bfdaa2aSSean Callanan 9579e70c9SSean Callanan #include "lldb/Expression/IRInterpreter.h" 1090ff7911SEwan Crawford #include "lldb/Core/Module.h" 11579e70c9SSean Callanan #include "lldb/Core/ModuleSpec.h" 1290ff7911SEwan Crawford #include "lldb/Core/ValueObject.h" 13579e70c9SSean Callanan #include "lldb/Expression/DiagnosticManager.h" 147071c5fdSTed Woodward #include "lldb/Expression/IRExecutionUnit.h" 15fefe43cdSSean Callanan #include "lldb/Expression/IRMemoryMap.h" 16bf9a7730SZachary Turner #include "lldb/Utility/ConstString.h" 17666cc0b2SZachary Turner #include "lldb/Utility/DataExtractor.h" 1801c3243fSZachary Turner #include "lldb/Utility/Endian.h" 196f9e6901SZachary Turner #include "lldb/Utility/Log.h" 20d821c997SPavel Labath #include "lldb/Utility/Scalar.h" 2197206d57SZachary Turner #include "lldb/Utility/Status.h" 22bf9a7730SZachary Turner #include "lldb/Utility/StreamString.h" 233bfdaa2aSSean Callanan 2490ff7911SEwan Crawford #include "lldb/Target/ABI.h" 2590ff7911SEwan Crawford #include "lldb/Target/ExecutionContext.h" 2690ff7911SEwan Crawford #include "lldb/Target/Target.h" 2790ff7911SEwan Crawford #include "lldb/Target/Thread.h" 2890ff7911SEwan Crawford #include "lldb/Target/ThreadPlan.h" 2990ff7911SEwan Crawford #include "lldb/Target/ThreadPlanCallFunctionUsingABI.h" 3090ff7911SEwan Crawford 311e157587SChandler Carruth #include "llvm/IR/Constants.h" 32fefe43cdSSean Callanan #include "llvm/IR/DataLayout.h" 331e157587SChandler Carruth #include "llvm/IR/Function.h" 341e157587SChandler Carruth #include "llvm/IR/Instructions.h" 35576a4374SSean Callanan #include "llvm/IR/Intrinsics.h" 3690ff7911SEwan Crawford #include "llvm/IR/LLVMContext.h" 371e157587SChandler Carruth #include "llvm/IR/Module.h" 38d05b8992SEduard Burtescu #include "llvm/IR/Operator.h" 393bfdaa2aSSean Callanan #include "llvm/Support/raw_ostream.h" 403bfdaa2aSSean Callanan 413bfdaa2aSSean Callanan #include <map> 423bfdaa2aSSean Callanan 433bfdaa2aSSean Callanan using namespace llvm; 443bfdaa2aSSean Callanan 45b9c1b51eSKate Stone static std::string PrintValue(const Value *value, bool truncate = false) { 463bfdaa2aSSean Callanan std::string s; 473bfdaa2aSSean Callanan raw_string_ostream rso(s); 483bfdaa2aSSean Callanan value->print(rso); 493bfdaa2aSSean Callanan rso.flush(); 503bfdaa2aSSean Callanan if (truncate) 513bfdaa2aSSean Callanan s.resize(s.length() - 1); 523bfdaa2aSSean Callanan 533bfdaa2aSSean Callanan size_t offset; 543bfdaa2aSSean Callanan while ((offset = s.find('\n')) != s.npos) 553bfdaa2aSSean Callanan s.erase(offset, 1); 563bfdaa2aSSean Callanan while (s[0] == ' ' || s[0] == '\t') 573bfdaa2aSSean Callanan s.erase(0, 1); 583bfdaa2aSSean Callanan 593bfdaa2aSSean Callanan return s; 603bfdaa2aSSean Callanan } 613bfdaa2aSSean Callanan 62b9c1b51eSKate Stone static std::string PrintType(const Type *type, bool truncate = false) { 633bfdaa2aSSean Callanan std::string s; 643bfdaa2aSSean Callanan raw_string_ostream rso(s); 653bfdaa2aSSean Callanan type->print(rso); 663bfdaa2aSSean Callanan rso.flush(); 673bfdaa2aSSean Callanan if (truncate) 683bfdaa2aSSean Callanan s.resize(s.length() - 1); 693bfdaa2aSSean Callanan return s; 703bfdaa2aSSean Callanan } 713bfdaa2aSSean Callanan 72b9c1b51eSKate Stone static bool CanIgnoreCall(const CallInst *call) { 73576a4374SSean Callanan const llvm::Function *called_function = call->getCalledFunction(); 74576a4374SSean Callanan 75576a4374SSean Callanan if (!called_function) 76576a4374SSean Callanan return false; 77576a4374SSean Callanan 78b9c1b51eSKate Stone if (called_function->isIntrinsic()) { 79b9c1b51eSKate Stone switch (called_function->getIntrinsicID()) { 80576a4374SSean Callanan default: 81576a4374SSean Callanan break; 82576a4374SSean Callanan case llvm::Intrinsic::dbg_declare: 83576a4374SSean Callanan case llvm::Intrinsic::dbg_value: 84576a4374SSean Callanan return true; 85576a4374SSean Callanan } 86576a4374SSean Callanan } 87576a4374SSean Callanan 88576a4374SSean Callanan return false; 89576a4374SSean Callanan } 90576a4374SSean Callanan 91b9c1b51eSKate Stone class InterpreterStackFrame { 923bfdaa2aSSean Callanan public: 9308052afaSSean Callanan typedef std::map<const Value *, lldb::addr_t> ValueMap; 9408052afaSSean Callanan 953bfdaa2aSSean Callanan ValueMap m_values; 968468dbecSMicah Villmow DataLayout &m_target_data; 977071c5fdSTed Woodward lldb_private::IRExecutionUnit &m_execution_unit; 983bfdaa2aSSean Callanan const BasicBlock *m_bb; 993fe71581SMarianne Mailhot-Sarrasin const BasicBlock *m_prev_bb; 1003bfdaa2aSSean Callanan BasicBlock::const_iterator m_ii; 1013bfdaa2aSSean Callanan BasicBlock::const_iterator m_ie; 1023bfdaa2aSSean Callanan 1031582ee68SSean Callanan lldb::addr_t m_frame_process_address; 1041582ee68SSean Callanan size_t m_frame_size; 1051582ee68SSean Callanan lldb::addr_t m_stack_pointer; 1061582ee68SSean Callanan 1073bfdaa2aSSean Callanan lldb::ByteOrder m_byte_order; 1083bfdaa2aSSean Callanan size_t m_addr_byte_size; 1093bfdaa2aSSean Callanan 1108468dbecSMicah Villmow InterpreterStackFrame(DataLayout &target_data, 1117071c5fdSTed Woodward lldb_private::IRExecutionUnit &execution_unit, 112df56540aSSean Callanan lldb::addr_t stack_frame_bottom, 113b9c1b51eSKate Stone lldb::addr_t stack_frame_top) 114b9c1b51eSKate Stone : m_target_data(target_data), m_execution_unit(execution_unit), 115b9c1b51eSKate Stone m_bb(nullptr), m_prev_bb(nullptr) { 116b9c1b51eSKate Stone m_byte_order = (target_data.isLittleEndian() ? lldb::eByteOrderLittle 117b9c1b51eSKate Stone : lldb::eByteOrderBig); 11895769bf4SSean Callanan m_addr_byte_size = (target_data.getPointerSize(0)); 1191582ee68SSean Callanan 120df56540aSSean Callanan m_frame_process_address = stack_frame_bottom; 121df56540aSSean Callanan m_frame_size = stack_frame_top - stack_frame_bottom; 122df56540aSSean Callanan m_stack_pointer = stack_frame_top; 1231582ee68SSean Callanan } 1241582ee68SSean Callanan 125b9c1b51eSKate Stone ~InterpreterStackFrame() {} 1263bfdaa2aSSean Callanan 127b9c1b51eSKate Stone void Jump(const BasicBlock *bb) { 1283fe71581SMarianne Mailhot-Sarrasin m_prev_bb = m_bb; 1293bfdaa2aSSean Callanan m_bb = bb; 1303bfdaa2aSSean Callanan m_ii = m_bb->begin(); 1313bfdaa2aSSean Callanan m_ie = m_bb->end(); 1323bfdaa2aSSean Callanan } 1333bfdaa2aSSean Callanan 134b9c1b51eSKate Stone std::string SummarizeValue(const Value *value) { 1353bfdaa2aSSean Callanan lldb_private::StreamString ss; 1363bfdaa2aSSean Callanan 1373bfdaa2aSSean Callanan ss.Printf("%s", PrintValue(value).c_str()); 1383bfdaa2aSSean Callanan 1393bfdaa2aSSean Callanan ValueMap::iterator i = m_values.find(value); 1403bfdaa2aSSean Callanan 141b9c1b51eSKate Stone if (i != m_values.end()) { 14208052afaSSean Callanan lldb::addr_t addr = i->second; 1433bfdaa2aSSean Callanan 14408052afaSSean Callanan ss.Printf(" 0x%llx", (unsigned long long)addr); 1453bfdaa2aSSean Callanan } 1463bfdaa2aSSean Callanan 147adcd0268SBenjamin Kramer return std::string(ss.GetString()); 1483bfdaa2aSSean Callanan } 1493bfdaa2aSSean Callanan 150*b725142cSPavel Labath bool AssignToMatchType(lldb_private::Scalar &scalar, llvm::APInt value, 151b9c1b51eSKate Stone Type *type) { 1523bfdaa2aSSean Callanan size_t type_size = m_target_data.getTypeStoreSize(type); 1533bfdaa2aSSean Callanan 154ae6ca2fcSFrederic Riss if (type_size > 8) 1553bfdaa2aSSean Callanan return false; 1563bfdaa2aSSean Callanan 157ae6ca2fcSFrederic Riss if (type_size != 1) 158ae6ca2fcSFrederic Riss type_size = PowerOf2Ceil(type_size); 159ae6ca2fcSFrederic Riss 160*b725142cSPavel Labath scalar = value.zextOrTrunc(type_size * 8); 1613bfdaa2aSSean Callanan return true; 1623bfdaa2aSSean Callanan } 1633bfdaa2aSSean Callanan 164b9c1b51eSKate Stone bool EvaluateValue(lldb_private::Scalar &scalar, const Value *value, 165b9c1b51eSKate Stone Module &module) { 1663bfdaa2aSSean Callanan const Constant *constant = dyn_cast<Constant>(value); 1673bfdaa2aSSean Callanan 168b9c1b51eSKate Stone if (constant) { 169415422ceSSean Callanan APInt value_apint; 170415422ceSSean Callanan 171415422ceSSean Callanan if (!ResolveConstantValue(value_apint, constant)) 172415422ceSSean Callanan return false; 173415422ceSSean Callanan 174*b725142cSPavel Labath return AssignToMatchType(scalar, value_apint, value->getType()); 175c3f0d9f3SDavide Italiano } 176c3f0d9f3SDavide Italiano 17708052afaSSean Callanan lldb::addr_t process_address = ResolveValue(value, module); 1783bfdaa2aSSean Callanan size_t value_size = m_target_data.getTypeStoreSize(value->getType()); 1793bfdaa2aSSean Callanan 18008052afaSSean Callanan lldb_private::DataExtractor value_extractor; 18197206d57SZachary Turner lldb_private::Status extract_error; 18208052afaSSean Callanan 183b9c1b51eSKate Stone m_execution_unit.GetMemoryData(value_extractor, process_address, 184b9c1b51eSKate Stone value_size, extract_error); 18508052afaSSean Callanan 18608052afaSSean Callanan if (!extract_error.Success()) 18708052afaSSean Callanan return false; 18808052afaSSean Callanan 189c7bece56SGreg Clayton lldb::offset_t offset = 0; 190ae6ca2fcSFrederic Riss if (value_size <= 8) { 19108052afaSSean Callanan uint64_t u64value = value_extractor.GetMaxU64(&offset, value_size); 192*b725142cSPavel Labath return AssignToMatchType(scalar, llvm::APInt(64, u64value), 193*b725142cSPavel Labath value->getType()); 1943bfdaa2aSSean Callanan } 1953bfdaa2aSSean Callanan 1963bfdaa2aSSean Callanan return false; 1973bfdaa2aSSean Callanan } 1983bfdaa2aSSean Callanan 199*b725142cSPavel Labath bool AssignValue(const Value *value, lldb_private::Scalar scalar, 200b9c1b51eSKate Stone Module &module) { 20108052afaSSean Callanan lldb::addr_t process_address = ResolveValue(value, module); 20208052afaSSean Callanan 20308052afaSSean Callanan if (process_address == LLDB_INVALID_ADDRESS) 20408052afaSSean Callanan return false; 2053bfdaa2aSSean Callanan 2063bfdaa2aSSean Callanan lldb_private::Scalar cast_scalar; 2073bfdaa2aSSean Callanan 208*b725142cSPavel Labath scalar.MakeUnsigned(); 209*b725142cSPavel Labath if (!AssignToMatchType(cast_scalar, scalar.UInt128(llvm::APInt()), 210*b725142cSPavel Labath value->getType())) 2113bfdaa2aSSean Callanan return false; 2123bfdaa2aSSean Callanan 21308052afaSSean Callanan size_t value_byte_size = m_target_data.getTypeStoreSize(value->getType()); 2143bfdaa2aSSean Callanan 21508052afaSSean Callanan lldb_private::DataBufferHeap buf(value_byte_size, 0); 2163bfdaa2aSSean Callanan 21797206d57SZachary Turner lldb_private::Status get_data_error; 21808052afaSSean Callanan 219b9c1b51eSKate Stone if (!cast_scalar.GetAsMemoryData(buf.GetBytes(), buf.GetByteSize(), 220b9c1b51eSKate Stone m_byte_order, get_data_error)) 2213bfdaa2aSSean Callanan return false; 2223bfdaa2aSSean Callanan 22397206d57SZachary Turner lldb_private::Status write_error; 2243bfdaa2aSSean Callanan 225b9c1b51eSKate Stone m_execution_unit.WriteMemory(process_address, buf.GetBytes(), 226b9c1b51eSKate Stone buf.GetByteSize(), write_error); 2275c9737a5SGreg Clayton 22808052afaSSean Callanan return write_error.Success(); 2293bfdaa2aSSean Callanan } 2303bfdaa2aSSean Callanan 231b9c1b51eSKate Stone bool ResolveConstantValue(APInt &value, const Constant *constant) { 232b9c1b51eSKate Stone switch (constant->getValueID()) { 2331582ee68SSean Callanan default: 2341582ee68SSean Callanan break; 2357071c5fdSTed Woodward case Value::FunctionVal: 236b9c1b51eSKate Stone if (const Function *constant_func = dyn_cast<Function>(constant)) { 2377071c5fdSTed Woodward lldb_private::ConstString name(constant_func->getName()); 238f2128b28SJim Ingham bool missing_weak = false; 239f2128b28SJim Ingham lldb::addr_t addr = m_execution_unit.FindSymbol(name, missing_weak); 240f2128b28SJim Ingham if (addr == LLDB_INVALID_ADDRESS || missing_weak) 2417071c5fdSTed Woodward return false; 2427071c5fdSTed Woodward value = APInt(m_target_data.getPointerSizeInBits(), addr); 2437071c5fdSTed Woodward return true; 2447071c5fdSTed Woodward } 2457071c5fdSTed Woodward break; 2461582ee68SSean Callanan case Value::ConstantIntVal: 247b9c1b51eSKate Stone if (const ConstantInt *constant_int = dyn_cast<ConstantInt>(constant)) { 24894a9a39eSSean Callanan value = constant_int->getValue(); 24994a9a39eSSean Callanan return true; 2503bfdaa2aSSean Callanan } 2511582ee68SSean Callanan break; 2521582ee68SSean Callanan case Value::ConstantFPVal: 253b9c1b51eSKate Stone if (const ConstantFP *constant_fp = dyn_cast<ConstantFP>(constant)) { 25494a9a39eSSean Callanan value = constant_fp->getValueAPF().bitcastToAPInt(); 25594a9a39eSSean Callanan return true; 2563bfdaa2aSSean Callanan } 2571582ee68SSean Callanan break; 2581582ee68SSean Callanan case Value::ConstantExprVal: 259b9c1b51eSKate Stone if (const ConstantExpr *constant_expr = 260b9c1b51eSKate Stone dyn_cast<ConstantExpr>(constant)) { 261b9c1b51eSKate Stone switch (constant_expr->getOpcode()) { 26280c48c10SSean Callanan default: 26380c48c10SSean Callanan return false; 26480c48c10SSean Callanan case Instruction::IntToPtr: 2652abffe05SSean Callanan case Instruction::PtrToInt: 26680c48c10SSean Callanan case Instruction::BitCast: 26794a9a39eSSean Callanan return ResolveConstantValue(value, constant_expr->getOperand(0)); 268b9c1b51eSKate Stone case Instruction::GetElementPtr: { 26994a9a39eSSean Callanan ConstantExpr::const_op_iterator op_cursor = constant_expr->op_begin(); 27094a9a39eSSean Callanan ConstantExpr::const_op_iterator op_end = constant_expr->op_end(); 27194a9a39eSSean Callanan 27294a9a39eSSean Callanan Constant *base = dyn_cast<Constant>(*op_cursor); 27394a9a39eSSean Callanan 27494a9a39eSSean Callanan if (!base) 27594a9a39eSSean Callanan return false; 27694a9a39eSSean Callanan 27794a9a39eSSean Callanan if (!ResolveConstantValue(value, base)) 27894a9a39eSSean Callanan return false; 27994a9a39eSSean Callanan 28094a9a39eSSean Callanan op_cursor++; 28194a9a39eSSean Callanan 28294a9a39eSSean Callanan if (op_cursor == op_end) 28394a9a39eSSean Callanan return true; // no offset to apply! 28494a9a39eSSean Callanan 28594a9a39eSSean Callanan SmallVector<Value *, 8> indices(op_cursor, op_end); 28694a9a39eSSean Callanan 287b9c1b51eSKate Stone Type *src_elem_ty = 288b9c1b51eSKate Stone cast<GEPOperator>(constant_expr)->getSourceElementType(); 289b9c1b51eSKate Stone uint64_t offset = 290b9c1b51eSKate Stone m_target_data.getIndexedOffsetInType(src_elem_ty, indices); 29194a9a39eSSean Callanan 29294a9a39eSSean Callanan const bool is_signed = true; 29394a9a39eSSean Callanan value += APInt(value.getBitWidth(), offset, is_signed); 29494a9a39eSSean Callanan 29594a9a39eSSean Callanan return true; 29694a9a39eSSean Callanan } 29780c48c10SSean Callanan } 29880c48c10SSean Callanan } 2991582ee68SSean Callanan break; 3001582ee68SSean Callanan case Value::ConstantPointerNullVal: 301b9c1b51eSKate Stone if (isa<ConstantPointerNull>(constant)) { 3021582ee68SSean Callanan value = APInt(m_target_data.getPointerSizeInBits(), 0); 3031582ee68SSean Callanan return true; 3041582ee68SSean Callanan } 3051582ee68SSean Callanan break; 3061582ee68SSean Callanan } 3073bfdaa2aSSean Callanan return false; 3083bfdaa2aSSean Callanan } 3093bfdaa2aSSean Callanan 310b9c1b51eSKate Stone bool MakeArgument(const Argument *value, uint64_t address) { 3111582ee68SSean Callanan lldb::addr_t data_address = Malloc(value->getType()); 3121582ee68SSean Callanan 3131582ee68SSean Callanan if (data_address == LLDB_INVALID_ADDRESS) 3141582ee68SSean Callanan return false; 3151582ee68SSean Callanan 31697206d57SZachary Turner lldb_private::Status write_error; 3171582ee68SSean Callanan 3187071c5fdSTed Woodward m_execution_unit.WritePointerToMemory(data_address, address, write_error); 3191582ee68SSean Callanan 320b9c1b51eSKate Stone if (!write_error.Success()) { 32197206d57SZachary Turner lldb_private::Status free_error; 3227071c5fdSTed Woodward m_execution_unit.Free(data_address, free_error); 3231582ee68SSean Callanan return false; 3241582ee68SSean Callanan } 3251582ee68SSean Callanan 3261582ee68SSean Callanan m_values[value] = data_address; 3271582ee68SSean Callanan 328b9c1b51eSKate Stone lldb_private::Log *log( 329b9c1b51eSKate Stone lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); 3301582ee68SSean Callanan 331b9c1b51eSKate Stone if (log) { 33263e5fb76SJonas Devlieghere LLDB_LOGF(log, "Made an allocation for argument %s", 333b9c1b51eSKate Stone PrintValue(value).c_str()); 33463e5fb76SJonas Devlieghere LLDB_LOGF(log, " Data region : %llx", (unsigned long long)address); 33563e5fb76SJonas Devlieghere LLDB_LOGF(log, " Ref region : %llx", 33663e5fb76SJonas Devlieghere (unsigned long long)data_address); 3371582ee68SSean Callanan } 3381582ee68SSean Callanan 3391582ee68SSean Callanan return true; 3401582ee68SSean Callanan } 3411582ee68SSean Callanan 342b9c1b51eSKate Stone bool ResolveConstant(lldb::addr_t process_address, const Constant *constant) { 34394a9a39eSSean Callanan APInt resolved_value; 34494a9a39eSSean Callanan 34594a9a39eSSean Callanan if (!ResolveConstantValue(resolved_value, constant)) 34694a9a39eSSean Callanan return false; 34794a9a39eSSean Callanan 34894a9a39eSSean Callanan size_t constant_size = m_target_data.getTypeStoreSize(constant->getType()); 3499521ad2aSUlrich Weigand lldb_private::DataBufferHeap buf(constant_size, 0); 35008052afaSSean Callanan 35197206d57SZachary Turner lldb_private::Status get_data_error; 35246fc0066SSean Callanan 353b9c1b51eSKate Stone lldb_private::Scalar resolved_scalar( 354b9c1b51eSKate Stone resolved_value.zextOrTrunc(llvm::NextPowerOf2(constant_size) * 8)); 355b9c1b51eSKate Stone if (!resolved_scalar.GetAsMemoryData(buf.GetBytes(), buf.GetByteSize(), 356b9c1b51eSKate Stone m_byte_order, get_data_error)) 3579521ad2aSUlrich Weigand return false; 35846fc0066SSean Callanan 35997206d57SZachary Turner lldb_private::Status write_error; 36008052afaSSean Callanan 361b9c1b51eSKate Stone m_execution_unit.WriteMemory(process_address, buf.GetBytes(), 362b9c1b51eSKate Stone buf.GetByteSize(), write_error); 36308052afaSSean Callanan 36408052afaSSean Callanan return write_error.Success(); 36594a9a39eSSean Callanan } 36694a9a39eSSean Callanan 367b9c1b51eSKate Stone lldb::addr_t Malloc(size_t size, uint8_t byte_alignment) { 3681582ee68SSean Callanan lldb::addr_t ret = m_stack_pointer; 36908052afaSSean Callanan 3701582ee68SSean Callanan ret -= size; 3711582ee68SSean Callanan ret -= (ret % byte_alignment); 37208052afaSSean Callanan 3731582ee68SSean Callanan if (ret < m_frame_process_address) 37408052afaSSean Callanan return LLDB_INVALID_ADDRESS; 3751582ee68SSean Callanan 3761582ee68SSean Callanan m_stack_pointer = ret; 3771582ee68SSean Callanan return ret; 37808052afaSSean Callanan } 37908052afaSSean Callanan 380b9c1b51eSKate Stone lldb::addr_t Malloc(llvm::Type *type) { 38197206d57SZachary Turner lldb_private::Status alloc_error; 38208052afaSSean Callanan 383b9c1b51eSKate Stone return Malloc(m_target_data.getTypeAllocSize(type), 384b9c1b51eSKate Stone m_target_data.getPrefTypeAlignment(type)); 38508052afaSSean Callanan } 38608052afaSSean Callanan 387b9c1b51eSKate Stone std::string PrintData(lldb::addr_t addr, llvm::Type *type) { 38808052afaSSean Callanan size_t length = m_target_data.getTypeStoreSize(type); 38908052afaSSean Callanan 39008052afaSSean Callanan lldb_private::DataBufferHeap buf(length, 0); 39108052afaSSean Callanan 39297206d57SZachary Turner lldb_private::Status read_error; 39308052afaSSean Callanan 3947071c5fdSTed Woodward m_execution_unit.ReadMemory(buf.GetBytes(), addr, length, read_error); 39508052afaSSean Callanan 39608052afaSSean Callanan if (!read_error.Success()) 39708052afaSSean Callanan return std::string("<couldn't read data>"); 39808052afaSSean Callanan 39908052afaSSean Callanan lldb_private::StreamString ss; 40008052afaSSean Callanan 401b9c1b51eSKate Stone for (size_t i = 0; i < length; i++) { 40208052afaSSean Callanan if ((!(i & 0xf)) && i) 40308052afaSSean Callanan ss.Printf("%02hhx - ", buf.GetBytes()[i]); 40408052afaSSean Callanan else 40508052afaSSean Callanan ss.Printf("%02hhx ", buf.GetBytes()[i]); 40608052afaSSean Callanan } 40708052afaSSean Callanan 408adcd0268SBenjamin Kramer return std::string(ss.GetString()); 40908052afaSSean Callanan } 41008052afaSSean Callanan 411b9c1b51eSKate Stone lldb::addr_t ResolveValue(const Value *value, Module &module) { 4123bfdaa2aSSean Callanan ValueMap::iterator i = m_values.find(value); 4133bfdaa2aSSean Callanan 4143bfdaa2aSSean Callanan if (i != m_values.end()) 4153bfdaa2aSSean Callanan return i->second; 4163bfdaa2aSSean Callanan 4171582ee68SSean Callanan // Fall back and allocate space [allocation type Alloca] 4181582ee68SSean Callanan 4191582ee68SSean Callanan lldb::addr_t data_address = Malloc(value->getType()); 4201582ee68SSean Callanan 421b9c1b51eSKate Stone if (const Constant *constant = dyn_cast<Constant>(value)) { 422b9c1b51eSKate Stone if (!ResolveConstant(data_address, constant)) { 42397206d57SZachary Turner lldb_private::Status free_error; 4247071c5fdSTed Woodward m_execution_unit.Free(data_address, free_error); 4251582ee68SSean Callanan return LLDB_INVALID_ADDRESS; 4261582ee68SSean Callanan } 4271582ee68SSean Callanan } 4281582ee68SSean Callanan 4291582ee68SSean Callanan m_values[value] = data_address; 4301582ee68SSean Callanan return data_address; 4313bfdaa2aSSean Callanan } 4323bfdaa2aSSean Callanan }; 4333bfdaa2aSSean Callanan 434b9c1b51eSKate Stone static const char *unsupported_opcode_error = 435b9c1b51eSKate Stone "Interpreter doesn't handle one of the expression's opcodes"; 436b9c1b51eSKate Stone static const char *unsupported_operand_error = 437b9c1b51eSKate Stone "Interpreter doesn't handle one of the expression's operands"; 438b9c1b51eSKate Stone static const char *interpreter_internal_error = 439b9c1b51eSKate Stone "Interpreter encountered an internal error"; 440b9c1b51eSKate Stone static const char *bad_value_error = 441b9c1b51eSKate Stone "Interpreter couldn't resolve a value during execution"; 442b9c1b51eSKate Stone static const char *memory_allocation_error = 443b9c1b51eSKate Stone "Interpreter couldn't allocate memory"; 444175a0d04SSean Callanan static const char *memory_write_error = "Interpreter couldn't write to memory"; 445175a0d04SSean Callanan static const char *memory_read_error = "Interpreter couldn't read from memory"; 446175a0d04SSean Callanan static const char *infinite_loop_error = "Interpreter ran for too many cycles"; 447b9c1b51eSKate Stone static const char *too_many_functions_error = 448b9c1b51eSKate Stone "Interpreter doesn't handle modules with multiple function bodies."; 449175a0d04SSean Callanan 450b9c1b51eSKate Stone static bool CanResolveConstant(llvm::Constant *constant) { 451b9c1b51eSKate Stone switch (constant->getValueID()) { 4528c62daf2SSean Callanan default: 4538c62daf2SSean Callanan return false; 4548c62daf2SSean Callanan case Value::ConstantIntVal: 4558c62daf2SSean Callanan case Value::ConstantFPVal: 4567071c5fdSTed Woodward case Value::FunctionVal: 4578c62daf2SSean Callanan return true; 4588c62daf2SSean Callanan case Value::ConstantExprVal: 459b9c1b51eSKate Stone if (const ConstantExpr *constant_expr = dyn_cast<ConstantExpr>(constant)) { 460b9c1b51eSKate Stone switch (constant_expr->getOpcode()) { 4618c62daf2SSean Callanan default: 4628c62daf2SSean Callanan return false; 4638c62daf2SSean Callanan case Instruction::IntToPtr: 4648c62daf2SSean Callanan case Instruction::PtrToInt: 4658c62daf2SSean Callanan case Instruction::BitCast: 4668c62daf2SSean Callanan return CanResolveConstant(constant_expr->getOperand(0)); 467b9c1b51eSKate Stone case Instruction::GetElementPtr: { 4688c62daf2SSean Callanan ConstantExpr::const_op_iterator op_cursor = constant_expr->op_begin(); 4698c62daf2SSean Callanan Constant *base = dyn_cast<Constant>(*op_cursor); 4708c62daf2SSean Callanan if (!base) 4718c62daf2SSean Callanan return false; 4728c62daf2SSean Callanan 4738c62daf2SSean Callanan return CanResolveConstant(base); 4748c62daf2SSean Callanan } 4758c62daf2SSean Callanan } 4768c62daf2SSean Callanan } else { 4778c62daf2SSean Callanan return false; 4788c62daf2SSean Callanan } 4798c62daf2SSean Callanan case Value::ConstantPointerNullVal: 4808c62daf2SSean Callanan return true; 4818c62daf2SSean Callanan } 4828c62daf2SSean Callanan } 4838c62daf2SSean Callanan 484b9c1b51eSKate Stone bool IRInterpreter::CanInterpret(llvm::Module &module, llvm::Function &function, 48597206d57SZachary Turner lldb_private::Status &error, 486b9c1b51eSKate Stone const bool support_function_calls) { 487b9c1b51eSKate Stone lldb_private::Log *log( 488b9c1b51eSKate Stone lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); 4893bfdaa2aSSean Callanan 49085fc8761SSean Callanan bool saw_function_with_body = false; 491af4adb07SRaphael Isemann for (Function &f : module) { 492af4adb07SRaphael Isemann if (f.begin() != f.end()) { 493b9c1b51eSKate Stone if (saw_function_with_body) { 49463e5fb76SJonas Devlieghere LLDB_LOGF(log, "More than one function in the module has a body"); 4953f998107SAdrian McCarthy error.SetErrorToGenericError(); 4963f998107SAdrian McCarthy error.SetErrorString(too_many_functions_error); 49785fc8761SSean Callanan return false; 4983f998107SAdrian McCarthy } 49985fc8761SSean Callanan saw_function_with_body = true; 50085fc8761SSean Callanan } 50185fc8761SSean Callanan } 50285fc8761SSean Callanan 503af4adb07SRaphael Isemann for (BasicBlock &bb : function) { 504af4adb07SRaphael Isemann for (Instruction &ii : bb) { 505af4adb07SRaphael Isemann switch (ii.getOpcode()) { 506b9c1b51eSKate Stone default: { 507af4adb07SRaphael Isemann LLDB_LOGF(log, "Unsupported instruction: %s", PrintValue(&ii).c_str()); 50844342735SSean Callanan error.SetErrorToGenericError(); 50944342735SSean Callanan error.SetErrorString(unsupported_opcode_error); 5103bfdaa2aSSean Callanan return false; 5113bfdaa2aSSean Callanan } 5123bfdaa2aSSean Callanan case Instruction::Add: 5133bfdaa2aSSean Callanan case Instruction::Alloca: 5143bfdaa2aSSean Callanan case Instruction::BitCast: 5153bfdaa2aSSean Callanan case Instruction::Br: 5163fe71581SMarianne Mailhot-Sarrasin case Instruction::PHI: 517576a4374SSean Callanan break; 518b9c1b51eSKate Stone case Instruction::Call: { 519af4adb07SRaphael Isemann CallInst *call_inst = dyn_cast<CallInst>(&ii); 520576a4374SSean Callanan 521b9c1b51eSKate Stone if (!call_inst) { 522576a4374SSean Callanan error.SetErrorToGenericError(); 523576a4374SSean Callanan error.SetErrorString(interpreter_internal_error); 524576a4374SSean Callanan return false; 525576a4374SSean Callanan } 526576a4374SSean Callanan 527b9c1b51eSKate Stone if (!CanIgnoreCall(call_inst) && !support_function_calls) { 52863e5fb76SJonas Devlieghere LLDB_LOGF(log, "Unsupported instruction: %s", 529af4adb07SRaphael Isemann PrintValue(&ii).c_str()); 530576a4374SSean Callanan error.SetErrorToGenericError(); 531576a4374SSean Callanan error.SetErrorString(unsupported_opcode_error); 532576a4374SSean Callanan return false; 533576a4374SSean Callanan } 534b9c1b51eSKate Stone } break; 5353bfdaa2aSSean Callanan case Instruction::GetElementPtr: 5363bfdaa2aSSean Callanan break; 537b9c1b51eSKate Stone case Instruction::ICmp: { 538af4adb07SRaphael Isemann ICmpInst *icmp_inst = dyn_cast<ICmpInst>(&ii); 5393bfdaa2aSSean Callanan 540b9c1b51eSKate Stone if (!icmp_inst) { 54144342735SSean Callanan error.SetErrorToGenericError(); 54244342735SSean Callanan error.SetErrorString(interpreter_internal_error); 5433bfdaa2aSSean Callanan return false; 544175a0d04SSean Callanan } 5453bfdaa2aSSean Callanan 546b9c1b51eSKate Stone switch (icmp_inst->getPredicate()) { 547b9c1b51eSKate Stone default: { 54863e5fb76SJonas Devlieghere LLDB_LOGF(log, "Unsupported ICmp predicate: %s", 549af4adb07SRaphael Isemann PrintValue(&ii).c_str()); 550175a0d04SSean Callanan 55144342735SSean Callanan error.SetErrorToGenericError(); 55244342735SSean Callanan error.SetErrorString(unsupported_opcode_error); 5533bfdaa2aSSean Callanan return false; 5543bfdaa2aSSean Callanan } 5553bfdaa2aSSean Callanan case CmpInst::ICMP_EQ: 5563bfdaa2aSSean Callanan case CmpInst::ICMP_NE: 5573bfdaa2aSSean Callanan case CmpInst::ICMP_UGT: 5583bfdaa2aSSean Callanan case CmpInst::ICMP_UGE: 5593bfdaa2aSSean Callanan case CmpInst::ICMP_ULT: 5603bfdaa2aSSean Callanan case CmpInst::ICMP_ULE: 5613bfdaa2aSSean Callanan case CmpInst::ICMP_SGT: 5623bfdaa2aSSean Callanan case CmpInst::ICMP_SGE: 5633bfdaa2aSSean Callanan case CmpInst::ICMP_SLT: 5643bfdaa2aSSean Callanan case CmpInst::ICMP_SLE: 5653bfdaa2aSSean Callanan break; 5663bfdaa2aSSean Callanan } 567b9c1b51eSKate Stone } break; 568087f437bSSean Callanan case Instruction::And: 569087f437bSSean Callanan case Instruction::AShr: 57080c48c10SSean Callanan case Instruction::IntToPtr: 5712abffe05SSean Callanan case Instruction::PtrToInt: 5723bfdaa2aSSean Callanan case Instruction::Load: 573087f437bSSean Callanan case Instruction::LShr: 5743bfdaa2aSSean Callanan case Instruction::Mul: 575087f437bSSean Callanan case Instruction::Or: 5763bfdaa2aSSean Callanan case Instruction::Ret: 5773bfdaa2aSSean Callanan case Instruction::SDiv: 578415422ceSSean Callanan case Instruction::SExt: 579087f437bSSean Callanan case Instruction::Shl: 580f466a6edSSean Callanan case Instruction::SRem: 5813bfdaa2aSSean Callanan case Instruction::Store: 5823bfdaa2aSSean Callanan case Instruction::Sub: 5838c46bacaSSean Callanan case Instruction::Trunc: 5843bfdaa2aSSean Callanan case Instruction::UDiv: 585f466a6edSSean Callanan case Instruction::URem: 586087f437bSSean Callanan case Instruction::Xor: 5871ef77434SSean Callanan case Instruction::ZExt: 5883bfdaa2aSSean Callanan break; 5893bfdaa2aSSean Callanan } 5903fa3e65dSSean Callanan 591af4adb07SRaphael Isemann for (unsigned oi = 0, oe = ii.getNumOperands(); oi != oe; ++oi) { 592af4adb07SRaphael Isemann Value *operand = ii.getOperand(oi); 5933fa3e65dSSean Callanan Type *operand_type = operand->getType(); 5943fa3e65dSSean Callanan 595d405d279SDavide Italiano switch (operand_type->getTypeID()) { 596d405d279SDavide Italiano default: 597d405d279SDavide Italiano break; 5982dea3f12SChristopher Tetreault case Type::FixedVectorTyID: 5992dea3f12SChristopher Tetreault case Type::ScalableVectorTyID: { 60063e5fb76SJonas Devlieghere LLDB_LOGF(log, "Unsupported operand type: %s", 601b9c1b51eSKate Stone PrintType(operand_type).c_str()); 6023fa3e65dSSean Callanan error.SetErrorString(unsupported_operand_error); 6033fa3e65dSSean Callanan return false; 604d405d279SDavide Italiano } 605d405d279SDavide Italiano } 6068c62daf2SSean Callanan 6075f6789efSDavide Italiano // The IR interpreter currently doesn't know about 6085f6789efSDavide Italiano // 128-bit integers. As they're not that frequent, 6095f6789efSDavide Italiano // we can just fall back to the JIT rather than 6105f6789efSDavide Italiano // choking. 6115f6789efSDavide Italiano if (operand_type->getPrimitiveSizeInBits() > 64) { 61263e5fb76SJonas Devlieghere LLDB_LOGF(log, "Unsupported operand type: %s", 6135f6789efSDavide Italiano PrintType(operand_type).c_str()); 6145f6789efSDavide Italiano error.SetErrorString(unsupported_operand_error); 6155f6789efSDavide Italiano return false; 6165f6789efSDavide Italiano } 6175f6789efSDavide Italiano 618d405d279SDavide Italiano if (Constant *constant = llvm::dyn_cast<Constant>(operand)) { 619b9c1b51eSKate Stone if (!CanResolveConstant(constant)) { 62063e5fb76SJonas Devlieghere LLDB_LOGF(log, "Unsupported constant: %s", 621b9c1b51eSKate Stone PrintValue(constant).c_str()); 6228c62daf2SSean Callanan error.SetErrorString(unsupported_operand_error); 6238c62daf2SSean Callanan return false; 6248c62daf2SSean Callanan } 6258c62daf2SSean Callanan } 6263fa3e65dSSean Callanan } 6273fa3e65dSSean Callanan } 6283fa3e65dSSean Callanan } 6293bfdaa2aSSean Callanan 6303f998107SAdrian McCarthy return true; 6313f998107SAdrian McCarthy } 63214cb2aaaSSean Callanan 633b9c1b51eSKate Stone bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function, 6341582ee68SSean Callanan llvm::ArrayRef<lldb::addr_t> args, 6357071c5fdSTed Woodward lldb_private::IRExecutionUnit &execution_unit, 63697206d57SZachary Turner lldb_private::Status &error, 637df56540aSSean Callanan lldb::addr_t stack_frame_bottom, 63890ff7911SEwan Crawford lldb::addr_t stack_frame_top, 639b9c1b51eSKate Stone lldb_private::ExecutionContext &exe_ctx) { 640b9c1b51eSKate Stone lldb_private::Log *log( 641b9c1b51eSKate Stone lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); 64214cb2aaaSSean Callanan 643b9c1b51eSKate Stone if (log) { 6441582ee68SSean Callanan std::string s; 6451582ee68SSean Callanan raw_string_ostream oss(s); 6461582ee68SSean Callanan 647248a1305SKonrad Kleine module.print(oss, nullptr); 6481582ee68SSean Callanan 6491582ee68SSean Callanan oss.flush(); 6501582ee68SSean Callanan 65163e5fb76SJonas Devlieghere LLDB_LOGF(log, "Module as passed in to IRInterpreter::Interpret: \n\"%s\"", 652b9c1b51eSKate Stone s.c_str()); 6531582ee68SSean Callanan } 6541582ee68SSean Callanan 65514cb2aaaSSean Callanan DataLayout data_layout(&module); 65614cb2aaaSSean Callanan 657b9c1b51eSKate Stone InterpreterStackFrame frame(data_layout, execution_unit, stack_frame_bottom, 658b9c1b51eSKate Stone stack_frame_top); 65914cb2aaaSSean Callanan 660b9c1b51eSKate Stone if (frame.m_frame_process_address == LLDB_INVALID_ADDRESS) { 6611582ee68SSean Callanan error.SetErrorString("Couldn't allocate stack frame"); 6621582ee68SSean Callanan } 6631582ee68SSean Callanan 6641582ee68SSean Callanan int arg_index = 0; 6651582ee68SSean Callanan 666b9c1b51eSKate Stone for (llvm::Function::arg_iterator ai = function.arg_begin(), 667b9c1b51eSKate Stone ae = function.arg_end(); 668b9c1b51eSKate Stone ai != ae; ++ai, ++arg_index) { 669b9c1b51eSKate Stone if (args.size() <= static_cast<size_t>(arg_index)) { 6701582ee68SSean Callanan error.SetErrorString("Not enough arguments passed in to function"); 6711582ee68SSean Callanan return false; 6721582ee68SSean Callanan } 6731582ee68SSean Callanan 6741582ee68SSean Callanan lldb::addr_t ptr = args[arg_index]; 6751582ee68SSean Callanan 67633e43ca6SDuncan P. N. Exon Smith frame.MakeArgument(&*ai, ptr); 6771582ee68SSean Callanan } 6781582ee68SSean Callanan 67914cb2aaaSSean Callanan uint32_t num_insts = 0; 68014cb2aaaSSean Callanan 68133e43ca6SDuncan P. N. Exon Smith frame.Jump(&function.front()); 68214cb2aaaSSean Callanan 683b9c1b51eSKate Stone while (frame.m_ii != frame.m_ie && (++num_insts < 4096)) { 68433e43ca6SDuncan P. N. Exon Smith const Instruction *inst = &*frame.m_ii; 68514cb2aaaSSean Callanan 68663e5fb76SJonas Devlieghere LLDB_LOGF(log, "Interpreting %s", PrintValue(inst).c_str()); 68714cb2aaaSSean Callanan 688b9c1b51eSKate Stone switch (inst->getOpcode()) { 68914cb2aaaSSean Callanan default: 69014cb2aaaSSean Callanan break; 691576a4374SSean Callanan 69214cb2aaaSSean Callanan case Instruction::Add: 69314cb2aaaSSean Callanan case Instruction::Sub: 69414cb2aaaSSean Callanan case Instruction::Mul: 69514cb2aaaSSean Callanan case Instruction::SDiv: 69614cb2aaaSSean Callanan case Instruction::UDiv: 69714cb2aaaSSean Callanan case Instruction::SRem: 69814cb2aaaSSean Callanan case Instruction::URem: 69914cb2aaaSSean Callanan case Instruction::Shl: 70014cb2aaaSSean Callanan case Instruction::LShr: 70114cb2aaaSSean Callanan case Instruction::AShr: 70214cb2aaaSSean Callanan case Instruction::And: 70314cb2aaaSSean Callanan case Instruction::Or: 704b9c1b51eSKate Stone case Instruction::Xor: { 70514cb2aaaSSean Callanan const BinaryOperator *bin_op = dyn_cast<BinaryOperator>(inst); 70614cb2aaaSSean Callanan 707b9c1b51eSKate Stone if (!bin_op) { 70863e5fb76SJonas Devlieghere LLDB_LOGF( 70963e5fb76SJonas Devlieghere log, 710b9c1b51eSKate Stone "getOpcode() returns %s, but instruction is not a BinaryOperator", 711b9c1b51eSKate Stone inst->getOpcodeName()); 71214cb2aaaSSean Callanan error.SetErrorToGenericError(); 71314cb2aaaSSean Callanan error.SetErrorString(interpreter_internal_error); 71414cb2aaaSSean Callanan return false; 71514cb2aaaSSean Callanan } 71614cb2aaaSSean Callanan 71714cb2aaaSSean Callanan Value *lhs = inst->getOperand(0); 71814cb2aaaSSean Callanan Value *rhs = inst->getOperand(1); 71914cb2aaaSSean Callanan 72014cb2aaaSSean Callanan lldb_private::Scalar L; 72114cb2aaaSSean Callanan lldb_private::Scalar R; 72214cb2aaaSSean Callanan 723b9c1b51eSKate Stone if (!frame.EvaluateValue(L, lhs, module)) { 72463e5fb76SJonas Devlieghere LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(lhs).c_str()); 72514cb2aaaSSean Callanan error.SetErrorToGenericError(); 72614cb2aaaSSean Callanan error.SetErrorString(bad_value_error); 72714cb2aaaSSean Callanan return false; 72814cb2aaaSSean Callanan } 72914cb2aaaSSean Callanan 730b9c1b51eSKate Stone if (!frame.EvaluateValue(R, rhs, module)) { 73163e5fb76SJonas Devlieghere LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(rhs).c_str()); 73214cb2aaaSSean Callanan error.SetErrorToGenericError(); 73314cb2aaaSSean Callanan error.SetErrorString(bad_value_error); 73414cb2aaaSSean Callanan return false; 73514cb2aaaSSean Callanan } 73614cb2aaaSSean Callanan 73714cb2aaaSSean Callanan lldb_private::Scalar result; 73814cb2aaaSSean Callanan 739b9c1b51eSKate Stone switch (inst->getOpcode()) { 74014cb2aaaSSean Callanan default: 74114cb2aaaSSean Callanan break; 74214cb2aaaSSean Callanan case Instruction::Add: 74314cb2aaaSSean Callanan result = L + R; 74414cb2aaaSSean Callanan break; 74514cb2aaaSSean Callanan case Instruction::Mul: 74614cb2aaaSSean Callanan result = L * R; 74714cb2aaaSSean Callanan break; 74814cb2aaaSSean Callanan case Instruction::Sub: 74914cb2aaaSSean Callanan result = L - R; 75014cb2aaaSSean Callanan break; 75114cb2aaaSSean Callanan case Instruction::SDiv: 7520b342b6dSSean Callanan L.MakeSigned(); 7530b342b6dSSean Callanan R.MakeSigned(); 75414cb2aaaSSean Callanan result = L / R; 75514cb2aaaSSean Callanan break; 75614cb2aaaSSean Callanan case Instruction::UDiv: 7579521ad2aSUlrich Weigand L.MakeUnsigned(); 7589521ad2aSUlrich Weigand R.MakeUnsigned(); 7599521ad2aSUlrich Weigand result = L / R; 76014cb2aaaSSean Callanan break; 76114cb2aaaSSean Callanan case Instruction::SRem: 7620b342b6dSSean Callanan L.MakeSigned(); 7630b342b6dSSean Callanan R.MakeSigned(); 76414cb2aaaSSean Callanan result = L % R; 76514cb2aaaSSean Callanan break; 76614cb2aaaSSean Callanan case Instruction::URem: 7679521ad2aSUlrich Weigand L.MakeUnsigned(); 7689521ad2aSUlrich Weigand R.MakeUnsigned(); 7699521ad2aSUlrich Weigand result = L % R; 77014cb2aaaSSean Callanan break; 77114cb2aaaSSean Callanan case Instruction::Shl: 77214cb2aaaSSean Callanan result = L << R; 77314cb2aaaSSean Callanan break; 77414cb2aaaSSean Callanan case Instruction::AShr: 77514cb2aaaSSean Callanan result = L >> R; 77614cb2aaaSSean Callanan break; 77714cb2aaaSSean Callanan case Instruction::LShr: 77814cb2aaaSSean Callanan result = L; 77914cb2aaaSSean Callanan result.ShiftRightLogical(R); 78014cb2aaaSSean Callanan break; 78114cb2aaaSSean Callanan case Instruction::And: 78214cb2aaaSSean Callanan result = L & R; 78314cb2aaaSSean Callanan break; 78414cb2aaaSSean Callanan case Instruction::Or: 78514cb2aaaSSean Callanan result = L | R; 78614cb2aaaSSean Callanan break; 78714cb2aaaSSean Callanan case Instruction::Xor: 78814cb2aaaSSean Callanan result = L ^ R; 78914cb2aaaSSean Callanan break; 79014cb2aaaSSean Callanan } 79114cb2aaaSSean Callanan 79214cb2aaaSSean Callanan frame.AssignValue(inst, result, module); 79314cb2aaaSSean Callanan 794b9c1b51eSKate Stone if (log) { 79563e5fb76SJonas Devlieghere LLDB_LOGF(log, "Interpreted a %s", inst->getOpcodeName()); 79663e5fb76SJonas Devlieghere LLDB_LOGF(log, " L : %s", frame.SummarizeValue(lhs).c_str()); 79763e5fb76SJonas Devlieghere LLDB_LOGF(log, " R : %s", frame.SummarizeValue(rhs).c_str()); 79863e5fb76SJonas Devlieghere LLDB_LOGF(log, " = : %s", frame.SummarizeValue(inst).c_str()); 79914cb2aaaSSean Callanan } 800b9c1b51eSKate Stone } break; 801b9c1b51eSKate Stone case Instruction::Alloca: { 802f18370feSRaphael Isemann const AllocaInst *alloca_inst = cast<AllocaInst>(inst); 80314cb2aaaSSean Callanan 804b9c1b51eSKate Stone if (alloca_inst->isArrayAllocation()) { 80563e5fb76SJonas Devlieghere LLDB_LOGF(log, 806b9c1b51eSKate Stone "AllocaInsts are not handled if isArrayAllocation() is true"); 80714cb2aaaSSean Callanan error.SetErrorToGenericError(); 80814cb2aaaSSean Callanan error.SetErrorString(unsupported_opcode_error); 80914cb2aaaSSean Callanan return false; 81014cb2aaaSSean Callanan } 81114cb2aaaSSean Callanan 81214cb2aaaSSean Callanan // The semantics of Alloca are: 813b9c1b51eSKate Stone // Create a region R of virtual memory of type T, backed by a data 814b9c1b51eSKate Stone // buffer 815b9c1b51eSKate Stone // Create a region P of virtual memory of type T*, backed by a data 816b9c1b51eSKate Stone // buffer 81714cb2aaaSSean Callanan // Write the virtual address of R into P 81814cb2aaaSSean Callanan 81914cb2aaaSSean Callanan Type *T = alloca_inst->getAllocatedType(); 82014cb2aaaSSean Callanan Type *Tptr = alloca_inst->getType(); 82114cb2aaaSSean Callanan 82214cb2aaaSSean Callanan lldb::addr_t R = frame.Malloc(T); 82314cb2aaaSSean Callanan 824b9c1b51eSKate Stone if (R == LLDB_INVALID_ADDRESS) { 82563e5fb76SJonas Devlieghere LLDB_LOGF(log, "Couldn't allocate memory for an AllocaInst"); 82614cb2aaaSSean Callanan error.SetErrorToGenericError(); 82714cb2aaaSSean Callanan error.SetErrorString(memory_allocation_error); 82814cb2aaaSSean Callanan return false; 82914cb2aaaSSean Callanan } 83014cb2aaaSSean Callanan 83114cb2aaaSSean Callanan lldb::addr_t P = frame.Malloc(Tptr); 83214cb2aaaSSean Callanan 833b9c1b51eSKate Stone if (P == LLDB_INVALID_ADDRESS) { 83463e5fb76SJonas Devlieghere LLDB_LOGF(log, 83563e5fb76SJonas Devlieghere "Couldn't allocate the result pointer for an AllocaInst"); 83614cb2aaaSSean Callanan error.SetErrorToGenericError(); 83714cb2aaaSSean Callanan error.SetErrorString(memory_allocation_error); 83814cb2aaaSSean Callanan return false; 83914cb2aaaSSean Callanan } 84014cb2aaaSSean Callanan 84197206d57SZachary Turner lldb_private::Status write_error; 84214cb2aaaSSean Callanan 8437071c5fdSTed Woodward execution_unit.WritePointerToMemory(P, R, write_error); 84414cb2aaaSSean Callanan 845b9c1b51eSKate Stone if (!write_error.Success()) { 84663e5fb76SJonas Devlieghere LLDB_LOGF(log, "Couldn't write the result pointer for an AllocaInst"); 84714cb2aaaSSean Callanan error.SetErrorToGenericError(); 84814cb2aaaSSean Callanan error.SetErrorString(memory_write_error); 84997206d57SZachary Turner lldb_private::Status free_error; 8507071c5fdSTed Woodward execution_unit.Free(P, free_error); 8517071c5fdSTed Woodward execution_unit.Free(R, free_error); 85214cb2aaaSSean Callanan return false; 85314cb2aaaSSean Callanan } 85414cb2aaaSSean Callanan 85514cb2aaaSSean Callanan frame.m_values[alloca_inst] = P; 85614cb2aaaSSean Callanan 857b9c1b51eSKate Stone if (log) { 85863e5fb76SJonas Devlieghere LLDB_LOGF(log, "Interpreted an AllocaInst"); 85963e5fb76SJonas Devlieghere LLDB_LOGF(log, " R : 0x%" PRIx64, R); 86063e5fb76SJonas Devlieghere LLDB_LOGF(log, " P : 0x%" PRIx64, P); 86114cb2aaaSSean Callanan } 862b9c1b51eSKate Stone } break; 86314cb2aaaSSean Callanan case Instruction::BitCast: 864b9c1b51eSKate Stone case Instruction::ZExt: { 865f18370feSRaphael Isemann const CastInst *cast_inst = cast<CastInst>(inst); 86614cb2aaaSSean Callanan 86714cb2aaaSSean Callanan Value *source = cast_inst->getOperand(0); 86814cb2aaaSSean Callanan 86914cb2aaaSSean Callanan lldb_private::Scalar S; 87014cb2aaaSSean Callanan 871b9c1b51eSKate Stone if (!frame.EvaluateValue(S, source, module)) { 87263e5fb76SJonas Devlieghere LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(source).c_str()); 87314cb2aaaSSean Callanan error.SetErrorToGenericError(); 87414cb2aaaSSean Callanan error.SetErrorString(bad_value_error); 87514cb2aaaSSean Callanan return false; 87614cb2aaaSSean Callanan } 87714cb2aaaSSean Callanan 87814cb2aaaSSean Callanan frame.AssignValue(inst, S, module); 879b9c1b51eSKate Stone } break; 880b9c1b51eSKate Stone case Instruction::SExt: { 881f18370feSRaphael Isemann const CastInst *cast_inst = cast<CastInst>(inst); 882415422ceSSean Callanan 883415422ceSSean Callanan Value *source = cast_inst->getOperand(0); 884415422ceSSean Callanan 885415422ceSSean Callanan lldb_private::Scalar S; 886415422ceSSean Callanan 887b9c1b51eSKate Stone if (!frame.EvaluateValue(S, source, module)) { 88863e5fb76SJonas Devlieghere LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(source).c_str()); 889415422ceSSean Callanan error.SetErrorToGenericError(); 890415422ceSSean Callanan error.SetErrorString(bad_value_error); 891415422ceSSean Callanan return false; 892415422ceSSean Callanan } 893415422ceSSean Callanan 894415422ceSSean Callanan S.MakeSigned(); 895415422ceSSean Callanan 896415422ceSSean Callanan lldb_private::Scalar S_signextend(S.SLongLong()); 897415422ceSSean Callanan 898415422ceSSean Callanan frame.AssignValue(inst, S_signextend, module); 899b9c1b51eSKate Stone } break; 900b9c1b51eSKate Stone case Instruction::Br: { 901f18370feSRaphael Isemann const BranchInst *br_inst = cast<BranchInst>(inst); 90214cb2aaaSSean Callanan 903b9c1b51eSKate Stone if (br_inst->isConditional()) { 90414cb2aaaSSean Callanan Value *condition = br_inst->getCondition(); 90514cb2aaaSSean Callanan 90614cb2aaaSSean Callanan lldb_private::Scalar C; 90714cb2aaaSSean Callanan 908b9c1b51eSKate Stone if (!frame.EvaluateValue(C, condition, module)) { 90963e5fb76SJonas Devlieghere LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(condition).c_str()); 91014cb2aaaSSean Callanan error.SetErrorToGenericError(); 91114cb2aaaSSean Callanan error.SetErrorString(bad_value_error); 91214cb2aaaSSean Callanan return false; 91314cb2aaaSSean Callanan } 91414cb2aaaSSean Callanan 9159521ad2aSUlrich Weigand if (!C.IsZero()) 91614cb2aaaSSean Callanan frame.Jump(br_inst->getSuccessor(0)); 91714cb2aaaSSean Callanan else 91814cb2aaaSSean Callanan frame.Jump(br_inst->getSuccessor(1)); 91914cb2aaaSSean Callanan 920b9c1b51eSKate Stone if (log) { 92163e5fb76SJonas Devlieghere LLDB_LOGF(log, "Interpreted a BrInst with a condition"); 92263e5fb76SJonas Devlieghere LLDB_LOGF(log, " cond : %s", 92363e5fb76SJonas Devlieghere frame.SummarizeValue(condition).c_str()); 92414cb2aaaSSean Callanan } 925b9c1b51eSKate Stone } else { 92614cb2aaaSSean Callanan frame.Jump(br_inst->getSuccessor(0)); 92714cb2aaaSSean Callanan 928b9c1b51eSKate Stone if (log) { 92963e5fb76SJonas Devlieghere LLDB_LOGF(log, "Interpreted a BrInst with no condition"); 93014cb2aaaSSean Callanan } 93114cb2aaaSSean Callanan } 93214cb2aaaSSean Callanan } 93314cb2aaaSSean Callanan continue; 934b9c1b51eSKate Stone case Instruction::PHI: { 935f18370feSRaphael Isemann const PHINode *phi_inst = cast<PHINode>(inst); 936b9c1b51eSKate Stone if (!frame.m_prev_bb) { 93763e5fb76SJonas Devlieghere LLDB_LOGF(log, 93863e5fb76SJonas Devlieghere "Encountered PHI node without having jumped from another " 939b9c1b51eSKate Stone "basic block"); 9403fe71581SMarianne Mailhot-Sarrasin error.SetErrorToGenericError(); 9413fe71581SMarianne Mailhot-Sarrasin error.SetErrorString(interpreter_internal_error); 9423fe71581SMarianne Mailhot-Sarrasin return false; 9433fe71581SMarianne Mailhot-Sarrasin } 9443fe71581SMarianne Mailhot-Sarrasin 9453fe71581SMarianne Mailhot-Sarrasin Value *value = phi_inst->getIncomingValueForBlock(frame.m_prev_bb); 9463fe71581SMarianne Mailhot-Sarrasin lldb_private::Scalar result; 947b9c1b51eSKate Stone if (!frame.EvaluateValue(result, value, module)) { 94863e5fb76SJonas Devlieghere LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(value).c_str()); 9493fe71581SMarianne Mailhot-Sarrasin error.SetErrorToGenericError(); 9503fe71581SMarianne Mailhot-Sarrasin error.SetErrorString(bad_value_error); 9513fe71581SMarianne Mailhot-Sarrasin return false; 9523fe71581SMarianne Mailhot-Sarrasin } 9533fe71581SMarianne Mailhot-Sarrasin frame.AssignValue(inst, result, module); 9543fe71581SMarianne Mailhot-Sarrasin 955b9c1b51eSKate Stone if (log) { 95663e5fb76SJonas Devlieghere LLDB_LOGF(log, "Interpreted a %s", inst->getOpcodeName()); 95763e5fb76SJonas Devlieghere LLDB_LOGF(log, " Incoming value : %s", 958b9c1b51eSKate Stone frame.SummarizeValue(value).c_str()); 9593fe71581SMarianne Mailhot-Sarrasin } 960b9c1b51eSKate Stone } break; 961b9c1b51eSKate Stone case Instruction::GetElementPtr: { 962f18370feSRaphael Isemann const GetElementPtrInst *gep_inst = cast<GetElementPtrInst>(inst); 96314cb2aaaSSean Callanan 96414cb2aaaSSean Callanan const Value *pointer_operand = gep_inst->getPointerOperand(); 965d05b8992SEduard Burtescu Type *src_elem_ty = gep_inst->getSourceElementType(); 96614cb2aaaSSean Callanan 96714cb2aaaSSean Callanan lldb_private::Scalar P; 96814cb2aaaSSean Callanan 969b9c1b51eSKate Stone if (!frame.EvaluateValue(P, pointer_operand, module)) { 97063e5fb76SJonas Devlieghere LLDB_LOGF(log, "Couldn't evaluate %s", 971b9c1b51eSKate Stone PrintValue(pointer_operand).c_str()); 97214cb2aaaSSean Callanan error.SetErrorToGenericError(); 97314cb2aaaSSean Callanan error.SetErrorString(bad_value_error); 97414cb2aaaSSean Callanan return false; 97514cb2aaaSSean Callanan } 97614cb2aaaSSean Callanan 97714cb2aaaSSean Callanan typedef SmallVector<Value *, 8> IndexVector; 97814cb2aaaSSean Callanan typedef IndexVector::iterator IndexIterator; 97914cb2aaaSSean Callanan 98014cb2aaaSSean Callanan SmallVector<Value *, 8> indices(gep_inst->idx_begin(), 98114cb2aaaSSean Callanan gep_inst->idx_end()); 98214cb2aaaSSean Callanan 98314cb2aaaSSean Callanan SmallVector<Value *, 8> const_indices; 98414cb2aaaSSean Callanan 985b9c1b51eSKate Stone for (IndexIterator ii = indices.begin(), ie = indices.end(); ii != ie; 986b9c1b51eSKate Stone ++ii) { 98714cb2aaaSSean Callanan ConstantInt *constant_index = dyn_cast<ConstantInt>(*ii); 98814cb2aaaSSean Callanan 989b9c1b51eSKate Stone if (!constant_index) { 99014cb2aaaSSean Callanan lldb_private::Scalar I; 99114cb2aaaSSean Callanan 992b9c1b51eSKate Stone if (!frame.EvaluateValue(I, *ii, module)) { 99363e5fb76SJonas Devlieghere LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(*ii).c_str()); 99414cb2aaaSSean Callanan error.SetErrorToGenericError(); 99514cb2aaaSSean Callanan error.SetErrorString(bad_value_error); 99614cb2aaaSSean Callanan return false; 99714cb2aaaSSean Callanan } 99814cb2aaaSSean Callanan 99963e5fb76SJonas Devlieghere LLDB_LOGF(log, "Evaluated constant index %s as %llu", 100063e5fb76SJonas Devlieghere PrintValue(*ii).c_str(), I.ULongLong(LLDB_INVALID_ADDRESS)); 100114cb2aaaSSean Callanan 1002b9c1b51eSKate Stone constant_index = cast<ConstantInt>(ConstantInt::get( 1003b9c1b51eSKate Stone (*ii)->getType(), I.ULongLong(LLDB_INVALID_ADDRESS))); 100414cb2aaaSSean Callanan } 100514cb2aaaSSean Callanan 100614cb2aaaSSean Callanan const_indices.push_back(constant_index); 100714cb2aaaSSean Callanan } 100814cb2aaaSSean Callanan 1009b9c1b51eSKate Stone uint64_t offset = 1010b9c1b51eSKate Stone data_layout.getIndexedOffsetInType(src_elem_ty, const_indices); 101114cb2aaaSSean Callanan 101214cb2aaaSSean Callanan lldb_private::Scalar Poffset = P + offset; 101314cb2aaaSSean Callanan 101414cb2aaaSSean Callanan frame.AssignValue(inst, Poffset, module); 101514cb2aaaSSean Callanan 1016b9c1b51eSKate Stone if (log) { 101763e5fb76SJonas Devlieghere LLDB_LOGF(log, "Interpreted a GetElementPtrInst"); 101863e5fb76SJonas Devlieghere LLDB_LOGF(log, " P : %s", 1019b9c1b51eSKate Stone frame.SummarizeValue(pointer_operand).c_str()); 102063e5fb76SJonas Devlieghere LLDB_LOGF(log, " Poffset : %s", frame.SummarizeValue(inst).c_str()); 102114cb2aaaSSean Callanan } 1022b9c1b51eSKate Stone } break; 1023b9c1b51eSKate Stone case Instruction::ICmp: { 1024f18370feSRaphael Isemann const ICmpInst *icmp_inst = cast<ICmpInst>(inst); 102514cb2aaaSSean Callanan 102614cb2aaaSSean Callanan CmpInst::Predicate predicate = icmp_inst->getPredicate(); 102714cb2aaaSSean Callanan 102814cb2aaaSSean Callanan Value *lhs = inst->getOperand(0); 102914cb2aaaSSean Callanan Value *rhs = inst->getOperand(1); 103014cb2aaaSSean Callanan 103114cb2aaaSSean Callanan lldb_private::Scalar L; 103214cb2aaaSSean Callanan lldb_private::Scalar R; 103314cb2aaaSSean Callanan 1034b9c1b51eSKate Stone if (!frame.EvaluateValue(L, lhs, module)) { 103563e5fb76SJonas Devlieghere LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(lhs).c_str()); 103614cb2aaaSSean Callanan error.SetErrorToGenericError(); 103714cb2aaaSSean Callanan error.SetErrorString(bad_value_error); 103814cb2aaaSSean Callanan return false; 103914cb2aaaSSean Callanan } 104014cb2aaaSSean Callanan 1041b9c1b51eSKate Stone if (!frame.EvaluateValue(R, rhs, module)) { 104263e5fb76SJonas Devlieghere LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(rhs).c_str()); 104314cb2aaaSSean Callanan error.SetErrorToGenericError(); 104414cb2aaaSSean Callanan error.SetErrorString(bad_value_error); 104514cb2aaaSSean Callanan return false; 104614cb2aaaSSean Callanan } 104714cb2aaaSSean Callanan 104814cb2aaaSSean Callanan lldb_private::Scalar result; 104914cb2aaaSSean Callanan 1050b9c1b51eSKate Stone switch (predicate) { 105114cb2aaaSSean Callanan default: 105214cb2aaaSSean Callanan return false; 105314cb2aaaSSean Callanan case CmpInst::ICMP_EQ: 105414cb2aaaSSean Callanan result = (L == R); 105514cb2aaaSSean Callanan break; 105614cb2aaaSSean Callanan case CmpInst::ICMP_NE: 105714cb2aaaSSean Callanan result = (L != R); 105814cb2aaaSSean Callanan break; 105914cb2aaaSSean Callanan case CmpInst::ICMP_UGT: 10609521ad2aSUlrich Weigand L.MakeUnsigned(); 10619521ad2aSUlrich Weigand R.MakeUnsigned(); 10629521ad2aSUlrich Weigand result = (L > R); 106314cb2aaaSSean Callanan break; 106414cb2aaaSSean Callanan case CmpInst::ICMP_UGE: 10659521ad2aSUlrich Weigand L.MakeUnsigned(); 10669521ad2aSUlrich Weigand R.MakeUnsigned(); 10679521ad2aSUlrich Weigand result = (L >= R); 106814cb2aaaSSean Callanan break; 106914cb2aaaSSean Callanan case CmpInst::ICMP_ULT: 10709521ad2aSUlrich Weigand L.MakeUnsigned(); 10719521ad2aSUlrich Weigand R.MakeUnsigned(); 10729521ad2aSUlrich Weigand result = (L < R); 107314cb2aaaSSean Callanan break; 107414cb2aaaSSean Callanan case CmpInst::ICMP_ULE: 10759521ad2aSUlrich Weigand L.MakeUnsigned(); 10769521ad2aSUlrich Weigand R.MakeUnsigned(); 10779521ad2aSUlrich Weigand result = (L <= R); 107814cb2aaaSSean Callanan break; 107914cb2aaaSSean Callanan case CmpInst::ICMP_SGT: 10800b342b6dSSean Callanan L.MakeSigned(); 10810b342b6dSSean Callanan R.MakeSigned(); 108214cb2aaaSSean Callanan result = (L > R); 108314cb2aaaSSean Callanan break; 108414cb2aaaSSean Callanan case CmpInst::ICMP_SGE: 10850b342b6dSSean Callanan L.MakeSigned(); 10860b342b6dSSean Callanan R.MakeSigned(); 108714cb2aaaSSean Callanan result = (L >= R); 108814cb2aaaSSean Callanan break; 108914cb2aaaSSean Callanan case CmpInst::ICMP_SLT: 10900b342b6dSSean Callanan L.MakeSigned(); 10910b342b6dSSean Callanan R.MakeSigned(); 109214cb2aaaSSean Callanan result = (L < R); 109314cb2aaaSSean Callanan break; 109414cb2aaaSSean Callanan case CmpInst::ICMP_SLE: 10950b342b6dSSean Callanan L.MakeSigned(); 10960b342b6dSSean Callanan R.MakeSigned(); 109714cb2aaaSSean Callanan result = (L <= R); 109814cb2aaaSSean Callanan break; 109914cb2aaaSSean Callanan } 110014cb2aaaSSean Callanan 110114cb2aaaSSean Callanan frame.AssignValue(inst, result, module); 110214cb2aaaSSean Callanan 1103b9c1b51eSKate Stone if (log) { 110463e5fb76SJonas Devlieghere LLDB_LOGF(log, "Interpreted an ICmpInst"); 110563e5fb76SJonas Devlieghere LLDB_LOGF(log, " L : %s", frame.SummarizeValue(lhs).c_str()); 110663e5fb76SJonas Devlieghere LLDB_LOGF(log, " R : %s", frame.SummarizeValue(rhs).c_str()); 110763e5fb76SJonas Devlieghere LLDB_LOGF(log, " = : %s", frame.SummarizeValue(inst).c_str()); 110814cb2aaaSSean Callanan } 1109b9c1b51eSKate Stone } break; 1110b9c1b51eSKate Stone case Instruction::IntToPtr: { 1111f18370feSRaphael Isemann const IntToPtrInst *int_to_ptr_inst = cast<IntToPtrInst>(inst); 111214cb2aaaSSean Callanan 111314cb2aaaSSean Callanan Value *src_operand = int_to_ptr_inst->getOperand(0); 111414cb2aaaSSean Callanan 111514cb2aaaSSean Callanan lldb_private::Scalar I; 111614cb2aaaSSean Callanan 1117b9c1b51eSKate Stone if (!frame.EvaluateValue(I, src_operand, module)) { 111863e5fb76SJonas Devlieghere LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(src_operand).c_str()); 111914cb2aaaSSean Callanan error.SetErrorToGenericError(); 112014cb2aaaSSean Callanan error.SetErrorString(bad_value_error); 112114cb2aaaSSean Callanan return false; 112214cb2aaaSSean Callanan } 112314cb2aaaSSean Callanan 112414cb2aaaSSean Callanan frame.AssignValue(inst, I, module); 112514cb2aaaSSean Callanan 1126b9c1b51eSKate Stone if (log) { 112763e5fb76SJonas Devlieghere LLDB_LOGF(log, "Interpreted an IntToPtr"); 112863e5fb76SJonas Devlieghere LLDB_LOGF(log, " Src : %s", frame.SummarizeValue(src_operand).c_str()); 112963e5fb76SJonas Devlieghere LLDB_LOGF(log, " = : %s", frame.SummarizeValue(inst).c_str()); 113014cb2aaaSSean Callanan } 1131b9c1b51eSKate Stone } break; 1132b9c1b51eSKate Stone case Instruction::PtrToInt: { 1133f18370feSRaphael Isemann const PtrToIntInst *ptr_to_int_inst = cast<PtrToIntInst>(inst); 113414cb2aaaSSean Callanan 113514cb2aaaSSean Callanan Value *src_operand = ptr_to_int_inst->getOperand(0); 113614cb2aaaSSean Callanan 113714cb2aaaSSean Callanan lldb_private::Scalar I; 113814cb2aaaSSean Callanan 1139b9c1b51eSKate Stone if (!frame.EvaluateValue(I, src_operand, module)) { 114063e5fb76SJonas Devlieghere LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(src_operand).c_str()); 114114cb2aaaSSean Callanan error.SetErrorToGenericError(); 114214cb2aaaSSean Callanan error.SetErrorString(bad_value_error); 114314cb2aaaSSean Callanan return false; 114414cb2aaaSSean Callanan } 114514cb2aaaSSean Callanan 114614cb2aaaSSean Callanan frame.AssignValue(inst, I, module); 114714cb2aaaSSean Callanan 1148b9c1b51eSKate Stone if (log) { 114963e5fb76SJonas Devlieghere LLDB_LOGF(log, "Interpreted a PtrToInt"); 115063e5fb76SJonas Devlieghere LLDB_LOGF(log, " Src : %s", frame.SummarizeValue(src_operand).c_str()); 115163e5fb76SJonas Devlieghere LLDB_LOGF(log, " = : %s", frame.SummarizeValue(inst).c_str()); 115214cb2aaaSSean Callanan } 1153b9c1b51eSKate Stone } break; 1154b9c1b51eSKate Stone case Instruction::Trunc: { 1155f18370feSRaphael Isemann const TruncInst *trunc_inst = cast<TruncInst>(inst); 11568c46bacaSSean Callanan 11578c46bacaSSean Callanan Value *src_operand = trunc_inst->getOperand(0); 11588c46bacaSSean Callanan 11598c46bacaSSean Callanan lldb_private::Scalar I; 11608c46bacaSSean Callanan 1161b9c1b51eSKate Stone if (!frame.EvaluateValue(I, src_operand, module)) { 116263e5fb76SJonas Devlieghere LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(src_operand).c_str()); 11638c46bacaSSean Callanan error.SetErrorToGenericError(); 11648c46bacaSSean Callanan error.SetErrorString(bad_value_error); 11658c46bacaSSean Callanan return false; 11668c46bacaSSean Callanan } 11678c46bacaSSean Callanan 11688c46bacaSSean Callanan frame.AssignValue(inst, I, module); 11698c46bacaSSean Callanan 1170b9c1b51eSKate Stone if (log) { 117163e5fb76SJonas Devlieghere LLDB_LOGF(log, "Interpreted a Trunc"); 117263e5fb76SJonas Devlieghere LLDB_LOGF(log, " Src : %s", frame.SummarizeValue(src_operand).c_str()); 117363e5fb76SJonas Devlieghere LLDB_LOGF(log, " = : %s", frame.SummarizeValue(inst).c_str()); 11748c46bacaSSean Callanan } 1175b9c1b51eSKate Stone } break; 1176b9c1b51eSKate Stone case Instruction::Load: { 1177f18370feSRaphael Isemann const LoadInst *load_inst = cast<LoadInst>(inst); 117814cb2aaaSSean Callanan 117914cb2aaaSSean Callanan // The semantics of Load are: 118014cb2aaaSSean Callanan // Create a region D that will contain the loaded data 118114cb2aaaSSean Callanan // Resolve the region P containing a pointer 118214cb2aaaSSean Callanan // Dereference P to get the region R that the data should be loaded from 118314cb2aaaSSean Callanan // Transfer a unit of type type(D) from R to D 118414cb2aaaSSean Callanan 118514cb2aaaSSean Callanan const Value *pointer_operand = load_inst->getPointerOperand(); 118614cb2aaaSSean Callanan 118714cb2aaaSSean Callanan Type *pointer_ty = pointer_operand->getType(); 118814cb2aaaSSean Callanan PointerType *pointer_ptr_ty = dyn_cast<PointerType>(pointer_ty); 1189b9c1b51eSKate Stone if (!pointer_ptr_ty) { 119063e5fb76SJonas Devlieghere LLDB_LOGF(log, "getPointerOperand()->getType() is not a PointerType"); 119114cb2aaaSSean Callanan error.SetErrorToGenericError(); 119214cb2aaaSSean Callanan error.SetErrorString(interpreter_internal_error); 119314cb2aaaSSean Callanan return false; 119414cb2aaaSSean Callanan } 119514cb2aaaSSean Callanan Type *target_ty = pointer_ptr_ty->getElementType(); 119614cb2aaaSSean Callanan 119714cb2aaaSSean Callanan lldb::addr_t D = frame.ResolveValue(load_inst, module); 119814cb2aaaSSean Callanan lldb::addr_t P = frame.ResolveValue(pointer_operand, module); 119914cb2aaaSSean Callanan 1200b9c1b51eSKate Stone if (D == LLDB_INVALID_ADDRESS) { 120163e5fb76SJonas Devlieghere LLDB_LOGF(log, "LoadInst's value doesn't resolve to anything"); 120214cb2aaaSSean Callanan error.SetErrorToGenericError(); 120314cb2aaaSSean Callanan error.SetErrorString(bad_value_error); 120414cb2aaaSSean Callanan return false; 120514cb2aaaSSean Callanan } 120614cb2aaaSSean Callanan 1207b9c1b51eSKate Stone if (P == LLDB_INVALID_ADDRESS) { 120863e5fb76SJonas Devlieghere LLDB_LOGF(log, "LoadInst's pointer doesn't resolve to anything"); 120914cb2aaaSSean Callanan error.SetErrorToGenericError(); 121014cb2aaaSSean Callanan error.SetErrorString(bad_value_error); 121114cb2aaaSSean Callanan return false; 121214cb2aaaSSean Callanan } 121314cb2aaaSSean Callanan 121414cb2aaaSSean Callanan lldb::addr_t R; 121597206d57SZachary Turner lldb_private::Status read_error; 12167071c5fdSTed Woodward execution_unit.ReadPointerFromMemory(&R, P, read_error); 121714cb2aaaSSean Callanan 1218b9c1b51eSKate Stone if (!read_error.Success()) { 121963e5fb76SJonas Devlieghere LLDB_LOGF(log, "Couldn't read the address to be loaded for a LoadInst"); 122014cb2aaaSSean Callanan error.SetErrorToGenericError(); 122114cb2aaaSSean Callanan error.SetErrorString(memory_read_error); 122214cb2aaaSSean Callanan return false; 122314cb2aaaSSean Callanan } 122414cb2aaaSSean Callanan 122514cb2aaaSSean Callanan size_t target_size = data_layout.getTypeStoreSize(target_ty); 122614cb2aaaSSean Callanan lldb_private::DataBufferHeap buffer(target_size, 0); 122714cb2aaaSSean Callanan 122814cb2aaaSSean Callanan read_error.Clear(); 1229b9c1b51eSKate Stone execution_unit.ReadMemory(buffer.GetBytes(), R, buffer.GetByteSize(), 1230b9c1b51eSKate Stone read_error); 1231b9c1b51eSKate Stone if (!read_error.Success()) { 123263e5fb76SJonas Devlieghere LLDB_LOGF(log, "Couldn't read from a region on behalf of a LoadInst"); 123314cb2aaaSSean Callanan error.SetErrorToGenericError(); 123414cb2aaaSSean Callanan error.SetErrorString(memory_read_error); 123514cb2aaaSSean Callanan return false; 123614cb2aaaSSean Callanan } 123714cb2aaaSSean Callanan 123897206d57SZachary Turner lldb_private::Status write_error; 1239b9c1b51eSKate Stone execution_unit.WriteMemory(D, buffer.GetBytes(), buffer.GetByteSize(), 1240b9c1b51eSKate Stone write_error); 1241b9c1b51eSKate Stone if (!write_error.Success()) { 124263e5fb76SJonas Devlieghere LLDB_LOGF(log, "Couldn't write to a region on behalf of a LoadInst"); 124314cb2aaaSSean Callanan error.SetErrorToGenericError(); 124414cb2aaaSSean Callanan error.SetErrorString(memory_read_error); 124514cb2aaaSSean Callanan return false; 124614cb2aaaSSean Callanan } 124714cb2aaaSSean Callanan 1248b9c1b51eSKate Stone if (log) { 124963e5fb76SJonas Devlieghere LLDB_LOGF(log, "Interpreted a LoadInst"); 125063e5fb76SJonas Devlieghere LLDB_LOGF(log, " P : 0x%" PRIx64, P); 125163e5fb76SJonas Devlieghere LLDB_LOGF(log, " R : 0x%" PRIx64, R); 125263e5fb76SJonas Devlieghere LLDB_LOGF(log, " D : 0x%" PRIx64, D); 125314cb2aaaSSean Callanan } 1254b9c1b51eSKate Stone } break; 1255b9c1b51eSKate Stone case Instruction::Ret: { 125614cb2aaaSSean Callanan return true; 125714cb2aaaSSean Callanan } 1258b9c1b51eSKate Stone case Instruction::Store: { 1259f18370feSRaphael Isemann const StoreInst *store_inst = cast<StoreInst>(inst); 126014cb2aaaSSean Callanan 126114cb2aaaSSean Callanan // The semantics of Store are: 126214cb2aaaSSean Callanan // Resolve the region D containing the data to be stored 126314cb2aaaSSean Callanan // Resolve the region P containing a pointer 126414cb2aaaSSean Callanan // Dereference P to get the region R that the data should be stored in 126514cb2aaaSSean Callanan // Transfer a unit of type type(D) from D to R 126614cb2aaaSSean Callanan 126714cb2aaaSSean Callanan const Value *value_operand = store_inst->getValueOperand(); 126814cb2aaaSSean Callanan const Value *pointer_operand = store_inst->getPointerOperand(); 126914cb2aaaSSean Callanan 127014cb2aaaSSean Callanan Type *pointer_ty = pointer_operand->getType(); 127114cb2aaaSSean Callanan PointerType *pointer_ptr_ty = dyn_cast<PointerType>(pointer_ty); 127214cb2aaaSSean Callanan if (!pointer_ptr_ty) 127314cb2aaaSSean Callanan return false; 127414cb2aaaSSean Callanan Type *target_ty = pointer_ptr_ty->getElementType(); 127514cb2aaaSSean Callanan 127614cb2aaaSSean Callanan lldb::addr_t D = frame.ResolveValue(value_operand, module); 127714cb2aaaSSean Callanan lldb::addr_t P = frame.ResolveValue(pointer_operand, module); 127814cb2aaaSSean Callanan 1279b9c1b51eSKate Stone if (D == LLDB_INVALID_ADDRESS) { 128063e5fb76SJonas Devlieghere LLDB_LOGF(log, "StoreInst's value doesn't resolve to anything"); 128114cb2aaaSSean Callanan error.SetErrorToGenericError(); 128214cb2aaaSSean Callanan error.SetErrorString(bad_value_error); 128314cb2aaaSSean Callanan return false; 128414cb2aaaSSean Callanan } 128514cb2aaaSSean Callanan 1286b9c1b51eSKate Stone if (P == LLDB_INVALID_ADDRESS) { 128763e5fb76SJonas Devlieghere LLDB_LOGF(log, "StoreInst's pointer doesn't resolve to anything"); 128814cb2aaaSSean Callanan error.SetErrorToGenericError(); 128914cb2aaaSSean Callanan error.SetErrorString(bad_value_error); 129014cb2aaaSSean Callanan return false; 129114cb2aaaSSean Callanan } 129214cb2aaaSSean Callanan 129314cb2aaaSSean Callanan lldb::addr_t R; 129497206d57SZachary Turner lldb_private::Status read_error; 12957071c5fdSTed Woodward execution_unit.ReadPointerFromMemory(&R, P, read_error); 129614cb2aaaSSean Callanan 1297b9c1b51eSKate Stone if (!read_error.Success()) { 129863e5fb76SJonas Devlieghere LLDB_LOGF(log, "Couldn't read the address to be loaded for a LoadInst"); 129914cb2aaaSSean Callanan error.SetErrorToGenericError(); 130014cb2aaaSSean Callanan error.SetErrorString(memory_read_error); 130114cb2aaaSSean Callanan return false; 130214cb2aaaSSean Callanan } 130314cb2aaaSSean Callanan 130414cb2aaaSSean Callanan size_t target_size = data_layout.getTypeStoreSize(target_ty); 130514cb2aaaSSean Callanan lldb_private::DataBufferHeap buffer(target_size, 0); 130614cb2aaaSSean Callanan 130714cb2aaaSSean Callanan read_error.Clear(); 1308b9c1b51eSKate Stone execution_unit.ReadMemory(buffer.GetBytes(), D, buffer.GetByteSize(), 1309b9c1b51eSKate Stone read_error); 1310b9c1b51eSKate Stone if (!read_error.Success()) { 131163e5fb76SJonas Devlieghere LLDB_LOGF(log, "Couldn't read from a region on behalf of a StoreInst"); 131214cb2aaaSSean Callanan error.SetErrorToGenericError(); 131314cb2aaaSSean Callanan error.SetErrorString(memory_read_error); 131414cb2aaaSSean Callanan return false; 131514cb2aaaSSean Callanan } 131614cb2aaaSSean Callanan 131797206d57SZachary Turner lldb_private::Status write_error; 1318b9c1b51eSKate Stone execution_unit.WriteMemory(R, buffer.GetBytes(), buffer.GetByteSize(), 1319b9c1b51eSKate Stone write_error); 1320b9c1b51eSKate Stone if (!write_error.Success()) { 132163e5fb76SJonas Devlieghere LLDB_LOGF(log, "Couldn't write to a region on behalf of a StoreInst"); 132214cb2aaaSSean Callanan error.SetErrorToGenericError(); 132349630e7fSSean Callanan error.SetErrorString(memory_write_error); 132414cb2aaaSSean Callanan return false; 132514cb2aaaSSean Callanan } 132614cb2aaaSSean Callanan 1327b9c1b51eSKate Stone if (log) { 132863e5fb76SJonas Devlieghere LLDB_LOGF(log, "Interpreted a StoreInst"); 132963e5fb76SJonas Devlieghere LLDB_LOGF(log, " D : 0x%" PRIx64, D); 133063e5fb76SJonas Devlieghere LLDB_LOGF(log, " P : 0x%" PRIx64, P); 133163e5fb76SJonas Devlieghere LLDB_LOGF(log, " R : 0x%" PRIx64, R); 133214cb2aaaSSean Callanan } 1333b9c1b51eSKate Stone } break; 1334b9c1b51eSKate Stone case Instruction::Call: { 1335f18370feSRaphael Isemann const CallInst *call_inst = cast<CallInst>(inst); 133690ff7911SEwan Crawford 133790ff7911SEwan Crawford if (CanIgnoreCall(call_inst)) 133890ff7911SEwan Crawford break; 133990ff7911SEwan Crawford 134090ff7911SEwan Crawford // Get the return type 134190ff7911SEwan Crawford llvm::Type *returnType = call_inst->getType(); 1342b9c1b51eSKate Stone if (returnType == nullptr) { 134390ff7911SEwan Crawford error.SetErrorToGenericError(); 134490ff7911SEwan Crawford error.SetErrorString("unable to access return type"); 134590ff7911SEwan Crawford return false; 134690ff7911SEwan Crawford } 134790ff7911SEwan Crawford 134890ff7911SEwan Crawford // Work with void, integer and pointer return types 1349b9c1b51eSKate Stone if (!returnType->isVoidTy() && !returnType->isIntegerTy() && 1350b9c1b51eSKate Stone !returnType->isPointerTy()) { 135190ff7911SEwan Crawford error.SetErrorToGenericError(); 135290ff7911SEwan Crawford error.SetErrorString("return type is not supported"); 135390ff7911SEwan Crawford return false; 135490ff7911SEwan Crawford } 135590ff7911SEwan Crawford 135690ff7911SEwan Crawford // Check we can actually get a thread 1357b9c1b51eSKate Stone if (exe_ctx.GetThreadPtr() == nullptr) { 135890ff7911SEwan Crawford error.SetErrorToGenericError(); 135990ff7911SEwan Crawford error.SetErrorStringWithFormat("unable to acquire thread"); 136090ff7911SEwan Crawford return false; 136190ff7911SEwan Crawford } 136290ff7911SEwan Crawford 136390ff7911SEwan Crawford // Make sure we have a valid process 1364b9c1b51eSKate Stone if (!exe_ctx.GetProcessPtr()) { 136590ff7911SEwan Crawford error.SetErrorToGenericError(); 136690ff7911SEwan Crawford error.SetErrorStringWithFormat("unable to get the process"); 136790ff7911SEwan Crawford return false; 136890ff7911SEwan Crawford } 136990ff7911SEwan Crawford 137090ff7911SEwan Crawford // Find the address of the callee function 137190ff7911SEwan Crawford lldb_private::Scalar I; 1372a58b62b4SCraig Topper const llvm::Value *val = call_inst->getCalledOperand(); 137390ff7911SEwan Crawford 1374b9c1b51eSKate Stone if (!frame.EvaluateValue(I, val, module)) { 137590ff7911SEwan Crawford error.SetErrorToGenericError(); 137690ff7911SEwan Crawford error.SetErrorString("unable to get address of function"); 137790ff7911SEwan Crawford return false; 137890ff7911SEwan Crawford } 137990ff7911SEwan Crawford lldb_private::Address funcAddr(I.ULongLong(LLDB_INVALID_ADDRESS)); 138090ff7911SEwan Crawford 1381579e70c9SSean Callanan lldb_private::DiagnosticManager diagnostics; 138290ff7911SEwan Crawford lldb_private::EvaluateExpressionOptions options; 138390ff7911SEwan Crawford 138490ff7911SEwan Crawford // We generally receive a function pointer which we must dereference 138590ff7911SEwan Crawford llvm::Type *prototype = val->getType(); 1386b9c1b51eSKate Stone if (!prototype->isPointerTy()) { 138790ff7911SEwan Crawford error.SetErrorToGenericError(); 138890ff7911SEwan Crawford error.SetErrorString("call need function pointer"); 138990ff7911SEwan Crawford return false; 139090ff7911SEwan Crawford } 139190ff7911SEwan Crawford 139290ff7911SEwan Crawford // Dereference the function pointer 139390ff7911SEwan Crawford prototype = prototype->getPointerElementType(); 1394b9c1b51eSKate Stone if (!(prototype->isFunctionTy() || prototype->isFunctionVarArg())) { 139590ff7911SEwan Crawford error.SetErrorToGenericError(); 139690ff7911SEwan Crawford error.SetErrorString("call need function pointer"); 139790ff7911SEwan Crawford return false; 139890ff7911SEwan Crawford } 139990ff7911SEwan Crawford 140090ff7911SEwan Crawford // Find number of arguments 140190ff7911SEwan Crawford const int numArgs = call_inst->getNumArgOperands(); 140290ff7911SEwan Crawford 140390ff7911SEwan Crawford // We work with a fixed array of 16 arguments which is our upper limit 140490ff7911SEwan Crawford static lldb_private::ABI::CallArgument rawArgs[16]; 1405b9c1b51eSKate Stone if (numArgs >= 16) { 140690ff7911SEwan Crawford error.SetErrorToGenericError(); 140790ff7911SEwan Crawford error.SetErrorStringWithFormat("function takes too many arguments"); 140890ff7911SEwan Crawford return false; 140990ff7911SEwan Crawford } 141090ff7911SEwan Crawford 141105097246SAdrian Prantl // Push all function arguments to the argument list that will be passed 141205097246SAdrian Prantl // to the call function thread plan 1413b9c1b51eSKate Stone for (int i = 0; i < numArgs; i++) { 141490ff7911SEwan Crawford // Get details of this argument 141590ff7911SEwan Crawford llvm::Value *arg_op = call_inst->getArgOperand(i); 141690ff7911SEwan Crawford llvm::Type *arg_ty = arg_op->getType(); 141790ff7911SEwan Crawford 141890ff7911SEwan Crawford // Ensure that this argument is an supported type 1419b9c1b51eSKate Stone if (!arg_ty->isIntegerTy() && !arg_ty->isPointerTy()) { 142090ff7911SEwan Crawford error.SetErrorToGenericError(); 142190ff7911SEwan Crawford error.SetErrorStringWithFormat("argument %d must be integer type", i); 142290ff7911SEwan Crawford return false; 142390ff7911SEwan Crawford } 142490ff7911SEwan Crawford 142590ff7911SEwan Crawford // Extract the arguments value 142690ff7911SEwan Crawford lldb_private::Scalar tmp_op = 0; 1427b9c1b51eSKate Stone if (!frame.EvaluateValue(tmp_op, arg_op, module)) { 142890ff7911SEwan Crawford error.SetErrorToGenericError(); 142990ff7911SEwan Crawford error.SetErrorStringWithFormat("unable to evaluate argument %d", i); 143090ff7911SEwan Crawford return false; 143190ff7911SEwan Crawford } 143290ff7911SEwan Crawford 143390ff7911SEwan Crawford // Check if this is a string literal or constant string pointer 1434b9c1b51eSKate Stone if (arg_ty->isPointerTy()) { 143590ff7911SEwan Crawford lldb::addr_t addr = tmp_op.ULongLong(); 143690ff7911SEwan Crawford size_t dataSize = 0; 143790ff7911SEwan Crawford 1438a322f36cSDavid Blaikie bool Success = execution_unit.GetAllocSize(addr, dataSize); 1439a322f36cSDavid Blaikie (void)Success; 1440a322f36cSDavid Blaikie assert(Success && 1441a322f36cSDavid Blaikie "unable to locate host data for transfer to device"); 144290ff7911SEwan Crawford // Create the required buffer 144390ff7911SEwan Crawford rawArgs[i].size = dataSize; 1444d5b44036SJonas Devlieghere rawArgs[i].data_up.reset(new uint8_t[dataSize + 1]); 144590ff7911SEwan Crawford 144690ff7911SEwan Crawford // Read string from host memory 1447d5b44036SJonas Devlieghere execution_unit.ReadMemory(rawArgs[i].data_up.get(), addr, dataSize, 1448b9c1b51eSKate Stone error); 1449a322f36cSDavid Blaikie assert(!error.Fail() && 1450a322f36cSDavid Blaikie "we have failed to read the string from memory"); 1451a322f36cSDavid Blaikie 145290ff7911SEwan Crawford // Add null terminator 1453d5b44036SJonas Devlieghere rawArgs[i].data_up[dataSize] = '\0'; 145490ff7911SEwan Crawford rawArgs[i].type = lldb_private::ABI::CallArgument::HostPointer; 1455b9c1b51eSKate Stone } else /* if ( arg_ty->isPointerTy() ) */ 145690ff7911SEwan Crawford { 145790ff7911SEwan Crawford rawArgs[i].type = lldb_private::ABI::CallArgument::TargetValue; 145890ff7911SEwan Crawford // Get argument size in bytes 145990ff7911SEwan Crawford rawArgs[i].size = arg_ty->getIntegerBitWidth() / 8; 146090ff7911SEwan Crawford // Push value into argument list for thread plan 146190ff7911SEwan Crawford rawArgs[i].value = tmp_op.ULongLong(); 146290ff7911SEwan Crawford } 146390ff7911SEwan Crawford } 146490ff7911SEwan Crawford 146590ff7911SEwan Crawford // Pack the arguments into an llvm::array 146690ff7911SEwan Crawford llvm::ArrayRef<lldb_private::ABI::CallArgument> args(rawArgs, numArgs); 146790ff7911SEwan Crawford 146890ff7911SEwan Crawford // Setup a thread plan to call the target function 1469b9c1b51eSKate Stone lldb::ThreadPlanSP call_plan_sp( 1470b9c1b51eSKate Stone new lldb_private::ThreadPlanCallFunctionUsingABI( 1471b9c1b51eSKate Stone exe_ctx.GetThreadRef(), funcAddr, *prototype, *returnType, args, 1472b9c1b51eSKate Stone options)); 147390ff7911SEwan Crawford 147490ff7911SEwan Crawford // Check if the plan is valid 1475579e70c9SSean Callanan lldb_private::StreamString ss; 1476b9c1b51eSKate Stone if (!call_plan_sp || !call_plan_sp->ValidatePlan(&ss)) { 147790ff7911SEwan Crawford error.SetErrorToGenericError(); 1478b9c1b51eSKate Stone error.SetErrorStringWithFormat( 1479b9c1b51eSKate Stone "unable to make ThreadPlanCallFunctionUsingABI for 0x%llx", 1480579e70c9SSean Callanan I.ULongLong()); 148190ff7911SEwan Crawford return false; 148290ff7911SEwan Crawford } 148390ff7911SEwan Crawford 148490ff7911SEwan Crawford exe_ctx.GetProcessPtr()->SetRunningUserExpression(true); 148590ff7911SEwan Crawford 148690ff7911SEwan Crawford // Execute the actual function call thread plan 1487b9c1b51eSKate Stone lldb::ExpressionResults res = exe_ctx.GetProcessRef().RunThreadPlan( 1488b9c1b51eSKate Stone exe_ctx, call_plan_sp, options, diagnostics); 148990ff7911SEwan Crawford 149090ff7911SEwan Crawford // Check that the thread plan completed successfully 1491b9c1b51eSKate Stone if (res != lldb::ExpressionResults::eExpressionCompleted) { 149290ff7911SEwan Crawford error.SetErrorToGenericError(); 149390ff7911SEwan Crawford error.SetErrorStringWithFormat("ThreadPlanCallFunctionUsingABI failed"); 149490ff7911SEwan Crawford return false; 149590ff7911SEwan Crawford } 149690ff7911SEwan Crawford 149790ff7911SEwan Crawford exe_ctx.GetProcessPtr()->SetRunningUserExpression(false); 149890ff7911SEwan Crawford 149990ff7911SEwan Crawford // Void return type 1500b9c1b51eSKate Stone if (returnType->isVoidTy()) { 150190ff7911SEwan Crawford // Cant assign to void types, so we leave the frame untouched 1502b9c1b51eSKate Stone } else 150390ff7911SEwan Crawford // Integer or pointer return type 1504b9c1b51eSKate Stone if (returnType->isIntegerTy() || returnType->isPointerTy()) { 150590ff7911SEwan Crawford // Get the encapsulated return value 150690ff7911SEwan Crawford lldb::ValueObjectSP retVal = call_plan_sp.get()->GetReturnValueObject(); 150790ff7911SEwan Crawford 150890ff7911SEwan Crawford lldb_private::Scalar returnVal = -1; 150990ff7911SEwan Crawford lldb_private::ValueObject *vobj = retVal.get(); 151090ff7911SEwan Crawford 151190ff7911SEwan Crawford // Check if the return value is valid 1512363f05b8SPavel Labath if (vobj == nullptr || !retVal) { 151390ff7911SEwan Crawford error.SetErrorToGenericError(); 151490ff7911SEwan Crawford error.SetErrorStringWithFormat("unable to get the return value"); 151590ff7911SEwan Crawford return false; 151690ff7911SEwan Crawford } 151790ff7911SEwan Crawford 151890ff7911SEwan Crawford // Extract the return value as a integer 151990ff7911SEwan Crawford lldb_private::Value &value = vobj->GetValue(); 152090ff7911SEwan Crawford returnVal = value.GetScalar(); 152190ff7911SEwan Crawford 152290ff7911SEwan Crawford // Push the return value as the result 152390ff7911SEwan Crawford frame.AssignValue(inst, returnVal, module); 152490ff7911SEwan Crawford } 1525b9c1b51eSKate Stone } break; 152614cb2aaaSSean Callanan } 152714cb2aaaSSean Callanan 152814cb2aaaSSean Callanan ++frame.m_ii; 152914cb2aaaSSean Callanan } 153014cb2aaaSSean Callanan 1531b9c1b51eSKate Stone if (num_insts >= 4096) { 153214cb2aaaSSean Callanan error.SetErrorToGenericError(); 153314cb2aaaSSean Callanan error.SetErrorString(infinite_loop_error); 153414cb2aaaSSean Callanan return false; 153514cb2aaaSSean Callanan } 153614cb2aaaSSean Callanan 153714cb2aaaSSean Callanan return false; 153814cb2aaaSSean Callanan } 1539