blob: 4e354ed01f9c3e32e198d83e4f0eee67dd791a26 [file] [log] [blame]
Stephen Hinesa6c24df2015-03-18 14:53:18 -07001//===- ARMException.cpp ---------------------------------------------------===//
2//
3// The MCLinker Project
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "ARMException.h"
11
12#include "ARMLDBackend.h"
13
Stephen Hinesa6c24df2015-03-18 14:53:18 -070014#include "mcld/Fragment/RegionFragment.h"
15#include "mcld/LD/ELFFileFormat.h"
16#include "mcld/LD/LDContext.h"
17#include "mcld/Support/MsgHandling.h"
18
19#include <memory>
20
21namespace mcld {
22
Stephen Hinescfcb2242016-03-08 00:18:09 -080023static RegionFragment* findRegionFragment(LDSection& pSection) {
24 SectionData* sectData = pSection.getSectionData();
25 for (SectionData::iterator it = sectData->begin(),
26 end = sectData->end(); it != end; ++it) {
27 if (it->getKind() == Fragment::Region) {
28 return static_cast<RegionFragment*>(&*it);
29 }
30 }
31 return NULL;
32}
33
Stephen Hinesa6c24df2015-03-18 14:53:18 -070034void ARMExData::addInputMap(Input* pInput,
Stephen Hinescfcb2242016-03-08 00:18:09 -080035 std::unique_ptr<ARMInputExMap> pExMap) {
Stephen Hinesa6c24df2015-03-18 14:53:18 -070036 assert(m_Inputs.find(pInput) == m_Inputs.end() &&
37 "multiple maps for an input");
38
39 ARMInputExMap* exMap = pExMap.get();
40
41 // Add mapping to the input-to-exdata map.
42 m_Inputs.insert(std::make_pair(pInput, std::move(pExMap)));
43
44 // Add mapping to the fragment-to-exdata map.
45 for (ARMInputExMap::iterator it = exMap->begin(), end = exMap->end();
46 it != end; ++it) {
47 ARMExSectionTuple* exTuple = it->second.get();
48 m_ExIdxToTuple[exTuple->getExIdxFragment()] = exTuple;
49 }
50}
51
Stephen Hinescfcb2242016-03-08 00:18:09 -080052std::unique_ptr<ARMExData> ARMExData::create(Module& pModule) {
53 std::unique_ptr<ARMExData> exData(new ARMExData());
Stephen Hinesa6c24df2015-03-18 14:53:18 -070054 for (Module::obj_iterator it = pModule.obj_begin(),
55 end = pModule.obj_end(); it != end; ++it) {
56 Input* input = *it;
Stephen Hinescfcb2242016-03-08 00:18:09 -080057 exData->addInputMap(input, ARMInputExMap::create(*input));
Stephen Hinesa6c24df2015-03-18 14:53:18 -070058 }
Stephen Hinescfcb2242016-03-08 00:18:09 -080059 return exData;
Stephen Hinesa6c24df2015-03-18 14:53:18 -070060}
61
Stephen Hinescfcb2242016-03-08 00:18:09 -080062std::unique_ptr<ARMInputExMap> ARMInputExMap::create(Input& pInput) {
Stephen Hinesa6c24df2015-03-18 14:53:18 -070063 std::unique_ptr<ARMInputExMap> exMap(new ARMInputExMap());
64
65 // Scan the input and collect all related sections.
66 LDContext* ctx = pInput.context();
67 for (LDContext::sect_iterator it = ctx->sectBegin(),
68 end = ctx->sectEnd(); it != end; ++it) {
69 LDSection* sect = *it;
Stephen Hinescfcb2242016-03-08 00:18:09 -080070 if (sect->type() == llvm::ELF::SHT_ARM_EXIDX) {
71 ARMExSectionTuple* exTuple = exMap->getOrCreateByExSection(*sect);
Stephen Hinesa6c24df2015-03-18 14:53:18 -070072 exTuple->setExIdxSection(sect);
73 exTuple->setTextSection(sect->getLink());
Stephen Hinescfcb2242016-03-08 00:18:09 -080074 if (sect->getLink() == NULL) {
75 fatal(diag::eh_missing_text_section) << sect->name() << pInput.name();
76 }
Stephen Hinesa6c24df2015-03-18 14:53:18 -070077 }
78 }
79
80 // Remove the invalid exception tuples and convert LDSection to RegionFragment
81 // or RelocData.
82 ARMInputExMap::iterator it = exMap->begin();
83 ARMInputExMap::iterator end = exMap->end();
84 while (it != end) {
85 ARMExSectionTuple* exTuple = it->second.get();
86 LDSection* const text = exTuple->getTextSection();
87 LDSection* const exIdx = exTuple->getExIdxSection();
Stephen Hinesa6c24df2015-03-18 14:53:18 -070088
89 // Ignore the exception section if the text section is ignored.
90 if ((text->kind() == LDFileFormat::Ignore) ||
91 (text->kind() == LDFileFormat::Folded)) {
92 // Set the related exception sections as LDFileFormat::Ignore.
93 exIdx->setKind(LDFileFormat::Ignore);
Stephen Hinesa6c24df2015-03-18 14:53:18 -070094 // Remove this tuple from the input exception map.
Stephen Hinescfcb2242016-03-08 00:18:09 -080095 ARMInputExMap::iterator deadIt = it++;
96 exMap->erase(deadIt);
Stephen Hinesa6c24df2015-03-18 14:53:18 -070097 continue;
98 }
99
100 // Get RegionFragment from ".text", ".ARM.exidx", and ".ARM.extab" sections.
101 RegionFragment* textFrag = findRegionFragment(*text);
102 RegionFragment* exIdxFrag = findRegionFragment(*exIdx);
Stephen Hinesa6c24df2015-03-18 14:53:18 -0700103
104 exTuple->setTextFragment(textFrag);
105 exTuple->setExIdxFragment(exIdxFrag);
Stephen Hinesa6c24df2015-03-18 14:53:18 -0700106
107 // If there is no region fragment in the .ARM.extab section, then we can
108 // skip this tuple.
Stephen Hinescfcb2242016-03-08 00:18:09 -0800109 if (exIdxFrag == NULL) {
110 ARMInputExMap::iterator deadIt = it++;
111 exMap->erase(deadIt);
Stephen Hinesa6c24df2015-03-18 14:53:18 -0700112 continue;
113 }
114
Stephen Hinesa6c24df2015-03-18 14:53:18 -0700115 // Check next tuple
116 ++it;
117 }
118
Stephen Hinescfcb2242016-03-08 00:18:09 -0800119 return exMap;
Stephen Hinesa6c24df2015-03-18 14:53:18 -0700120}
121
122} // namespace mcld