Skip to content
IRInterpreter.cpp 71.4 KiB
Newer Older
                        log->Printf("Unsupported instruction: %s", PrintValue(ii).c_str());
                    err.SetErrorToGenericError();
                    err.SetErrorString(unsupported_opcode_error);
                    return false;
                }
            case Instruction::Add:
            case Instruction::Alloca:
            case Instruction::BitCast:
            case Instruction::Br:
            case Instruction::GetElementPtr:
                break;
            case Instruction::ICmp:
                {
                    ICmpInst *icmp_inst = dyn_cast<ICmpInst>(ii);
                    
                    if (!icmp_inst)
                    {
                        err.SetErrorToGenericError();
                        err.SetErrorString(interpreter_internal_error);
                    
                    switch (icmp_inst->getPredicate())
                    {
                    default:
                        {
                            if (log)
                                log->Printf("Unsupported ICmp predicate: %s", PrintValue(ii).c_str());
                            
                            err.SetErrorToGenericError();
                            err.SetErrorString(unsupported_opcode_error);
                            return false;
                        }
                    case CmpInst::ICMP_EQ:
                    case CmpInst::ICMP_NE:
                    case CmpInst::ICMP_UGT:
                    case CmpInst::ICMP_UGE:
                    case CmpInst::ICMP_ULT:
                    case CmpInst::ICMP_ULE:
                    case CmpInst::ICMP_SGT:
                    case CmpInst::ICMP_SGE:
                    case CmpInst::ICMP_SLT:
                    case CmpInst::ICMP_SLE:
                        break;
                    }
                }
                break;
            case Instruction::And:
            case Instruction::AShr:
            case Instruction::IntToPtr:
            case Instruction::PtrToInt:
            case Instruction::Load:
            case Instruction::LShr:
            case Instruction::Mul:
            case Instruction::Or:
            case Instruction::Ret:
            case Instruction::SDiv:
            case Instruction::Shl:
            case Instruction::SRem:
            case Instruction::Store:
            case Instruction::Sub:
            case Instruction::UDiv:
            case Instruction::URem:
            case Instruction::Xor:
            case Instruction::ZExt:
                break;
            }
        }
    }
    
    return true;
}

