Beispiel #1
0
void ReleaseDialog::release()
{
    setTitle("发布版本");
    QString pwd = lineedit_pwd->text();
    QString name = lineedit_name->text();
    if(pwd.isEmpty() || name.isEmpty() || name.size() > 16)
    {
        QString prompt;
        prompt = QString("必须设置加密密码\n填写版本信息。");
        if(name.size() > 16)
            prompt = QString("版本信息不能超过16个字符。");
        QMessageBox box(QMessageBox::Information, "提示", prompt);
        box.setStandardButtons(QMessageBox::Ok);
        box.setButtonText(QMessageBox::Ok, "确定");
        box.exec();
        return;
    }

    ////name 最大16个字符
    if(!setFilePath())
    {
        QMessageBox::information(NULL, "提示", "文件路径设置失败!");
        return;
    }

    bar->setHidden(false);

    QDateTime start,end;
    getDateTime(start, end);
    QString jsonfilePath = getReadFilePath(start, end);

    this->setCursor(Qt::WaitCursor);
    ///读JSON下载资源
    readJsonFile(jsonfilePath);

    ///打包
    QStringList fileNames = getCurrentDirFiles(releasePath);
    QString destPath  = QCoreApplication::applicationDirPath();
    destPath.append("/ZIP/");
    QDir dir(destPath);
    if(!dir.exists())
        dir.mkpath(destPath);
    QString destName = currentDate.toString("yyyy-MM-dd_hh_mm_ss");
    destName.append(".zip");
    destPath.append(destName);

    QFile destFile(destPath);
    if(destFile.exists())
    {
    }

    zipFile zf;
    QByteArray dest = destPath.toLocal8Bit();
    zf = zipOpen(dest.data(), APPEND_STATUS_CREATE);


    if (zf == NULL)
    {
        QMessageBox::information(NULL, "提示", "打开压缩文件失败!");
        return;
    }

   label_title->setText("压缩文件……");
//   LOKI_ON_BLOCK_EXIT(zipClose, zf, (const char *)NULL);
   for (int i=0; i<fileNames.size(); i++)
   {
       QString tempStr = fileNames.at(i);
       QString path = releasePath;
       path.remove("music");
       QString temprel = path;
       QString deststr = tempStr.remove(temprel);
       if (!ZipAddFile(zf, deststr, fileNames.at(i),  pwd,  true)) //"default_yqc"
       {
           continue;
       }
   }

   int errclose = zipClose(zf, NULL);
   if (errclose != ZIP_OK)
       qDebug() << " zipClose ret : " << errclose;


   label_title->setText("上传压缩包……");

   QFile file(destPath);
   qDebug() << " size " << file.size();
   if(file.size()/1024/1024 >= 1024)
   {
        QMessageBox::information(this, "提示", "上传文件大小必须小于1G!");
        return;
   }
   ///上传打包文件
//   QString url;
//   CurlUpload *curlUpload = new CurlUpload();
//   bool ok = curlUpload->uploadYQDyun(destName, destPath, url);


//   if(!ok)
//   {
//       url = "";
//       label_title->setText("上传失败");
//       label_title->setStyleSheet("color:rgb(255, 0, 0);");
//   }
//   else
//   {
//       label_title->setText("上传成功");
//       label_title->setStyleSheet("color:rgb(0, 255, 0);");
//   }

//   qDebug() << " upload yun : ok : " << ok;
//   qDebug() << " zip name " << destName;
//   qDebug() << " url " << url;
//   /// post 表格数据
   QDateTime time = QDateTime::currentDateTime();
   QString timeStr = time.toString("yyyy-MM-dd-hh-mm-ss");
   int version = time.toTime_t(); ///时间戳
//   QString postStr = QString("name=%1&url=%2&time=%3&remark=%4&version=%5")
//                            .arg(name)
//                            .arg(url)
//                            .arg(timeStr)
//                            .arg(pwd)
//                            .arg(version);


//   CurlUpload *curlDownlaod = new CurlUpload();
//   curlDownlaod->postJson(postStr);


   _yun.name = name;
   _yun.timeStr = timeStr;
   _yun.pwd = pwd;
   _yun.version = QString::number(version);

   this->setCursor(Qt::ArrowCursor);
//   return;

   ////
   ///线程上传
   retSize = "-2";
   Thread *workerThread = new Thread(this, 4);
   connect(workerThread, &Thread::resultYun, this, &ReleaseDialog::uploadsuccess);
   connect(workerThread, &Thread::start_upload, this, &ReleaseDialog::timeStart);
   connect(workerThread, &Thread::finished, workerThread, &QObject::deleteLater);
   workerThread->setUploadYun(destName, destPath, &retSize);
   workerThread->start();
   startValue = true;
}
Beispiel #2
0
bool
ABIMacOSX_arm::PrepareTrivialCall (Thread &thread, 
                                   addr_t sp, 
                                   addr_t function_addr, 
                                   addr_t return_addr, 
                                   llvm::ArrayRef<addr_t> args) const
{
    RegisterContext *reg_ctx = thread.GetRegisterContext().get();
    if (!reg_ctx)
        return false;    

    const uint32_t pc_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
    const uint32_t sp_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
    const uint32_t ra_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA);

    RegisterValue reg_value;

    const char *reg_names[] = { "r0", "r1", "r2", "r3" };
    
    llvm::ArrayRef<addr_t>::iterator ai = args.begin(), ae = args.end();
    
    for (size_t i = 0; i < llvm::array_lengthof(reg_names); ++i)
    {
        if (ai == ae)
            break;
        
        reg_value.SetUInt32(*ai);
        if (!reg_ctx->WriteRegister(reg_ctx->GetRegisterInfoByName(reg_names[i]), reg_value))
            return false;
        
        ++ai;
    }
    
    if (ai != ae)
    {
        // Spill onto the stack
        size_t num_stack_regs = ae - ai;
        
        sp -= (num_stack_regs * 4);
        // Keep the stack 8 byte aligned, not that we need to
        sp &= ~(8ull-1ull);
        
        // just using arg1 to get the right size
        const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1);
        
        addr_t arg_pos = sp;
        
        for (; ai != ae; ++ai)
        {
            reg_value.SetUInt32(*ai);
            if (reg_ctx->WriteRegisterValueToMemory(reg_info, arg_pos, reg_info->byte_size, reg_value).Fail())
                return false;
            arg_pos += reg_info->byte_size;
        }
    }
    
    TargetSP target_sp (thread.CalculateTarget());
    Address so_addr;

    // Figure out if our return address is ARM or Thumb by using the 
    // Address::GetCallableLoadAddress(Target*) which will figure out the ARM
    // thumb-ness and set the correct address bits for us.
    so_addr.SetLoadAddress (return_addr, target_sp.get());
    return_addr = so_addr.GetCallableLoadAddress (target_sp.get());

    // Set "lr" to the return address
    if (!reg_ctx->WriteRegisterFromUnsigned (ra_reg_num, return_addr))
        return false;

    // Set "sp" to the requested value
    if (!reg_ctx->WriteRegisterFromUnsigned (sp_reg_num, sp))
        return false;
    
    // If bit zero or 1 is set, this must be a thumb function, no need to figure
    // this out from the symbols.
    so_addr.SetLoadAddress (function_addr, target_sp.get());
    function_addr = so_addr.GetCallableLoadAddress (target_sp.get());
    
    const RegisterInfo *cpsr_reg_info = reg_ctx->GetRegisterInfoByName("cpsr");
    const uint32_t curr_cpsr = reg_ctx->ReadRegisterAsUnsigned(cpsr_reg_info, 0);

    // Make a new CPSR and mask out any Thumb IT (if/then) bits
    uint32_t new_cpsr = curr_cpsr & ~MASK_CPSR_IT_MASK;
    // If bit zero or 1 is set, this must be thumb...
    if (function_addr & 1ull)
        new_cpsr |= MASK_CPSR_T;    // Set T bit in CPSR
    else
        new_cpsr &= ~MASK_CPSR_T;   // Clear T bit in CPSR

    if (new_cpsr != curr_cpsr)
    {
        if (!reg_ctx->WriteRegisterFromUnsigned (cpsr_reg_info, new_cpsr))
            return false;
    }

    function_addr &= ~1ull;   // clear bit zero since the CPSR will take care of the mode for us
    
    // Set "pc" to the address requested
    if (!reg_ctx->WriteRegisterFromUnsigned (pc_reg_num, function_addr))
        return false;

    return true;
}
Beispiel #3
0
ValueObjectSP
ABIMacOSX_arm::GetReturnValueObjectImpl (Thread &thread,
                                         lldb_private::ClangASTType &clang_type) const
{
    Value value;
    ValueObjectSP return_valobj_sp;
    
    if (!clang_type)
        return return_valobj_sp;
    
    clang::ASTContext *ast_context = clang_type.GetASTContext();
    if (!ast_context)
        return return_valobj_sp;

    //value.SetContext (Value::eContextTypeClangType, clang_type.GetOpaqueQualType());
    value.SetClangType (clang_type);
            
    RegisterContext *reg_ctx = thread.GetRegisterContext().get();
    if (!reg_ctx)
        return return_valobj_sp;
        
    bool is_signed;
    
    // Get the pointer to the first stack argument so we have a place to start 
    // when reading data
    
    const RegisterInfo *r0_reg_info = reg_ctx->GetRegisterInfoByName("r0", 0);
    if (clang_type.IsIntegerType (is_signed))
    {
        size_t bit_width = clang_type.GetBitSize();
        
        switch (bit_width)
        {
            default:
                return return_valobj_sp;
            case 64:
            {
                const RegisterInfo *r1_reg_info = reg_ctx->GetRegisterInfoByName("r1", 0);
                uint64_t raw_value;
                raw_value = reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX;
                raw_value |= ((uint64_t)(reg_ctx->ReadRegisterAsUnsigned(r1_reg_info, 0) & UINT32_MAX)) << 32;
                if (is_signed)
                    value.GetScalar() = (int64_t)raw_value;
                else
                    value.GetScalar() = (uint64_t)raw_value;
            }
                break;
            case 32:
                if (is_signed)
                    value.GetScalar() = (int32_t)(reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX);
                else
                    value.GetScalar() = (uint32_t)(reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX);
                break;
            case 16:
                if (is_signed)
                    value.GetScalar() = (int16_t)(reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT16_MAX);
                else
                    value.GetScalar() = (uint16_t)(reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT16_MAX);
                break;
            case 8:
                if (is_signed)
                    value.GetScalar() = (int8_t)(reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT8_MAX);
                else
                    value.GetScalar() = (uint8_t)(reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT8_MAX);
                break;
        }
    }
    else if (clang_type.IsPointerType ())
    {
        uint32_t ptr = thread.GetRegisterContext()->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX;
        value.GetScalar() = ptr;
    }
    else
    {
        // not handled yet
        return return_valobj_sp;
    }
    
    // If we get here, we have a valid Value, so make our ValueObject out of it:
    
    return_valobj_sp = ValueObjectConstResult::Create(thread.GetStackFrameAtIndex(0).get(),
                                                      value,
                                                      ConstString(""));
    return return_valobj_sp;
}
Beispiel #4
0
bool ThreadSpec::IndexMatches(Thread &thread) const {
  if (m_index == UINT32_MAX)
    return true;
  uint32_t index = thread.GetIndexID();
  return IndexMatches(index);
}
Beispiel #5
0
void Thread::split(Position& pos, SearchStack* ss, const Score alpha, const Score beta, Score& bestScore,
				   Move& bestMove, const Depth depth, const Move threatMove, const int moveCount,
				   MovePicker& mp, const NodeType nodeType, const bool cutNode)
{
	assert(pos.isOK());
	assert(bestScore <= alpha && alpha < beta && beta <= ScoreInfinite);
	assert(-ScoreInfinite < bestScore);
	assert(searcher->threads.minSplitDepth() <= depth);

	assert(searching);
	assert(splitPointsSize < MaxSplitPointsPerThread);

	SplitPoint& sp = splitPoints[splitPointsSize];

	sp.masterThread = this;
	sp.parentSplitPoint = activeSplitPoint;
	sp.slavesMask = UINT64_C(1) << idx;
	sp.depth = depth;
	sp.bestMove = bestMove;
	sp.threatMove = threatMove;
	sp.alpha = alpha;
	sp.beta = beta;
	sp.nodeType = nodeType;
	sp.cutNode = cutNode;
	sp.bestScore = bestScore;
	sp.movePicker = &mp;
	sp.moveCount = moveCount;
	sp.pos = &pos;
	sp.nodes = 0;
	sp.cutoff = false;
	sp.ss = ss;

	searcher->threads.mutex_.lock();
	sp.mutex.lock();

	++splitPointsSize;
	activeSplitPoint = &sp;
	activePosition = nullptr;

	// thisThread が常に含まれるので 1
	size_t slavesCount = 1;
	Thread* slave;

	while ((slave = searcher->threads.availableSlave(this)) != nullptr
		   && ++slavesCount <= searcher->threads.maxThreadsPerSplitPoint_ && !Fake)
	{
		sp.slavesMask |= UINT64_C(1) << slave->idx;
		slave->activeSplitPoint = &sp;
		slave->searching = true;
		slave->notifyOne();
	}

	if (1 < slavesCount || Fake) {
		sp.mutex.unlock();
		searcher->threads.mutex_.unlock();
		Thread::idleLoop();
		assert(!searching);
		assert(!activePosition);
		searcher->threads.mutex_.lock();
		sp.mutex.lock();
	}

	searching = true;
	--splitPointsSize;
	activeSplitPoint = sp.parentSplitPoint;
	activePosition = &pos;
	pos.setNodesSearched(pos.nodesSearched() + sp.nodes);
	bestMove = sp.bestMove;
	bestScore = sp.bestScore;

	searcher->threads.mutex_.unlock();
	sp.mutex.unlock();
}
Beispiel #6
0
    void test_memover1(void)
    {
        VM::setAlertGCCallback(alertGC);

        Bytecode* myBytecode = gCodeManager.readBytecode("test.hyb");
        CPPUNIT_ASSERT(myBytecode != NULL);
        myBytecode->setInitialized();

        Value mcls(HC_Class, (void*) myBytecode->mainClass());

        alert_count = prev_alert_count = 0;
        int c = 0;
        while (c < 30) {
            Context* context = gCodeManager.createContext();
            Thread* pThread = gThreadManager.createTmpThread();
            pThread->initialize(context);
            context->pushInt(10);
            context->methodCall(mcls, HSym_create_XClass, 1);
            pThread->start();
            while (pThread->isActive())
                pThread->exec1tick();
            context->pop();
            gCodeManager.releaseContext(context);
            if (check_alert()) ++c;
        }
        c = 0;
        while (c < 30) {
            Context* context = gCodeManager.createContext();
            Thread* pThread = gThreadManager.createTmpThread();
            pThread->initialize(context);
            context->pushInt(500);
            context->methodCall(mcls, HSym_create_XClass, 1);
            pThread->start();
            while (pThread->isActive())
                pThread->exec1tick();
            context->pop();
            gCodeManager.releaseContext(context);
            if (check_alert()) ++c;
        }
        c = 0;
        while (c < 30) {
            Context* context = gCodeManager.createContext();
            Thread* pThread = gThreadManager.createTmpThread();
            pThread->initialize(context);
            context->methodCall(mcls, HSym_create_YClass, 0);
            pThread->start();
            while (pThread->isActive())
                pThread->exec1tick();
            context->pop();
            gCodeManager.releaseContext(context);
            if (check_alert()) ++c;
        }
    }
