Path: blob/main/contrib/llvm-project/lldb/source/Expression/IRInterpreter.cpp
39587 views
//===-- IRInterpreter.cpp -------------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "lldb/Expression/IRInterpreter.h"9#include "lldb/Core/Debugger.h"10#include "lldb/Core/Module.h"11#include "lldb/Core/ModuleSpec.h"12#include "lldb/Core/ValueObject.h"13#include "lldb/Expression/DiagnosticManager.h"14#include "lldb/Expression/IRExecutionUnit.h"15#include "lldb/Expression/IRMemoryMap.h"16#include "lldb/Utility/ConstString.h"17#include "lldb/Utility/DataExtractor.h"18#include "lldb/Utility/Endian.h"19#include "lldb/Utility/LLDBLog.h"20#include "lldb/Utility/Log.h"21#include "lldb/Utility/Scalar.h"22#include "lldb/Utility/Status.h"23#include "lldb/Utility/StreamString.h"2425#include "lldb/Target/ABI.h"26#include "lldb/Target/ExecutionContext.h"27#include "lldb/Target/Target.h"28#include "lldb/Target/Thread.h"29#include "lldb/Target/ThreadPlan.h"30#include "lldb/Target/ThreadPlanCallFunctionUsingABI.h"3132#include "llvm/IR/Constants.h"33#include "llvm/IR/DataLayout.h"34#include "llvm/IR/Function.h"35#include "llvm/IR/Instructions.h"36#include "llvm/IR/Intrinsics.h"37#include "llvm/IR/LLVMContext.h"38#include "llvm/IR/Module.h"39#include "llvm/IR/Operator.h"40#include "llvm/Support/raw_ostream.h"4142#include <map>4344using namespace llvm;45using lldb_private::LLDBLog;4647static std::string PrintValue(const Value *value, bool truncate = false) {48std::string s;49raw_string_ostream rso(s);50value->print(rso);51rso.flush();52if (truncate)53s.resize(s.length() - 1);5455size_t offset;56while ((offset = s.find('\n')) != s.npos)57s.erase(offset, 1);58while (s[0] == ' ' || s[0] == '\t')59s.erase(0, 1);6061return s;62}6364static std::string PrintType(const Type *type, bool truncate = false) {65std::string s;66raw_string_ostream rso(s);67type->print(rso);68rso.flush();69if (truncate)70s.resize(s.length() - 1);71return s;72}7374static bool CanIgnoreCall(const CallInst *call) {75const llvm::Function *called_function = call->getCalledFunction();7677if (!called_function)78return false;7980if (called_function->isIntrinsic()) {81switch (called_function->getIntrinsicID()) {82default:83break;84case llvm::Intrinsic::dbg_declare:85case llvm::Intrinsic::dbg_value:86return true;87}88}8990return false;91}9293class InterpreterStackFrame {94public:95typedef std::map<const Value *, lldb::addr_t> ValueMap;9697ValueMap m_values;98DataLayout &m_target_data;99lldb_private::IRExecutionUnit &m_execution_unit;100const BasicBlock *m_bb = nullptr;101const BasicBlock *m_prev_bb = nullptr;102BasicBlock::const_iterator m_ii;103BasicBlock::const_iterator m_ie;104105lldb::addr_t m_frame_process_address;106size_t m_frame_size;107lldb::addr_t m_stack_pointer;108109lldb::ByteOrder m_byte_order;110size_t m_addr_byte_size;111112InterpreterStackFrame(DataLayout &target_data,113lldb_private::IRExecutionUnit &execution_unit,114lldb::addr_t stack_frame_bottom,115lldb::addr_t stack_frame_top)116: m_target_data(target_data), m_execution_unit(execution_unit) {117m_byte_order = (target_data.isLittleEndian() ? lldb::eByteOrderLittle118: lldb::eByteOrderBig);119m_addr_byte_size = (target_data.getPointerSize(0));120121m_frame_process_address = stack_frame_bottom;122m_frame_size = stack_frame_top - stack_frame_bottom;123m_stack_pointer = stack_frame_top;124}125126~InterpreterStackFrame() = default;127128void Jump(const BasicBlock *bb) {129m_prev_bb = m_bb;130m_bb = bb;131m_ii = m_bb->begin();132m_ie = m_bb->end();133}134135std::string SummarizeValue(const Value *value) {136lldb_private::StreamString ss;137138ss.Printf("%s", PrintValue(value).c_str());139140ValueMap::iterator i = m_values.find(value);141142if (i != m_values.end()) {143lldb::addr_t addr = i->second;144145ss.Printf(" 0x%llx", (unsigned long long)addr);146}147148return std::string(ss.GetString());149}150151bool AssignToMatchType(lldb_private::Scalar &scalar, llvm::APInt value,152Type *type) {153size_t type_size = m_target_data.getTypeStoreSize(type);154155if (type_size > 8)156return false;157158if (type_size != 1)159type_size = PowerOf2Ceil(type_size);160161scalar = value.zextOrTrunc(type_size * 8);162return true;163}164165bool EvaluateValue(lldb_private::Scalar &scalar, const Value *value,166Module &module) {167const Constant *constant = dyn_cast<Constant>(value);168169if (constant) {170if (constant->getValueID() == Value::ConstantFPVal) {171if (auto *cfp = dyn_cast<ConstantFP>(constant)) {172if (cfp->getType()->isDoubleTy())173scalar = cfp->getValueAPF().convertToDouble();174else if (cfp->getType()->isFloatTy())175scalar = cfp->getValueAPF().convertToFloat();176else177return false;178return true;179}180return false;181}182APInt value_apint;183184if (!ResolveConstantValue(value_apint, constant))185return false;186187return AssignToMatchType(scalar, value_apint, value->getType());188}189190lldb::addr_t process_address = ResolveValue(value, module);191size_t value_size = m_target_data.getTypeStoreSize(value->getType());192193lldb_private::DataExtractor value_extractor;194lldb_private::Status extract_error;195196m_execution_unit.GetMemoryData(value_extractor, process_address,197value_size, extract_error);198199if (!extract_error.Success())200return false;201202lldb::offset_t offset = 0;203if (value_size <= 8) {204Type *ty = value->getType();205if (ty->isDoubleTy()) {206scalar = value_extractor.GetDouble(&offset);207return true;208} else if (ty->isFloatTy()) {209scalar = value_extractor.GetFloat(&offset);210return true;211} else {212uint64_t u64value = value_extractor.GetMaxU64(&offset, value_size);213return AssignToMatchType(scalar, llvm::APInt(64, u64value),214value->getType());215}216}217218return false;219}220221bool AssignValue(const Value *value, lldb_private::Scalar scalar,222Module &module) {223lldb::addr_t process_address = ResolveValue(value, module);224225if (process_address == LLDB_INVALID_ADDRESS)226return false;227228lldb_private::Scalar cast_scalar;229Type *vty = value->getType();230if (vty->isFloatTy() || vty->isDoubleTy()) {231cast_scalar = scalar;232} else {233scalar.MakeUnsigned();234if (!AssignToMatchType(cast_scalar, scalar.UInt128(llvm::APInt()),235value->getType()))236return false;237}238239size_t value_byte_size = m_target_data.getTypeStoreSize(value->getType());240241lldb_private::DataBufferHeap buf(value_byte_size, 0);242243lldb_private::Status get_data_error;244245if (!cast_scalar.GetAsMemoryData(buf.GetBytes(), buf.GetByteSize(),246m_byte_order, get_data_error))247return false;248249lldb_private::Status write_error;250251m_execution_unit.WriteMemory(process_address, buf.GetBytes(),252buf.GetByteSize(), write_error);253254return write_error.Success();255}256257bool ResolveConstantValue(APInt &value, const Constant *constant) {258switch (constant->getValueID()) {259default:260break;261case Value::FunctionVal:262if (const Function *constant_func = dyn_cast<Function>(constant)) {263lldb_private::ConstString name(constant_func->getName());264bool missing_weak = false;265lldb::addr_t addr = m_execution_unit.FindSymbol(name, missing_weak);266if (addr == LLDB_INVALID_ADDRESS)267return false;268value = APInt(m_target_data.getPointerSizeInBits(), addr);269return true;270}271break;272case Value::ConstantIntVal:273if (const ConstantInt *constant_int = dyn_cast<ConstantInt>(constant)) {274value = constant_int->getValue();275return true;276}277break;278case Value::ConstantFPVal:279if (const ConstantFP *constant_fp = dyn_cast<ConstantFP>(constant)) {280value = constant_fp->getValueAPF().bitcastToAPInt();281return true;282}283break;284case Value::ConstantExprVal:285if (const ConstantExpr *constant_expr =286dyn_cast<ConstantExpr>(constant)) {287switch (constant_expr->getOpcode()) {288default:289return false;290case Instruction::IntToPtr:291case Instruction::PtrToInt:292case Instruction::BitCast:293return ResolveConstantValue(value, constant_expr->getOperand(0));294case Instruction::GetElementPtr: {295ConstantExpr::const_op_iterator op_cursor = constant_expr->op_begin();296ConstantExpr::const_op_iterator op_end = constant_expr->op_end();297298Constant *base = dyn_cast<Constant>(*op_cursor);299300if (!base)301return false;302303if (!ResolveConstantValue(value, base))304return false;305306op_cursor++;307308if (op_cursor == op_end)309return true; // no offset to apply!310311SmallVector<Value *, 8> indices(op_cursor, op_end);312Type *src_elem_ty =313cast<GEPOperator>(constant_expr)->getSourceElementType();314315// DataLayout::getIndexedOffsetInType assumes the indices are316// instances of ConstantInt.317uint64_t offset =318m_target_data.getIndexedOffsetInType(src_elem_ty, indices);319320const bool is_signed = true;321value += APInt(value.getBitWidth(), offset, is_signed);322323return true;324}325}326}327break;328case Value::ConstantPointerNullVal:329if (isa<ConstantPointerNull>(constant)) {330value = APInt(m_target_data.getPointerSizeInBits(), 0);331return true;332}333break;334}335return false;336}337338bool MakeArgument(const Argument *value, uint64_t address) {339lldb::addr_t data_address = Malloc(value->getType());340341if (data_address == LLDB_INVALID_ADDRESS)342return false;343344lldb_private::Status write_error;345346m_execution_unit.WritePointerToMemory(data_address, address, write_error);347348if (!write_error.Success()) {349lldb_private::Status free_error;350m_execution_unit.Free(data_address, free_error);351return false;352}353354m_values[value] = data_address;355356lldb_private::Log *log(GetLog(LLDBLog::Expressions));357358if (log) {359LLDB_LOGF(log, "Made an allocation for argument %s",360PrintValue(value).c_str());361LLDB_LOGF(log, " Data region : %llx", (unsigned long long)address);362LLDB_LOGF(log, " Ref region : %llx",363(unsigned long long)data_address);364}365366return true;367}368369bool ResolveConstant(lldb::addr_t process_address, const Constant *constant) {370APInt resolved_value;371372if (!ResolveConstantValue(resolved_value, constant))373return false;374375size_t constant_size = m_target_data.getTypeStoreSize(constant->getType());376lldb_private::DataBufferHeap buf(constant_size, 0);377378lldb_private::Status get_data_error;379380lldb_private::Scalar resolved_scalar(381resolved_value.zextOrTrunc(llvm::NextPowerOf2(constant_size) * 8));382if (!resolved_scalar.GetAsMemoryData(buf.GetBytes(), buf.GetByteSize(),383m_byte_order, get_data_error))384return false;385386lldb_private::Status write_error;387388m_execution_unit.WriteMemory(process_address, buf.GetBytes(),389buf.GetByteSize(), write_error);390391return write_error.Success();392}393394lldb::addr_t Malloc(size_t size, uint8_t byte_alignment) {395lldb::addr_t ret = m_stack_pointer;396397ret -= size;398ret -= (ret % byte_alignment);399400if (ret < m_frame_process_address)401return LLDB_INVALID_ADDRESS;402403m_stack_pointer = ret;404return ret;405}406407lldb::addr_t Malloc(llvm::Type *type) {408lldb_private::Status alloc_error;409410return Malloc(m_target_data.getTypeAllocSize(type),411m_target_data.getPrefTypeAlign(type).value());412}413414std::string PrintData(lldb::addr_t addr, llvm::Type *type) {415size_t length = m_target_data.getTypeStoreSize(type);416417lldb_private::DataBufferHeap buf(length, 0);418419lldb_private::Status read_error;420421m_execution_unit.ReadMemory(buf.GetBytes(), addr, length, read_error);422423if (!read_error.Success())424return std::string("<couldn't read data>");425426lldb_private::StreamString ss;427428for (size_t i = 0; i < length; i++) {429if ((!(i & 0xf)) && i)430ss.Printf("%02hhx - ", buf.GetBytes()[i]);431else432ss.Printf("%02hhx ", buf.GetBytes()[i]);433}434435return std::string(ss.GetString());436}437438lldb::addr_t ResolveValue(const Value *value, Module &module) {439ValueMap::iterator i = m_values.find(value);440441if (i != m_values.end())442return i->second;443444// Fall back and allocate space [allocation type Alloca]445446lldb::addr_t data_address = Malloc(value->getType());447448if (const Constant *constant = dyn_cast<Constant>(value)) {449if (!ResolveConstant(data_address, constant)) {450lldb_private::Status free_error;451m_execution_unit.Free(data_address, free_error);452return LLDB_INVALID_ADDRESS;453}454}455456m_values[value] = data_address;457return data_address;458}459};460461static const char *unsupported_opcode_error =462"Interpreter doesn't handle one of the expression's opcodes";463static const char *unsupported_operand_error =464"Interpreter doesn't handle one of the expression's operands";465static const char *interpreter_internal_error =466"Interpreter encountered an internal error";467static const char *interrupt_error =468"Interrupted while interpreting expression";469static const char *bad_value_error =470"Interpreter couldn't resolve a value during execution";471static const char *memory_allocation_error =472"Interpreter couldn't allocate memory";473static const char *memory_write_error = "Interpreter couldn't write to memory";474static const char *memory_read_error = "Interpreter couldn't read from memory";475static const char *timeout_error =476"Reached timeout while interpreting expression";477static const char *too_many_functions_error =478"Interpreter doesn't handle modules with multiple function bodies.";479480static bool CanResolveConstant(llvm::Constant *constant) {481switch (constant->getValueID()) {482default:483return false;484case Value::ConstantIntVal:485case Value::ConstantFPVal:486case Value::FunctionVal:487return true;488case Value::ConstantExprVal:489if (const ConstantExpr *constant_expr = dyn_cast<ConstantExpr>(constant)) {490switch (constant_expr->getOpcode()) {491default:492return false;493case Instruction::IntToPtr:494case Instruction::PtrToInt:495case Instruction::BitCast:496return CanResolveConstant(constant_expr->getOperand(0));497case Instruction::GetElementPtr: {498// Check that the base can be constant-resolved.499ConstantExpr::const_op_iterator op_cursor = constant_expr->op_begin();500Constant *base = dyn_cast<Constant>(*op_cursor);501if (!base || !CanResolveConstant(base))502return false;503504// Check that all other operands are just ConstantInt.505for (Value *op : make_range(constant_expr->op_begin() + 1,506constant_expr->op_end())) {507ConstantInt *constant_int = dyn_cast<ConstantInt>(op);508if (!constant_int)509return false;510}511return true;512}513}514} else {515return false;516}517case Value::ConstantPointerNullVal:518return true;519}520}521522bool IRInterpreter::CanInterpret(llvm::Module &module, llvm::Function &function,523lldb_private::Status &error,524const bool support_function_calls) {525lldb_private::Log *log(GetLog(LLDBLog::Expressions));526527bool saw_function_with_body = false;528for (Function &f : module) {529if (f.begin() != f.end()) {530if (saw_function_with_body) {531LLDB_LOGF(log, "More than one function in the module has a body");532error.SetErrorToGenericError();533error.SetErrorString(too_many_functions_error);534return false;535}536saw_function_with_body = true;537LLDB_LOGF(log, "Saw function with body: %s", f.getName().str().c_str());538}539}540541for (BasicBlock &bb : function) {542for (Instruction &ii : bb) {543switch (ii.getOpcode()) {544default: {545LLDB_LOGF(log, "Unsupported instruction: %s", PrintValue(&ii).c_str());546error.SetErrorToGenericError();547error.SetErrorString(unsupported_opcode_error);548return false;549}550case Instruction::Add:551case Instruction::Alloca:552case Instruction::BitCast:553case Instruction::Br:554case Instruction::PHI:555break;556case Instruction::Call: {557CallInst *call_inst = dyn_cast<CallInst>(&ii);558559if (!call_inst) {560error.SetErrorToGenericError();561error.SetErrorString(interpreter_internal_error);562return false;563}564565if (!CanIgnoreCall(call_inst) && !support_function_calls) {566LLDB_LOGF(log, "Unsupported instruction: %s",567PrintValue(&ii).c_str());568error.SetErrorToGenericError();569error.SetErrorString(unsupported_opcode_error);570return false;571}572} break;573case Instruction::GetElementPtr:574break;575case Instruction::FCmp:576case Instruction::ICmp: {577CmpInst *cmp_inst = dyn_cast<CmpInst>(&ii);578579if (!cmp_inst) {580error.SetErrorToGenericError();581error.SetErrorString(interpreter_internal_error);582return false;583}584585switch (cmp_inst->getPredicate()) {586default: {587LLDB_LOGF(log, "Unsupported ICmp predicate: %s",588PrintValue(&ii).c_str());589590error.SetErrorToGenericError();591error.SetErrorString(unsupported_opcode_error);592return false;593}594case CmpInst::FCMP_OEQ:595case CmpInst::ICMP_EQ:596case CmpInst::FCMP_UNE:597case CmpInst::ICMP_NE:598case CmpInst::FCMP_OGT:599case CmpInst::ICMP_UGT:600case CmpInst::FCMP_OGE:601case CmpInst::ICMP_UGE:602case CmpInst::FCMP_OLT:603case CmpInst::ICMP_ULT:604case CmpInst::FCMP_OLE:605case CmpInst::ICMP_ULE:606case CmpInst::ICMP_SGT:607case CmpInst::ICMP_SGE:608case CmpInst::ICMP_SLT:609case CmpInst::ICMP_SLE:610break;611}612} break;613case Instruction::And:614case Instruction::AShr:615case Instruction::IntToPtr:616case Instruction::PtrToInt:617case Instruction::Load:618case Instruction::LShr:619case Instruction::Mul:620case Instruction::Or:621case Instruction::Ret:622case Instruction::SDiv:623case Instruction::SExt:624case Instruction::Shl:625case Instruction::SRem:626case Instruction::Store:627case Instruction::Sub:628case Instruction::Trunc:629case Instruction::UDiv:630case Instruction::URem:631case Instruction::Xor:632case Instruction::ZExt:633break;634case Instruction::FAdd:635case Instruction::FSub:636case Instruction::FMul:637case Instruction::FDiv:638break;639}640641for (unsigned oi = 0, oe = ii.getNumOperands(); oi != oe; ++oi) {642Value *operand = ii.getOperand(oi);643Type *operand_type = operand->getType();644645switch (operand_type->getTypeID()) {646default:647break;648case Type::FixedVectorTyID:649case Type::ScalableVectorTyID: {650LLDB_LOGF(log, "Unsupported operand type: %s",651PrintType(operand_type).c_str());652error.SetErrorString(unsupported_operand_error);653return false;654}655}656657// The IR interpreter currently doesn't know about658// 128-bit integers. As they're not that frequent,659// we can just fall back to the JIT rather than660// choking.661if (operand_type->getPrimitiveSizeInBits() > 64) {662LLDB_LOGF(log, "Unsupported operand type: %s",663PrintType(operand_type).c_str());664error.SetErrorString(unsupported_operand_error);665return false;666}667668if (Constant *constant = llvm::dyn_cast<Constant>(operand)) {669if (!CanResolveConstant(constant)) {670LLDB_LOGF(log, "Unsupported constant: %s",671PrintValue(constant).c_str());672error.SetErrorString(unsupported_operand_error);673return false;674}675}676}677}678}679680return true;681}682683bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function,684llvm::ArrayRef<lldb::addr_t> args,685lldb_private::IRExecutionUnit &execution_unit,686lldb_private::Status &error,687lldb::addr_t stack_frame_bottom,688lldb::addr_t stack_frame_top,689lldb_private::ExecutionContext &exe_ctx,690lldb_private::Timeout<std::micro> timeout) {691lldb_private::Log *log(GetLog(LLDBLog::Expressions));692693if (log) {694std::string s;695raw_string_ostream oss(s);696697module.print(oss, nullptr);698699oss.flush();700701LLDB_LOGF(log, "Module as passed in to IRInterpreter::Interpret: \n\"%s\"",702s.c_str());703}704705DataLayout data_layout(&module);706707InterpreterStackFrame frame(data_layout, execution_unit, stack_frame_bottom,708stack_frame_top);709710if (frame.m_frame_process_address == LLDB_INVALID_ADDRESS) {711error.SetErrorString("Couldn't allocate stack frame");712}713714int arg_index = 0;715716for (llvm::Function::arg_iterator ai = function.arg_begin(),717ae = function.arg_end();718ai != ae; ++ai, ++arg_index) {719if (args.size() <= static_cast<size_t>(arg_index)) {720error.SetErrorString("Not enough arguments passed in to function");721return false;722}723724lldb::addr_t ptr = args[arg_index];725726frame.MakeArgument(&*ai, ptr);727}728729frame.Jump(&function.front());730731lldb_private::Process *process = exe_ctx.GetProcessPtr();732lldb_private::Target *target = exe_ctx.GetTargetPtr();733734using clock = std::chrono::steady_clock;735736// Compute the time at which the timeout has been exceeded.737std::optional<clock::time_point> end_time;738if (timeout && timeout->count() > 0)739end_time = clock::now() + *timeout;740741while (frame.m_ii != frame.m_ie) {742// Timeout reached: stop interpreting.743if (end_time && clock::now() >= *end_time) {744error.SetErrorToGenericError();745error.SetErrorString(timeout_error);746return false;747}748749// If we have access to the debugger we can honor an interrupt request.750if (target) {751if (INTERRUPT_REQUESTED(target->GetDebugger(),752"Interrupted in IR interpreting.")) {753error.SetErrorToGenericError();754error.SetErrorString(interrupt_error);755return false;756}757}758759const Instruction *inst = &*frame.m_ii;760761LLDB_LOGF(log, "Interpreting %s", PrintValue(inst).c_str());762763switch (inst->getOpcode()) {764default:765break;766767case Instruction::Add:768case Instruction::Sub:769case Instruction::Mul:770case Instruction::SDiv:771case Instruction::UDiv:772case Instruction::SRem:773case Instruction::URem:774case Instruction::Shl:775case Instruction::LShr:776case Instruction::AShr:777case Instruction::And:778case Instruction::Or:779case Instruction::Xor:780case Instruction::FAdd:781case Instruction::FSub:782case Instruction::FMul:783case Instruction::FDiv: {784const BinaryOperator *bin_op = dyn_cast<BinaryOperator>(inst);785786if (!bin_op) {787LLDB_LOGF(788log,789"getOpcode() returns %s, but instruction is not a BinaryOperator",790inst->getOpcodeName());791error.SetErrorToGenericError();792error.SetErrorString(interpreter_internal_error);793return false;794}795796Value *lhs = inst->getOperand(0);797Value *rhs = inst->getOperand(1);798799lldb_private::Scalar L;800lldb_private::Scalar R;801802if (!frame.EvaluateValue(L, lhs, module)) {803LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(lhs).c_str());804error.SetErrorToGenericError();805error.SetErrorString(bad_value_error);806return false;807}808809if (!frame.EvaluateValue(R, rhs, module)) {810LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(rhs).c_str());811error.SetErrorToGenericError();812error.SetErrorString(bad_value_error);813return false;814}815816lldb_private::Scalar result;817818switch (inst->getOpcode()) {819default:820break;821case Instruction::Add:822case Instruction::FAdd:823result = L + R;824break;825case Instruction::Mul:826case Instruction::FMul:827result = L * R;828break;829case Instruction::Sub:830case Instruction::FSub:831result = L - R;832break;833case Instruction::SDiv:834L.MakeSigned();835R.MakeSigned();836result = L / R;837break;838case Instruction::UDiv:839L.MakeUnsigned();840R.MakeUnsigned();841result = L / R;842break;843case Instruction::FDiv:844result = L / R;845break;846case Instruction::SRem:847L.MakeSigned();848R.MakeSigned();849result = L % R;850break;851case Instruction::URem:852L.MakeUnsigned();853R.MakeUnsigned();854result = L % R;855break;856case Instruction::Shl:857result = L << R;858break;859case Instruction::AShr:860result = L >> R;861break;862case Instruction::LShr:863result = L;864result.ShiftRightLogical(R);865break;866case Instruction::And:867result = L & R;868break;869case Instruction::Or:870result = L | R;871break;872case Instruction::Xor:873result = L ^ R;874break;875}876877frame.AssignValue(inst, result, module);878879if (log) {880LLDB_LOGF(log, "Interpreted a %s", inst->getOpcodeName());881LLDB_LOGF(log, " L : %s", frame.SummarizeValue(lhs).c_str());882LLDB_LOGF(log, " R : %s", frame.SummarizeValue(rhs).c_str());883LLDB_LOGF(log, " = : %s", frame.SummarizeValue(inst).c_str());884}885} break;886case Instruction::Alloca: {887const AllocaInst *alloca_inst = cast<AllocaInst>(inst);888889if (alloca_inst->isArrayAllocation()) {890LLDB_LOGF(log,891"AllocaInsts are not handled if isArrayAllocation() is true");892error.SetErrorToGenericError();893error.SetErrorString(unsupported_opcode_error);894return false;895}896897// The semantics of Alloca are:898// Create a region R of virtual memory of type T, backed by a data899// buffer900// Create a region P of virtual memory of type T*, backed by a data901// buffer902// Write the virtual address of R into P903904Type *T = alloca_inst->getAllocatedType();905Type *Tptr = alloca_inst->getType();906907lldb::addr_t R = frame.Malloc(T);908909if (R == LLDB_INVALID_ADDRESS) {910LLDB_LOGF(log, "Couldn't allocate memory for an AllocaInst");911error.SetErrorToGenericError();912error.SetErrorString(memory_allocation_error);913return false;914}915916lldb::addr_t P = frame.Malloc(Tptr);917918if (P == LLDB_INVALID_ADDRESS) {919LLDB_LOGF(log,920"Couldn't allocate the result pointer for an AllocaInst");921error.SetErrorToGenericError();922error.SetErrorString(memory_allocation_error);923return false;924}925926lldb_private::Status write_error;927928execution_unit.WritePointerToMemory(P, R, write_error);929930if (!write_error.Success()) {931LLDB_LOGF(log, "Couldn't write the result pointer for an AllocaInst");932error.SetErrorToGenericError();933error.SetErrorString(memory_write_error);934lldb_private::Status free_error;935execution_unit.Free(P, free_error);936execution_unit.Free(R, free_error);937return false;938}939940frame.m_values[alloca_inst] = P;941942if (log) {943LLDB_LOGF(log, "Interpreted an AllocaInst");944LLDB_LOGF(log, " R : 0x%" PRIx64, R);945LLDB_LOGF(log, " P : 0x%" PRIx64, P);946}947} break;948case Instruction::BitCast:949case Instruction::ZExt: {950const CastInst *cast_inst = cast<CastInst>(inst);951952Value *source = cast_inst->getOperand(0);953954lldb_private::Scalar S;955956if (!frame.EvaluateValue(S, source, module)) {957LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(source).c_str());958error.SetErrorToGenericError();959error.SetErrorString(bad_value_error);960return false;961}962963frame.AssignValue(inst, S, module);964} break;965case Instruction::SExt: {966const CastInst *cast_inst = cast<CastInst>(inst);967968Value *source = cast_inst->getOperand(0);969970lldb_private::Scalar S;971972if (!frame.EvaluateValue(S, source, module)) {973LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(source).c_str());974error.SetErrorToGenericError();975error.SetErrorString(bad_value_error);976return false;977}978979S.MakeSigned();980981lldb_private::Scalar S_signextend(S.SLongLong());982983frame.AssignValue(inst, S_signextend, module);984} break;985case Instruction::Br: {986const BranchInst *br_inst = cast<BranchInst>(inst);987988if (br_inst->isConditional()) {989Value *condition = br_inst->getCondition();990991lldb_private::Scalar C;992993if (!frame.EvaluateValue(C, condition, module)) {994LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(condition).c_str());995error.SetErrorToGenericError();996error.SetErrorString(bad_value_error);997return false;998}9991000if (!C.IsZero())1001frame.Jump(br_inst->getSuccessor(0));1002else1003frame.Jump(br_inst->getSuccessor(1));10041005if (log) {1006LLDB_LOGF(log, "Interpreted a BrInst with a condition");1007LLDB_LOGF(log, " cond : %s",1008frame.SummarizeValue(condition).c_str());1009}1010} else {1011frame.Jump(br_inst->getSuccessor(0));10121013if (log) {1014LLDB_LOGF(log, "Interpreted a BrInst with no condition");1015}1016}1017}1018continue;1019case Instruction::PHI: {1020const PHINode *phi_inst = cast<PHINode>(inst);1021if (!frame.m_prev_bb) {1022LLDB_LOGF(log,1023"Encountered PHI node without having jumped from another "1024"basic block");1025error.SetErrorToGenericError();1026error.SetErrorString(interpreter_internal_error);1027return false;1028}10291030Value *value = phi_inst->getIncomingValueForBlock(frame.m_prev_bb);1031lldb_private::Scalar result;1032if (!frame.EvaluateValue(result, value, module)) {1033LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(value).c_str());1034error.SetErrorToGenericError();1035error.SetErrorString(bad_value_error);1036return false;1037}1038frame.AssignValue(inst, result, module);10391040if (log) {1041LLDB_LOGF(log, "Interpreted a %s", inst->getOpcodeName());1042LLDB_LOGF(log, " Incoming value : %s",1043frame.SummarizeValue(value).c_str());1044}1045} break;1046case Instruction::GetElementPtr: {1047const GetElementPtrInst *gep_inst = cast<GetElementPtrInst>(inst);10481049const Value *pointer_operand = gep_inst->getPointerOperand();1050Type *src_elem_ty = gep_inst->getSourceElementType();10511052lldb_private::Scalar P;10531054if (!frame.EvaluateValue(P, pointer_operand, module)) {1055LLDB_LOGF(log, "Couldn't evaluate %s",1056PrintValue(pointer_operand).c_str());1057error.SetErrorToGenericError();1058error.SetErrorString(bad_value_error);1059return false;1060}10611062typedef SmallVector<Value *, 8> IndexVector;1063typedef IndexVector::iterator IndexIterator;10641065SmallVector<Value *, 8> indices(gep_inst->idx_begin(),1066gep_inst->idx_end());10671068SmallVector<Value *, 8> const_indices;10691070for (IndexIterator ii = indices.begin(), ie = indices.end(); ii != ie;1071++ii) {1072ConstantInt *constant_index = dyn_cast<ConstantInt>(*ii);10731074if (!constant_index) {1075lldb_private::Scalar I;10761077if (!frame.EvaluateValue(I, *ii, module)) {1078LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(*ii).c_str());1079error.SetErrorToGenericError();1080error.SetErrorString(bad_value_error);1081return false;1082}10831084LLDB_LOGF(log, "Evaluated constant index %s as %llu",1085PrintValue(*ii).c_str(), I.ULongLong(LLDB_INVALID_ADDRESS));10861087constant_index = cast<ConstantInt>(ConstantInt::get(1088(*ii)->getType(), I.ULongLong(LLDB_INVALID_ADDRESS)));1089}10901091const_indices.push_back(constant_index);1092}10931094uint64_t offset =1095data_layout.getIndexedOffsetInType(src_elem_ty, const_indices);10961097lldb_private::Scalar Poffset = P + offset;10981099frame.AssignValue(inst, Poffset, module);11001101if (log) {1102LLDB_LOGF(log, "Interpreted a GetElementPtrInst");1103LLDB_LOGF(log, " P : %s",1104frame.SummarizeValue(pointer_operand).c_str());1105LLDB_LOGF(log, " Poffset : %s", frame.SummarizeValue(inst).c_str());1106}1107} break;1108case Instruction::FCmp:1109case Instruction::ICmp: {1110const CmpInst *icmp_inst = cast<CmpInst>(inst);11111112CmpInst::Predicate predicate = icmp_inst->getPredicate();11131114Value *lhs = inst->getOperand(0);1115Value *rhs = inst->getOperand(1);11161117lldb_private::Scalar L;1118lldb_private::Scalar R;11191120if (!frame.EvaluateValue(L, lhs, module)) {1121LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(lhs).c_str());1122error.SetErrorToGenericError();1123error.SetErrorString(bad_value_error);1124return false;1125}11261127if (!frame.EvaluateValue(R, rhs, module)) {1128LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(rhs).c_str());1129error.SetErrorToGenericError();1130error.SetErrorString(bad_value_error);1131return false;1132}11331134lldb_private::Scalar result;11351136switch (predicate) {1137default:1138return false;1139case CmpInst::ICMP_EQ:1140case CmpInst::FCMP_OEQ:1141result = (L == R);1142break;1143case CmpInst::ICMP_NE:1144case CmpInst::FCMP_UNE:1145result = (L != R);1146break;1147case CmpInst::ICMP_UGT:1148L.MakeUnsigned();1149R.MakeUnsigned();1150result = (L > R);1151break;1152case CmpInst::ICMP_UGE:1153L.MakeUnsigned();1154R.MakeUnsigned();1155result = (L >= R);1156break;1157case CmpInst::FCMP_OGE:1158result = (L >= R);1159break;1160case CmpInst::FCMP_OGT:1161result = (L > R);1162break;1163case CmpInst::ICMP_ULT:1164L.MakeUnsigned();1165R.MakeUnsigned();1166result = (L < R);1167break;1168case CmpInst::FCMP_OLT:1169result = (L < R);1170break;1171case CmpInst::ICMP_ULE:1172L.MakeUnsigned();1173R.MakeUnsigned();1174result = (L <= R);1175break;1176case CmpInst::FCMP_OLE:1177result = (L <= R);1178break;1179case CmpInst::ICMP_SGT:1180L.MakeSigned();1181R.MakeSigned();1182result = (L > R);1183break;1184case CmpInst::ICMP_SGE:1185L.MakeSigned();1186R.MakeSigned();1187result = (L >= R);1188break;1189case CmpInst::ICMP_SLT:1190L.MakeSigned();1191R.MakeSigned();1192result = (L < R);1193break;1194case CmpInst::ICMP_SLE:1195L.MakeSigned();1196R.MakeSigned();1197result = (L <= R);1198break;1199}12001201frame.AssignValue(inst, result, module);12021203if (log) {1204LLDB_LOGF(log, "Interpreted an ICmpInst");1205LLDB_LOGF(log, " L : %s", frame.SummarizeValue(lhs).c_str());1206LLDB_LOGF(log, " R : %s", frame.SummarizeValue(rhs).c_str());1207LLDB_LOGF(log, " = : %s", frame.SummarizeValue(inst).c_str());1208}1209} break;1210case Instruction::IntToPtr: {1211const IntToPtrInst *int_to_ptr_inst = cast<IntToPtrInst>(inst);12121213Value *src_operand = int_to_ptr_inst->getOperand(0);12141215lldb_private::Scalar I;12161217if (!frame.EvaluateValue(I, src_operand, module)) {1218LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(src_operand).c_str());1219error.SetErrorToGenericError();1220error.SetErrorString(bad_value_error);1221return false;1222}12231224frame.AssignValue(inst, I, module);12251226if (log) {1227LLDB_LOGF(log, "Interpreted an IntToPtr");1228LLDB_LOGF(log, " Src : %s", frame.SummarizeValue(src_operand).c_str());1229LLDB_LOGF(log, " = : %s", frame.SummarizeValue(inst).c_str());1230}1231} break;1232case Instruction::PtrToInt: {1233const PtrToIntInst *ptr_to_int_inst = cast<PtrToIntInst>(inst);12341235Value *src_operand = ptr_to_int_inst->getOperand(0);12361237lldb_private::Scalar I;12381239if (!frame.EvaluateValue(I, src_operand, module)) {1240LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(src_operand).c_str());1241error.SetErrorToGenericError();1242error.SetErrorString(bad_value_error);1243return false;1244}12451246frame.AssignValue(inst, I, module);12471248if (log) {1249LLDB_LOGF(log, "Interpreted a PtrToInt");1250LLDB_LOGF(log, " Src : %s", frame.SummarizeValue(src_operand).c_str());1251LLDB_LOGF(log, " = : %s", frame.SummarizeValue(inst).c_str());1252}1253} break;1254case Instruction::Trunc: {1255const TruncInst *trunc_inst = cast<TruncInst>(inst);12561257Value *src_operand = trunc_inst->getOperand(0);12581259lldb_private::Scalar I;12601261if (!frame.EvaluateValue(I, src_operand, module)) {1262LLDB_LOGF(log, "Couldn't evaluate %s", PrintValue(src_operand).c_str());1263error.SetErrorToGenericError();1264error.SetErrorString(bad_value_error);1265return false;1266}12671268frame.AssignValue(inst, I, module);12691270if (log) {1271LLDB_LOGF(log, "Interpreted a Trunc");1272LLDB_LOGF(log, " Src : %s", frame.SummarizeValue(src_operand).c_str());1273LLDB_LOGF(log, " = : %s", frame.SummarizeValue(inst).c_str());1274}1275} break;1276case Instruction::Load: {1277const LoadInst *load_inst = cast<LoadInst>(inst);12781279// The semantics of Load are:1280// Create a region D that will contain the loaded data1281// Resolve the region P containing a pointer1282// Dereference P to get the region R that the data should be loaded from1283// Transfer a unit of type type(D) from R to D12841285const Value *pointer_operand = load_inst->getPointerOperand();12861287lldb::addr_t D = frame.ResolveValue(load_inst, module);1288lldb::addr_t P = frame.ResolveValue(pointer_operand, module);12891290if (D == LLDB_INVALID_ADDRESS) {1291LLDB_LOGF(log, "LoadInst's value doesn't resolve to anything");1292error.SetErrorToGenericError();1293error.SetErrorString(bad_value_error);1294return false;1295}12961297if (P == LLDB_INVALID_ADDRESS) {1298LLDB_LOGF(log, "LoadInst's pointer doesn't resolve to anything");1299error.SetErrorToGenericError();1300error.SetErrorString(bad_value_error);1301return false;1302}13031304lldb::addr_t R;1305lldb_private::Status read_error;1306execution_unit.ReadPointerFromMemory(&R, P, read_error);13071308if (!read_error.Success()) {1309LLDB_LOGF(log, "Couldn't read the address to be loaded for a LoadInst");1310error.SetErrorToGenericError();1311error.SetErrorString(memory_read_error);1312return false;1313}13141315Type *target_ty = load_inst->getType();1316size_t target_size = data_layout.getTypeStoreSize(target_ty);1317lldb_private::DataBufferHeap buffer(target_size, 0);13181319read_error.Clear();1320execution_unit.ReadMemory(buffer.GetBytes(), R, buffer.GetByteSize(),1321read_error);1322if (!read_error.Success()) {1323LLDB_LOGF(log, "Couldn't read from a region on behalf of a LoadInst");1324error.SetErrorToGenericError();1325error.SetErrorString(memory_read_error);1326return false;1327}13281329lldb_private::Status write_error;1330execution_unit.WriteMemory(D, buffer.GetBytes(), buffer.GetByteSize(),1331write_error);1332if (!write_error.Success()) {1333LLDB_LOGF(log, "Couldn't write to a region on behalf of a LoadInst");1334error.SetErrorToGenericError();1335error.SetErrorString(memory_write_error);1336return false;1337}13381339if (log) {1340LLDB_LOGF(log, "Interpreted a LoadInst");1341LLDB_LOGF(log, " P : 0x%" PRIx64, P);1342LLDB_LOGF(log, " R : 0x%" PRIx64, R);1343LLDB_LOGF(log, " D : 0x%" PRIx64, D);1344}1345} break;1346case Instruction::Ret: {1347return true;1348}1349case Instruction::Store: {1350const StoreInst *store_inst = cast<StoreInst>(inst);13511352// The semantics of Store are:1353// Resolve the region D containing the data to be stored1354// Resolve the region P containing a pointer1355// Dereference P to get the region R that the data should be stored in1356// Transfer a unit of type type(D) from D to R13571358const Value *value_operand = store_inst->getValueOperand();1359const Value *pointer_operand = store_inst->getPointerOperand();13601361lldb::addr_t D = frame.ResolveValue(value_operand, module);1362lldb::addr_t P = frame.ResolveValue(pointer_operand, module);13631364if (D == LLDB_INVALID_ADDRESS) {1365LLDB_LOGF(log, "StoreInst's value doesn't resolve to anything");1366error.SetErrorToGenericError();1367error.SetErrorString(bad_value_error);1368return false;1369}13701371if (P == LLDB_INVALID_ADDRESS) {1372LLDB_LOGF(log, "StoreInst's pointer doesn't resolve to anything");1373error.SetErrorToGenericError();1374error.SetErrorString(bad_value_error);1375return false;1376}13771378lldb::addr_t R;1379lldb_private::Status read_error;1380execution_unit.ReadPointerFromMemory(&R, P, read_error);13811382if (!read_error.Success()) {1383LLDB_LOGF(log, "Couldn't read the address to be loaded for a LoadInst");1384error.SetErrorToGenericError();1385error.SetErrorString(memory_read_error);1386return false;1387}13881389Type *target_ty = value_operand->getType();1390size_t target_size = data_layout.getTypeStoreSize(target_ty);1391lldb_private::DataBufferHeap buffer(target_size, 0);13921393read_error.Clear();1394execution_unit.ReadMemory(buffer.GetBytes(), D, buffer.GetByteSize(),1395read_error);1396if (!read_error.Success()) {1397LLDB_LOGF(log, "Couldn't read from a region on behalf of a StoreInst");1398error.SetErrorToGenericError();1399error.SetErrorString(memory_read_error);1400return false;1401}14021403lldb_private::Status write_error;1404execution_unit.WriteMemory(R, buffer.GetBytes(), buffer.GetByteSize(),1405write_error);1406if (!write_error.Success()) {1407LLDB_LOGF(log, "Couldn't write to a region on behalf of a StoreInst");1408error.SetErrorToGenericError();1409error.SetErrorString(memory_write_error);1410return false;1411}14121413if (log) {1414LLDB_LOGF(log, "Interpreted a StoreInst");1415LLDB_LOGF(log, " D : 0x%" PRIx64, D);1416LLDB_LOGF(log, " P : 0x%" PRIx64, P);1417LLDB_LOGF(log, " R : 0x%" PRIx64, R);1418}1419} break;1420case Instruction::Call: {1421const CallInst *call_inst = cast<CallInst>(inst);14221423if (CanIgnoreCall(call_inst))1424break;14251426// Get the return type1427llvm::Type *returnType = call_inst->getType();1428if (returnType == nullptr) {1429error.SetErrorToGenericError();1430error.SetErrorString("unable to access return type");1431return false;1432}14331434// Work with void, integer and pointer return types1435if (!returnType->isVoidTy() && !returnType->isIntegerTy() &&1436!returnType->isPointerTy()) {1437error.SetErrorToGenericError();1438error.SetErrorString("return type is not supported");1439return false;1440}14411442// Check we can actually get a thread1443if (exe_ctx.GetThreadPtr() == nullptr) {1444error.SetErrorToGenericError();1445error.SetErrorString("unable to acquire thread");1446return false;1447}14481449// Make sure we have a valid process1450if (!process) {1451error.SetErrorToGenericError();1452error.SetErrorString("unable to get the process");1453return false;1454}14551456// Find the address of the callee function1457lldb_private::Scalar I;1458const llvm::Value *val = call_inst->getCalledOperand();14591460if (!frame.EvaluateValue(I, val, module)) {1461error.SetErrorToGenericError();1462error.SetErrorString("unable to get address of function");1463return false;1464}1465lldb_private::Address funcAddr(I.ULongLong(LLDB_INVALID_ADDRESS));14661467lldb_private::DiagnosticManager diagnostics;1468lldb_private::EvaluateExpressionOptions options;14691470llvm::FunctionType *prototype = call_inst->getFunctionType();14711472// Find number of arguments1473const int numArgs = call_inst->arg_size();14741475// We work with a fixed array of 16 arguments which is our upper limit1476static lldb_private::ABI::CallArgument rawArgs[16];1477if (numArgs >= 16) {1478error.SetErrorToGenericError();1479error.SetErrorString("function takes too many arguments");1480return false;1481}14821483// Push all function arguments to the argument list that will be passed1484// to the call function thread plan1485for (int i = 0; i < numArgs; i++) {1486// Get details of this argument1487llvm::Value *arg_op = call_inst->getArgOperand(i);1488llvm::Type *arg_ty = arg_op->getType();14891490// Ensure that this argument is an supported type1491if (!arg_ty->isIntegerTy() && !arg_ty->isPointerTy()) {1492error.SetErrorToGenericError();1493error.SetErrorStringWithFormat("argument %d must be integer type", i);1494return false;1495}14961497// Extract the arguments value1498lldb_private::Scalar tmp_op = 0;1499if (!frame.EvaluateValue(tmp_op, arg_op, module)) {1500error.SetErrorToGenericError();1501error.SetErrorStringWithFormat("unable to evaluate argument %d", i);1502return false;1503}15041505// Check if this is a string literal or constant string pointer1506if (arg_ty->isPointerTy()) {1507lldb::addr_t addr = tmp_op.ULongLong();1508size_t dataSize = 0;15091510bool Success = execution_unit.GetAllocSize(addr, dataSize);1511UNUSED_IF_ASSERT_DISABLED(Success);1512assert(Success &&1513"unable to locate host data for transfer to device");1514// Create the required buffer1515rawArgs[i].size = dataSize;1516rawArgs[i].data_up.reset(new uint8_t[dataSize + 1]);15171518// Read string from host memory1519execution_unit.ReadMemory(rawArgs[i].data_up.get(), addr, dataSize,1520error);1521assert(!error.Fail() &&1522"we have failed to read the string from memory");15231524// Add null terminator1525rawArgs[i].data_up[dataSize] = '\0';1526rawArgs[i].type = lldb_private::ABI::CallArgument::HostPointer;1527} else /* if ( arg_ty->isPointerTy() ) */1528{1529rawArgs[i].type = lldb_private::ABI::CallArgument::TargetValue;1530// Get argument size in bytes1531rawArgs[i].size = arg_ty->getIntegerBitWidth() / 8;1532// Push value into argument list for thread plan1533rawArgs[i].value = tmp_op.ULongLong();1534}1535}15361537// Pack the arguments into an llvm::array1538llvm::ArrayRef<lldb_private::ABI::CallArgument> args(rawArgs, numArgs);15391540// Setup a thread plan to call the target function1541lldb::ThreadPlanSP call_plan_sp(1542new lldb_private::ThreadPlanCallFunctionUsingABI(1543exe_ctx.GetThreadRef(), funcAddr, *prototype, *returnType, args,1544options));15451546// Check if the plan is valid1547lldb_private::StreamString ss;1548if (!call_plan_sp || !call_plan_sp->ValidatePlan(&ss)) {1549error.SetErrorToGenericError();1550error.SetErrorStringWithFormat(1551"unable to make ThreadPlanCallFunctionUsingABI for 0x%llx",1552I.ULongLong());1553return false;1554}15551556process->SetRunningUserExpression(true);15571558// Execute the actual function call thread plan1559lldb::ExpressionResults res =1560process->RunThreadPlan(exe_ctx, call_plan_sp, options, diagnostics);15611562// Check that the thread plan completed successfully1563if (res != lldb::ExpressionResults::eExpressionCompleted) {1564error.SetErrorToGenericError();1565error.SetErrorString("ThreadPlanCallFunctionUsingABI failed");1566return false;1567}15681569process->SetRunningUserExpression(false);15701571// Void return type1572if (returnType->isVoidTy()) {1573// Cant assign to void types, so we leave the frame untouched1574} else1575// Integer or pointer return type1576if (returnType->isIntegerTy() || returnType->isPointerTy()) {1577// Get the encapsulated return value1578lldb::ValueObjectSP retVal = call_plan_sp.get()->GetReturnValueObject();15791580lldb_private::Scalar returnVal = -1;1581lldb_private::ValueObject *vobj = retVal.get();15821583// Check if the return value is valid1584if (vobj == nullptr || !retVal) {1585error.SetErrorToGenericError();1586error.SetErrorString("unable to get the return value");1587return false;1588}15891590// Extract the return value as a integer1591lldb_private::Value &value = vobj->GetValue();1592returnVal = value.GetScalar();15931594// Push the return value as the result1595frame.AssignValue(inst, returnVal, module);1596}1597} break;1598}15991600++frame.m_ii;1601}16021603return false;1604}160516061607