void GarbageCollection::stripSections() { // Traverse all the input Regular and BSS sections, if a section is not found // in the ReferencedSections, then it should be garbage collected Module::obj_iterator obj, objEnd = m_Module.obj_end(); for (obj = m_Module.obj_begin(); obj != objEnd; ++obj) { 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; if (m_ReferencedSections.find(section) == m_ReferencedSections.end()) section->setKind(LDFileFormat::Ignore); } } // Traverse all the relocation sections, if its target section is set to // Ignore, then set the relocation section to Ignore as well Module::obj_iterator input, inEnd = m_Module.obj_end(); for (input = m_Module.obj_begin(); input != inEnd; ++input) { LDContext::sect_iterator rs, rsEnd = (*input)->context()->relocSectEnd(); for (rs = (*input)->context()->relocSectBegin(); rs != rsEnd; ++rs) { LDSection* reloc_sect = *rs; if (LDFileFormat::Ignore == reloc_sect->getLink()->kind()) reloc_sect->setKind(LDFileFormat::Ignore); } } }
bool ARMGNULDBackend::mergeSection(Module& pModule, const Input& pInput, LDSection& pSection) { switch (pSection.type()) { case llvm::ELF::SHT_ARM_ATTRIBUTES: { return attribute().merge(pInput, pSection); } case llvm::ELF::SHT_ARM_EXIDX: { assert(NULL != pSection.getLink()); if ((pSection.getLink()->kind() == LDFileFormat::Ignore) || (pSection.getLink()->kind() == LDFileFormat::Folded)) { // if the target section of the .ARM.exidx is Ignore, then it should be // ignored as well pSection.setKind(LDFileFormat::Ignore); return true; } } /** fall through **/ default: { ObjectBuilder builder(pModule); builder.MergeSection(pInput, pSection); return true; } } // end of switch return true; }
void IdenticalCodeFolding::foldIdenticalCode() { // 1. Find folding candidates. FoldingCandidates candidate_list; findCandidates(candidate_list); // 2. Initialize constant section content for (size_t i = 0; i < candidate_list.size(); ++i) { candidate_list[i].initConstantContent(m_Backend, m_KeptSections); } // 3. Find identical code until convergence bool converged = false; size_t iterations = 0; while (!converged && (iterations < m_Config.options().getICFIterations())) { converged = matchCandidates(candidate_list); ++iterations; } if (m_Config.options().printICFSections()) { debug(diag::debug_icf_iterations) << iterations; } // 4. Fold the identical code typedef std::set<Input*> FoldedObjects; FoldedObjects folded_objs; KeptSections::iterator kept, keptEnd = m_KeptSections.end(); size_t index = 0; for (kept = m_KeptSections.begin(); kept != keptEnd; ++kept, ++index) { LDSection* sect = (*kept).first; Input* obj = (*kept).second.first; size_t kept_index = (*kept).second.second; if (index != kept_index) { sect->setKind(LDFileFormat::Folded); folded_objs.insert(obj); if (m_Config.options().printICFSections()) { KeptSections::iterator it = m_KeptSections.begin() + kept_index; LDSection* kept_sect = (*it).first; Input* kept_obj = (*it).second.first; debug(diag::debug_icf_folded_section) << sect->name() << obj->name() << kept_sect->name() << kept_obj->name(); } } } // Adjust the fragment reference of the folded symbols. FoldedObjects::iterator fobj, fobjEnd = folded_objs.end(); for (fobj = folded_objs.begin(); fobj != fobjEnd; ++fobj) { LDContext::sym_iterator sym, symEnd = (*fobj)->context()->symTabEnd(); for (sym = (*fobj)->context()->symTabBegin(); sym != symEnd; ++sym) { if ((*sym)->hasFragRef() && ((*sym)->type() == ResolveInfo::Function)) { LDSymbol* out_sym = (*sym)->resolveInfo()->outSymbol(); FragmentRef* frag_ref = out_sym->fragRef(); LDSection* sect = &(frag_ref->frag()->getParent()->getSection()); if (sect->kind() == LDFileFormat::Folded) { size_t kept_index = m_KeptSections[sect].second; LDSection* kept_sect = (*(m_KeptSections.begin() + kept_index)).first; frag_ref->assign(kept_sect->getSectionData()->front(), frag_ref->offset()); } } } // for each symbol } // for each folded object }