Beispiel #7
0
ValueObjectSP
ABISysV_arm::GetReturnValueObjectImpl (Thread &thread,
                                       lldb_private::CompilerType &compiler_type) const
{
    Value value;
    ValueObjectSP return_valobj_sp;
    
    if (!compiler_type)
        return return_valobj_sp;
    
    //value.SetContext (Value::eContextTypeClangType, compiler_type.GetOpaqueQualType());
    value.SetCompilerType (compiler_type);
            
    RegisterContext *reg_ctx = thread.GetRegisterContext().get();
    if (!reg_ctx)
        return return_valobj_sp;
        
    bool is_signed;
    bool is_complex;
    uint32_t float_count;
    
    // Get the pointer to the first stack argument so we have a place to start 
    // when reading data
    
    const RegisterInfo *r0_reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1);
    size_t bit_width = compiler_type.GetBitSize(&thread);

    if (compiler_type.IsIntegerType (is_signed))
    {       
        switch (bit_width)
        {
            default:
                return return_valobj_sp;
            case 64:
            {
                const RegisterInfo *r1_reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2);
                uint64_t raw_value;
                raw_value = reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX;
                raw_value |= ((uint64_t)(reg_ctx->ReadRegisterAsUnsigned(r1_reg_info, 0) & UINT32_MAX)) << 32;
                if (is_signed)
                    value.GetScalar() = (int64_t)raw_value;
                else
                    value.GetScalar() = (uint64_t)raw_value;
            }
                break;
            case 32:
                if (is_signed)
                    value.GetScalar() = (int32_t)(reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX);
                else
                    value.GetScalar() = (uint32_t)(reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX);
                break;
            case 16:
                if (is_signed)
                    value.GetScalar() = (int16_t)(reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT16_MAX);
                else
                    value.GetScalar() = (uint16_t)(reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT16_MAX);
                break;
            case 8:
                if (is_signed)
                    value.GetScalar() = (int8_t)(reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT8_MAX);
                else
                    value.GetScalar() = (uint8_t)(reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT8_MAX);
                break;
        }
    }
    else if (compiler_type.IsPointerType ())
    {
        uint32_t ptr = thread.GetRegisterContext()->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX;
        value.GetScalar() = ptr;
    }
    else if (compiler_type.IsVectorType(nullptr, nullptr))
    {
        size_t byte_size = compiler_type.GetByteSize(&thread);
        if (byte_size <= 16)
        {
            DataBufferHeap buffer(16, 0);
            uint32_t* buffer_ptr = (uint32_t*)buffer.GetBytes();
            
            for (uint32_t i = 0; 4*i < byte_size; ++i)
            {
                const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + i);
                buffer_ptr[i] = reg_ctx->ReadRegisterAsUnsigned(reg_info, 0) & UINT32_MAX;
            }
            value.SetBytes(buffer.GetBytes(), byte_size);
        }
        else
        {
            if (!GetReturnValuePassedInMemory(thread, reg_ctx, byte_size, value))
                return return_valobj_sp;
        }
    }
    else if (compiler_type.IsFloatingPointType(float_count, is_complex))
    {
        if (float_count == 1 && !is_complex)
        {
            switch (bit_width)
            {
                default:
                    return return_valobj_sp;
                case 64:
                {
                    static_assert(sizeof(double) == sizeof(uint64_t), "");
                    const RegisterInfo *r1_reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2);
                    uint64_t raw_value;
                    raw_value = reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX;
                    raw_value |= ((uint64_t)(reg_ctx->ReadRegisterAsUnsigned(r1_reg_info, 0) & UINT32_MAX)) << 32;
                    value.GetScalar() = *reinterpret_cast<double*>(&raw_value);
                    break;
                }
                case 16: // Half precision returned after a conversion to single precision
                case 32:
                {
                    static_assert(sizeof(float) == sizeof(uint32_t), "");
                    uint32_t raw_value = reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX;
                    value.GetScalar() = *reinterpret_cast<float*>(&raw_value);
                    break;
                }
            }
        }
        else
        {
            // not handled yet
            return return_valobj_sp;
        }
    }
    else if (compiler_type.IsAggregateType())
    {
        size_t byte_size = compiler_type.GetByteSize(&thread);
        if (byte_size <= 4)
        {
            RegisterValue r0_reg_value;
            uint32_t raw_value = reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX;
            value.SetBytes(&raw_value, byte_size);
        }
        else
        {
            if (!GetReturnValuePassedInMemory(thread, reg_ctx, byte_size, value))
                return return_valobj_sp;
        }
    }
    else
    {
        // not handled yet
        return return_valobj_sp;
    }
    
    // If we get here, we have a valid Value, so make our ValueObject out of it:
    
    return_valobj_sp = ValueObjectConstResult::Create(thread.GetStackFrameAtIndex(0).get(),
                                                      value,
                                                      ConstString(""));
    return return_valobj_sp;
}
Beispiel #8
0
ValueObjectSP
ABISysV_ppc::GetReturnValueObjectSimple (Thread &thread,
                                            ClangASTType &return_clang_type) const
{
    ValueObjectSP return_valobj_sp;
    Value value;

    if (!return_clang_type)
        return return_valobj_sp;

    //value.SetContext (Value::eContextTypeClangType, return_value_type);
    value.SetClangType (return_clang_type);

    RegisterContext *reg_ctx = thread.GetRegisterContext().get();
    if (!reg_ctx)
        return return_valobj_sp;

    const uint32_t type_flags = return_clang_type.GetTypeInfo ();
    if (type_flags & eTypeIsScalar)
    {
        value.SetValueType(Value::eValueTypeScalar);

        bool success = false;
        if (type_flags & eTypeIsInteger)
        {
            // Extract the register context so we can read arguments from registers

            const size_t byte_size = return_clang_type.GetByteSize(nullptr);
            uint64_t raw_value = thread.GetRegisterContext()->ReadRegisterAsUnsigned(reg_ctx->GetRegisterInfoByName("r3", 0), 0);
            const bool is_signed = (type_flags & eTypeIsSigned) != 0;
            switch (byte_size)
            {
            default:
                break;

            case sizeof(uint64_t):
                if (is_signed)
                    value.GetScalar() = (int64_t)(raw_value);
                else
                    value.GetScalar() = (uint64_t)(raw_value);
                success = true;
                break;

            case sizeof(uint32_t):
                if (is_signed)
                    value.GetScalar() = (int32_t)(raw_value & UINT32_MAX);
                else
                    value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX);
                success = true;
                break;

            case sizeof(uint16_t):
                if (is_signed)
                    value.GetScalar() = (int16_t)(raw_value & UINT16_MAX);
                else
                    value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX);
                success = true;
                break;

            case sizeof(uint8_t):
                if (is_signed)
                    value.GetScalar() = (int8_t)(raw_value & UINT8_MAX);
                else
                    value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX);
                success = true;
                break;
            }
        }
        else if (type_flags & eTypeIsFloat)
        {
            if (type_flags & eTypeIsComplex)
            {
                // Don't handle complex yet.
            }
            else
            {
                const size_t byte_size = return_clang_type.GetByteSize(nullptr);
                if (byte_size <= sizeof(long double))
                {
                    const RegisterInfo *f1_info = reg_ctx->GetRegisterInfoByName("f1", 0);
                    RegisterValue f1_value;
                    if (reg_ctx->ReadRegister (f1_info, f1_value))
                    {
                        DataExtractor data;
                        if (f1_value.GetData(data))
                        {
                            lldb::offset_t offset = 0;
                            if (byte_size == sizeof(float))
                            {
                                value.GetScalar() = (float) data.GetFloat(&offset);
                                success = true;
                            }
                            else if (byte_size == sizeof(double))
                            {
                                value.GetScalar() = (double) data.GetDouble(&offset);
                                success = true;
                            }
                        }
                    }
                }
            }
        }

        if (success)
            return_valobj_sp = ValueObjectConstResult::Create (thread.GetStackFrameAtIndex(0).get(),
                                                               value,
                                                               ConstString(""));

    }
    else if (type_flags & eTypeIsPointer)
    {
        unsigned r3_id = reg_ctx->GetRegisterInfoByName("r3", 0)->kinds[eRegisterKindLLDB];
        value.GetScalar() = (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(r3_id, 0);
        value.SetValueType(Value::eValueTypeScalar);
        return_valobj_sp = ValueObjectConstResult::Create (thread.GetStackFrameAtIndex(0).get(),
                                                           value,
                                                           ConstString(""));
    }
    else if (type_flags & eTypeIsVector)
    {
        const size_t byte_size = return_clang_type.GetByteSize(nullptr);
        if (byte_size > 0)
        {

            const RegisterInfo *altivec_reg = reg_ctx->GetRegisterInfoByName("v2", 0);
            if (altivec_reg)
            {
                if (byte_size <= altivec_reg->byte_size)
                {
                    ProcessSP process_sp (thread.GetProcess());
                    if (process_sp)
                    {
                        std::unique_ptr<DataBufferHeap> heap_data_ap (new DataBufferHeap(byte_size, 0));
                        const ByteOrder byte_order = process_sp->GetByteOrder();
                        RegisterValue reg_value;
                        if (reg_ctx->ReadRegister(altivec_reg, reg_value))
                        {
                            Error error;
                            if (reg_value.GetAsMemoryData (altivec_reg,
                                                           heap_data_ap->GetBytes(),
                                                           heap_data_ap->GetByteSize(),
                                                           byte_order,
                                                           error))
                            {
                                DataExtractor data (DataBufferSP (heap_data_ap.release()),
                                                    byte_order,
                                                    process_sp->GetTarget().GetArchitecture().GetAddressByteSize());
                                return_valobj_sp = ValueObjectConstResult::Create (&thread,
                                                                                   return_clang_type,
                                                                                   ConstString(""),
                                                                                   data);
                            }
                        }
                    }
                }
            }
        }
    }

    return return_valobj_sp;
}
Beispiel #9
0
ValueObjectSP
ABISysV_ppc::GetReturnValueObjectImpl (Thread &thread, ClangASTType &return_clang_type) const
{
    ValueObjectSP return_valobj_sp;

    if (!return_clang_type)
        return return_valobj_sp;

    ExecutionContext exe_ctx (thread.shared_from_this());
    return_valobj_sp = GetReturnValueObjectSimple(thread, return_clang_type);
    if (return_valobj_sp)
        return return_valobj_sp;

    RegisterContextSP reg_ctx_sp = thread.GetRegisterContext();
    if (!reg_ctx_sp)
        return return_valobj_sp;

    const size_t bit_width = return_clang_type.GetBitSize(&thread);
    if (return_clang_type.IsAggregateType())
    {
        Target *target = exe_ctx.GetTargetPtr();
        bool is_memory = true;
        if (bit_width <= 128)
        {
            ByteOrder target_byte_order = target->GetArchitecture().GetByteOrder();
            DataBufferSP data_sp (new DataBufferHeap(16, 0));
            DataExtractor return_ext (data_sp,
                                      target_byte_order,
                                      target->GetArchitecture().GetAddressByteSize());

            const RegisterInfo *r3_info = reg_ctx_sp->GetRegisterInfoByName("r3", 0);
            const RegisterInfo *rdx_info = reg_ctx_sp->GetRegisterInfoByName("rdx", 0);

            RegisterValue r3_value, rdx_value;
            reg_ctx_sp->ReadRegister (r3_info, r3_value);
            reg_ctx_sp->ReadRegister (rdx_info, rdx_value);

            DataExtractor r3_data, rdx_data;

            r3_value.GetData(r3_data);
            rdx_value.GetData(rdx_data);

            uint32_t fp_bytes = 0;       // Tracks how much of the xmm registers we've consumed so far
            uint32_t integer_bytes = 0;  // Tracks how much of the r3/rds registers we've consumed so far

            const uint32_t num_children = return_clang_type.GetNumFields ();

            // Since we are in the small struct regime, assume we are not in memory.
            is_memory = false;

            for (uint32_t idx = 0; idx < num_children; idx++)
            {
                std::string name;
                uint64_t field_bit_offset = 0;
                bool is_signed;
                bool is_complex;
                uint32_t count;

                ClangASTType field_clang_type = return_clang_type.GetFieldAtIndex (idx, name, &field_bit_offset, NULL, NULL);
                const size_t field_bit_width = field_clang_type.GetBitSize(&thread);

                // If there are any unaligned fields, this is stored in memory.
                if (field_bit_offset % field_bit_width != 0)
                {
                    is_memory = true;
                    break;
                }

                uint32_t field_byte_width = field_bit_width/8;
                uint32_t field_byte_offset = field_bit_offset/8;


                DataExtractor *copy_from_extractor = NULL;
                uint32_t       copy_from_offset    = 0;

                if (field_clang_type.IsIntegerType (is_signed) || field_clang_type.IsPointerType ())
                {
                    if (integer_bytes < 8)
                    {
                        if (integer_bytes + field_byte_width <= 8)
                        {
                            // This is in RAX, copy from register to our result structure:
                            copy_from_extractor = &r3_data;
                            copy_from_offset = integer_bytes;
                            integer_bytes += field_byte_width;
                        }
                        else
                        {
                            // The next field wouldn't fit in the remaining space, so we pushed it to rdx.
                            copy_from_extractor = &rdx_data;
                            copy_from_offset = 0;
                            integer_bytes = 8 + field_byte_width;

                        }
                    }
                    else if (integer_bytes + field_byte_width <= 16)
                    {
                        copy_from_extractor = &rdx_data;
                        copy_from_offset = integer_bytes - 8;
                        integer_bytes += field_byte_width;
                    }
                    else
                    {
                        // The last field didn't fit.  I can't see how that would happen w/o the overall size being
                        // greater than 16 bytes.  For now, return a NULL return value object.
                        return return_valobj_sp;
                    }
                }
                else if (field_clang_type.IsFloatingPointType (count, is_complex))
                {
                    // Structs with long doubles are always passed in memory.
                    if (field_bit_width == 128)
                    {
                        is_memory = true;
                        break;
                    }
                    else if (field_bit_width == 64)
                    {
                        copy_from_offset = 0;
                        fp_bytes += field_byte_width;
                    }
                    else if (field_bit_width == 32)
                    {
                        // This one is kind of complicated.  If we are in an "eightbyte" with another float, we'll
                        // be stuffed into an xmm register with it.  If we are in an "eightbyte" with one or more ints,
                        // then we will be stuffed into the appropriate GPR with them.
                        bool in_gpr;
                        if (field_byte_offset % 8 == 0)
                        {
                            // We are at the beginning of one of the eightbytes, so check the next element (if any)
                            if (idx == num_children - 1)
                                in_gpr = false;
                            else
                            {
                                uint64_t next_field_bit_offset = 0;
                                ClangASTType next_field_clang_type = return_clang_type.GetFieldAtIndex (idx + 1,
                                                                                                        name,
                                                                                                        &next_field_bit_offset,
                                                                                                        NULL,
                                                                                                        NULL);
                                if (next_field_clang_type.IsIntegerType (is_signed))
                                    in_gpr = true;
                                else
                                {
                                    copy_from_offset = 0;
                                    in_gpr = false;
                                }
                            }

                        }
                        else if (field_byte_offset % 4 == 0)
                        {
                            // We are inside of an eightbyte, so see if the field before us is floating point:
                            // This could happen if somebody put padding in the structure.
                            if (idx == 0)
                                in_gpr = false;
                            else
                            {
                                uint64_t prev_field_bit_offset = 0;
                                ClangASTType prev_field_clang_type = return_clang_type.GetFieldAtIndex (idx - 1,
                                                                                                        name,
                                                                                                        &prev_field_bit_offset,
                                                                                                        NULL,
                                                                                                        NULL);
                                if (prev_field_clang_type.IsIntegerType (is_signed))
                                    in_gpr = true;
                                else
                                {
                                    copy_from_offset = 4;
                                    in_gpr = false;
                                }
                            }

                        }
                        else
                        {
                            is_memory = true;
                            continue;
                        }

                        // Okay, we've figured out whether we are in GPR or XMM, now figure out which one.
                        if (in_gpr)
                        {
                            if (integer_bytes < 8)
                            {
                                // This is in RAX, copy from register to our result structure:
                                copy_from_extractor = &r3_data;
                                copy_from_offset = integer_bytes;
                                integer_bytes += field_byte_width;
                            }
                            else
                            {
                                copy_from_extractor = &rdx_data;
                                copy_from_offset = integer_bytes - 8;
                                integer_bytes += field_byte_width;
                            }
                        }
                        else
                        {
                            fp_bytes += field_byte_width;
                        }
                    }
                }

                // These two tests are just sanity checks.  If I somehow get the
                // type calculation wrong above it is better to just return nothing
                // than to assert or crash.
                if (!copy_from_extractor)
                    return return_valobj_sp;
                if (copy_from_offset + field_byte_width > copy_from_extractor->GetByteSize())
                    return return_valobj_sp;

                copy_from_extractor->CopyByteOrderedData (copy_from_offset,
                                                          field_byte_width,
                                                          data_sp->GetBytes() + field_byte_offset,
                                                          field_byte_width,
                                                          target_byte_order);
            }

            if (!is_memory)
            {
                // The result is in our data buffer.  Let's make a variable object out of it:
                return_valobj_sp = ValueObjectConstResult::Create (&thread,
                                                                   return_clang_type,
                                                                   ConstString(""),
                                                                   return_ext);
            }
        }


        // FIXME: This is just taking a guess, r3 may very well no longer hold the return storage location.
        // If we are going to do this right, when we make a new frame we should check to see if it uses a memory
        // return, and if we are at the first instruction and if so stash away the return location.  Then we would
        // only return the memory return value if we know it is valid.

        if (is_memory)
        {
            unsigned r3_id = reg_ctx_sp->GetRegisterInfoByName("r3", 0)->kinds[eRegisterKindLLDB];
            lldb::addr_t storage_addr = (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(r3_id, 0);
            return_valobj_sp = ValueObjectMemory::Create (&thread,
                                                          "",
                                                          Address (storage_addr, NULL),
                                                          return_clang_type);
        }
    }

    return return_valobj_sp;
}
Beispiel #10
0
bool
ABISysV_ppc::GetArgumentValues (Thread &thread,
                                ValueList &values) const
{
    unsigned int num_values = values.GetSize();
    unsigned int value_index;

    // Extract the register context so we can read arguments from registers

    RegisterContext *reg_ctx = thread.GetRegisterContext().get();

    if (!reg_ctx)
        return false;

    // Get the pointer to the first stack argument so we have a place to start
    // when reading data

    addr_t sp = reg_ctx->GetSP(0);

    if (!sp)
        return false;

    addr_t current_stack_argument = sp + 48; // jump over return address

    uint32_t argument_register_ids[8];

    argument_register_ids[0] = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1)->kinds[eRegisterKindLLDB];
    argument_register_ids[1] = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2)->kinds[eRegisterKindLLDB];
    argument_register_ids[2] = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG3)->kinds[eRegisterKindLLDB];
    argument_register_ids[3] = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG4)->kinds[eRegisterKindLLDB];
    argument_register_ids[4] = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG5)->kinds[eRegisterKindLLDB];
    argument_register_ids[5] = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG6)->kinds[eRegisterKindLLDB];
    argument_register_ids[6] = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG7)->kinds[eRegisterKindLLDB];
    argument_register_ids[7] = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG8)->kinds[eRegisterKindLLDB];

    unsigned int current_argument_register = 0;

    for (value_index = 0;
         value_index < num_values;
         ++value_index)
    {
        Value *value = values.GetValueAtIndex(value_index);

        if (!value)
            return false;

        // We currently only support extracting values with Clang QualTypes.
        // Do we care about others?
        ClangASTType clang_type = value->GetClangType();
        if (!clang_type)
            return false;
        bool is_signed;

        if (clang_type.IsIntegerType (is_signed))
        {
            ReadIntegerArgument(value->GetScalar(),
                                clang_type.GetBitSize(&thread),
                                is_signed,
                                thread,
                                argument_register_ids,
                                current_argument_register,
                                current_stack_argument);
        }
        else if (clang_type.IsPointerType ())
        {
            ReadIntegerArgument(value->GetScalar(),
                                clang_type.GetBitSize(&thread),
                                false,
                                thread,
                                argument_register_ids,
                                current_argument_register,
                                current_stack_argument);
        }
    }

    return true;
}
Beispiel #11
0
Error
ABISysV_ppc::SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value_sp)
{
    Error error;
    if (!new_value_sp)
    {
        error.SetErrorString("Empty value object for return value.");
        return error;
    }

    ClangASTType clang_type = new_value_sp->GetClangType();
    if (!clang_type)
    {
        error.SetErrorString ("Null clang type for return value.");
        return error;
    }

    Thread *thread = frame_sp->GetThread().get();

    bool is_signed;
    uint32_t count;
    bool is_complex;

    RegisterContext *reg_ctx = thread->GetRegisterContext().get();

    bool set_it_simple = false;
    if (clang_type.IsIntegerType (is_signed) || clang_type.IsPointerType())
    {
        const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName("r3", 0);

        DataExtractor data;
        Error data_error;
        size_t num_bytes = new_value_sp->GetData(data, data_error);
        if (data_error.Fail())
        {
            error.SetErrorStringWithFormat("Couldn't convert return value to raw data: %s", data_error.AsCString());
            return error;
        }
        lldb::offset_t offset = 0;
        if (num_bytes <= 8)
        {
            uint64_t raw_value = data.GetMaxU64(&offset, num_bytes);

            if (reg_ctx->WriteRegisterFromUnsigned (reg_info, raw_value))
                set_it_simple = true;
        }
        else
        {
            error.SetErrorString("We don't support returning longer than 64 bit integer values at present.");
        }

    }
    else if (clang_type.IsFloatingPointType (count, is_complex))
    {
        if (is_complex)
            error.SetErrorString ("We don't support returning complex values at present");
        else
        {
            size_t bit_width = clang_type.GetBitSize(frame_sp.get());
            if (bit_width <= 64)
            {
                DataExtractor data;
                Error data_error;
                size_t num_bytes = new_value_sp->GetData(data, data_error);
                if (data_error.Fail())
                {
                    error.SetErrorStringWithFormat("Couldn't convert return value to raw data: %s", data_error.AsCString());
                    return error;
                }

                unsigned char buffer[16];
                ByteOrder byte_order = data.GetByteOrder();

                data.CopyByteOrderedData (0, num_bytes, buffer, 16, byte_order);
                set_it_simple = true;
            }
            else
            {
                // FIXME - don't know how to do 80 bit long doubles yet.
                error.SetErrorString ("We don't support returning float values > 64 bits at present");
            }
        }
    }

    if (!set_it_simple)
    {
        // Okay we've got a structure or something that doesn't fit in a simple register.
        // We should figure out where it really goes, but we don't support this yet.
        error.SetErrorString ("We only support setting simple integer and float return types at present.");
    }

    return error;
}
Beispiel #12
0
bool
ABISysV_ppc::PrepareTrivialCall (Thread &thread,
                                    addr_t sp,
                                    addr_t func_addr,
                                    addr_t return_addr,
                                    llvm::ArrayRef<addr_t> args) const
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));

    if (log)
    {
        StreamString s;
        s.Printf("ABISysV_ppc::PrepareTrivialCall (tid = 0x%" PRIx64 ", sp = 0x%" PRIx64 ", func_addr = 0x%" PRIx64 ", return_addr = 0x%" PRIx64,
                    thread.GetID(),
                    (uint64_t)sp,
                    (uint64_t)func_addr,
                    (uint64_t)return_addr);

        for (size_t i = 0; i < args.size(); ++i)
            s.Printf (", arg%zd = 0x%" PRIx64, i + 1, args[i]);
        s.PutCString (")");
        log->PutCString(s.GetString().c_str());
    }

    RegisterContext *reg_ctx = thread.GetRegisterContext().get();
    if (!reg_ctx)
        return false;

    const RegisterInfo *reg_info = NULL;

    if (args.size() > 8) // TODO handle more than 8 arguments
        return false;

    for (size_t i = 0; i < args.size(); ++i)
    {
        reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + i);
        if (log)
            log->Printf("About to write arg%zd (0x%" PRIx64 ") into %s", i + 1, args[i], reg_info->name);
        if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i]))
            return false;
    }

    // First, align the SP

    if (log)
        log->Printf("16-byte aligning SP: 0x%" PRIx64 " to 0x%" PRIx64, (uint64_t)sp, (uint64_t)(sp & ~0xfull));

    sp &= ~(0xfull); // 16-byte alignment

    sp -= 8;

    Error error;
    const RegisterInfo *pc_reg_info = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
    const RegisterInfo *sp_reg_info = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
    ProcessSP process_sp (thread.GetProcess());

    RegisterValue reg_value;

