BOOL PlayerSystem::OnStubDisconnected( IEvent* pEvent ) { ConnectedEvent* pConnectedEvent = (ConnectedEvent*)pEvent; Stub* pStub = pConnectedEvent->GetStub(); if( pStub->StubType() != STUB_TYPE_PLAYER ) { return TRUE; } PlayerID_t nPlayerID = pStub->StubID( ); Player* pPlayer = m_pPlayerManager->GetPlayer( nPlayerID ); if( !pPlayer ) { g_Log.SaveLog( LOG_LV_WARNING, "PlayerSystem::OnDisconnected Error! can not find the player<%d>", nPlayerID ); return TRUE; } // 离开场景 if( !SceneSystem::m_pSceneSystem->GetScene()->LeaveScene(pPlayer) ) { g_Log.SaveLog( LOG_LV_ERROR, "player<%d> leave scene error!", pPlayer->PlayerID() ); } pPlayer->UnAttachStub( ); m_pPlayerManager->RemovePlayer( nPlayerID ); return TRUE; }
bool MipsGNULDBackend::relaxRelocation(IRBuilder& pBuilder, Relocation& pRel) { uint64_t sym_value = 0x0; LDSymbol* symbol = pRel.symInfo()->outSymbol(); if (symbol->hasFragRef()) { uint64_t value = symbol->fragRef()->getOutputOffset(); uint64_t addr = symbol->fragRef()->frag()->getParent()->getSection().addr(); sym_value = addr + value; } Stub* stub = getStubFactory()->create( pRel, sym_value, pBuilder, *getBRIslandFactory()); if (stub == NULL) return false; assert(stub->symInfo() != NULL); // increase the size of .symtab and .strtab LDSection& symtab = getOutputFormat()->getSymTab(); LDSection& strtab = getOutputFormat()->getStrTab(); symtab.setSize(symtab.size() + sizeof(llvm::ELF::Elf32_Sym)); strtab.setSize(strtab.size() + stub->symInfo()->nameSize() + 1); return true; }
void js::ForOfPIC::Chain::eraseChain() { // Should never need to clear the chain of a disabled stub. MOZ_ASSERT(!disabled_); // Free all stubs. Stub *stub = stubs_; while (stub) { Stub *next = stub->next(); js_delete(stub); stub = next; } stubs_ = nullptr; }
js::ForOfPIC::Stub * js::ForOfPIC::Chain::getMatchingStub(JSObject *obj) { // Ensure PIC is initialized and not disabled. if (!initialized_ || disabled_) return nullptr; // Check if there is a matching stub. for (Stub *stub = stubs(); stub != nullptr; stub = stub->next()) { if (stub->shape() == obj->lastProperty()) return stub; } return nullptr; }
void AArch64GNULDBackend::scanErrata(Module& pModule, IRBuilder& pBuilder, size_t& num_new_stubs, size_t& stubs_strlen) { // TODO: Implement AArch64 ErrataStubFactory to create the specific erratum // stub and simplify the logics. for (Module::iterator sect = pModule.begin(), sectEnd = pModule.end(); sect != sectEnd; ++sect) { if (((*sect)->kind() == LDFileFormat::TEXT) && (*sect)->hasSectionData()) { SectionData* sd = (*sect)->getSectionData(); for (SectionData::iterator it = sd->begin(), ie = sd->end(); it != ie; ++it) { Fragment* frag = llvm::dyn_cast<RegionFragment>(it); if (frag != NULL) { FragmentRef* frag_ref = FragmentRef::Create(*frag, 0); for (unsigned offset = 0; offset < frag->size(); offset += AArch64InsnHelpers::InsnSize) { Stub* stub = getStubFactory()->create(*frag_ref, pBuilder, *getBRIslandFactory()); if (stub != NULL) { // A stub symbol should be local assert(stub->symInfo() != NULL && stub->symInfo()->isLocal()); const AArch64CA53ErratumStub* erratum_stub = reinterpret_cast<const AArch64CA53ErratumStub*>(stub); assert(erratum_stub != NULL); // Rewrite the erratum instruction as a branch to the stub. uint64_t offset = frag_ref->offset() + erratum_stub->getErratumInsnOffset(); Relocation* reloc = Relocation::Create(llvm::ELF::R_AARCH64_JUMP26, *(FragmentRef::Create(*frag, offset)), /* pAddend */0); reloc->setSymInfo(stub->symInfo()); reloc->target() = AArch64InsnHelpers::buildBranchInsn(); addExtraRelocation(reloc); ++num_new_stubs; stubs_strlen += stub->symInfo()->nameSize() + 1; } frag_ref->assign(*frag, offset + AArch64InsnHelpers::InsnSize); } // for each INSN } } // for each FRAGMENT } } // for each TEXT section }
/// addStub - add a stub into the island bool BranchIsland::addStub(const Stub* pPrototype, const Relocation& pReloc, Stub& pStub) { bool exist = false; Key key(pPrototype, pReloc.symInfo()->outSymbol(), pReloc.addend()); StubEntryType* entry = m_StubMap.insert(key, exist); if (!exist) { entry->setValue(&pStub); m_pRear = &pStub; SectionData* sd = m_Entry.getParent(); // insert alignment fragment // TODO: check if we can reduce this alignment fragment for some cases AlignFragment* align_frag = new AlignFragment(pStub.alignment(), 0x0, 1u, pStub.alignment() - 1); align_frag->setParent(sd); sd->getFragmentList().insert(end(), align_frag); align_frag->setOffset(align_frag->getPrevNode()->getOffset() + align_frag->getPrevNode()->size()); // insert stub fragment pStub.setParent(sd); sd->getFragmentList().insert(end(), &pStub); pStub.setOffset(pStub.getPrevNode()->getOffset() + pStub.getPrevNode()->size()); } return !exist; }
/// create - create a stub if needed, otherwise return NULL Stub* StubFactory::create(Relocation& pReloc, uint64_t pTargetSymValue, IRBuilder& pBuilder, BranchIslandFactory& pBRIslandFactory) { // find if there is a prototype stub for the input relocation Stub* prototype = findPrototype(pReloc, pReloc.place(), pTargetSymValue); if (NULL != prototype) { // find the island for the input relocation BranchIsland* island = pBRIslandFactory.find(*(pReloc.targetRef().frag())); if (NULL == island) { island = pBRIslandFactory.produce(*(pReloc.targetRef().frag())); } // find if there is such a stub in the island already assert(NULL != island); Stub* stub = island->findStub(prototype, pReloc); if (NULL != stub) { // reset the branch target to the stub instead! pReloc.setSymInfo(stub->symInfo()); } else { // create a stub from the prototype stub = prototype->clone(); // build a name for stub symbol std::string name("__"); name.append(pReloc.symInfo()->name()); name.append("_"); name.append(stub->name()); name.append("@"); name.append(island->name()); // create LDSymbol for the stub LDSymbol* symbol = pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>( name, ResolveInfo::Function, ResolveInfo::Define, ResolveInfo::Local, stub->size(), // size stub->initSymValue(), // value FragmentRef::Create(*stub, stub->initSymValue()), ResolveInfo::Default); stub->setSymInfo(symbol->resolveInfo()); // add relocations of this stub (i.e., set the branch target of the stub) for (Stub::fixup_iterator it = stub->fixup_begin(), ie = stub->fixup_end(); it != ie; ++it) { Relocation* reloc = Relocation::Create((*it)->type(), *(FragmentRef::Create(*stub, (*it)->offset())), (*it)->addend()); reloc->setSymInfo(pReloc.symInfo()); island->addRelocation(*reloc); } // add stub to the branch island island->addStub(prototype, pReloc, *stub); // reset the branch target of the input reloc to this stub instead! pReloc.setSymInfo(stub->symInfo()); return stub; } } return NULL; }
/*! * Function: slot_get_graph * Description: When "Get Graph" is clicked, this function is responsible for generating the graph based on the data passed, * a full description of each part is given below * @param bool check when it is check */ void MainWindow::slot_get_graph(bool) { Stub *stub = new Stub(); //! stub contains data for testing purpose. //! This is the variable for bar width; the value will be calculated and scaled accordingly, depending on how //! many checkboxes were selected double barWidth = 0; double i = 0; //! loop index; counts how many checkboxes where checked int barsAdded = 0; //! Creating the legend box ui -> customPlot -> legend -> clearItems(); ui -> customPlot -> axisRect()->insetLayout()->setInsetAlignment(0,Qt::AlignTop|Qt::AlignRight); ui -> customPlot -> legend -> setVisible(true); ui->customPlot->clearPlottables(); //! clear the graph //! Set graph interval ui->customPlot->xAxis->setAutoTickStep(0); ui->customPlot->xAxis->setTicks(1); ui->customPlot->xAxis->setTickStep(1.0); ui->customPlot->xAxis->setSubTickCount(0); chartcolour *colourSelect = new chartcolour(); ui->customPlot->legend->clearItems(); //!Clears the existing data from the legend ui->customPlot->axisRect()->setAutoMargins(QCP::msLeft | QCP::msTop | QCP::msBottom); ui->customPlot->axisRect()->setMargins(QMargins(0,0,150,0)); ui->customPlot->axisRect()->insetLayout()->setInsetPlacement(0, QCPLayoutInset::ipFree); ui->customPlot->axisRect()->insetLayout()->setInsetRect(0, QRectF(1.1,0,0.1,0.1)); //! Scaling the bar width based on the number of cities checked if (ui->barrie->isChecked()) { ++i; } if (ui->calgary->isChecked()) { ++i; } if (ui->hamilton->isChecked()) { ++i; } if (ui->london->isChecked()) { ++i; } if (ui->ottawa->isChecked()) { ++i; } if (ui->sudbury->isChecked()) { ++i; } if (ui->thunderBay->isChecked()) { ++i; } if (ui->toronto->isChecked()) { ++i; } if (ui->windsor->isChecked()) { ++i; } if (ui->winnipeg->isChecked()) { ++i; } //! Calculating the new bar width double totalWidth = 0.8; barWidth = totalWidth / i; double setBack = totalWidth/2; double offset = 0; //! Plot data and create a bar graph for Barrie if this city is selected if(ui->barrie->isChecked()) { //! if barrie is checked QCPBars *myBars = new QCPBars(ui->customPlot->xAxis, ui->customPlot->yAxis); myBars->setWidth(barWidth); myBars->setBrush(QBrush(QColor(colourSelect->getColour(barsAdded)))); myBars->setName("Barrie"); ui->customPlot->addPlottable(myBars); //! Barrie data QVector<double> barrieDatatemp = stub->getData("Barrie"); QVector<double> barrieData; QVector<double> valueYears; offset = (barWidth*barsAdded)+(barWidth/2); /*! Checks which years are checked. Plots the years selected, and scales the graph accordingly. */ if(ui->twoThousandNine->isChecked()) { valueYears << 2009-setBack+offset; barrieData << barrieDatatemp.at(0); } if(ui->twoThousandTen->isChecked()) { valueYears << 2010-setBack+offset; barrieData << barrieDatatemp.at(1); } if(ui->twoThousandEleven->isChecked()) { valueYears << 2011-setBack+offset; barrieData << barrieDatatemp.at(2); } //!valueYears << 2009-setBack+offset << 2010-setBack+offset<< 2011-setBack+offset; ++barsAdded; myBars->setData(valueYears, barrieData); ui->customPlot->rescaleAxes(); ui->customPlot->replot(); } //! Plot data and create a bar graph for Calgary if this city is selected if (ui->calgary->isChecked()) { //! This is for Calgary QCPBars *myBars2 = new QCPBars(ui->customPlot->xAxis, ui->customPlot->yAxis); myBars2->setWidth(barWidth); myBars2->setBrush(QBrush(QColor(colourSelect->getColour(barsAdded)))); ui->customPlot->addPlottable(myBars2); //! now we can modify properties of myBars myBars2->setName("Calgary"); //! Calgary Data QVector<double> calgaryDatatemp = stub->getData("Calgary"); QVector<double> calgaryData; QVector<double> valueYears; offset = (barWidth*barsAdded)+(barWidth/2); /*! Checks which years are checked. Plots the years selected, and scales the graph accordingly. */ if(ui->twoThousandNine->isChecked()) { valueYears << 2009-setBack+offset; calgaryData << calgaryDatatemp.at(0); } if(ui->twoThousandTen->isChecked()) { valueYears << 2010-setBack+offset; calgaryData << calgaryDatatemp.at(1); } if(ui->twoThousandEleven->isChecked()) { valueYears << 2011-setBack+offset; calgaryData << calgaryDatatemp.at(2); } //! valueYears2 << 2009-setBack+offset << 2010-setBack+offset<< 2011-setBack+offset; //!2008.60+barWidth*barsAdded << 2009.60+barWidth*barsAdded << 2010.60+barWidth*barsAdded; ++barsAdded; myBars2->setData(valueYears, calgaryData); ui->customPlot->rescaleAxes(); ui->customPlot->replot(); } //!Plot data and create a bar graph for London if this city is selected if (ui->london->isChecked()) { QCPBars *myBars3 = new QCPBars(ui->customPlot->xAxis, ui->customPlot->yAxis); myBars3->setWidth(barWidth); myBars3->setBrush(QBrush(QColor(colourSelect->getColour(barsAdded)))); myBars3->setName("London"); ui->customPlot->addPlottable(myBars3); //! London data QVector<double> londonDatatemp = stub->getData("London"); QVector<double> londonData; QVector<double> valueYears; offset = (barWidth*barsAdded)+(barWidth/2); /*! Checks which years are checked. Plots the years selected, and scales the graph accordingly. */ if(ui->twoThousandNine->isChecked()) { valueYears << 2009-setBack+offset; londonData << londonDatatemp.at(0); } if(ui->twoThousandTen->isChecked()) { valueYears << 2010-setBack+offset; londonData << londonDatatemp.at(1); } if(ui->twoThousandEleven->isChecked()) { valueYears << 2011-setBack+offset; londonData << londonDatatemp.at(2); } //! valueYears << 2009-setBack+offset << 2010-setBack+offset<< 2011-setBack+offset; ++barsAdded; myBars3->setData(valueYears, londonData); ui->customPlot->rescaleAxes(); ui->customPlot->replot(); } //!Plot data and create a bar graph for Hamilton if this city is selected if (ui->hamilton->isChecked()) { QCPBars *myBars4 = new QCPBars(ui->customPlot->xAxis, ui->customPlot->yAxis); myBars4->setWidth(barWidth); myBars4->setBrush(QBrush(QColor(colourSelect->getColour(barsAdded)))); myBars4->setName("Hamilton"); ui->customPlot->addPlottable(myBars4); //! Hamilton data QVector<double> hamiltonDatatemp = stub->getData("Hamilton"); QVector<double> hamiltonData; QVector<double> valueYears; offset = (barWidth*barsAdded)+(barWidth/2); /*! Checks which years are checked. Plots the years selected, and scales the graph accordingly. */ if(ui->twoThousandNine->isChecked()) { valueYears << 2009-setBack+offset; hamiltonData << hamiltonDatatemp.at(0); } if(ui->twoThousandTen->isChecked()) { valueYears << 2010-setBack+offset; hamiltonData << hamiltonDatatemp.at(1); } if(ui->twoThousandEleven->isChecked()) { valueYears << 2011-setBack+offset; hamiltonData << hamiltonDatatemp.at(2); } ++barsAdded; myBars4->setData(valueYears, hamiltonData); ui->customPlot->rescaleAxes(); ui->customPlot->replot(); } //! Plot data and create a bar graph for Ottawa if this city is selected if (ui->ottawa->isChecked()) { QCPBars *myBars5 = new QCPBars(ui->customPlot->xAxis, ui->customPlot->yAxis); myBars5->setWidth(barWidth); myBars5->setBrush(QBrush(QColor(colourSelect->getColour(barsAdded)))); myBars5->setName("Ottawa"); ui->customPlot->addPlottable(myBars5); //! Ottawa data QVector<double> ottawaDatatemp = stub->getData("Ottawa"); QVector<double> ottawaData; QVector<double> valueYears; offset = (barWidth*barsAdded)+(barWidth/2); /*! Checks which years are checked. Plots the years selected, and scales the graph accordingly. */ if(ui->twoThousandNine->isChecked()) { valueYears << 2009-setBack+offset; ottawaData << ottawaDatatemp.at(0); } if(ui->twoThousandTen->isChecked()) { valueYears << 2010-setBack+offset; ottawaData << ottawaDatatemp.at(1); } if(ui->twoThousandEleven->isChecked()) { valueYears << 2011-setBack+offset; ottawaData << ottawaDatatemp.at(2); } ++barsAdded; myBars5->setData(valueYears, ottawaData); ui->customPlot->rescaleAxes(); ui->customPlot->replot(); } //! Plot data and create a bar graph for Sudbury (Greater) if this city is selected if (ui->sudbury->isChecked()) { QCPBars *myBars6 = new QCPBars(ui->customPlot->xAxis, ui->customPlot->yAxis); myBars6->setWidth(barWidth); myBars6->setBrush(QBrush(QColor(colourSelect->getColour(barsAdded)))); myBars6->setName("Sudbury"); ui->customPlot->addPlottable(myBars6); //! Sudbury data QVector<double> sudburyDatatemp = stub->getData("Sudbury (Greater)"); QVector<double> sudburyData; QVector<double> valueYears; offset = (barWidth*barsAdded)+(barWidth/2); /*! Checks which years are checked. Plots the years selected, and scales the graph accordingly. */ if(ui->twoThousandNine->isChecked()) { valueYears << 2009-setBack+offset; sudburyData << sudburyDatatemp.at(0); } if(ui->twoThousandTen->isChecked()) { valueYears << 2010-setBack+offset; sudburyData << sudburyDatatemp.at(1); } if(ui->twoThousandEleven->isChecked()) { valueYears << 2011-setBack+offset; sudburyData << sudburyDatatemp.at(2); } ++barsAdded; myBars6->setData(valueYears, sudburyData); ui->customPlot->rescaleAxes(); ui->customPlot->replot(); } //! Plot data and create a bar graph for Thunder Bay if this city is selected if (ui->thunderBay->isChecked()) { QCPBars *myBars7 = new QCPBars(ui->customPlot->xAxis, ui->customPlot->yAxis); myBars7->setWidth(barWidth); myBars7->setBrush(QBrush(QColor(colourSelect->getColour(barsAdded)))); myBars7->setName("Thunder Bay"); ui->customPlot->addPlottable(myBars7); //! Thunder Bay data QVector<double> thunderDatatemp = stub->getData("Thunder Bay"); QVector<double> thunderData; QVector<double> valueYears; offset = (barWidth*barsAdded)+(barWidth/2); /*! Checks which years are checked. Plots the years selected, and scales the graph accordingly. */ if(ui->twoThousandNine->isChecked()) { valueYears << 2009-setBack+offset; thunderData << thunderDatatemp.at(0); } if(ui->twoThousandTen->isChecked()) { valueYears << 2010-setBack+offset; thunderData << thunderDatatemp.at(1); } if(ui->twoThousandEleven->isChecked()) { valueYears << 2011-setBack+offset; thunderData << thunderDatatemp.at(2); } ++barsAdded; myBars7->setData(valueYears, thunderData); ui->customPlot->rescaleAxes(); ui->customPlot->replot(); } //! Plot data and create a bar graph for Toronto if this city is selected if (ui->toronto->isChecked()) { QCPBars *myBars8 = new QCPBars(ui->customPlot->xAxis, ui->customPlot->yAxis); myBars8->setWidth(barWidth); myBars8->setBrush(QBrush(QColor(colourSelect->getColour(barsAdded)))); myBars8->setName("Toronto"); ui->customPlot->addPlottable(myBars8); //! Sudbury data QVector<double> torontoDatatest = stub->getData("Toronto"); QVector<double> torontoData; QVector<double> valueYears; offset = (barWidth*barsAdded)+(barWidth/2); /*! Checks which years are checked. Plots the years selected, and scales the graph accordingly. */ if(ui->twoThousandNine->isChecked()) { valueYears << 2009-setBack+offset; torontoData << torontoDatatest.at(0); } if(ui->twoThousandTen->isChecked()) { valueYears << 2010-setBack+offset; torontoData << torontoDatatest.at(1); } if(ui->twoThousandEleven->isChecked()) { valueYears << 2011-setBack+offset; torontoData << torontoDatatest.at(2); } ++barsAdded; myBars8->setData(valueYears, torontoData); ui->customPlot->rescaleAxes(); ui->customPlot->replot(); } //! Plot data and create a bar graph for Winnipeg if this city is selected if (ui->winnipeg->isChecked()) { QCPBars *myBars9 = new QCPBars(ui->customPlot->xAxis, ui->customPlot->yAxis); myBars9->setWidth(barWidth); myBars9->setBrush(QBrush(QColor(colourSelect->getColour(barsAdded)))); myBars9->setName("Winnipeg"); ui->customPlot->addPlottable(myBars9); //! Sudbury data QVector<double> winnipegDatatemp = stub->getData("Winnipeg"); QVector<double> winnipegData; QVector<double> valueYears; offset = (barWidth*barsAdded)+(barWidth/2); /*! Checks which years are checked. Plots the years selected, and scales the graph accordingly. */ if(ui->twoThousandNine->isChecked()) { valueYears << 2009-setBack+offset; winnipegData << winnipegDatatemp.at(0); } if(ui->twoThousandTen->isChecked()) { valueYears << 2010-setBack+offset; winnipegData << winnipegDatatemp.at(1); } if(ui->twoThousandEleven->isChecked()) { valueYears << 2011-setBack+offset; winnipegData << winnipegDatatemp.at(2); } ++barsAdded; myBars9->setData(valueYears, winnipegData); ui->customPlot->rescaleAxes(); ui->customPlot->replot(); } //! Plot data and create a bar graph for Windsor if this city is selected if (ui->windsor->isChecked()) { QCPBars *myBars10 = new QCPBars(ui->customPlot->xAxis, ui->customPlot->yAxis); myBars10->setWidth(barWidth); myBars10->setBrush(QBrush(QColor(colourSelect->getColour(barsAdded)))); myBars10->setName("Windor"); ui->customPlot->addPlottable(myBars10); //! Sudbury data QVector<double> windsorDatatemp = stub->getData("Windsor"); QVector<double> windsorData; QVector<double> valueYears; offset = (barWidth*barsAdded)+(barWidth/2); /*! Checks which years are checked. Plots the years selected, and scales the graph accordingly. */ if(ui->twoThousandNine->isChecked()) { valueYears << 2009-setBack+offset; windsorData << windsorDatatemp.at(0); } if(ui->twoThousandTen->isChecked()) { valueYears << 2010-setBack+offset; windsorData << windsorDatatemp.at(1); } if(ui->twoThousandEleven->isChecked()) { valueYears << 2011-setBack+offset; windsorData << windsorDatatemp.at(2); } ++barsAdded; myBars10->setData(valueYears, windsorData); ui->customPlot->rescaleAxes(); ui->customPlot->replot(); } }
//--------------------------------------------------------- // Returns the equivalent hashed Stub, creating a new hash // entry if necessary. If the latter, will call out to CompileMLStub. // // Refcounting: // The caller is responsible for DecRef'ing the returned stub in // order to avoid leaks. // // // On successful exit, *pMode is set to describe // the compiled nature of the MLStub. // // callerContext can be used by the caller to push some context through // to the compilation routine. // // Returns NULL for out of memory or other fatal error. //--------------------------------------------------------- Stub *MLStubCache::Canonicalize(const BYTE * pRawMLStub, MLStubCompilationMode *pMode, void *callerContext) { m_crst.Enter(); MLCHASHENTRY *phe = (MLCHASHENTRY*)Find((LPVOID)pRawMLStub); if (phe) { Stub *pstub = phe->m_pMLStub; pstub->IncRef(); *pMode = (MLStubCompilationMode) (phe->m_compilationMode); m_crst.Leave(); return pstub; } m_crst.Leave(); { CPUSTUBLINKER sl; CPUSTUBLINKER slempty; CPUSTUBLINKER *psl = &sl; MLStubCompilationMode mode; mode = CompileMLStub(pRawMLStub, psl, callerContext); if (mode == INTERPRETED) { // CompileMLStub returns INTERPRETED for error cases: // in this case, redirect to the empty stublinker so // we don't accidentally pick up any crud that // CompileMLStub threw into the stublinker before // it ran into the error condition. psl = &slempty; } *pMode = mode; UINT32 offset; Stub *pstub; if (NULL == (pstub = FinishLinking(psl, pRawMLStub, &offset))) { return NULL; } if (offset > 0xffff) { return NULL; } m_crst.Enter(); bool bNew; phe = (MLCHASHENTRY*)FindOrAdd((LPVOID)pRawMLStub, /*modifies*/bNew); if (phe) { if (bNew) { // Note: FinishLinking already does the IncRef. phe->m_pMLStub = pstub; phe->m_offsetOfRawMLStub = (UINT16)offset; phe->m_compilationMode = mode; } else { // If we got here, some other thread got in // and enregistered an identical stub during // the window in which we were out of the m_crst. //Under DEBUG, two identical ML streams can actually compile // to different compiled stubs due to the checked build's // toggling between inlined TLSGetValue and api TLSGetValue. //_ASSERTE(phe->m_offsetOfRawMLStub == (UINT16)offset); _ASSERTE(phe->m_compilationMode == mode); pstub->DecRef(); // Destroy the stub we just created pstub = phe->m_pMLStub; //Use the previously created stub } // IncRef so that caller has firm ownership of stub. pstub->IncRef(); } m_crst.Leave(); if (phe) { return pstub; } else { // Couldn't grow hash table due to lack of memory. // Destroy the stub and return NULL. pstub->DecRef(); } } return NULL; }
bool AArch64GNULDBackend::doRelax(Module& pModule, IRBuilder& pBuilder, bool& pFinished) { assert(getStubFactory() != NULL && getBRIslandFactory() != NULL); // Number of new stubs added size_t num_new_stubs = 0; // String lengh to hold new stub symbols size_t stubs_strlen = 0; if (config().targets().fixCA53Erratum835769() || config().targets().fixCA53Erratum843419()) { scanErrata(pModule, pBuilder, num_new_stubs, stubs_strlen); } ELFFileFormat* file_format = getOutputFormat(); // check branch relocs and create the related stubs if needed Module::obj_iterator input, inEnd = pModule.obj_end(); for (input = pModule.obj_begin(); input != inEnd; ++input) { LDContext::sect_iterator rs, rsEnd = (*input)->context()->relocSectEnd(); for (rs = (*input)->context()->relocSectBegin(); rs != rsEnd; ++rs) { if (LDFileFormat::Ignore == (*rs)->kind() || !(*rs)->hasRelocData()) continue; RelocData::iterator reloc, rEnd = (*rs)->getRelocData()->end(); for (reloc = (*rs)->getRelocData()->begin(); reloc != rEnd; ++reloc) { Relocation* relocation = llvm::cast<Relocation>(reloc); switch (relocation->type()) { case llvm::ELF::R_AARCH64_CALL26: case llvm::ELF::R_AARCH64_JUMP26: { // calculate the possible symbol value uint64_t sym_value = 0x0; LDSymbol* symbol = relocation->symInfo()->outSymbol(); if (symbol->hasFragRef()) { uint64_t value = symbol->fragRef()->getOutputOffset(); uint64_t addr = symbol->fragRef()->frag()->getParent()->getSection().addr(); sym_value = addr + value; } if ((relocation->symInfo()->reserved() & AArch64Relocator::ReservePLT) != 0x0) { // FIXME: we need to find out the address of the specific plt // entry assert(file_format->hasPLT()); sym_value = file_format->getPLT().addr(); } Stub* stub = getStubFactory()->create(*relocation, // relocation sym_value, // symbol value pBuilder, *getBRIslandFactory()); if (stub != NULL) { // a stub symbol should be local assert(stub->symInfo() != NULL && stub->symInfo()->isLocal()); // reset the branch target of the reloc to this stub instead relocation->setSymInfo(stub->symInfo()); ++num_new_stubs; stubs_strlen += stub->symInfo()->nameSize() + 1; } break; } default: { break; } } // end of switch } // for all relocations } // for all relocation section } // for all inputs // Find the first fragment w/ invalid offset due to stub insertion. std::vector<Fragment*> invalid_frags; pFinished = true; for (BranchIslandFactory::iterator island = getBRIslandFactory()->begin(), island_end = getBRIslandFactory()->end(); island != island_end; ++island) { if ((*island).size() > stubGroupSize()) { error(diag::err_no_space_to_place_stubs) << stubGroupSize(); return false; } if ((*island).numOfStubs() == 0) { continue; } Fragment* exit = &*(*island).end(); if (exit == (*island).begin()->getParent()->end()) { continue; } if (((*island).offset() + (*island).size()) > exit->getOffset()) { if (invalid_frags.empty() || (invalid_frags.back()->getParent() != (*island).getParent())) { invalid_frags.push_back(exit); pFinished = false; } continue; } } // Reset the offset of invalid fragments. for (auto it = invalid_frags.begin(), ie = invalid_frags.end(); it != ie; ++it) { Fragment* invalid = *it; while (invalid != NULL) { invalid->setOffset(invalid->getPrevNode()->getOffset() + invalid->getPrevNode()->size()); invalid = invalid->getNextNode(); } } // Fix up the size of .symtab, .strtab, and TEXT sections if (num_new_stubs == 0) { return false; } else { switch (config().options().getStripSymbolMode()) { case GeneralOptions::StripSymbolMode::StripAllSymbols: case GeneralOptions::StripSymbolMode::StripLocals: break; default: { LDSection& symtab = file_format->getSymTab(); LDSection& strtab = file_format->getStrTab(); symtab.setSize(symtab.size() + sizeof(llvm::ELF::Elf64_Sym) * num_new_stubs); symtab.setInfo(symtab.getInfo() + num_new_stubs); strtab.setSize(strtab.size() + stubs_strlen); } } // switch (config().options().getStripSymbolMode()) SectionData* prev = NULL; for (BranchIslandFactory::iterator island = getBRIslandFactory()->begin(), island_end = getBRIslandFactory()->end(); island != island_end; ++island) { SectionData* sd = (*island).begin()->getParent(); if ((*island).numOfStubs() != 0) { if (sd != prev) { sd->getSection().setSize(sd->back().getOffset() + sd->back().size()); } } prev = sd; } return true; } // if (num_new_stubs == 0) }
void processEvent (int ev) { Log l("client "); // client l.info("getting remote Echo...\n"); Stub<Echo> e; e.remote = reg->getRemote("test.Echo"); l.info("using Echo(remote:%08x)...\n", e.remote.get()); { string ret; if (e.echo(ret, "hi")) { l.error("echo failed.\n"); } printf("%s\n", ret.c_str()); } { vector<string> args; args.push_back("a"); args.push_back("b"); args.push_back("c"); string ret; if (e.concat(ret, args)) { l.error("concat failed.\n"); } printf("%s\n", ret.c_str()); } { Ref<TestException> ex1; printf("Invoking touchmenot()\n"); switch (e.touchmenot(ex1)) { default: l.error("Unexpected return\n"); break; case 0: printf("Silently returned.\n"); break; case 1: printf("Got exception :%d\n", *ex1->i); break; } } Ref<EchoCallback> cb = new EchoCallbackImpl(); if (e.recursiveEcho("rrrrrrrrrrrrrrrrrrrrrrrrrrr", cb)) { l.error("recursiveEcho failed\n"); } Person p; p.name = "Sooin"; p.callback = cb; if (e.hello(p)) { l.error("hello failed.\n"); } if (e.asyncEcho("hi again", cb)) { l.error("asyncEcho failed.\n"); } printf("starting doubleit test.\n"); { int32_t ret; if (e.doubleit(ret, 3) == 0) { printf("doubleit(3) returns %d\n", ret); } else { l.error("doubleit failed.\n"); } } }
bool HexagonLDBackend::doRelax(Module& pModule, IRBuilder& pBuilder, bool& pFinished) { assert(NULL != getStubFactory() && NULL != getBRIslandFactory()); bool isRelaxed = false; ELFFileFormat* file_format = getOutputFormat(); // check branch relocs and create the related stubs if needed Module::obj_iterator input, inEnd = pModule.obj_end(); for (input = pModule.obj_begin(); input != inEnd; ++input) { LDContext::sect_iterator rs, rsEnd = (*input)->context()->relocSectEnd(); for (rs = (*input)->context()->relocSectBegin(); rs != rsEnd; ++rs) { if (LDFileFormat::Ignore == (*rs)->kind() || !(*rs)->hasRelocData()) continue; RelocData::iterator reloc, rEnd = (*rs)->getRelocData()->end(); for (reloc = (*rs)->getRelocData()->begin(); reloc != rEnd; ++reloc) { switch (reloc->type()) { case llvm::ELF::R_HEX_B22_PCREL: case llvm::ELF::R_HEX_B15_PCREL: case llvm::ELF::R_HEX_B7_PCREL: case llvm::ELF::R_HEX_B13_PCREL: case llvm::ELF::R_HEX_B9_PCREL: { Relocation* relocation = llvm::cast<Relocation>(reloc); uint64_t sym_value = 0x0; LDSymbol* symbol = relocation->symInfo()->outSymbol(); if (symbol->hasFragRef()) { uint64_t value = symbol->fragRef()->getOutputOffset(); uint64_t addr = symbol->fragRef()->frag()->getParent()->getSection().addr(); sym_value = addr + value; } Stub* stub = getStubFactory()->create(*relocation, // relocation sym_value, //symbol value pBuilder, *getBRIslandFactory()); if (NULL != stub) { assert(NULL != stub->symInfo()); // increase the size of .symtab and .strtab LDSection& symtab = file_format->getSymTab(); LDSection& strtab = file_format->getStrTab(); symtab.setSize(symtab.size() + sizeof(llvm::ELF::Elf32_Sym)); strtab.setSize(strtab.size() + stub->symInfo()->nameSize() + 1); isRelaxed = true; } } break; default: break; } } } } // find the first fragment w/ invalid offset due to stub insertion Fragment* invalid = NULL; pFinished = true; for (BranchIslandFactory::iterator island = getBRIslandFactory()->begin(), island_end = getBRIslandFactory()->end(); island != island_end; ++island) { if ((*island).end() == file_format->getText().getSectionData()->end()) break; Fragment* exit = (*island).end(); if (((*island).offset() + (*island).size()) > exit->getOffset()) { invalid = exit; pFinished = false; break; } } // reset the offset of invalid fragments while (NULL != invalid) { invalid->setOffset(invalid->getPrevNode()->getOffset() + invalid->getPrevNode()->size()); invalid = invalid->getNextNode(); } // reset the size of .text if (isRelaxed) { file_format->getText().setSize( file_format->getText().getSectionData()->back().getOffset() + file_format->getText().getSectionData()->back().size()); } return isRelaxed; }
/// create - create a stub if needed, otherwise return NULL Stub* StubFactory::create(Relocation& pReloc, uint64_t pTargetSymValue, IRBuilder& pBuilder, BranchIslandFactory& pBRIslandFactory) { // find if there is a prototype stub for the input relocation Stub* stub = NULL; Stub* prototype = findPrototype(pReloc, pReloc.place(), pTargetSymValue); if (prototype != NULL) { const Fragment* frag = pReloc.targetRef().frag(); // find the islands for the input relocation std::pair<BranchIsland*, BranchIsland*> islands = pBRIslandFactory.getIslands(*frag); if (islands.first == NULL) { // early exit if we can not find the forward island. return NULL; } // find if there is such a stub in the backward island first. if (islands.second != NULL) { stub = islands.second->findStub(prototype, pReloc); } if (stub != NULL) { // reset the branch target to the stub instead! pReloc.setSymInfo(stub->symInfo()); } else { // find if there is such a stub in the forward island. stub = islands.first->findStub(prototype, pReloc); if (stub != NULL) { // reset the branch target to the stub instead! pReloc.setSymInfo(stub->symInfo()); } else { // create a stub from the prototype stub = prototype->clone(); // build a name for stub symbol std::string name("__"); name.append(pReloc.symInfo()->name()) .append("_") .append(stub->name()) .append("@") .append(islands.first->name()); // create LDSymbol for the stub LDSymbol* symbol = pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Unresolve>( name, ResolveInfo::Function, ResolveInfo::Define, ResolveInfo::Local, stub->size(), // size stub->initSymValue(), // value FragmentRef::Create(*stub, stub->initSymValue()), ResolveInfo::Default); stub->setSymInfo(symbol->resolveInfo()); // add relocations of this stub (i.e., set the branch target of the // stub) for (Stub::fixup_iterator it = stub->fixup_begin(), ie = stub->fixup_end(); it != ie; ++it) { Relocation* reloc = Relocation::Create((*it)->type(), *(FragmentRef::Create(*stub, (*it)->offset())), (*it)->addend()); reloc->setSymInfo(pReloc.symInfo()); islands.first->addRelocation(*reloc); } // add stub to the forward branch island islands.first->addStub(prototype, pReloc, *stub); // reset the branch target of the input reloc to this stub instead! pReloc.setSymInfo(stub->symInfo()); } } } return stub; }
/// doRelax bool ARMGNULDBackend::doRelax(Module& pModule, IRBuilder& pBuilder, bool& pFinished) { assert(NULL != getStubFactory() && NULL != getBRIslandFactory()); bool isRelaxed = false; ELFFileFormat* file_format = getOutputFormat(); // check branch relocs and create the related stubs if needed Module::obj_iterator input, inEnd = pModule.obj_end(); for (input = pModule.obj_begin(); input != inEnd; ++input) { LDContext::sect_iterator rs, rsEnd = (*input)->context()->relocSectEnd(); for (rs = (*input)->context()->relocSectBegin(); rs != rsEnd; ++rs) { if (LDFileFormat::Ignore == (*rs)->kind() || !(*rs)->hasRelocData()) continue; RelocData::iterator reloc, rEnd = (*rs)->getRelocData()->end(); for (reloc = (*rs)->getRelocData()->begin(); reloc != rEnd; ++reloc) { Relocation* relocation = llvm::cast<Relocation>(reloc); switch (relocation->type()) { case llvm::ELF::R_ARM_PC24: case llvm::ELF::R_ARM_CALL: case llvm::ELF::R_ARM_JUMP24: case llvm::ELF::R_ARM_PLT32: case llvm::ELF::R_ARM_THM_CALL: case llvm::ELF::R_ARM_THM_XPC22: case llvm::ELF::R_ARM_THM_JUMP24: case llvm::ELF::R_ARM_THM_JUMP19: { // calculate the possible symbol value uint64_t sym_value = 0x0; LDSymbol* symbol = relocation->symInfo()->outSymbol(); if (symbol->hasFragRef()) { uint64_t value = symbol->fragRef()->getOutputOffset(); uint64_t addr = symbol->fragRef()->frag()->getParent()->getSection().addr(); sym_value = addr + value; } if (relocation->symInfo()->isGlobal() && (relocation->symInfo()->reserved() & ARMRelocator::ReservePLT) != 0x0) { // FIXME: we need to find out the address of the specific plt entry assert(file_format->hasPLT()); sym_value = file_format->getPLT().addr(); } Stub* stub = getStubFactory()->create(*relocation, // relocation sym_value, // symbol value pBuilder, *getBRIslandFactory()); if (NULL != stub) { switch (config().options().getStripSymbolMode()) { case GeneralOptions::StripAllSymbols: case GeneralOptions::StripLocals: break; default: { // a stub symbol should be local assert(NULL != stub->symInfo() && stub->symInfo()->isLocal()); LDSection& symtab = file_format->getSymTab(); LDSection& strtab = file_format->getStrTab(); // increase the size of .symtab and .strtab if needed if (config().targets().is32Bits()) symtab.setSize(symtab.size() + sizeof(llvm::ELF::Elf32_Sym)); else symtab.setSize(symtab.size() + sizeof(llvm::ELF::Elf64_Sym)); symtab.setInfo(symtab.getInfo() + 1); strtab.setSize(strtab.size() + stub->symInfo()->nameSize() + 1); } } // end of switch isRelaxed = true; } break; } case llvm::ELF::R_ARM_V4BX: /* FIXME: bypass R_ARM_V4BX relocation now */ break; default: break; } // end of switch } // for all relocations } // for all relocation section } // for all inputs // find the first fragment w/ invalid offset due to stub insertion Fragment* invalid = NULL; pFinished = true; for (BranchIslandFactory::iterator island = getBRIslandFactory()->begin(), island_end = getBRIslandFactory()->end(); island != island_end; ++island) { if ((*island).end() == file_format->getText().getSectionData()->end()) break; Fragment* exit = (*island).end(); if (((*island).offset() + (*island).size()) > exit->getOffset()) { invalid = exit; pFinished = false; break; } } // reset the offset of invalid fragments while (NULL != invalid) { invalid->setOffset(invalid->getPrevNode()->getOffset() + invalid->getPrevNode()->size()); invalid = invalid->getNextNode(); } // reset the size of .text if (isRelaxed) { file_format->getText().setSize( file_format->getText().getSectionData()->back().getOffset() + file_format->getText().getSectionData()->back().size()); } return isRelaxed; }