IdenticalCodeFolding.cpp revision b3323086ee04f9db9e85f7cae46510f91a137237
1b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou//===- IndenticalCodeFolding.cpp ------------------------------------------===// 2b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou// 3b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou// The MCLinker Project 4b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou// 5b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou// This file is distributed under the University of Illinois Open Source 6b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou// License. See LICENSE.TXT for details. 7b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou// 8b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou//===----------------------------------------------------------------------===// 9b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou 10b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou#include <mcld/Fragment/RegionFragment.h> 11b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou#include <mcld/LD/IdenticalCodeFolding.h> 12b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou#include <mcld/LD/LDContext.h> 13b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou#include <mcld/LD/LDSection.h> 14b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou#include <mcld/LD/RelocData.h> 15b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou#include <mcld/LD/Relocator.h> 16b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou#include <mcld/LD/ResolveInfo.h> 17b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou#include <mcld/LD/SectionData.h> 18b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou#include <mcld/LinkerConfig.h> 19b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou#include <mcld/MC/Input.h> 20b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou#include <mcld/GeneralOptions.h> 21b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou#include <mcld/Module.h> 22b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou#include <mcld/Support/Demangle.h> 23b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou#include <mcld/Support/MsgHandling.h> 24b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou#include <mcld/Target/GNULDBackend.h> 25b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou 26b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou#include <llvm/ADT/StringRef.h> 27b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou#include <llvm/Support/Casting.h> 28b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou#include <llvm/Support/Format.h> 29b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou 30b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou#include <cassert> 31b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou#include <map> 32b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou#include <set> 33b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou 34b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou#include <zlib.h> 35b3323086ee04f9db9e85f7cae46510f91a137237Pete Chouusing namespace mcld; 36b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou 37b3323086ee04f9db9e85f7cae46510f91a137237Pete Choustatic bool isSymCtorOrDtor(const ResolveInfo& pSym) 38b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou{ 39b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou // We can always fold ctors and dtors since accessing function pointer in C++ 40b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou // is forbidden. 41b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou llvm::StringRef name(pSym.name(), pSym.nameSize()); 42b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou if (!name.startswith("_ZZ") && !name.startswith("_ZN")) { 43b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou return false; 44b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } 45b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou return isCtorOrDtor(pSym.name(), pSym.nameSize()); 46b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou} 47b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou 48b3323086ee04f9db9e85f7cae46510f91a137237Pete ChouIdenticalCodeFolding::IdenticalCodeFolding(const LinkerConfig& pConfig, 49b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou const TargetLDBackend& pBackend, 50b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou Module& pModule) 51b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou : m_Config(pConfig), m_Backend(pBackend), m_Module(pModule) 52b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou{ 53b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou} 54b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou 55b3323086ee04f9db9e85f7cae46510f91a137237Pete Chouvoid IdenticalCodeFolding::foldIdenticalCode() 56b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou{ 57b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou // 1. Find folding candidates. 58b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou FoldingCandidates candidate_list; 59b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou findCandidates(candidate_list); 60b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou 61b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou // 2. Initialize constant section content 62b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou for (size_t i = 0; i < candidate_list.size(); ++i) { 63b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou candidate_list[i].initConstantContent(m_Backend, m_KeptSections); 64b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } 65b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou 66b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou // 3. Find identical code until convergence 67b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou bool converged = false; 68b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou size_t iterations = 0; 69b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou while (!converged && (iterations < m_Config.options().getICFIterations())) { 70b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou converged = matchCandidates(candidate_list); 71b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou ++iterations; 72b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } 73b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou if (m_Config.options().printICFSections()) { 74b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou debug(diag::debug_icf_iterations) << iterations; 75b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } 76b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou 77b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou // 4. Fold the identical code 78b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou typedef std::set<Input*> FoldedObjects; 79b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou FoldedObjects folded_objs; 80b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou KeptSections::iterator kept, keptEnd = m_KeptSections.end(); 81b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou size_t index = 0; 82b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou for (kept = m_KeptSections.begin(); kept != keptEnd; ++kept, ++index) { 83b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou LDSection* sect = (*kept).first; 84b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou Input* obj = (*kept).second.first; 85b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou size_t kept_index = (*kept).second.second; 86b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou if (index != kept_index) { 87b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou sect->setKind(LDFileFormat::Folded); 88b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou folded_objs.insert(obj); 89b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou 90b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou if (m_Config.options().printICFSections()) { 91b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou KeptSections::iterator it = m_KeptSections.begin() + kept_index; 92b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou LDSection* kept_sect = (*it).first; 93b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou Input* kept_obj = (*it).second.first; 94b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou debug(diag::debug_icf_folded_section) << sect->name() 95b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou << obj->name() 96b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou << kept_sect->name() 97b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou << kept_obj->name(); 98b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } 99b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } 100b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } 101b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou 102b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou // Adjust the fragment reference of the folded symbols. 103b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou FoldedObjects::iterator fobj, fobjEnd = folded_objs.end(); 104b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou for (fobj = folded_objs.begin(); fobj != fobjEnd; ++fobj) { 105b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou LDContext::sym_iterator sym, symEnd = (*fobj)->context()->symTabEnd(); 106b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou for (sym = (*fobj)->context()->symTabBegin(); sym != symEnd; ++sym) { 107b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou if ((*sym)->hasFragRef() && ((*sym)->type() == ResolveInfo::Function)) { 108b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou LDSymbol* out_sym = (*sym)->resolveInfo()->outSymbol(); 109b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou FragmentRef* frag_ref = out_sym->fragRef(); 110b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou LDSection* sect = &(frag_ref->frag()->getParent()->getSection()); 111b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou if (sect->kind() == LDFileFormat::Folded) { 112b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou size_t kept_index = m_KeptSections[sect].second; 113b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou LDSection* kept_sect = 114b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou (*(m_KeptSections.begin() + kept_index)).first; 115b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou frag_ref->assign(kept_sect->getSectionData()->front(), 116b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou frag_ref->offset()); 117b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } 118b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } 119b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } // for each symbol 120b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } // for each folded object 121b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou} 122b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou 123b3323086ee04f9db9e85f7cae46510f91a137237Pete Chouvoid IdenticalCodeFolding::findCandidates(FoldingCandidates& pCandidateList) 124b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou{ 125b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou Module::obj_iterator obj, objEnd = m_Module.obj_end(); 126b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou for (obj = m_Module.obj_begin(); obj != objEnd; ++obj) { 127b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou std::set<const LDSection*> funcptr_access_set; 128b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou typedef std::map<LDSection*, LDSection*> CandidateMap; 129b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou CandidateMap candidate_map; 130b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou LDContext::sect_iterator sect, sectEnd = (*obj)->context()->sectEnd(); 131b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou for (sect = (*obj)->context()->sectBegin(); sect != sectEnd; ++sect) { 132b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou switch ((*sect)->kind()) { 133b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou case LDFileFormat::TEXT: { 134b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou candidate_map.insert(std::make_pair(*sect, (LDSection*)NULL)); 135b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou break; 136b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } 137b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou case LDFileFormat::Relocation: { 138b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou LDSection* target = (*sect)->getLink(); 139b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou if (target->kind() == LDFileFormat::TEXT) { 140b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou candidate_map[target] = *sect; 141b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } 142b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou 143b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou // Safe icf 144b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou if (m_Config.options().getICFMode() == GeneralOptions::ICF_Safe) { 145b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou RelocData::iterator rel, relEnd = (*sect)->getRelocData()->end(); 146b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou for (rel = (*sect)->getRelocData()->begin(); rel != relEnd; ++rel) { 147b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou LDSymbol* sym = rel->symInfo()->outSymbol(); 148b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou if (sym->hasFragRef() && (sym->type() == ResolveInfo::Function)) { 149b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou const LDSection* def = 150b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou &sym->fragRef()->frag()->getParent()->getSection(); 151b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou if (!isSymCtorOrDtor(*rel->symInfo()) && 152b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou m_Backend.mayHaveUnsafeFunctionPointerAccess(*target) && 153b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou m_Backend. 154b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou getRelocator()->mayHaveFunctionPointerAccess(*rel)) { 155b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou funcptr_access_set.insert(def); 156b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } 157b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } 158b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } // for each reloc 159b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } 160b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou 161b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou break; 162b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } 163b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou default: { 164b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou // skip 165b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou break;; 166b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } 167b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } // end of switch 168b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } // for each section 169b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou 170b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou CandidateMap::iterator candidate, candidateEnd = candidate_map.end(); 171b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou for (candidate = candidate_map.begin(); candidate != candidateEnd; 172b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou ++candidate) { 173b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou if ((m_Config.options().getICFMode() == GeneralOptions::ICF_All) || 174b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou (funcptr_access_set.count(candidate->first) == 0)) { 175b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou size_t index = m_KeptSections.size(); 176b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou m_KeptSections[candidate->first] = ObjectAndId(*obj, index); 177b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou pCandidateList.push_back(FoldingCandidate(candidate->first, 178b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou candidate->second, 179b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou *obj)); 180b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } 181b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } // for each possible candidate 182b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou 183b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } // for each obj 184b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou} 185b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou 186b3323086ee04f9db9e85f7cae46510f91a137237Pete Choubool IdenticalCodeFolding::matchCandidates(FoldingCandidates& pCandidateList) 187b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou{ 188b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou typedef std::multimap<uint32_t, size_t> ChecksumMap; 189b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou ChecksumMap checksum_map; 190b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou std::vector<std::string> contents(pCandidateList.size()); 191b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou bool converged = true; 192b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou 193b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou for (size_t index = 0; index < pCandidateList.size(); ++index) { 194b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou contents[index] = pCandidateList[index]. 195b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou getContentWithVariables(m_Backend, m_KeptSections); 196b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou uint32_t checksum = ::crc32(0xFFFFFFFF, 197b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou (const uint8_t*)contents[index].c_str(), 198b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou contents[index].length()); 199b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou 200b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou size_t count = checksum_map.count(checksum); 201b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou if (count == 0) { 202b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou checksum_map.insert(std::make_pair(checksum, index)); 203b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } else { 204b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou std::pair<ChecksumMap::iterator, ChecksumMap::iterator> ret = 205b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou checksum_map.equal_range(checksum); 206b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou for (ChecksumMap::iterator it = ret.first; it != ret.second; ++it) { 207b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou size_t kept_index = (*it).second; 208b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou if (contents[index].compare(contents[kept_index]) == 0) { 209b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou m_KeptSections[pCandidateList[index].sect].second = kept_index; 210b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou converged = false; 211b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou break; 212b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } 213b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } 214b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } 215b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } 216b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou 217b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou return converged; 218b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou} 219b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou 220b3323086ee04f9db9e85f7cae46510f91a137237Pete Chouvoid IdenticalCodeFolding::FoldingCandidate::initConstantContent( 221b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou const TargetLDBackend& pBackend, 222b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou const IdenticalCodeFolding::KeptSections& pKeptSections) 223b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou{ 224b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou // Get the static content from text. 225b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou assert(sect != NULL && sect->hasSectionData()); 226b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou SectionData::const_iterator frag, fragEnd = sect->getSectionData()->end(); 227b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou for (frag = sect->getSectionData()->begin(); frag != fragEnd; ++frag) { 228b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou switch (frag->getKind()) { 229b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou case Fragment::Region: { 230b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou const RegionFragment& region = llvm::cast<RegionFragment>(*frag); 231b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou content.append(region.getRegion().begin(), region.size()); 232b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou break; 233b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } 234b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou default: { 235b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou // FIXME: Currently we only take care of RegionFragment. 236b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou break; 237b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } 238b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } 239b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } 240b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou 241b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou // Get the static content from relocs. 242b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou if (reloc_sect != NULL && reloc_sect->hasRelocData()) { 243b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou RelocData::iterator rel, relEnd = reloc_sect->getRelocData()->end(); 244b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou for (rel = reloc_sect->getRelocData()->begin(); rel != relEnd; ++rel) { 245b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou llvm::format_object4<Relocation::Type, Relocation::Address, 246b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou Relocation::Address, Relocation::Address> 247b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou rel_info("%x%llx%llx%llx", rel->type(), rel->symValue(), 248b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou rel->addend(), rel->place()); 249b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou char rel_str[48]; 250b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou rel_info.print(rel_str, sizeof(rel_str)); 251b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou content.append(rel_str); 252b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou 253b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou // Handle the recursive call. 254b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou LDSymbol* sym = rel->symInfo()->outSymbol(); 255b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou if ((sym->type() == ResolveInfo::Function) && sym->hasFragRef()) { 256b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou LDSection* def = &sym->fragRef()->frag()->getParent()->getSection(); 257b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou if (def == sect) { 258b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou continue; 259b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } 260b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } 261b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou 262b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou if (!pBackend.isSymbolPreemptible(*rel->symInfo()) && 263b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou sym->hasFragRef() && 264b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou (pKeptSections.find( 265b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou &sym->fragRef()->frag()->getParent()->getSection()) != 266b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou pKeptSections.end())) { 267b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou // Mark this reloc as a variable. 268b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou variable_relocs.push_back(rel); 269b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } else { 270b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou // TODO: Support inlining merge sections if possible (target-dependent). 271b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou if ((sym->binding() == ResolveInfo::Local) || 272b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou (sym->binding() == ResolveInfo::Absolute)) { 273b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou // ABS or Local symbols. 274b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou content.append(sym->name()) 275b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou .append(obj->name()) 276b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou .append(obj->path().native()); 277b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } else { 278b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou content.append(sym->name()); 279b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } 280b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } 281b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } 282b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } 283b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou} 284b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou 285b3323086ee04f9db9e85f7cae46510f91a137237Pete Choustd::string IdenticalCodeFolding::FoldingCandidate::getContentWithVariables( 286b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou const TargetLDBackend& pBackend, 287b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou const IdenticalCodeFolding::KeptSections& pKeptSections) 288b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou{ 289b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou std::string result(content); 290b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou // Compute the variable content from relocs. 291b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou std::vector<Relocation*>::const_iterator rel, relEnd = variable_relocs.end(); 292b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou for (rel = variable_relocs.begin(); rel != relEnd; ++rel) { 293b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou LDSymbol* sym = (*rel)->symInfo()->outSymbol(); 294b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou LDSection* def = &sym->fragRef()->frag()->getParent()->getSection(); 295b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou // Use the kept section index. 296b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou KeptSections::const_iterator it = pKeptSections.find(def); 297b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou llvm::format_object1<size_t> kept_info("%x", (*it).second.second); 298b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou char kept_str[8]; 299b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou kept_info.print(kept_str, sizeof(kept_str)); 300b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou result.append(kept_str); 301b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou } 302b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou 303b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou return result; 304b3323086ee04f9db9e85f7cae46510f91a137237Pete Chou} 305