#if 0
    // This code adds an extra frame so that we don't lose the function that we came from
    // by pushing the PC and the FP and then writing the current FP to point to the FP value
    // we just pushed. It is disabled for now until the stack backtracing code can be debugged.

    // Save current PC
    const RegisterInfo *fp_reg_info = reg_ctx->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FP);
    if (reg_ctx->ReadRegister(pc_reg_info, reg_value))
    {
        if (log)
            log->Printf("Pushing the current PC onto the stack: 0x%" PRIx64 ": 0x%" PRIx64, (uint64_t)sp, reg_value.GetAsUInt64());

        if (!process_sp->WritePointerToMemory(sp, reg_value.GetAsUInt64(), error))
            return false;

        sp -= 8;

        // Save current FP
        if (reg_ctx->ReadRegister(fp_reg_info, reg_value))
        {
            if (log)
                log->Printf("Pushing the current FP onto the stack: 0x%" PRIx64 ": 0x%" PRIx64, (uint64_t)sp, reg_value.GetAsUInt64());

            if (!process_sp->WritePointerToMemory(sp, reg_value.GetAsUInt64(), error))
                return false;
        }
        // Setup FP backchain
        reg_value.SetUInt64 (sp);

        if (log)
            log->Printf("Writing FP:  0x%" PRIx64 " (for FP backchain)", reg_value.GetAsUInt64());

        if (!reg_ctx->WriteRegister(fp_reg_info, reg_value))
        {
            return false;
        }

        sp -= 8;
    }
