1 //===- InputSection.cpp ---------------------------------------------------===//
2 //
3 //                             The LLVM Linker
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 "InputSection.h"
11 #include "Config.h"
12 #include "Error.h"
13 #include "InputFiles.h"
14 #include "OutputSections.h"
15 #include "Target.h"
16 
17 using namespace llvm;
18 using namespace llvm::ELF;
19 using namespace llvm::object;
20 
21 using namespace lld;
22 using namespace lld::elf2;
23 
24 template <class ELFT>
25 InputSectionBase<ELFT>::InputSectionBase(ObjectFile<ELFT> *File,
26                                          const Elf_Shdr *Header,
27                                          Kind SectionKind)
28     : Header(Header), File(File), SectionKind(SectionKind) {}
29 
30 template <class ELFT> StringRef InputSectionBase<ELFT>::getSectionName() const {
31   ErrorOr<StringRef> Name = File->getObj().getSectionName(this->Header);
32   error(Name);
33   return *Name;
34 }
35 
36 template <class ELFT>
37 ArrayRef<uint8_t> InputSectionBase<ELFT>::getSectionData() const {
38   ErrorOr<ArrayRef<uint8_t>> Ret =
39       this->File->getObj().getSectionContents(this->Header);
40   error(Ret);
41   return *Ret;
42 }
43 
44 template <class ELFT>
45 typename ELFFile<ELFT>::uintX_t
46 InputSectionBase<ELFT>::getOffset(uintX_t Offset) {
47   switch (SectionKind) {
48   case Regular:
49     return cast<InputSection<ELFT>>(this)->OutSecOff + Offset;
50   case EHFrame:
51     return cast<EHInputSection<ELFT>>(this)->getOffset(Offset);
52   case Merge:
53     return cast<MergeInputSection<ELFT>>(this)->getOffset(Offset);
54   }
55   llvm_unreachable("Invalid section kind");
56 }
57 
58 template <class ELFT>
59 typename ELFFile<ELFT>::uintX_t
60 InputSectionBase<ELFT>::getOffset(const Elf_Sym &Sym) {
61   return getOffset(Sym.st_value);
62 }
63 
64 // Returns a section that Rel relocation is pointing to.
65 template <class ELFT>
66 InputSectionBase<ELFT> *
67 InputSectionBase<ELFT>::getRelocTarget(const Elf_Rel &Rel) {
68   // Global symbol
69   uint32_t SymIndex = Rel.getSymbol(Config->Mips64EL);
70   if (SymbolBody *B = File->getSymbolBody(SymIndex))
71     if (auto *D = dyn_cast<DefinedRegular<ELFT>>(B->repl()))
72       return &D->Section;
73   // Local symbol
74   if (const Elf_Sym *Sym = File->getLocalSymbol(SymIndex))
75     if (InputSectionBase<ELFT> *Sec = File->getSection(*Sym))
76       return Sec;
77   return nullptr;
78 }
79 
80 template <class ELFT>
81 InputSectionBase<ELFT> *
82 InputSectionBase<ELFT>::getRelocTarget(const Elf_Rela &Rel) {
83   return getRelocTarget(reinterpret_cast<const Elf_Rel &>(Rel));
84 }
85 
86 template <class ELFT>
87 InputSection<ELFT>::InputSection(ObjectFile<ELFT> *F, const Elf_Shdr *Header)
88     : InputSectionBase<ELFT>(F, Header, Base::Regular) {}
89 
90 template <class ELFT>
91 bool InputSection<ELFT>::classof(const InputSectionBase<ELFT> *S) {
92   return S->SectionKind == Base::Regular;
93 }
94 
95 template <class ELFT>
96 template <bool isRela>
97 void InputSectionBase<ELFT>::relocate(
98     uint8_t *Buf, uint8_t *BufEnd,
99     iterator_range<const Elf_Rel_Impl<ELFT, isRela> *> Rels) {
100   typedef Elf_Rel_Impl<ELFT, isRela> RelType;
101   for (const RelType &RI : Rels) {
102     uint32_t SymIndex = RI.getSymbol(Config->Mips64EL);
103     uint32_t Type = RI.getType(Config->Mips64EL);
104     uintX_t Offset = getOffset(RI.r_offset);
105     if (Offset == (uintX_t)-1)
106       continue;
107 
108     uint8_t *BufLoc = Buf + Offset;
109     uintX_t AddrLoc = OutSec->getVA() + Offset;
110 
111     if (Target->isTlsLocalDynamicReloc(Type)) {
112       Target->relocateOne(BufLoc, BufEnd, Type, AddrLoc,
113                           Out<ELFT>::Got->getVA() +
114                               Out<ELFT>::LocalModuleTlsIndexOffset +
115                               getAddend<ELFT>(RI));
116       continue;
117     }
118 
119     // Handle relocations for local symbols -- they never get
120     // resolved so we don't allocate a SymbolBody.
121     const Elf_Shdr *SymTab = File->getSymbolTable();
122     if (SymIndex < SymTab->sh_info) {
123       uintX_t SymVA = getLocalRelTarget(*File, RI);
124       Target->relocateOne(BufLoc, BufEnd, Type, AddrLoc, SymVA);
125       continue;
126     }
127 
128     SymbolBody &Body = *File->getSymbolBody(SymIndex)->repl();
129 
130     if (Target->isTlsGlobalDynamicReloc(Type)) {
131       Target->relocateOne(BufLoc, BufEnd, Type, AddrLoc,
132                           Out<ELFT>::Got->getEntryAddr(Body) +
133                               getAddend<ELFT>(RI));
134       continue;
135     }
136 
137     if (Target->isTlsOptimized(Type, Body)) {
138       Target->relocateTlsOptimize(BufLoc, BufEnd, AddrLoc,
139                                   getSymVA<ELFT>(Body));
140       continue;
141     }
142 
143     uintX_t SymVA = getSymVA<ELFT>(Body);
144     if (Target->relocNeedsPlt(Type, Body)) {
145       SymVA = Out<ELFT>::Plt->getEntryAddr(Body);
146       Type = Target->getPltRefReloc(Type);
147     } else if (Target->relocNeedsGot(Type, Body)) {
148       SymVA = Out<ELFT>::Got->getEntryAddr(Body);
149       Type = Body.isTLS() ? Target->getTlsGotReloc()
150                           : Target->getGotRefReloc(Type);
151     } else if (Target->relocPointsToGot(Type)) {
152       SymVA = Out<ELFT>::Got->getVA();
153       Type = Target->getPCRelReloc();
154     } else if (!Target->relocNeedsCopy(Type, Body) &&
155                isa<SharedSymbol<ELFT>>(Body)) {
156       continue;
157     }
158     Target->relocateOne(BufLoc, BufEnd, Type, AddrLoc,
159                         SymVA + getAddend<ELFT>(RI));
160   }
161 }
162 
163 template <class ELFT> void InputSection<ELFT>::writeTo(uint8_t *Buf) {
164   if (this->Header->sh_type == SHT_NOBITS)
165     return;
166   // Copy section contents from source object file to output file.
167   ArrayRef<uint8_t> Data = this->getSectionData();
168   memcpy(Buf + OutSecOff, Data.data(), Data.size());
169 
170   ELFFile<ELFT> &EObj = this->File->getObj();
171   uint8_t *BufEnd = Buf + OutSecOff + Data.size();
172   // Iterate over all relocation sections that apply to this section.
173   for (const Elf_Shdr *RelSec : this->RelocSections) {
174     if (RelSec->sh_type == SHT_RELA)
175       this->relocate(Buf, BufEnd, EObj.relas(RelSec));
176     else
177       this->relocate(Buf, BufEnd, EObj.rels(RelSec));
178   }
179 }
180 
181 template <class ELFT>
182 SplitInputSection<ELFT>::SplitInputSection(
183     ObjectFile<ELFT> *File, const Elf_Shdr *Header,
184     typename InputSectionBase<ELFT>::Kind SectionKind)
185     : InputSectionBase<ELFT>(File, Header, SectionKind) {}
186 
187 template <class ELFT>
188 EHInputSection<ELFT>::EHInputSection(ObjectFile<ELFT> *F,
189                                      const Elf_Shdr *Header)
190     : SplitInputSection<ELFT>(F, Header, InputSectionBase<ELFT>::EHFrame) {}
191 
192 template <class ELFT>
193 bool EHInputSection<ELFT>::classof(const InputSectionBase<ELFT> *S) {
194   return S->SectionKind == InputSectionBase<ELFT>::EHFrame;
195 }
196 
197 template <class ELFT>
198 typename EHInputSection<ELFT>::uintX_t
199 EHInputSection<ELFT>::getOffset(uintX_t Offset) {
200   std::pair<uintX_t, uintX_t> *I = this->getRangeAndSize(Offset).first;
201   uintX_t Base = I->second;
202   if (Base == uintX_t(-1))
203     return -1; // Not in the output
204 
205   uintX_t Addend = Offset - I->first;
206   return Base + Addend;
207 }
208 
209 template <class ELFT>
210 MergeInputSection<ELFT>::MergeInputSection(ObjectFile<ELFT> *F,
211                                            const Elf_Shdr *Header)
212     : SplitInputSection<ELFT>(F, Header, InputSectionBase<ELFT>::Merge) {}
213 
214 template <class ELFT>
215 bool MergeInputSection<ELFT>::classof(const InputSectionBase<ELFT> *S) {
216   return S->SectionKind == InputSectionBase<ELFT>::Merge;
217 }
218 
219 template <class ELFT>
220 std::pair<std::pair<typename ELFFile<ELFT>::uintX_t,
221                     typename ELFFile<ELFT>::uintX_t> *,
222           typename ELFFile<ELFT>::uintX_t>
223 SplitInputSection<ELFT>::getRangeAndSize(uintX_t Offset) {
224   ArrayRef<uint8_t> D = this->getSectionData();
225   StringRef Data((const char *)D.data(), D.size());
226   uintX_t Size = Data.size();
227   if (Offset >= Size)
228     error("Entry is past the end of the section");
229 
230   // Find the element this offset points to.
231   auto I = std::upper_bound(
232       Offsets.begin(), Offsets.end(), Offset,
233       [](const uintX_t &A, const std::pair<uintX_t, uintX_t> &B) {
234         return A < B.first;
235       });
236   uintX_t End = I == Offsets.end() ? Data.size() : I->first;
237   --I;
238   return std::make_pair(&*I, End);
239 }
240 
241 template <class ELFT>
242 typename MergeInputSection<ELFT>::uintX_t
243 MergeInputSection<ELFT>::getOffset(uintX_t Offset) {
244   std::pair<std::pair<uintX_t, uintX_t> *, uintX_t> T =
245       this->getRangeAndSize(Offset);
246   std::pair<uintX_t, uintX_t> *I = T.first;
247   uintX_t End = T.second;
248   uintX_t Start = I->first;
249 
250   // Compute the Addend and if the Base is cached, return.
251   uintX_t Addend = Offset - Start;
252   uintX_t &Base = I->second;
253   if (Base != uintX_t(-1))
254     return Base + Addend;
255 
256   // Map the base to the offset in the output section and cashe it.
257   ArrayRef<uint8_t> D = this->getSectionData();
258   StringRef Data((const char *)D.data(), D.size());
259   StringRef Entry = Data.substr(Start, End - Start);
260   Base =
261       static_cast<MergeOutputSection<ELFT> *>(this->OutSec)->getOffset(Entry);
262   return Base + Addend;
263 }
264 
265 namespace lld {
266 namespace elf2 {
267 template class InputSectionBase<object::ELF32LE>;
268 template class InputSectionBase<object::ELF32BE>;
269 template class InputSectionBase<object::ELF64LE>;
270 template class InputSectionBase<object::ELF64BE>;
271 
272 template class InputSection<object::ELF32LE>;
273 template class InputSection<object::ELF32BE>;
274 template class InputSection<object::ELF64LE>;
275 template class InputSection<object::ELF64BE>;
276 
277 template class EHInputSection<object::ELF32LE>;
278 template class EHInputSection<object::ELF32BE>;
279 template class EHInputSection<object::ELF64LE>;
280 template class EHInputSection<object::ELF64BE>;
281 
282 template class MergeInputSection<object::ELF32LE>;
283 template class MergeInputSection<object::ELF32BE>;
284 template class MergeInputSection<object::ELF64LE>;
285 template class MergeInputSection<object::ELF64BE>;
286 }
287 }
288