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