#endif

    if (log)
        log->Printf("Pushing the return address onto the stack: 0x%" PRIx64 ": 0x%" PRIx64, (uint64_t)sp, (uint64_t)return_addr);

    // Save return address onto the stack
    if (!process_sp->WritePointerToMemory(sp, return_addr, error))
        return false;

    // %r1 is set to the actual stack value.

    if (log)
        log->Printf("Writing SP: 0x%" PRIx64, (uint64_t)sp);

    if (!reg_ctx->WriteRegisterFromUnsigned (sp_reg_info, sp))
        return false;

    // %pc is set to the address of the called function.

    if (log)
        log->Printf("Writing IP: 0x%" PRIx64, (uint64_t)func_addr);

    if (!reg_ctx->WriteRegisterFromUnsigned (pc_reg_info, func_addr))
        return false;

    return true;
}
Beispiel #13
0
/// <summary>
/// Execute code in context of any existing thread
/// </summary>
/// <param name="pCode">Cde to execute</param>
/// <param name="size">Code size.</param>
/// <param name="callResult">Execution result</param>
/// <param name="thd">Target thread</param>
/// <returns>Status</returns>
NTSTATUS RemoteExec::ExecInAnyThread( PVOID pCode, size_t size, uint64_t& callResult, Thread& thd )
{
    NTSTATUS dwResult = STATUS_SUCCESS;
    CONTEXT_T ctx;

    // Prepare for remote exec
    CreateRPCEnvironment( true );

    // Write code
    dwResult = CopyCode( pCode, size );
    if (dwResult != STATUS_SUCCESS)
        return dwResult;

    if (_hWaitEvent)
        ResetEvent( _hWaitEvent );

    if (!thd.Suspend())
        return LastNtStatus();

    if (thd.GetContext( ctx, CONTEXT_ALL, true ))
    {
        AsmJit::Assembler a;
        AsmJitHelper ah( a );

#ifdef _M_AMD64
        const int count = 15;
        AsmJit::GPReg regs[] = { AsmJit::rax, AsmJit::rbx, AsmJit::rcx, AsmJit::rdx, AsmJit::rsi,
                                 AsmJit::rdi, AsmJit::r8,  AsmJit::r9,  AsmJit::r10, AsmJit::r11,
                                 AsmJit::r12, AsmJit::r13, AsmJit::r14, AsmJit::r15, AsmJit::rbp
                               };
        //
        // Preserve thread context
        // I don't care about FPU, XMM and anything else
        //
        a.sub(AsmJit::rsp, count * WordSize);  // Stack must be aligned on 16 bytes
        a.pushfq();                            //

        // Save registers
        for (int i = 0; i < count; i++)
            a.mov( AsmJit::Mem( AsmJit::rsp, i * WordSize ), regs[i] );

        ah.GenCall( _userCode.ptr<size_t>(), { _userData.ptr<size_t>() } );
        AddReturnWithEvent( ah, rt_int32, INTRET_OFFSET );

        // Restore registers
        for (int i = 0; i < count; i++)
            a.mov( regs[i], AsmJit::Mem( AsmJit::rsp, i * WordSize ) );

        a.popfq();
        a.add( AsmJit::rsp, count * WordSize );

        a.jmp( ctx.Rip );
#else
        a.pushad();
        a.pushfd();

        ah.GenCall( _userCode.ptr<size_t>(), { _userData.ptr<size_t>() } );
        AddReturnWithEvent( ah, rt_int32, INTRET_OFFSET );

        a.popfd();
        a.popad();

        a.push( ctx.NIP );
        a.ret();
#endif

        if (_userCode.Write( size, a.getCodeSize(), a.make() ) == STATUS_SUCCESS)
        {
            ctx.NIP = _userCode.ptr<size_t>() + size;

            if (!thd.SetContext( ctx, true ))
                dwResult = LastNtStatus();
        }
        else
            dwResult = LastNtStatus();
    }
    else
        dwResult = LastNtStatus();

    thd.Resume();

    if (dwResult == STATUS_SUCCESS)
    {
        WaitForSingleObject( _hWaitEvent, INFINITE );
        callResult = _userData.Read<size_t>( INTRET_OFFSET, 0 );
    }

    return dwResult;
}
//----------------------------------------------------------------------
// ThreadPlanCallFunction: Plan to call a single function
//----------------------------------------------------------------------
bool
ThreadPlanCallFunction::ConstructorSetup (Thread &thread,
                                          ABI *& abi,
                                          lldb::addr_t &start_load_addr,
                                          lldb::addr_t &function_load_addr)
{
    SetIsMasterPlan (true);
    SetOkayToDiscard (false);
    SetPrivate (true);

    ProcessSP process_sp (thread.GetProcess());
    if (!process_sp)
        return false;

    abi = process_sp->GetABI().get();

    if (!abi)
        return false;

    Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP));

    SetBreakpoints();

    m_function_sp = thread.GetRegisterContext()->GetSP() - abi->GetRedZoneSize();
    // If we can't read memory at the point of the process where we are planning to put our function, we're
    // not going to get any further...
    Error error;
    process_sp->ReadUnsignedIntegerFromMemory(m_function_sp, 4, 0, error);
    if (!error.Success())
    {
        m_constructor_errors.Printf ("Trying to put the stack in unreadable memory at: 0x%" PRIx64 ".", m_function_sp);
        if (log)
            log->Printf ("ThreadPlanCallFunction(%p): %s.",
                         static_cast<void*>(this),
                         m_constructor_errors.GetData());
        return false;
    }

    Module *exe_module = GetTarget().GetExecutableModulePointer();

    if (exe_module == NULL)
    {
        m_constructor_errors.Printf ("Can't execute code without an executable module.");
        if (log)
            log->Printf ("ThreadPlanCallFunction(%p): %s.",
                         static_cast<void*>(this),
                         m_constructor_errors.GetData());
        return false;
    }
    else
    {
        ObjectFile *objectFile = exe_module->GetObjectFile();
        if (!objectFile)
        {
            m_constructor_errors.Printf ("Could not find object file for module \"%s\".", 
                                         exe_module->GetFileSpec().GetFilename().AsCString());

            if (log)
                log->Printf ("ThreadPlanCallFunction(%p): %s.",
                             static_cast<void*>(this),
                             m_constructor_errors.GetData());
            return false;
        }

        m_start_addr = objectFile->GetEntryPointAddress();
        if (!m_start_addr.IsValid())
        {
            m_constructor_errors.Printf ("Could not find entry point address for executable module \"%s\".", 
                                         exe_module->GetFileSpec().GetFilename().AsCString());
            if (log)
                log->Printf ("ThreadPlanCallFunction(%p): %s.",
                             static_cast<void*>(this),
                             m_constructor_errors.GetData());
            return false;
        }
    }

    start_load_addr = m_start_addr.GetLoadAddress (&GetTarget());

    // Checkpoint the thread state so we can restore it later.
    if (log && log->GetVerbose())
        ReportRegisterState ("About to checkpoint thread before function call.  Original register state was:");

    if (!thread.CheckpointThreadState (m_stored_thread_state))
    {
        m_constructor_errors.Printf ("Setting up ThreadPlanCallFunction, failed to checkpoint thread state.");
        if (log)
            log->Printf ("ThreadPlanCallFunction(%p): %s.",
                         static_cast<void*>(this),
                         m_constructor_errors.GetData());
        return false;
    }
    function_load_addr = m_function_addr.GetLoadAddress (&GetTarget());

    return true;
}
Beispiel #15
0
    void test_instance(void)
    {
        MemPool* pool = gMemPool;

        // ffi定義が無いのでbindFfiClassTable不要
        Bytecode* myBytecode = gCodeManager.readBytecode("test.hyb");
        CPPUNIT_ASSERT(myBytecode != NULL);
        myBytecode->setInitialized();

        // gc_test_instance() をスレッドで実行
        Thread* pThread = gThreadManager.createTmpThread();
        Context* context = gCodeManager.createContext();
        pThread->initialize(context);
        context->pushClass(myBytecode->mainClass());
        context->methodCall(HSym_gc_test_instance, 0);
        gCodeManager.releaseContext(context); // contextのdeleteはGCまかせ
        pThread->start();

        GC::full();

        pThread->exec1tick();

        int n, m;
        n = GC::countObjects(pool);  // start

        pThread->exec1tick();
        GC::full();
        m = GC::countObjects(pool);
        CPPUNIT_ASSERT_EQUAL(n-1, m);       // -1

        pThread->exec1tick();
        GC::full();
        n = GC::countObjects(pool);
        CPPUNIT_ASSERT_EQUAL(m, n);       // -0

        pThread->exec1tick();
        GC::full();
        m = GC::countObjects(pool);
        CPPUNIT_ASSERT_EQUAL(n, m);       // -0

        pThread->exec1tick();
        GC::full();
        n = GC::countObjects(pool);
        CPPUNIT_ASSERT_EQUAL(m-3, n);       // -3

        pThread->exec1tick();
        GC::full();
        m = GC::countObjects(pool);
        CPPUNIT_ASSERT_EQUAL(n-1, m);       // -1

        CPPUNIT_ASSERT_EQUAL(Thread::WAITING_TICK, pThread->state());
        pThread->exec1tick();
        CPPUNIT_ASSERT_EQUAL(Thread::TERMINATED, pThread->state());
        GC::full();
        n = GC::countObjects(pool);
        CPPUNIT_ASSERT_EQUAL(m-2, n);       // -2

        // pThread,context は GC に回収されている
    }
