void Stub::applyFixup(Relocation& pSrcReloc, IRBuilder& pBuilder, BranchIsland& pIsland) { // build a name for stub symbol std::string sym_name("__"); sym_name.append(pSrcReloc.symInfo()->name()) .append("_") .append(name()) .append("@") .append(pIsland.name()); // create LDSymbol for the stub LDSymbol* symbol = pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Unresolve>( sym_name, ResolveInfo::Function, ResolveInfo::Define, ResolveInfo::Local, size(), initSymValue(), FragmentRef::Create(*this, initSymValue()), ResolveInfo::Default); setSymInfo(symbol->resolveInfo()); // add relocations of this stub (i.e., set the branch target of the stub) for (fixup_iterator it = fixup_begin(), ie = fixup_end(); it != ie; ++it) { Relocation* reloc = Relocation::Create((*it)->type(), *(FragmentRef::Create(*this, (*it)->offset())), (*it)->addend()); reloc->setSymInfo(pSrcReloc.symInfo()); pIsland.addRelocation(*reloc); } }
void GarbageCollection::getEntrySections(SectionVecTy& pEntry) { // all the KEEP sections defined in ldscript are entries, traverse all the // input sections and check the SectionMap to find the KEEP sections Module::obj_iterator obj, objEnd = m_Module.obj_end(); SectionMap& sect_map = m_Module.getScript().sectionMap(); for (obj = m_Module.obj_begin(); obj != objEnd; ++obj) { const std::string input_name = (*obj)->name(); LDContext::sect_iterator sect, sectEnd = (*obj)->context()->sectEnd(); for (sect = (*obj)->context()->sectBegin(); sect != sectEnd; ++sect) { LDSection* section = *sect; if (LDFileFormat::Regular != section->kind() && LDFileFormat::BSS != section->kind()) continue; SectionMap::Input* sm_input = sect_map.find(input_name, section->name()).second; if ((sm_input != NULL) && (InputSectDesc::Keep == sm_input->policy())) pEntry.push_back(section); } } // get the sections those the entry symbols defined in Module::SymbolTable& sym_tab = m_Module.getSymbolTable(); if (LinkerConfig::Exec == m_Config.codeGenType()) { assert(NULL != m_pEntry); pEntry.push_back(&m_pEntry->fragRef()->frag()->getParent()->getSection()); } else { // when building shared objects, the global define symbols are entries SymbolCategory::iterator it, end = sym_tab.regularEnd(); for (it = sym_tab.dynamicBegin(); it != end; ++it) { LDSymbol* sym = *it; if (!sym->resolveInfo()->isDefine() || !sym->hasFragRef()) continue; // only the target symbols defined in the concerned sections can make // the reference const LDSection* sect = &sym->fragRef()->frag()->getParent()->getSection(); if (sect->kind() != LDFileFormat::Regular && sect->kind() != LDFileFormat::BSS) continue; pEntry.push_back(sect); } } }
/// 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; }
/// 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; }