bool 
IRInterpreter::runOnFunction (lldb::ClangExpressionVariableSP &result,
                              const lldb_private::ConstString &result_name,
                              lldb_private::TypeFromParser result_type,
                              Function &llvm_function,
                              Module &llvm_module,
                              lldb_private::Error &err)
{
    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
    
    lldb_private::ClangExpressionDeclMap::TargetInfo target_info = m_decl_map.GetTargetInfo();
    
    if (!target_info.IsValid())
    {
        err.SetErrorToGenericError();
        err.SetErrorString(interpreter_initialization_error);
    
    lldb::addr_t alloc_min;
    lldb::addr_t alloc_max;
    
    switch (target_info.address_byte_size)
    {
    default:
        err.SetErrorToGenericError();
        err.SetErrorString(interpreter_initialization_error);
        return false;    
    case 4:
        alloc_min = 0x00001000llu;
        alloc_max = 0x0000ffffllu;
        break;
    case 8:
        alloc_min = 0x0000000000001000llu;
        alloc_max = 0x000000000000ffffllu;
        break;
    }
    
    DataLayout target_data(&llvm_module);
    if (target_data.getPointerSize(0) != target_info.address_byte_size)
    {
        err.SetErrorToGenericError();
        err.SetErrorString(interpreter_initialization_error);
    if (target_data.isLittleEndian() != (target_info.byte_order == lldb::eByteOrderLittle))
    {
        err.SetErrorToGenericError();
        err.SetErrorString(interpreter_initialization_error);
    
    Memory memory(target_data, m_decl_map, alloc_min, alloc_max);
    InterpreterStackFrame frame(target_data, memory, m_decl_map);

    uint32_t num_insts = 0;
    
    frame.Jump(llvm_function.begin());
    
    while (frame.m_ii != frame.m_ie && (++num_insts < 4096))
    {
        const Instruction *inst = frame.m_ii;
        
        if (log)
            log->Printf("Interpreting %s", PrintValue(inst).c_str());
        
        switch (inst->getOpcode())
        {
        default:
            break;
        case Instruction::Add:
        case Instruction::Sub:
        case Instruction::Mul:
        case Instruction::SDiv:
        case Instruction::UDiv:
        case Instruction::SRem:
        case Instruction::URem:
        case Instruction::Shl:
        case Instruction::LShr:
        case Instruction::AShr:
        case Instruction::And:
        case Instruction::Or:
        case Instruction::Xor:
            {
                const BinaryOperator *bin_op = dyn_cast<BinaryOperator>(inst);
                
                if (!bin_op)
                {
                    if (log)
                        log->Printf("getOpcode() returns %s, but instruction is not a BinaryOperator", inst->getOpcodeName());
                    err.SetErrorToGenericError();
                    err.SetErrorString(interpreter_internal_error);
                    return false;                
                }
                
                Value *lhs = inst->getOperand(0);
                Value *rhs = inst->getOperand(1);
                
                lldb_private::Scalar L;
                lldb_private::Scalar R;
                
                if (!frame.EvaluateValue(L, lhs, llvm_module))
                {
                    if (log)
                        log->Printf("Couldn't evaluate %s", PrintValue(lhs).c_str());
                    err.SetErrorToGenericError();
                    err.SetErrorString(bad_value_error);
                    return false;
                }
                
                if (!frame.EvaluateValue(R, rhs, llvm_module))
                {
                    if (log)
                        log->Printf("Couldn't evaluate %s", PrintValue(rhs).c_str());
                    err.SetErrorToGenericError();
                    err.SetErrorString(bad_value_error);                 
                    return false;
                }
                
                lldb_private::Scalar result;
                
                switch (inst->getOpcode())
                {
                default:
                    break;
                case Instruction::Add:
                    result = L + R;
                    break;
                case Instruction::Mul:
                    result = L * R;
                    break;
                case Instruction::Sub:
                    result = L - R;
                    break;
                case Instruction::SDiv:
                    result = L / R;
                    break;
                case Instruction::UDiv:
                    result = L.GetRawBits64(0) / R.GetRawBits64(1);
                    break;
                case Instruction::SRem:
                    result = L % R;
                    break;
                case Instruction::URem:
                    result = L.GetRawBits64(0) % R.GetRawBits64(1);
                    break;
                case Instruction::Shl:
                    result = L << R;
                    break;
                case Instruction::AShr:
                    result = L >> R;
                    break;
                case Instruction::LShr:
                    result = L;
                    result.ShiftRightLogical(R);
                    break;
                case Instruction::And:
                    result = L & R;
                    break;
                case Instruction::Or:
                    result = L | R;
                    break;
                case Instruction::Xor:
                    result = L ^ R;
                    break;
                }
                                
                frame.AssignValue(inst, result, llvm_module);
                
                if (log)
                {
                    log->Printf("Interpreted a %s", inst->getOpcodeName());
                    log->Printf("  L : %s", frame.SummarizeValue(lhs).c_str());
                    log->Printf("  R : %s", frame.SummarizeValue(rhs).c_str());
                    log->Printf("  = : %s", frame.SummarizeValue(inst).c_str());
                }
            }
            break;
        case Instruction::Alloca:
            {
                const AllocaInst *alloca_inst = dyn_cast<AllocaInst>(inst);
                
                if (!alloca_inst)
                {
                    if (log)
                        log->Printf("getOpcode() returns Alloca, but instruction is not an AllocaInst");
                    err.SetErrorToGenericError();
                    err.SetErrorString(interpreter_internal_error);
                    return false;
                }
                
                if (alloca_inst->isArrayAllocation())
                {
                    if (log)
                        log->Printf("AllocaInsts are not handled if isArrayAllocation() is true");
                    err.SetErrorToGenericError();
                    err.SetErrorString(unsupported_opcode_error);
                    return false;
                }
                
                // The semantics of Alloca are:
                //   Create a region R of virtual memory of type T, backed by a data buffer
                //   Create a region P of virtual memory of type T*, backed by a data buffer
                //   Write the virtual address of R into P
                
                Type *T = alloca_inst->getAllocatedType();
                Type *Tptr = alloca_inst->getType();
                
                Memory::Region R = memory.Malloc(T);
                
                if (R.IsInvalid())
                {
                    if (log)
                        log->Printf("Couldn't allocate memory for an AllocaInst");
                    err.SetErrorToGenericError();
                    err.SetErrorString(memory_allocation_error);
                    return false;
                }
                
                Memory::Region P = memory.Malloc(Tptr);
                
                if (P.IsInvalid())
                {
                    if (log)
                        log->Printf("Couldn't allocate the result pointer for an AllocaInst");
                    err.SetErrorToGenericError();
                    err.SetErrorString(memory_allocation_error);
                    return false;
                }
                
                DataEncoderSP P_encoder = memory.GetEncoder(P);
                
                if (P_encoder->PutAddress(0, R.m_base) == UINT32_MAX)
                {
                    if (log)
                        log->Printf("Couldn't write the result pointer for an AllocaInst");
                    err.SetErrorToGenericError();
                    err.SetErrorString(memory_write_error);
                    return false;
                }
                
                frame.m_values[alloca_inst] = P;
                
                if (log)
                {
                    log->Printf("Interpreted an AllocaInst");
                    log->Printf("  R : %s", memory.SummarizeRegion(R).c_str());
                    log->Printf("  P : %s", frame.SummarizeValue(alloca_inst).c_str());
                }
            }
            break;
        case Instruction::BitCast:
        case Instruction::ZExt:
                const CastInst *cast_inst = dyn_cast<CastInst>(inst);
                if (!cast_inst)
                        log->Printf("getOpcode() returns %s, but instruction is not a BitCastInst", cast_inst->getOpcodeName());
                    err.SetErrorToGenericError();
                    err.SetErrorString(interpreter_internal_error);
                Value *source = cast_inst->getOperand(0);
                
                lldb_private::Scalar S;
                
                if (!frame.EvaluateValue(S, source, llvm_module))
                {
                    if (log)
                        log->Printf("Couldn't evaluate %s", PrintValue(source).c_str());
                    err.SetErrorToGenericError();
                    err.SetErrorString(bad_value_error);
                    return false;
                }
                
                frame.AssignValue(inst, S, llvm_module);
            }
            break;
        case Instruction::Br:
            {
                const BranchInst *br_inst = dyn_cast<BranchInst>(inst);
                
                if (!br_inst)
                {
                    if (log)
                        log->Printf("getOpcode() returns Br, but instruction is not a BranchInst");
                    err.SetErrorToGenericError();
                    err.SetErrorString(interpreter_internal_error);
                    return false;
                }
                
                if (br_inst->isConditional())
                {
                    Value *condition = br_inst->getCondition();
                    
                    lldb_private::Scalar C;
                    
                    if (!frame.EvaluateValue(C, condition, llvm_module))
                    {
                        if (log)
                            log->Printf("Couldn't evaluate %s", PrintValue(condition).c_str());
                        err.SetErrorToGenericError();
                        err.SetErrorString(bad_value_error);
                        return false;
                    }
                
                    if (C.GetRawBits64(0))
                        frame.Jump(br_inst->getSuccessor(0));
                    else
                        frame.Jump(br_inst->getSuccessor(1));
                    
                    if (log)
                    {
                        log->Printf("Interpreted a BrInst with a condition");
                        log->Printf("  cond : %s", frame.SummarizeValue(condition).c_str());
                    }
                }
                else
                {
                    frame.Jump(br_inst->getSuccessor(0));
                    
                    if (log)
                    {
                        log->Printf("Interpreted a BrInst with no condition");
                    }
                }
            }
            continue;
        case Instruction::GetElementPtr:
            {
                const GetElementPtrInst *gep_inst = dyn_cast<GetElementPtrInst>(inst);
                
                if (!gep_inst)
                {
                    if (log)
                        log->Printf("getOpcode() returns GetElementPtr, but instruction is not a GetElementPtrInst");
                    err.SetErrorToGenericError();
                    err.SetErrorString(interpreter_internal_error);
                    return false;
                }
             
                const Value *pointer_operand = gep_inst->getPointerOperand();
                Type *pointer_type = pointer_operand->getType();
                
                lldb_private::Scalar P;
                
                if (!frame.EvaluateValue(P, pointer_operand, llvm_module))
                {
                    if (log)
                        log->Printf("Couldn't evaluate %s", PrintValue(pointer_operand).c_str());
                    err.SetErrorToGenericError();
                    err.SetErrorString(bad_value_error);
                typedef SmallVector <Value *, 8> IndexVector;
                typedef IndexVector::iterator IndexIterator;
                
                SmallVector <Value *, 8> indices (gep_inst->idx_begin(),
                                                  gep_inst->idx_end());
                
                SmallVector <Value *, 8> const_indices;
                
                for (IndexIterator ii = indices.begin(), ie = indices.end();
                     ii != ie;
                     ++ii)
                {
                    ConstantInt *constant_index = dyn_cast<ConstantInt>(*ii);
                    
                    if (!constant_index)
                    {
                        lldb_private::Scalar I;
                        
                        if (!frame.EvaluateValue(I, *ii, llvm_module))
                        {
                            if (log)
                                log->Printf("Couldn't evaluate %s", PrintValue(*ii).c_str());
                            err.SetErrorToGenericError();
                            err.SetErrorString(bad_value_error);
                            return false;
                        }
                        
                        if (log)
                            log->Printf("Evaluated constant index %s as %llu", PrintValue(*ii).c_str(), I.ULongLong(LLDB_INVALID_ADDRESS));
                        
                        constant_index = cast<ConstantInt>(ConstantInt::get((*ii)->getType(), I.ULongLong(LLDB_INVALID_ADDRESS)));
                    }
                    
                    const_indices.push_back(constant_index);
                }
                
                uint64_t offset = target_data.getIndexedOffset(pointer_type, const_indices);
                
                lldb_private::Scalar Poffset = P + offset;
                
                frame.AssignValue(inst, Poffset, llvm_module);
                
                if (log)
                {
                    log->Printf("Interpreted a GetElementPtrInst");
                    log->Printf("  P       : %s", frame.SummarizeValue(pointer_operand).c_str());
                    log->Printf("  Poffset : %s", frame.SummarizeValue(inst).c_str());
                }
            }
            break;
        case Instruction::ICmp:
            {
                const ICmpInst *icmp_inst = dyn_cast<ICmpInst>(inst);
                
                if (!icmp_inst)
                {
                    if (log)
                        log->Printf("getOpcode() returns ICmp, but instruction is not an ICmpInst");
                    err.SetErrorToGenericError();
                    err.SetErrorString(interpreter_internal_error);
                    return false;
                }
                
                CmpInst::Predicate predicate = icmp_inst->getPredicate();
                
                Value *lhs = inst->getOperand(0);
                Value *rhs = inst->getOperand(1);
                
                lldb_private::Scalar L;
                lldb_private::Scalar R;
                
                if (!frame.EvaluateValue(L, lhs, llvm_module))
                {
                    if (log)
                        log->Printf("Couldn't evaluate %s", PrintValue(lhs).c_str());
                    err.SetErrorToGenericError();
                    err.SetErrorString(bad_value_error);
                    return false;
                }
                
                if (!frame.EvaluateValue(R, rhs, llvm_module))
                {
                    if (log)
                        log->Printf("Couldn't evaluate %s", PrintValue(rhs).c_str());
                    err.SetErrorToGenericError();
                    err.SetErrorString(bad_value_error);
                    return false;
                }
                
                lldb_private::Scalar result;

                switch (predicate)
                {
                default:
                    return false;
                case CmpInst::ICMP_EQ:
                    result = (L == R);
                    break;
                case CmpInst::ICMP_NE:
                    result = (L != R);
                    break;    
                case CmpInst::ICMP_UGT:
                    result = (L.GetRawBits64(0) > R.GetRawBits64(0));
                    break;
                case CmpInst::ICMP_UGE:
                    result = (L.GetRawBits64(0) >= R.GetRawBits64(0));
                    break;
                case CmpInst::ICMP_ULT:
                    result = (L.GetRawBits64(0) < R.GetRawBits64(0));
                    break;
                case CmpInst::ICMP_ULE:
                    result = (L.GetRawBits64(0) <= R.GetRawBits64(0));
                    break;
                case CmpInst::ICMP_SGT:
                    result = (L > R);
                    break;
                case CmpInst::ICMP_SGE:
                    result = (L >= R);
                    break;
                case CmpInst::ICMP_SLT:
                    result = (L < R);
                    break;
                case CmpInst::ICMP_SLE:
                    result = (L <= R);
                    break;
                }
                
                frame.AssignValue(inst, result, llvm_module);
                
                if (log)
                {
                    log->Printf("Interpreted an ICmpInst");
                    log->Printf("  L : %s", frame.SummarizeValue(lhs).c_str());
                    log->Printf("  R : %s", frame.SummarizeValue(rhs).c_str());
                    log->Printf("  = : %s", frame.SummarizeValue(inst).c_str());
                }
            }
            break;
        case Instruction::IntToPtr:
            {
                const IntToPtrInst *int_to_ptr_inst = dyn_cast<IntToPtrInst>(inst);
                
                if (!int_to_ptr_inst)
                {
                    if (log)
                        log->Printf("getOpcode() returns IntToPtr, but instruction is not an IntToPtrInst");
                    err.SetErrorToGenericError();
                    err.SetErrorString(interpreter_internal_error);
                    return false;
                }
                
                Value *src_operand = int_to_ptr_inst->getOperand(0);
                
                lldb_private::Scalar I;
                
                if (!frame.EvaluateValue(I, src_operand, llvm_module))
                {
                    if (log)
                        log->Printf("Couldn't evaluate %s", PrintValue(src_operand).c_str());
                    err.SetErrorToGenericError();
                    err.SetErrorString(bad_value_error);
                
                frame.AssignValue(inst, I, llvm_module);
                
                if (log)
                {
                    log->Printf("Interpreted an IntToPtr");
                    log->Printf("  Src : %s", frame.SummarizeValue(src_operand).c_str());
                    log->Printf("  =   : %s", frame.SummarizeValue(inst).c_str()); 
                }
            }
            break;
        case Instruction::PtrToInt:
            {
                const PtrToIntInst *ptr_to_int_inst = dyn_cast<PtrToIntInst>(inst);
                
                if (!ptr_to_int_inst)
                {
                    if (log)
                        log->Printf("getOpcode() returns PtrToInt, but instruction is not an PtrToIntInst");
                    err.SetErrorToGenericError();
                    err.SetErrorString(interpreter_internal_error);
                    return false;
                }
                
                Value *src_operand = ptr_to_int_inst->getOperand(0);
                
                lldb_private::Scalar I;
                
                if (!frame.EvaluateValue(I, src_operand, llvm_module))
                {
                    if (log)
                        log->Printf("Couldn't evaluate %s", PrintValue(src_operand).c_str());
                    err.SetErrorToGenericError();
                    err.SetErrorString(bad_value_error);
                    return false;
                }
                
                frame.AssignValue(inst, I, llvm_module);
                
                if (log)
                {
                    log->Printf("Interpreted a PtrToInt");
                    log->Printf("  Src : %s", frame.SummarizeValue(src_operand).c_str());
                    log->Printf("  =   : %s", frame.SummarizeValue(inst).c_str());
                }
            }
            break;
        case Instruction::Load:
            {
                const LoadInst *load_inst = dyn_cast<LoadInst>(inst);
                
                if (!load_inst)
                {
                    if (log)
                        log->Printf("getOpcode() returns Load, but instruction is not a LoadInst");
                    err.SetErrorToGenericError();
                    err.SetErrorString(interpreter_internal_error);
                    return false;
                }
                
                // The semantics of Load are:
                //   Create a region D that will contain the loaded data
                //   Resolve the region P containing a pointer
                //   Dereference P to get the region R that the data should be loaded from
                //   Transfer a unit of type type(D) from R to D
                                
                const Value *pointer_operand = load_inst->getPointerOperand();
                
                Type *pointer_ty = pointer_operand->getType();
                PointerType *pointer_ptr_ty = dyn_cast<PointerType>(pointer_ty);
                if (!pointer_ptr_ty)
                {
                    if (log)
                        log->Printf("getPointerOperand()->getType() is not a PointerType");
                    err.SetErrorToGenericError();
                    err.SetErrorString(interpreter_internal_error);
                Type *target_ty = pointer_ptr_ty->getElementType();
                
                Memory::Region D = frame.ResolveValue(load_inst, llvm_module);
                Memory::Region P = frame.ResolveValue(pointer_operand, llvm_module);
                
                if (D.IsInvalid())
                {
                    if (log)
                        log->Printf("LoadInst's value doesn't resolve to anything");
                    err.SetErrorToGenericError();
                    err.SetErrorString(bad_value_error);
                    return false;
                }
                
                if (P.IsInvalid())
                {
                    if (log)
                        log->Printf("LoadInst's pointer doesn't resolve to anything");
                    err.SetErrorToGenericError();
                    err.SetErrorString(bad_value_error);
                    return false;
                }
                
                DataExtractorSP P_extractor(memory.GetExtractor(P));
                DataEncoderSP D_encoder(memory.GetEncoder(D));

Greg Clayton's avatar
Greg Clayton committed
                lldb::offset_t offset = 0;
                lldb::addr_t pointer = P_extractor->GetAddress(&offset);
                
                Memory::Region R = memory.Lookup(pointer, target_ty);
                
                if (R.IsValid())
                {
                    if (!memory.Read(D_encoder->GetDataStart(), R.m_base, target_data.getTypeStoreSize(target_ty)))
                    {
                        if (log)
                            log->Printf("Couldn't read from a region on behalf of a LoadInst");
                        err.SetErrorToGenericError();
                        err.SetErrorString(memory_read_error);
                        return false;
                    }
                }
                else
                {
                    if (!memory.ReadFromRawPtr(D_encoder->GetDataStart(), pointer, target_data.getTypeStoreSize(target_ty)))
                    {
                        if (log)
                            log->Printf("Couldn't read from a raw pointer on behalf of a LoadInst");
                        err.SetErrorToGenericError();
                        err.SetErrorString(memory_read_error);
                
                if (log)
                {
                    log->Printf("Interpreted a LoadInst");
                    log->Printf("  P : %s", frame.SummarizeValue(pointer_operand).c_str());
                    if (R.IsValid())
                        log->Printf("  R : %s", memory.SummarizeRegion(R).c_str());
                    else
                        log->Printf("  R : raw pointer 0x%llx", (unsigned long long)pointer);
                    log->Printf("  D : %s", frame.SummarizeValue(load_inst).c_str());
                }
            }
            break;
        case Instruction::Ret:
            {
                if (result_name.IsEmpty())
                    return true;
                
                GlobalValue *result_value = llvm_module.getNamedValue(result_name.GetCString());
                
                if (!frame.ConstructResult(result, result_value, result_name, result_type, llvm_module))
                {
                    if (log)
                        log->Printf("Couldn't construct the expression's result");
                    err.SetErrorToGenericError();
                    err.SetErrorString(bad_result_error);
                    return false;
                }
                
                return true;
            }
        case Instruction::Store:
            {
                const StoreInst *store_inst = dyn_cast<StoreInst>(inst);
                
                if (!store_inst)
                {
                    if (log)
                        log->Printf("getOpcode() returns Store, but instruction is not a StoreInst");
                    err.SetErrorToGenericError();
                    err.SetErrorString(interpreter_internal_error);
                    return false;
                }
                
                // The semantics of Store are:
                //   Resolve the region D containing the data to be stored
                //   Resolve the region P containing a pointer
                //   Dereference P to get the region R that the data should be stored in
                //   Transfer a unit of type type(D) from D to R
                
                const Value *value_operand = store_inst->getValueOperand();
                const Value *pointer_operand = store_inst->getPointerOperand();
                
                Type *pointer_ty = pointer_operand->getType();
                PointerType *pointer_ptr_ty = dyn_cast<PointerType>(pointer_ty);
                if (!pointer_ptr_ty)
                    return false;
                Type *target_ty = pointer_ptr_ty->getElementType();
                
                Memory::Region D = frame.ResolveValue(value_operand, llvm_module);
                Memory::Region P = frame.ResolveValue(pointer_operand, llvm_module);
                
                if (D.IsInvalid())
                {
                    if (log)
                        log->Printf("StoreInst's value doesn't resolve to anything");
                    err.SetErrorToGenericError();
                    err.SetErrorString(bad_value_error);
                    return false;
                }
                
                if (P.IsInvalid())
                {
                    if (log)
                        log->Printf("StoreInst's pointer doesn't resolve to anything");
                    err.SetErrorToGenericError();
                    err.SetErrorString(bad_value_error);
                    return false;
                }
                
                DataExtractorSP P_extractor(memory.GetExtractor(P));
                DataExtractorSP D_extractor(memory.GetExtractor(D));

                if (!P_extractor || !D_extractor)
                    return false;
                
Greg Clayton's avatar
Greg Clayton committed
                lldb::offset_t offset = 0;
                lldb::addr_t pointer = P_extractor->GetAddress(&offset);
                
                Memory::Region R = memory.Lookup(pointer, target_ty);
                
                    if (!memory.Write(R.m_base, D_extractor->GetDataStart(), target_data.getTypeStoreSize(target_ty)))
                    {
                        if (log)
                            log->Printf("Couldn't write to a region on behalf of a LoadInst");
                        err.SetErrorToGenericError();
                        err.SetErrorString(memory_write_error);
                        return false;
                    }
                }
                else
                {
                    if (!memory.WriteToRawPtr(pointer, D_extractor->GetDataStart(), target_data.getTypeStoreSize(target_ty)))
                    {
                        if (log)
                            log->Printf("Couldn't write to a raw pointer on behalf of a LoadInst");
                        err.SetErrorToGenericError();
                        err.SetErrorString(memory_write_error);
                }
                
                
                if (log)
                {
                    log->Printf("Interpreted a StoreInst");
                    log->Printf("  D : %s", frame.SummarizeValue(value_operand).c_str());
                    log->Printf("  P : %s", frame.SummarizeValue(pointer_operand).c_str());
                    log->Printf("  R : %s", memory.SummarizeRegion(R).c_str());
                }
            }
            break;
        }
        
        ++frame.m_ii;
    }
    
    if (num_insts >= 4096)
    {
        err.SetErrorToGenericError();
        err.SetErrorString(infinite_loop_error);