Beispiel #16
0
 static void* trampoline(void* arg) {
   Thread* self = reinterpret_cast<Thread*>(arg);
   self->perform();
   if(self->delete_on_exit()) delete self;
   return NULL;
 }
Beispiel #17
0
    void test_threadGC(void)
    {
        Bytecode* myBytecode = gCodeManager.readBytecode("test.hyb");
        myBytecode->setInitialized();

        Context* context = gCodeManager.createContext();
        Thread* pThread = gThreadManager.createTmpThread();
        context->pushClass(myBytecode->mainClass());
        context->methodCall(HSym_gc_test_thread_sweep, 0);
        pThread->initialize(context);
        pThread->start();
        gCodeManager.releaseContext(context);
        while (gThreadManager.isThreadRunning())
            gThreadManager.exec1tick();
        gThreadManager.destroyTmpThread(pThread);
        GC::full();
        GC::coalesce();

        pThread = gThreadManager.createTmpThread();
        context = gCodeManager.createContext();
        context->pushClass(myBytecode->mainClass());
        context->methodCall(HSym_gc_test_thread_sweep, 0);
        pThread->initialize(context);
        pThread->start();
        gCodeManager.releaseContext(context);
        while (gThreadManager.isThreadRunning())
            gThreadManager.exec1tick();
        gThreadManager.destroyTmpThread(pThread);
        GC::unmark();
        pThread = gThreadManager.createTmpThread();
        context = gCodeManager.createContext();
        context->pushClass(myBytecode->mainClass());
        context->methodCall(HSym_gc_test_thread_sweep, 0);
        pThread->initialize(context);
        pThread->start();
        gCodeManager.releaseContext(context);
        while (gThreadManager.isThreadRunning())
            gThreadManager.exec1tick();
        gThreadManager.destroyTmpThread(pThread);
        GC::markAll();
        GC::sweep();
        GC::coalesce();

        pThread = gThreadManager.createTmpThread();
        context = gCodeManager.createContext();
        context->pushClass(myBytecode->mainClass());
        context->methodCall(HSym_gc_test_thread_sweep, 0);
        pThread->initialize(context);
        pThread->start();
        gCodeManager.releaseContext(context);
        while (gThreadManager.isThreadRunning())
            gThreadManager.exec1tick();
        gThreadManager.destroyTmpThread(pThread);
        GC::unmark();
        GC::markAll();
        pThread = gThreadManager.createTmpThread();
        context = gCodeManager.createContext();
        context->pushClass(myBytecode->mainClass());
        context->methodCall(HSym_gc_test_thread_sweep, 0);
        pThread->initialize(context);
        pThread->start();
        gCodeManager.releaseContext(context);
        while (gThreadManager.isThreadRunning())
            gThreadManager.exec1tick();
        gThreadManager.destroyTmpThread(pThread);
        GC::sweep();
        GC::coalesce();

    }
 void start(){
     tlog("start(). this="<<this);
     thread = Thread<Counter, int>::createThread(this, &Counter::run);
     thread->start(0);
 }
	extern "C" void *ThreadStartup(void *_tgtObject) {
		Thread *tgtObject = (Thread *)_tgtObject;
		tgtObject->run();
		return NULL;
	}
