ARMException.cpp revision a6c24dff8b7fa2551a3a885e77a2e814f5b764a2
1a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines//===- ARMException.cpp ---------------------------------------------------===// 2a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines// 3a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines// The MCLinker Project 4a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines// 5a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines// This file is distributed under the University of Illinois Open Source 6a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines// License. See LICENSE.TXT for details. 7a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines// 8a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines//===----------------------------------------------------------------------===// 9a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines 10a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines#include "ARMException.h" 11a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines 12a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines#include "ARMLDBackend.h" 13a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines 14a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines#include "mcld/ADT/ilist_sort.h" 15a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines#include "mcld/Fragment/RegionFragment.h" 16a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines#include "mcld/LD/ELFFileFormat.h" 17a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines#include "mcld/LD/LDContext.h" 18a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines#include "mcld/Support/MsgHandling.h" 19a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines 20a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines#include <memory> 21a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines 22a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hinesnamespace mcld { 23a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines 24a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hinesvoid ARMExData::addInputMap(Input* pInput, 25a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines std::unique_ptr<ARMInputExMap>&& pExMap) { 26a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines assert(m_Inputs.find(pInput) == m_Inputs.end() && 27a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines "multiple maps for an input"); 28a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines 29a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines ARMInputExMap* exMap = pExMap.get(); 30a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines 31a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines // Add mapping to the input-to-exdata map. 32a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines m_Inputs.insert(std::make_pair(pInput, std::move(pExMap))); 33a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines 34a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines // Add mapping to the fragment-to-exdata map. 35a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines for (ARMInputExMap::iterator it = exMap->begin(), end = exMap->end(); 36a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines it != end; ++it) { 37a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines ARMExSectionTuple* exTuple = it->second.get(); 38a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines m_ExIdxToTuple[exTuple->getExIdxFragment()] = exTuple; 39a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines } 40a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines} 41a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines 42a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hinesvoid ARMGNULDBackend::scanInputExceptionSections(Module& pModule) { 43a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines for (Module::obj_iterator it = pModule.obj_begin(), 44a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines end = pModule.obj_end(); it != end; ++it) { 45a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines Input* input = *it; 46a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines scanInputExceptionSections(pModule, *input); 47a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines } 48a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines} 49a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines 50a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hinesstatic RegionFragment* findRegionFragment(LDSection& pSection) { 51a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines SectionData* sectData = pSection.getSectionData(); 52a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines for (SectionData::iterator it = sectData->begin(), 53a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines end = sectData->end(); it != end; ++it) { 54a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines if (it->getKind() == Fragment::Region) { 55a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines return static_cast<RegionFragment*>(&*it); 56a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines } 57a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines } 58a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines return NULL; 59a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines} 60a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines 61a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hinesvoid ARMGNULDBackend::scanInputExceptionSections(Module& pModule, 62a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines Input& pInput) { 63a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines std::unique_ptr<ARMInputExMap> exMap(new ARMInputExMap()); 64a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines 65a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines // Scan the input and collect all related sections. 66a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines LDContext* ctx = pInput.context(); 67a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines for (LDContext::sect_iterator it = ctx->sectBegin(), 68a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines end = ctx->sectEnd(); it != end; ++it) { 69a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines LDSection* sect = *it; 70a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines llvm::StringRef name(sect->name()); 71a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines 72a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines if (name.startswith(".ARM.exidx")) { 73a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines ARMExSectionTuple* exTuple = exMap->getOrCreateByExSection(name); 74a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines exTuple->setExIdxSection(sect); 75a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines exTuple->setTextSection(sect->getLink()); 76a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines } else if (name.startswith(".ARM.extab")) { 77a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines ARMExSectionTuple* exTuple = exMap->getOrCreateByExSection(name); 78a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines exTuple->setExTabSection(sect); 79a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines } else if (name.startswith(".rel.ARM.exidx")) { 80a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines ARMExSectionTuple* exTuple = exMap->getOrCreateByRelExSection(name); 81a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines exTuple->setRelExIdxSection(sect); 82a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines } else if (name.startswith(".rel.ARM.extab")) { 83a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines ARMExSectionTuple* exTuple = exMap->getOrCreateByRelExSection(name); 84a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines exTuple->setRelExIdxSection(sect); 85a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines } 86a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines } 87a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines 88a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines // Remove the invalid exception tuples and convert LDSection to RegionFragment 89a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines // or RelocData. 90a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines ARMInputExMap::iterator it = exMap->begin(); 91a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines ARMInputExMap::iterator end = exMap->end(); 92a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines while (it != end) { 93a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines ARMExSectionTuple* exTuple = it->second.get(); 94a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines LDSection* const text = exTuple->getTextSection(); 95a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines LDSection* const exIdx = exTuple->getExIdxSection(); 96a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines LDSection* const exTab = exTuple->getExTabSection(); 97a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines LDSection* const relExIdx = exTuple->getRelExIdxSection(); 98a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines LDSection* const relExTab = exTuple->getRelExTabSection(); 99a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines 100a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines // Check the .ARM.exidx section. 101a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines if (!exIdx) { 102a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines if (exTab) { 103a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines fatal(diag::eh_missing_exidx_section) << exTab->name() << pInput.name(); 104a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines } else if (relExIdx) { 105a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines fatal(diag::eh_missing_exidx_section) << relExIdx->name() 106a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines << pInput.name(); 107a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines } else if (relExTab) { 108a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines fatal(diag::eh_missing_exidx_section) << relExTab->name() 109a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines << pInput.name(); 110a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines } else { 111a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines llvm_unreachable("unexpected bad exception tuple"); 112a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines } 113a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines } 114a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines 115a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines // Check the text section. 116a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines if (!text) { 117a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines fatal(diag::eh_missing_text_section) << exIdx->name() << pInput.name(); 118a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines } 119a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines 120a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines // Ignore the exception section if the text section is ignored. 121a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines if ((text->kind() == LDFileFormat::Ignore) || 122a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines (text->kind() == LDFileFormat::Folded)) { 123a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines // Set the related exception sections as LDFileFormat::Ignore. 124a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines exIdx->setKind(LDFileFormat::Ignore); 125a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines if (exTab) { 126a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines exTab->setKind(LDFileFormat::Ignore); 127a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines } 128a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines // Remove this tuple from the input exception map. 129a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines exMap->erase(it++); 130a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines continue; 131a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines } 132a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines 133a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines // Get RegionFragment from ".text", ".ARM.exidx", and ".ARM.extab" sections. 134a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines RegionFragment* textFrag = findRegionFragment(*text); 135a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines RegionFragment* exIdxFrag = findRegionFragment(*exIdx); 136a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines RegionFragment* exTabFrag = exTab ? findRegionFragment(*exTab) : NULL; 137a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines 138a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines exTuple->setTextFragment(textFrag); 139a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines exTuple->setExIdxFragment(exIdxFrag); 140a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines exTuple->setExTabFragment(exTabFrag); 141a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines 142a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines // Get the RelocData from ".rel.ARM.exidx" and ".rel.ARM.extab" sections. 143a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines RelocData* exIdxRD = relExIdx ? relExIdx->getRelocData() : NULL; 144a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines RelocData* exTabRD = relExTab ? relExTab->getRelocData() : NULL; 145a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines 146a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines exTuple->setExIdxRelocData(exIdxRD); 147a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines exTuple->setExTabRelocData(exTabRD); 148a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines 149a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines // If there is no region fragment in the .ARM.extab section, then we can 150a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines // skip this tuple. 151a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines if (!exIdxFrag) { 152a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines exMap->erase(it++); 153a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines continue; 154a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines } 155a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines 156a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines // TODO: Sort the RelocData w.r.t. the fixup offset. 157a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines 158a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines // Check next tuple 159a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines ++it; 160a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines } 161a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines 162a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines // Add input map 163a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines m_ExData.addInputMap(&pInput, std::move(exMap)); 164a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines} 165a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines 166a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hinesclass ExIdxFragmentComparator { 167a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines private: 168a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines const ARMExData& m_ExData; 169a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines 170a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines public: 171a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines ExIdxFragmentComparator(const ARMExData& pExData) 172a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines : m_ExData(pExData) { 173a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines } 174a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines 175a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines bool operator()(const Fragment& a, const Fragment& b) { 176a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines ARMExSectionTuple* tupleA = m_ExData.getTupleByExIdx(&a); 177a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines ARMExSectionTuple* tupleB = m_ExData.getTupleByExIdx(&b); 178a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines 179a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines Fragment* textFragA = tupleA->getTextFragment(); 180a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines Fragment* textFragB = tupleB->getTextFragment(); 181a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines 182a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines uint64_t addrA = textFragA->getParent()->getSection().addr() + 183a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines textFragA->getOffset(); 184a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines uint64_t addrB = textFragB->getParent()->getSection().addr() + 185a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines textFragB->getOffset(); 186a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines return (addrA < addrB); 187a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines } 188a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines}; 189a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines 190a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hinesvoid ARMGNULDBackend::rewriteARMExIdxSection(Module& pModule) { 191a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines if (!m_pEXIDX->hasSectionData()) { 192a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines // Return if this is empty section. 193a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines return; 194a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines } 195a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines 196a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines SectionData* sectData = m_pEXIDX->getSectionData(); 197a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines SectionData::FragmentListType& list = sectData->getFragmentList(); 198a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines 199a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines // Move the first and last fragment to temporary list. 200a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines SectionData::FragmentListType tmp; 201a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines { 202a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines SectionData::iterator first = sectData->begin(); 203a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines SectionData::iterator last = sectData->end(); 204a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines --last; 205a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines 206a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines assert(first->getKind() == Fragment::Alignment); 207a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines assert(last->getKind() == Fragment::Null); 208a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines 209a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines tmp.splice(tmp.end(), list, first); 210a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines tmp.splice(tmp.end(), list, last); 211a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines } 212a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines 213a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines // Sort the region fragments in the .ARM.exidx output section. 214a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines sort(list, ExIdxFragmentComparator(m_ExData)); 215a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines 216a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines // Add the first and last fragment back. 217a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines list.splice(list.begin(), tmp, tmp.begin()); 218a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines list.splice(list.end(), tmp, tmp.begin()); 219a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines 220a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines // Update the fragment offsets. 221a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines uint64_t offset = 0; 222a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines for (SectionData::iterator it = sectData->begin(), end = sectData->end(); 223a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines it != end; ++it) { 224a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines it->setOffset(offset); 225a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines offset += it->size(); 226a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines } 227a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines 228a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines // Rebuild the section header. 229a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines setOutputSectionAddress(pModule); 230a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines} 231a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines 232a6c24dff8b7fa2551a3a885e77a2e814f5b764a2Stephen Hines} // namespace mcld 233