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 (Type == Target->getTlsLocalDynamicReloc()) {
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     uintX_t SymVA = getSymVA<ELFT>(Body);
130     if (Target->relocNeedsPlt(Type, Body)) {
131       SymVA = Out<ELFT>::Plt->getEntryAddr(Body);
132       Type = Target->getPLTRefReloc(Type);
133     } else if (Target->relocNeedsGot(Type, Body)) {
134       SymVA = Out<ELFT>::Got->getEntryAddr(Body);
135       Type = Target->getGotRefReloc();
136     } else if (Target->relocPointsToGot(Type)) {
137       SymVA = Out<ELFT>::Got->getVA();
138       Type = Target->getPCRelReloc();
139     } else if (!Target->relocNeedsCopy(Type, Body) &&
140                isa<SharedSymbol<ELFT>>(Body)) {
141       continue;
142     }
143     Target->relocateOne(BufLoc, BufEnd, Type, AddrLoc,
144                         SymVA + getAddend<ELFT>(RI));
145   }
146 }
147 
148 template <class ELFT> void InputSection<ELFT>::writeTo(uint8_t *Buf) {
149   if (this->Header->sh_type == SHT_NOBITS)
150     return;
151   // Copy section contents from source object file to output file.
152   ArrayRef<uint8_t> Data = this->getSectionData();
153   memcpy(Buf + OutSecOff, Data.data(), Data.size());
154 
155   ELFFile<ELFT> &EObj = this->File->getObj();
156   uint8_t *BufEnd = Buf + OutSecOff + Data.size();
157   // Iterate over all relocation sections that apply to this section.
158   for (const Elf_Shdr *RelSec : this->RelocSections) {
159     if (RelSec->sh_type == SHT_RELA)
160       this->relocate(Buf, BufEnd, EObj.relas(RelSec));
161     else
162       this->relocate(Buf, BufEnd, EObj.rels(RelSec));
163   }
164 }
165 
166 template <class ELFT>
167 SplitInputSection<ELFT>::SplitInputSection(
168     ObjectFile<ELFT> *File, const Elf_Shdr *Header,
169     typename InputSectionBase<ELFT>::Kind SectionKind)
170     : InputSectionBase<ELFT>(File, Header, SectionKind) {}
171 
172 template <class ELFT>
173 EHInputSection<ELFT>::EHInputSection(ObjectFile<ELFT> *F,
174                                      const Elf_Shdr *Header)
175     : SplitInputSection<ELFT>(F, Header, InputSectionBase<ELFT>::EHFrame) {}
176 
177 template <class ELFT>
178 bool EHInputSection<ELFT>::classof(const InputSectionBase<ELFT> *S) {
179   return S->SectionKind == InputSectionBase<ELFT>::EHFrame;
180 }
181 
182 template <class ELFT>
183 typename EHInputSection<ELFT>::uintX_t
184 EHInputSection<ELFT>::getOffset(uintX_t Offset) {
185   std::pair<uintX_t, uintX_t> *I = this->getRangeAndSize(Offset).first;
186   uintX_t Base = I->second;
187   if (Base == size_t(-1))
188     return -1; // Not in the output
189 
190   uintX_t Addend = Offset - I->first;
191   return Base + Addend;
192 }
193 
194 template <class ELFT>
195 MergeInputSection<ELFT>::MergeInputSection(ObjectFile<ELFT> *F,
196                                            const Elf_Shdr *Header)
197     : SplitInputSection<ELFT>(F, Header, InputSectionBase<ELFT>::Merge) {}
198 
199 template <class ELFT>
200 bool MergeInputSection<ELFT>::classof(const InputSectionBase<ELFT> *S) {
201   return S->SectionKind == InputSectionBase<ELFT>::Merge;
202 }
203 
204 template <class ELFT>
205 std::pair<std::pair<typename ELFFile<ELFT>::uintX_t,
206                     typename ELFFile<ELFT>::uintX_t> *,
207           typename ELFFile<ELFT>::uintX_t>
208 SplitInputSection<ELFT>::getRangeAndSize(uintX_t Offset) {
209   ArrayRef<uint8_t> D = this->getSectionData();
210   StringRef Data((const char *)D.data(), D.size());
211   uintX_t Size = Data.size();
212   if (Offset >= Size)
213     error("Entry is past the end of the section");
214 
215   // Find the element this offset points to.
216   auto I = std::upper_bound(
217       Offsets.begin(), Offsets.end(), Offset,
218       [](const uintX_t &A, const std::pair<uintX_t, uintX_t> &B) {
219         return A < B.first;
220       });
221   uintX_t End = I == Offsets.end() ? Data.size() : I->first;
222   --I;
223   return std::make_pair(&*I, End);
224 }
225 
226 template <class ELFT>
227 typename MergeInputSection<ELFT>::uintX_t
228 MergeInputSection<ELFT>::getOffset(uintX_t Offset) {
229   std::pair<std::pair<uintX_t, uintX_t> *, size_t> T =
230       this->getRangeAndSize(Offset);
231   std::pair<uintX_t, uintX_t> *I = T.first;
232   uintX_t End = T.second;
233   uintX_t Start = I->first;
234 
235   // Compute the Addend and if the Base is cached, return.
236   uintX_t Addend = Offset - Start;
237   uintX_t &Base = I->second;
238   if (Base != uintX_t(-1))
239     return Base + Addend;
240 
241   // Map the base to the offset in the output section and cashe it.
242   ArrayRef<uint8_t> D = this->getSectionData();
243   StringRef Data((const char *)D.data(), D.size());
244   StringRef Entry = Data.substr(Start, End - Start);
245   Base =
246       static_cast<MergeOutputSection<ELFT> *>(this->OutSec)->getOffset(Entry);
247   return Base + Addend;
248 }
249 
250 namespace lld {
251 namespace elf2 {
252 template class InputSectionBase<object::ELF32LE>;
253 template class InputSectionBase<object::ELF32BE>;
254 template class InputSectionBase<object::ELF64LE>;
255 template class InputSectionBase<object::ELF64BE>;
256 
257 template class InputSection<object::ELF32LE>;
258 template class InputSection<object::ELF32BE>;
259 template class InputSection<object::ELF64LE>;
260 template class InputSection<object::ELF64BE>;
261 
262 template class EHInputSection<object::ELF32LE>;
263 template class EHInputSection<object::ELF32BE>;
264 template class EHInputSection<object::ELF64LE>;
265 template class EHInputSection<object::ELF64BE>;
266 
267 template class MergeInputSection<object::ELF32LE>;
268 template class MergeInputSection<object::ELF32BE>;
269 template class MergeInputSection<object::ELF64LE>;
270 template class MergeInputSection<object::ELF64BE>;
271 }
272 }
273