Beispiel #20
0
// global thread caallback
unsigned int _ou_thread_proc(void* param) {
	Thread* tp = (Thread*)param;
	tp->run();
	return 0;
}
void tst_QMutex::tryLock()
{
    // test non-recursive mutex
    {
        class Thread : public QThread
        {
        public:
            void run()
            {
                testsTurn.release();

                threadsTurn.acquire();
                QVERIFY(!normalMutex.tryLock());
                testsTurn.release();

                threadsTurn.acquire();
                QVERIFY(normalMutex.tryLock());
                QVERIFY(lockCount.testAndSetRelaxed(0, 1));
                QVERIFY(!normalMutex.tryLock());
                QVERIFY(lockCount.testAndSetRelaxed(1, 0));
                normalMutex.unlock();
                testsTurn.release();

                threadsTurn.acquire();
                QTime timer;
                timer.start();
                QVERIFY(!normalMutex.tryLock(1000));
                QVERIFY(timer.elapsed() >= 1000);
                testsTurn.release();

                threadsTurn.acquire();
                timer.start();
                QVERIFY(normalMutex.tryLock(1000));
                QVERIFY(timer.elapsed() <= 1000);
                QVERIFY(lockCount.testAndSetRelaxed(0, 1));
                timer.start();
                QVERIFY(!normalMutex.tryLock(1000));
                QVERIFY(timer.elapsed() >= 1000);
                QVERIFY(lockCount.testAndSetRelaxed(1, 0));
                normalMutex.unlock();
                testsTurn.release();

                threadsTurn.acquire();
            }
        };

        Thread thread;
        thread.start();

        testsTurn.acquire();
        normalMutex.lock();
        QVERIFY(lockCount.testAndSetRelaxed(0, 1));
        threadsTurn.release();

        testsTurn.acquire();
        QVERIFY(lockCount.testAndSetRelaxed(1, 0));
        normalMutex.unlock();
        threadsTurn.release();

        testsTurn.acquire();
        normalMutex.lock();
        QVERIFY(lockCount.testAndSetRelaxed(0, 1));
        threadsTurn.release();

        testsTurn.acquire();
        QVERIFY(lockCount.testAndSetRelaxed(1, 0));
        normalMutex.unlock();
        threadsTurn.release();

        // wait for thread to finish
        testsTurn.acquire();
        threadsTurn.release();
        thread.wait();
    }

    // test recursive mutex
    {
        class Thread : public QThread
        {
        public:
            void run()
            {
                testsTurn.release();

                threadsTurn.acquire();
                QVERIFY(!recursiveMutex.tryLock());
                testsTurn.release();

                threadsTurn.acquire();
                QVERIFY(recursiveMutex.tryLock());
                QVERIFY(lockCount.testAndSetRelaxed(0, 1));
                QVERIFY(recursiveMutex.tryLock());
                QVERIFY(lockCount.testAndSetRelaxed(1, 2));
                QVERIFY(lockCount.testAndSetRelaxed(2, 1));
                recursiveMutex.unlock();
                QVERIFY(lockCount.testAndSetRelaxed(1, 0));
                recursiveMutex.unlock();
                testsTurn.release();

                threadsTurn.acquire();
                QTime timer;
                timer.start();
                QVERIFY(!recursiveMutex.tryLock(1000));
                QVERIFY(timer.elapsed() >= 1000);
                testsTurn.release();

                threadsTurn.acquire();
                timer.start();
                QVERIFY(recursiveMutex.tryLock(1000));
                QVERIFY(timer.elapsed() <= 1000);
                QVERIFY(lockCount.testAndSetRelaxed(0, 1));
                QVERIFY(recursiveMutex.tryLock(1000));
                QVERIFY(lockCount.testAndSetRelaxed(1, 2));
                QVERIFY(lockCount.testAndSetRelaxed(2, 1));
                recursiveMutex.unlock();
                QVERIFY(lockCount.testAndSetRelaxed(1, 0));
                recursiveMutex.unlock();
                testsTurn.release();

                threadsTurn.acquire();
            }
        };

        Thread thread;
        thread.start();

        testsTurn.acquire();
        recursiveMutex.lock();
        QVERIFY(lockCount.testAndSetRelaxed(0, 1));
        recursiveMutex.lock();
        QVERIFY(lockCount.testAndSetRelaxed(1, 2));
        threadsTurn.release();

        testsTurn.acquire();
        QVERIFY(lockCount.testAndSetRelaxed(2, 1));
        recursiveMutex.unlock();
        QVERIFY(lockCount.testAndSetRelaxed(1, 0));
        recursiveMutex.unlock();
        threadsTurn.release();

        testsTurn.acquire();
        recursiveMutex.lock();
        QVERIFY(lockCount.testAndSetRelaxed(0, 1));
        recursiveMutex.lock();
        QVERIFY(lockCount.testAndSetRelaxed(1, 2));
        threadsTurn.release();

        testsTurn.acquire();
        QVERIFY(lockCount.testAndSetRelaxed(2, 1));
        recursiveMutex.unlock();
        QVERIFY(lockCount.testAndSetRelaxed(1, 0));
        recursiveMutex.unlock();
        threadsTurn.release();

        // stop thread
        testsTurn.acquire();
        threadsTurn.release();
        thread.wait();
    }
}
Beispiel #22
0
uint32_t EventableResource::getTruncatedEV(Thread &thread) const
{
    if (EV == getID())
        return EV;
    return (EV & 0xffff) | thread.getParent().ram_base;
}
Beispiel #23
0
void Thread::split(Position& pos, Stack* ss, Value alpha, Value beta, Value* bestValue,
                   Move* bestMove, Depth depth, int moveCount,
                   MovePicker* movePicker, int nodeType, bool cutNode) {

  assert(searching);
  assert(-VALUE_INFINITE < *bestValue && *bestValue <= alpha && alpha < beta && beta <= VALUE_INFINITE);
  assert(depth >= Threads.minimumSplitDepth);
  assert(splitPointsSize < MAX_SPLITPOINTS_PER_THREAD);

  // Pick and init the next available split point
  SplitPoint& sp = splitPoints[splitPointsSize];

  sp.spinlock.acquire(); // No contention here until we don't increment splitPointsSize

  sp.master = this;
  sp.parentSplitPoint = activeSplitPoint;
  sp.slavesMask = 0, sp.slavesMask.set(idx);
  sp.depth = depth;
  sp.bestValue = *bestValue;
  sp.bestMove = *bestMove;
  sp.alpha = alpha;
  sp.beta = beta;
  sp.nodeType = nodeType;
  sp.cutNode = cutNode;
  sp.movePicker = movePicker;
  sp.moveCount = moveCount;
  sp.pos = &pos;
  sp.nodes = 0;
  sp.cutoff = false;
  sp.ss = ss;
  sp.allSlavesSearching = true; // Must be set under lock protection

  ++splitPointsSize;
  activeSplitPoint = &sp;
  activePosition = nullptr;

  // Try to allocate available threads
  Thread* slave;

  while (    sp.slavesMask.count() < MAX_SLAVES_PER_SPLITPOINT
         && (slave = Threads.available_slave(&sp)) != nullptr)
  {
     slave->spinlock.acquire();

      if (slave->can_join(activeSplitPoint))
      {
          activeSplitPoint->slavesMask.set(slave->idx);
          slave->activeSplitPoint = activeSplitPoint;
          slave->searching = true;
      }

      slave->spinlock.release();
  }

  // Everything is set up. The master thread enters the idle loop, from which
  // it will instantly launch a search, because its 'searching' flag is set.
  // The thread will return from the idle loop when all slaves have finished
  // their work at this split point.
  sp.spinlock.release();

  Thread::idle_loop(); // Force a call to base class idle_loop()

  // In the helpful master concept, a master can help only a sub-tree of its
  // split point and because everything is finished here, it's not possible
  // for the master to be booked.
  assert(!searching);
  assert(!activePosition);

  searching = true;

  // We have returned from the idle loop, which means that all threads are
  // finished. Note that decreasing splitPointsSize must be done under lock
  // protection to avoid a race with Thread::can_join().
  sp.spinlock.acquire();

  --splitPointsSize;
  activeSplitPoint = sp.parentSplitPoint;
  activePosition = &pos;
  pos.set_nodes_searched(pos.nodes_searched() + sp.nodes);
  *bestMove = sp.bestMove;
  *bestValue = sp.bestValue;

  sp.spinlock.release();
}
Beispiel #24
0
void Thread::CheckCurrentForKill()
{ // static
    Thread* thread = Thread::Current();
    if ( thread != NULL )
        thread->CheckForKill();
}
Beispiel #25
0
	void* Thread::_launch( void* argument )
	{
		Thread* thread = static_cast< Thread* >( argument );	
		thread->execute();
		return 0;
	}
