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 InputSection<ELFT>::InputSection(ObjectFile<ELFT> *F, const Elf_Shdr *Header)
26     : File(F), Header(Header) {}
27 
28 template <class ELFT>
29 void InputSection<ELFT>::relocateOne(uint8_t *Buf, uint8_t *BufEnd,
30                                      const Elf_Rel &Rel, uint32_t Type,
31                                      uintX_t BaseAddr, uintX_t SymVA) {
32   Target->relocateOne(Buf, BufEnd, reinterpret_cast<const void *>(&Rel), Type,
33                       BaseAddr, SymVA);
34 }
35 
36 template <class ELFT>
37 void InputSection<ELFT>::relocateOne(uint8_t *Buf, uint8_t *BufEnd,
38                                      const Elf_Rela &Rel, uint32_t Type,
39                                      uintX_t BaseAddr, uintX_t SymVA) {
40   Target->relocateOne(Buf, BufEnd, reinterpret_cast<const void *>(&Rel), Type,
41                       BaseAddr, SymVA + Rel.r_addend);
42 }
43 
44 template <class ELFT>
45 template <bool isRela>
46 void InputSection<ELFT>::relocate(
47     uint8_t *Buf, uint8_t *BufEnd,
48     iterator_range<const Elf_Rel_Impl<ELFT, isRela> *> Rels,
49     const ObjectFile<ELFT> &File, uintX_t BaseAddr) {
50   typedef Elf_Rel_Impl<ELFT, isRela> RelType;
51   bool IsMips64EL = File.getObj().isMips64EL();
52   for (const RelType &RI : Rels) {
53     uint32_t SymIndex = RI.getSymbol(IsMips64EL);
54     uint32_t Type = RI.getType(IsMips64EL);
55 
56     // Handle relocations for local symbols -- they never get
57     // resolved so we don't allocate a SymbolBody.
58     const Elf_Shdr *SymTab = File.getSymbolTable();
59     if (SymIndex < SymTab->sh_info) {
60       uintX_t SymVA = getLocalRelTarget(File, RI);
61       relocateOne(Buf, BufEnd, RI, Type, BaseAddr, SymVA);
62       continue;
63     }
64 
65     SymbolBody &Body = *File.getSymbolBody(SymIndex)->repl();
66     uintX_t SymVA = getSymVA<ELFT>(Body);
67     if (Target->relocNeedsPlt(Type, Body)) {
68       SymVA = Out<ELFT>::Plt->getEntryAddr(Body);
69       Type = Target->getPLTRefReloc(Type);
70     } else if (Target->relocNeedsGot(Type, Body)) {
71       SymVA = Out<ELFT>::Got->getEntryAddr(Body);
72       Type = Target->getGotRefReloc();
73     } else if (Target->relocPointsToGot(Type)) {
74       SymVA = Out<ELFT>::Got->getVA();
75       Type = Target->getPCRelReloc();
76     } else if (isa<SharedSymbol<ELFT>>(Body)) {
77       continue;
78     }
79     relocateOne(Buf, BufEnd, RI, Type, BaseAddr, SymVA);
80   }
81 }
82 
83 template <class ELFT> void InputSection<ELFT>::writeTo(uint8_t *Buf) {
84   if (Header->sh_type == SHT_NOBITS)
85     return;
86   // Copy section contents from source object file to output file.
87   ArrayRef<uint8_t> Data = *File->getObj().getSectionContents(Header);
88   memcpy(Buf + OutSecOff, Data.data(), Data.size());
89 
90   ELFFile<ELFT> &EObj = File->getObj();
91   uint8_t *Base = Buf + OutSecOff;
92   uintX_t BaseAddr = OutSec->getVA() + OutSecOff;
93   // Iterate over all relocation sections that apply to this section.
94   for (const Elf_Shdr *RelSec : RelocSections) {
95     if (RelSec->sh_type == SHT_RELA)
96       relocate(Base, Base + Data.size(), EObj.relas(RelSec), *File, BaseAddr);
97     else
98       relocate(Base, Base + Data.size(), EObj.rels(RelSec), *File, BaseAddr);
99   }
100 }
101 
102 template <class ELFT> StringRef InputSection<ELFT>::getSectionName() const {
103   ErrorOr<StringRef> Name = File->getObj().getSectionName(Header);
104   error(Name);
105   return *Name;
106 }
107 
108 namespace lld {
109 namespace elf2 {
110 template class InputSection<object::ELF32LE>;
111 template class InputSection<object::ELF32BE>;
112 template class InputSection<object::ELF64LE>;
113 template class InputSection<object::ELF64BE>;
114 }
115 }
116