bool
UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly (AddressRange& range, 
                                                                   Thread& thread, 
                                                                   UnwindPlan& unwind_plan)
{
    if (range.GetByteSize() > 0 && 
        range.GetBaseAddress().IsValid() &&
        m_inst_emulator_ap.get())
    {
     
        // The instruction emulation subclass setup the unwind plan for the
        // first instruction.
        m_inst_emulator_ap->CreateFunctionEntryUnwind (unwind_plan);

        // CreateFunctionEntryUnwind should have created the first row. If it
        // doesn't, then we are done.
        if (unwind_plan.GetRowCount() == 0)
            return false;
        
        ExecutionContext exe_ctx;
        thread.CalculateExecutionContext(exe_ctx);
        const bool prefer_file_cache = true;
        DisassemblerSP disasm_sp (Disassembler::DisassembleRange (m_arch,
                                                                  NULL,
                                                                  NULL,
                                                                  exe_ctx,
                                                                  range,
                                                                  prefer_file_cache));
        
        Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));

        if (disasm_sp)
        {
            
            m_range_ptr = &range;
            m_thread_ptr = &thread;
            m_unwind_plan_ptr = &unwind_plan;

            const uint32_t addr_byte_size = m_arch.GetAddressByteSize();
            const bool show_address = true;
            const bool show_bytes = true;
            m_inst_emulator_ap->GetRegisterInfo (unwind_plan.GetRegisterKind(), 
                                                 unwind_plan.GetInitialCFARegister(), 
                                                 m_cfa_reg_info);
            
            m_fp_is_cfa = false;
            m_register_values.clear();
            m_pushed_regs.clear();

            // Initialize the CFA with a known value. In the 32 bit case
            // it will be 0x80000000, and in the 64 bit case 0x8000000000000000.
            // We use the address byte size to be safe for any future address sizes
            m_initial_sp = (1ull << ((addr_byte_size * 8) - 1));
            RegisterValue cfa_reg_value;
            cfa_reg_value.SetUInt (m_initial_sp, m_cfa_reg_info.byte_size);
            SetRegisterValue (m_cfa_reg_info, cfa_reg_value);

            const InstructionList &inst_list = disasm_sp->GetInstructionList ();
            const size_t num_instructions = inst_list.GetSize();

            if (num_instructions > 0)
            {
                Instruction *inst = inst_list.GetInstructionAtIndex (0).get();
                const addr_t base_addr = inst->GetAddress().GetFileAddress();

                // Make a copy of the current instruction Row and save it in m_curr_row
                // so we can add updates as we process the instructions.  
                UnwindPlan::RowSP last_row = unwind_plan.GetLastRow();
                UnwindPlan::Row *newrow = new UnwindPlan::Row;
                if (last_row.get())
                    *newrow = *last_row.get();
                m_curr_row.reset(newrow);

                // Once we've seen the initial prologue instructions complete, save a
                // copy of the CFI at that point into prologue_completed_row for possible
                // use later.
                int instructions_since_last_prologue_insn = 0;     // # of insns since last CFI was update

                bool reinstate_prologue_next_instruction = false;  // Next iteration, re-install the prologue row of CFI

                bool last_instruction_restored_return_addr_reg = false;  // re-install the prologue row of CFI if the next instruction is a branch immediate

                bool return_address_register_has_been_saved = false; // if we've seen the ra register get saved yet

                UnwindPlan::RowSP prologue_completed_row;          // copy of prologue row of CFI

                // cache the pc register number (in whatever register numbering this UnwindPlan uses) for
                // quick reference during instruction parsing.
                uint32_t pc_reg_num = LLDB_INVALID_REGNUM;
                RegisterInfo pc_reg_info;
                if (m_inst_emulator_ap->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, pc_reg_info))
                    pc_reg_num = pc_reg_info.kinds[unwind_plan.GetRegisterKind()];
                else
                    pc_reg_num = LLDB_INVALID_REGNUM;

                // cache the return address register number (in whatever register numbering this UnwindPlan uses) for
                // quick reference during instruction parsing.
                uint32_t ra_reg_num = LLDB_INVALID_REGNUM;
                RegisterInfo ra_reg_info;
                if (m_inst_emulator_ap->GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, ra_reg_info))
                    ra_reg_num = ra_reg_info.kinds[unwind_plan.GetRegisterKind()];
                else
                    ra_reg_num = LLDB_INVALID_REGNUM;

                for (size_t idx=0; idx<num_instructions; ++idx)
                {
                    m_curr_row_modified = false;
                    m_curr_insn_restored_a_register = false;
                    inst = inst_list.GetInstructionAtIndex (idx).get();
                    if (inst)
                    {
                        if (log && log->GetVerbose ())
                        {
                            StreamString strm;
                            inst->Dump(&strm, inst_list.GetMaxOpcocdeByteSize (), show_address, show_bytes, NULL);
                            log->PutCString (strm.GetData());
                        }

                        m_inst_emulator_ap->SetInstruction (inst->GetOpcode(), 
                                                            inst->GetAddress(), 
                                                            exe_ctx.GetTargetPtr());

                        m_inst_emulator_ap->EvaluateInstruction (eEmulateInstructionOptionIgnoreConditions);

                        // Were there any changes to the CFI while evaluating this instruction?
                        if (m_curr_row_modified)
                        {
                            reinstate_prologue_next_instruction = false;
                            m_curr_row->SetOffset (inst->GetAddress().GetFileAddress() + inst->GetOpcode().GetByteSize() - base_addr);
                            // Append the new row
                            unwind_plan.AppendRow (m_curr_row);

                            // Allocate a new Row for m_curr_row, copy the current state into it
                            UnwindPlan::Row *newrow = new UnwindPlan::Row;
                            *newrow = *m_curr_row.get();
                            m_curr_row.reset(newrow);

                            // If m_curr_insn_restored_a_register == true, we're looking at an epilogue instruction.
                            // Set instructions_since_last_prologue_insn to a very high number so we don't append 
                            // any of these epilogue instructions to our prologue_complete row.
                            if (m_curr_insn_restored_a_register == false && instructions_since_last_prologue_insn < 8)
                              instructions_since_last_prologue_insn = 0;
                            else
                              instructions_since_last_prologue_insn = 99;

                            UnwindPlan::Row::RegisterLocation pc_regloc;
                            UnwindPlan::Row::RegisterLocation ra_regloc;

                            // While parsing the instructions of this function, if we've ever
                            // seen the return address register (aka lr on arm) in a non-IsSame() state,
                            // it has been saved on the stack.  If it's ever back to IsSame(), we've
                            // executed an epilogue.
                            if (ra_reg_num != LLDB_INVALID_REGNUM
                                && m_curr_row->GetRegisterInfo (ra_reg_num, ra_regloc)
                                && !ra_regloc.IsSame())
                            {
                                return_address_register_has_been_saved = true;
                            }

                            // If the caller's pc is "same", we've just executed an epilogue and we return to the caller
                            // after this instruction completes executing.
                            // If there are any instructions past this, there must have been flow control over this
                            // epilogue so we'll reinstate the original prologue setup instructions.
                            if (prologue_completed_row.get()
                                && pc_reg_num != LLDB_INVALID_REGNUM 
                                && m_curr_row->GetRegisterInfo (pc_reg_num, pc_regloc)
                                && pc_regloc.IsSame())
                            {
                                if (log && log->GetVerbose())
                                    log->Printf("UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly -- pc is <same>, restore prologue instructions.");
                                reinstate_prologue_next_instruction = true;
                            }
                            else if (prologue_completed_row.get()
                                     && return_address_register_has_been_saved
                                     && ra_reg_num != LLDB_INVALID_REGNUM
                                     && m_curr_row->GetRegisterInfo (ra_reg_num, ra_regloc)
                                     && ra_regloc.IsSame())
                            {
                                if (log && log->GetVerbose())
                                    log->Printf("UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly -- lr is <same>, restore prologue instruction if the next instruction is a branch immediate.");
                                last_instruction_restored_return_addr_reg = true;
                            }
                        }
                        else
                        {
                            // If the previous instruction was a return-to-caller (epilogue), and we're still executing
                            // instructions in this function, there must be a code path that jumps over that epilogue.
                            // Also detect the case where we epilogue & branch imm to another function (tail-call opt)
                            // instead of a normal pop lr-into-pc exit.
                            // Reinstate the frame setup from the prologue.
                            if (reinstate_prologue_next_instruction
                                || (m_curr_insn_is_branch_immediate && last_instruction_restored_return_addr_reg))
                            {
                                if (log && log->GetVerbose())
                                    log->Printf("UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly -- Reinstating prologue instruction set");
                                UnwindPlan::Row *newrow = new UnwindPlan::Row;
                                *newrow = *prologue_completed_row.get();
                                m_curr_row.reset(newrow);
                                m_curr_row->SetOffset (inst->GetAddress().GetFileAddress() + inst->GetOpcode().GetByteSize() - base_addr);
                                unwind_plan.AppendRow(m_curr_row);

                                newrow = new UnwindPlan::Row;
                                *newrow = *m_curr_row.get();
                                m_curr_row.reset(newrow);

                                reinstate_prologue_next_instruction = false;
                                last_instruction_restored_return_addr_reg = false; 
                                m_curr_insn_is_branch_immediate = false;
                            }

                            // clear both of these if either one wasn't set
                            if (last_instruction_restored_return_addr_reg)
                            {
                                last_instruction_restored_return_addr_reg = false;
                            }
                            if (m_curr_insn_is_branch_immediate)
                            {
                                m_curr_insn_is_branch_immediate = false;
                            }
 
                            // Stop updating the prologue instructions if we've seen 8 non-prologue instructions
                            // in a row.
                            if (instructions_since_last_prologue_insn++ < 8)
                            {
                                UnwindPlan::Row *newrow = new UnwindPlan::Row;
                                *newrow = *m_curr_row.get();
                                prologue_completed_row.reset(newrow);
                                if (log && log->GetVerbose())
                                    log->Printf("UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly -- saving a copy of the current row as the prologue row.");
                            }
                        }
                    }
                }
            }
            // FIXME: The DisassemblerLLVMC has a reference cycle and won't go away if it has any active instructions.
            // I'll fix that but for now, just clear the list and it will go away nicely.
            disasm_sp->GetInstructionList().Clear();
        }
        
        if (log && log->GetVerbose ())
        {
            StreamString strm;
            lldb::addr_t base_addr = range.GetBaseAddress().GetLoadAddress(thread.CalculateTarget().get());
            strm.Printf ("Resulting unwind rows for [0x%" PRIx64 " - 0x%" PRIx64 "):", base_addr, base_addr + range.GetByteSize());
            unwind_plan.Dump(strm, &thread, base_addr);
            log->PutCString (strm.GetData());
        }
        return unwind_plan.GetRowCount() > 0;
    }
    return false;
}
Beispiel #27
0
bool
ABIMacOSX_arm::GetArgumentValues (Thread &thread,
                                  ValueList &values) const
{
    uint32_t num_values = values.GetSize();
    
    
    ExecutionContext exe_ctx (thread.shared_from_this());
    // For now, assume that the types in the AST values come from the Target's 
    // scratch AST.    
    
    // Extract the register context so we can read arguments from registers
    
    RegisterContext *reg_ctx = thread.GetRegisterContext().get();
    
    if (!reg_ctx)
        return false;
        
    addr_t sp = 0;

    for (uint32_t value_idx = 0; value_idx < num_values; ++value_idx)
    {
        // We currently only support extracting values with Clang QualTypes.
        // Do we care about others?
        Value *value = values.GetValueAtIndex(value_idx);
        
        if (!value)
            return false;
        
        ClangASTType clang_type = value->GetClangType();
        if (clang_type)
        {
            bool is_signed = false;
            size_t bit_width = 0;
            if (clang_type.IsIntegerType (is_signed))
            {
                bit_width = clang_type.GetBitSize();
            }
            else if (clang_type.IsPointerOrReferenceType ())
            {
                bit_width = clang_type.GetBitSize();
            }
            else
            {
                // We only handle integer, pointer and reference types currently...
                return false;
            }
            
            if (bit_width <= (exe_ctx.GetProcessRef().GetAddressByteSize() * 8))
            {
                if (value_idx < 4)
                {
                    // Arguments 1-4 are in r0-r3...
                    const RegisterInfo *arg_reg_info = NULL;
                    // Search by generic ID first, then fall back to by name
                    uint32_t arg_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + value_idx);
                    if (arg_reg_num != LLDB_INVALID_REGNUM)
                    {
                        arg_reg_info = reg_ctx->GetRegisterInfoAtIndex(arg_reg_num);
                    }
                    else
                    {
                        switch (value_idx)
                        {
                            case 0: arg_reg_info = reg_ctx->GetRegisterInfoByName("r0"); break;
                            case 1: arg_reg_info = reg_ctx->GetRegisterInfoByName("r1"); break;
                            case 2: arg_reg_info = reg_ctx->GetRegisterInfoByName("r2"); break;
                            case 3: arg_reg_info = reg_ctx->GetRegisterInfoByName("r3"); break;
                        }
                    }

                    if (arg_reg_info)
                    {
                        RegisterValue reg_value;
                        
                        if (reg_ctx->ReadRegister(arg_reg_info, reg_value))
                        {
                            if (is_signed)
                                reg_value.SignExtend(bit_width);
                            if (!reg_value.GetScalarValue(value->GetScalar()))
                                return false;
                            continue;
                        }
                    }
                    return false;
                }
                else
                {
                    if (sp == 0)
                    {
                        // Read the stack pointer if it already hasn't been read
                        sp = reg_ctx->GetSP(0);
                        if (sp == 0)
                            return false;
                    }

                    // Arguments 5 on up are on the stack
                    const uint32_t arg_byte_size = (bit_width + (8-1)) / 8;
                    Error error;
                    if (!exe_ctx.GetProcessRef().ReadScalarIntegerFromMemory(sp, arg_byte_size, is_signed, value->GetScalar(), error))
                        return false;

                    sp += arg_byte_size;
                }
            }
        }
    }
    return true;
}
bool
AppleObjCRuntime::GetObjectDescription (Stream &strm, Value &value, ExecutionContextScope *exe_scope)
{
    if (!m_read_objc_library)
        return false;
        
    ExecutionContext exe_ctx;
    exe_scope->CalculateExecutionContext(exe_ctx);
    Process *process = exe_ctx.GetProcessPtr();
    if (!process)
        return false;
    
    // We need other parts of the exe_ctx, but the processes have to match.
    assert (m_process == process);
    
    // Get the function address for the print function.
    const Address *function_address = GetPrintForDebuggerAddr();
    if (!function_address)
        return false;
    
    Target *target = exe_ctx.GetTargetPtr();
    ClangASTType clang_type = value.GetClangType();
    if (clang_type)
    {
        if (!clang_type.IsObjCObjectPointerType())
        {
            strm.Printf ("Value doesn't point to an ObjC object.\n");
            return false;
        }
    }
    else 
    {
        // If it is not a pointer, see if we can make it into a pointer.
        ClangASTContext *ast_context = target->GetScratchClangASTContext();
        ClangASTType opaque_type = ast_context->GetBasicType(eBasicTypeObjCID);
        if (!opaque_type)
            opaque_type = ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
        //value.SetContext(Value::eContextTypeClangType, opaque_type_ptr);
        value.SetClangType (opaque_type);
    }

    ValueList arg_value_list;
    arg_value_list.PushValue(value);
    
    // This is the return value:
    ClangASTContext *ast_context = target->GetScratchClangASTContext();
    
    ClangASTType return_clang_type = ast_context->GetCStringType(true);
    Value ret;
//    ret.SetContext(Value::eContextTypeClangType, return_clang_type);
    ret.SetClangType (return_clang_type);
    
    if (exe_ctx.GetFramePtr() == NULL)
    {
        Thread *thread = exe_ctx.GetThreadPtr();
        if (thread == NULL)
        {
            exe_ctx.SetThreadSP(process->GetThreadList().GetSelectedThread());
            thread = exe_ctx.GetThreadPtr();
        }
        if (thread)
        {
            exe_ctx.SetFrameSP(thread->GetSelectedFrame());
        }
    }
    
    // Now we're ready to call the function:
    ClangFunction func (*exe_ctx.GetBestExecutionContextScope(),
                        return_clang_type, 
                        *function_address, 
                        arg_value_list,
                        "objc-object-description");

    StreamString error_stream;
    
    lldb::addr_t wrapper_struct_addr = LLDB_INVALID_ADDRESS;
    func.InsertFunction(exe_ctx, wrapper_struct_addr, error_stream);

    EvaluateExpressionOptions options;
    options.SetUnwindOnError(true);
    options.SetTryAllThreads(true);
    options.SetStopOthers(true);
    options.SetIgnoreBreakpoints(true);
    options.SetTimeoutUsec(PO_FUNCTION_TIMEOUT_USEC);
    
    ExpressionResults results = func.ExecuteFunction (exe_ctx, 
                                                     &wrapper_struct_addr,
                                                     options,
                                                     error_stream, 
                                                     ret);
    if (results != eExpressionCompleted)
    {
        strm.Printf("Error evaluating Print Object function: %d.\n", results);
        return false;
    }
       
    addr_t result_ptr = ret.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
    
    char buf[512];
    size_t cstr_len = 0;    
    size_t full_buffer_len = sizeof (buf) - 1;
    size_t curr_len = full_buffer_len;
    while (curr_len == full_buffer_len)
    {
        Error error;
        curr_len = process->ReadCStringFromMemory(result_ptr + cstr_len, buf, sizeof(buf), error);
        strm.Write (buf, curr_len);
        cstr_len += curr_len;
    }
    return cstr_len > 0;
}
Beispiel #29
0
Error
ABIMacOSX_arm::SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value_sp)
{
    Error error;
    if (!new_value_sp)
    {
        error.SetErrorString("Empty value object for return value.");
        return error;
    }
    
    ClangASTType clang_type = new_value_sp->GetClangType();
    if (!clang_type)
    {
        error.SetErrorString ("Null clang type for return value.");
        return error;
    }
    
    Thread *thread = frame_sp->GetThread().get();
    
    bool is_signed;
    uint32_t count;
    bool is_complex;
    
    RegisterContext *reg_ctx = thread->GetRegisterContext().get();

    bool set_it_simple = false;
    if (clang_type.IsIntegerType (is_signed) || clang_type.IsPointerType())
    {
        DataExtractor data;
        Error data_error;
        size_t num_bytes = new_value_sp->GetData(data, data_error);
        if (data_error.Fail())
        {
            error.SetErrorStringWithFormat("Couldn't convert return value to raw data: %s", data_error.AsCString());
            return error;
        }
        lldb::offset_t offset = 0;
        if (num_bytes <= 8)
        {
            const RegisterInfo *r0_info = reg_ctx->GetRegisterInfoByName("r0", 0);
            if (num_bytes <= 4)
            {
                uint32_t raw_value = data.GetMaxU32(&offset, num_bytes);
        
                if (reg_ctx->WriteRegisterFromUnsigned (r0_info, raw_value))
                    set_it_simple = true;
            }
            else
            {
                uint32_t raw_value = data.GetMaxU32(&offset, 4);
        
                if (reg_ctx->WriteRegisterFromUnsigned (r0_info, raw_value))
                {
                    const RegisterInfo *r1_info = reg_ctx->GetRegisterInfoByName("r1", 0);
                    uint32_t raw_value = data.GetMaxU32(&offset, num_bytes - offset);
                
                    if (reg_ctx->WriteRegisterFromUnsigned (r1_info, raw_value))
                        set_it_simple = true;
                }
            }
        }
        else
        {
            error.SetErrorString("We don't support returning longer than 64 bit integer values at present.");
        }
    }
    else if (clang_type.IsFloatingPointType (count, is_complex))
    {
        if (is_complex)
            error.SetErrorString ("We don't support returning complex values at present");
        else
            error.SetErrorString ("We don't support returning float values at present");
    }
    
    if (!set_it_simple)
        error.SetErrorString ("We only support setting simple integer return types at present.");
    
    return error;
}
void Thread::split(Position& pos, const Stack* ss, Value alpha, Value beta, Value* bestValue,
                   Move* bestMove, Depth depth, int moveCount,
                   MovePicker* movePicker, int nodeType, bool cutNode) {

    assert(pos.pos_is_ok());
    assert(-VALUE_INFINITE < *bestValue && *bestValue <= alpha && alpha < beta && beta <= VALUE_INFINITE);
    assert(depth >= Threads.minimumSplitDepth);
    assert(searching);
    assert(splitPointsSize < MAX_SPLITPOINTS_PER_THREAD);

    // Pick the next available split point from the split point stack
    SplitPoint& sp = splitPoints[splitPointsSize];

    sp.masterThread = this;
    sp.parentSplitPoint = activeSplitPoint;
    sp.slavesMask = 0, sp.slavesMask.set(idx);
    sp.depth = depth;
    sp.bestValue = *bestValue;
    sp.bestMove = *bestMove;
    sp.alpha = alpha;
    sp.beta = beta;
    sp.nodeType = nodeType;
    sp.cutNode = cutNode;
    sp.movePicker = movePicker;
    sp.moveCount = moveCount;
    sp.pos = &pos;
    sp.nodes = 0;
    sp.cutoff = false;
    sp.ss = ss;

    // Try to allocate available threads and ask them to start searching setting
    // 'searching' flag. This must be done under lock protection to avoid concurrent
    // allocation of the same slave by another master.
    Threads.mutex.lock();
    sp.mutex.lock();

    sp.allSlavesSearching = true; // Must be set under lock protection
    ++splitPointsSize;
    activeSplitPoint = &sp;
    activePosition = NULL;

    if (!Fake)
        for (Thread* slave; (slave = Threads.available_slave(this)) != NULL; )
        {
            sp.slavesMask.set(slave->idx);
            slave->activeSplitPoint = &sp;
            slave->searching = true; // Slave leaves idle_loop()
            slave->notify_one(); // Could be sleeping
        }

    // Everything is set up. The master thread enters the idle loop, from which
    // it will instantly launch a search, because its 'searching' flag is set.
    // The thread will return from the idle loop when all slaves have finished
    // their work at this split point.
    sp.mutex.unlock();
    Threads.mutex.unlock();

    Thread::idle_loop(); // Force a call to base class idle_loop()

    // In the helpful master concept, a master can help only a sub-tree of its
    // split point and because everything is finished here, it's not possible
    // for the master to be booked.
    assert(!searching);
    assert(!activePosition);

    // We have returned from the idle loop, which means that all threads are
    // finished. Note that setting 'searching' and decreasing splitPointsSize is
    // done under lock protection to avoid a race with Thread::available_to().
    Threads.mutex.lock();
    sp.mutex.lock();

    searching = true;
    --splitPointsSize;
    activeSplitPoint = sp.parentSplitPoint;
    activePosition = &pos;
    pos.set_nodes_searched(pos.nodes_searched() + sp.nodes);
    *bestMove = sp.bestMove;
    *bestValue = sp.bestValue;

    sp.mutex.unlock();
    Threads.mutex.unlock();
}