blob: 2b57e5f13fda6d9d3877f912e820ccfb89e8afb9 [file] [log] [blame]
Rafael Espindola9d06ab62015-09-22 00:01:39 +00001//===- InputSection.cpp ---------------------------------------------------===//
Michael J. Spencer84487f12015-07-24 21:03:07 +00002//
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
Rafael Espindola9d06ab62015-09-22 00:01:39 +000010#include "InputSection.h"
Rafael Espindola192e1fa2015-08-06 15:08:23 +000011#include "Error.h"
Michael J. Spencer67bc8d62015-08-27 23:15:56 +000012#include "InputFiles.h"
Rafael Espindola4ea00212015-09-21 22:01:00 +000013#include "OutputSections.h"
Rafael Espindola01205f72015-09-22 18:19:46 +000014#include "Target.h"
Rafael Espindola4ea00212015-09-21 22:01:00 +000015
Michael J. Spencer84487f12015-07-24 21:03:07 +000016using namespace llvm;
17using namespace llvm::ELF;
Rafael Espindola4ea00212015-09-21 22:01:00 +000018using namespace llvm::object;
Michael J. Spencer84487f12015-07-24 21:03:07 +000019
20using namespace lld;
21using namespace lld::elf2;
22
23template <class ELFT>
Rafael Espindola53d5cea2015-09-21 17:47:00 +000024InputSection<ELFT>::InputSection(ObjectFile<ELFT> *F, const Elf_Shdr *Header)
Michael J. Spencer67bc8d62015-08-27 23:15:56 +000025 : File(F), Header(Header) {}
Michael J. Spencer84487f12015-07-24 21:03:07 +000026
Rafael Espindola4ea00212015-09-21 22:01:00 +000027template <class ELFT>
Rafael Espindola4ea00212015-09-21 22:01:00 +000028template <bool isRela>
29void InputSection<ELFT>::relocate(
30 uint8_t *Buf, iterator_range<const Elf_Rel_Impl<ELFT, isRela> *> Rels,
31 const ObjectFile<ELFT> &File, uintX_t BaseAddr,
Michael J. Spencer2812aa82015-09-23 16:57:31 +000032 const OutputSection<ELFT> &BssSec, const PltSection<ELFT> &PltSec,
33 const GotSection<ELFT> &GotSec) {
Rafael Espindola4ea00212015-09-21 22:01:00 +000034 typedef Elf_Rel_Impl<ELFT, isRela> RelType;
35 bool IsMips64EL = File.getObj()->isMips64EL();
36 for (const RelType &RI : Rels) {
37 uint32_t SymIndex = RI.getSymbol(IsMips64EL);
38 uint32_t Type = RI.getType(IsMips64EL);
39 uintX_t SymVA;
40
41 // Handle relocations for local symbols -- they never get
42 // resolved so we don't allocate a SymbolBody.
43 const Elf_Shdr *SymTab = File.getSymbolTable();
44 if (SymIndex < SymTab->sh_info) {
45 const Elf_Sym *Sym = File.getObj()->getRelocationSymbol(&RI, SymTab);
46 if (!Sym)
47 continue;
48 SymVA = getLocalSymVA(Sym, File);
49 } else {
50 const SymbolBody *Body = File.getSymbolBody(SymIndex);
51 if (!Body)
52 continue;
Rafael Espindolacdfecff2015-09-23 20:08:25 +000053 uint32_t OrigType = Type;
Rafael Espindola4ea00212015-09-21 22:01:00 +000054 switch (Body->kind()) {
55 case SymbolBody::DefinedRegularKind:
56 SymVA = getSymVA<ELFT>(cast<DefinedRegular<ELFT>>(Body));
57 break;
58 case SymbolBody::DefinedAbsoluteKind:
59 SymVA = cast<DefinedAbsolute<ELFT>>(Body)->Sym.st_value;
60 break;
61 case SymbolBody::DefinedCommonKind: {
62 auto *DC = cast<DefinedCommon<ELFT>>(Body);
Michael J. Spencer2812aa82015-09-23 16:57:31 +000063 SymVA = BssSec.getVA() + DC->OffsetInBSS;
Rafael Espindola4ea00212015-09-21 22:01:00 +000064 break;
65 }
66 case SymbolBody::SharedKind:
Rafael Espindolacdfecff2015-09-23 20:08:25 +000067 if (Target->relocNeedsPlt(Type))
Rafael Espindola01205f72015-09-22 18:19:46 +000068 Type = Target->getPCRelReloc();
Rafael Espindolacdfecff2015-09-23 20:08:25 +000069 else if (Target->relocNeedsGot(Type))
Rafael Espindola01205f72015-09-22 18:19:46 +000070 Type = Target->getPCRelReloc();
Rafael Espindolacdfecff2015-09-23 20:08:25 +000071 else
Rafael Espindola4ea00212015-09-21 22:01:00 +000072 continue;
Rafael Espindola4ea00212015-09-21 22:01:00 +000073 break;
74 case SymbolBody::UndefinedKind:
75 assert(Body->isWeak() && "Undefined symbol reached writer");
76 SymVA = 0;
77 break;
78 case SymbolBody::LazyKind:
79 llvm_unreachable("Lazy symbol reached writer");
80 }
Rafael Espindolacdfecff2015-09-23 20:08:25 +000081
82 if (Target->relocNeedsPlt(OrigType))
83 SymVA = PltSec.getEntryAddr(*Body);
84 else if (Target->relocNeedsGot(OrigType))
85 SymVA = GotSec.getEntryAddr(*Body);
Rafael Espindola4ea00212015-09-21 22:01:00 +000086 }
87
Rafael Espindolac4010882015-09-22 20:54:08 +000088 Target->relocateOne(Buf, reinterpret_cast<const void *>(&RI), Type,
89 BaseAddr, SymVA);
Rafael Espindola4ea00212015-09-21 22:01:00 +000090 }
91}
92
93template <class ELFT>
Michael J. Spencer2812aa82015-09-23 16:57:31 +000094void InputSection<ELFT>::writeTo(uint8_t *Buf,
95 const OutputSection<ELFT> &BssSec,
96 const PltSection<ELFT> &PltSec,
Rafael Espindola4ea00212015-09-21 22:01:00 +000097 const GotSection<ELFT> &GotSec) {
Michael J. Spencer84487f12015-07-24 21:03:07 +000098 if (Header->sh_type == SHT_NOBITS)
99 return;
100 // Copy section contents from source object file to output file.
Michael J. Spencer67bc8d62015-08-27 23:15:56 +0000101 ArrayRef<uint8_t> Data = *File->getObj()->getSectionContents(Header);
Rafael Espindola674b5d52015-08-13 15:54:36 +0000102 memcpy(Buf + OutputSectionOff, Data.data(), Data.size());
Rafael Espindola4ea00212015-09-21 22:01:00 +0000103
104 const ObjectFile<ELFT> *File = getFile();
105 ELFFile<ELFT> *EObj = File->getObj();
106 uint8_t *Base = Buf + getOutputSectionOff();
107 uintX_t BaseAddr = Out->getVA() + getOutputSectionOff();
108 // Iterate over all relocation sections that apply to this section.
109 for (const Elf_Shdr *RelSec : RelocSections) {
110 if (RelSec->sh_type == SHT_RELA)
Michael J. Spencer2812aa82015-09-23 16:57:31 +0000111 relocate(Base, EObj->relas(RelSec), *File, BaseAddr, BssSec, PltSec,
112 GotSec);
Rafael Espindola4ea00212015-09-21 22:01:00 +0000113 else
Michael J. Spencer2812aa82015-09-23 16:57:31 +0000114 relocate(Base, EObj->rels(RelSec), *File, BaseAddr, BssSec, PltSec,
115 GotSec);
Rafael Espindola4ea00212015-09-21 22:01:00 +0000116 }
Michael J. Spencer84487f12015-07-24 21:03:07 +0000117}
118
Rafael Espindola53d5cea2015-09-21 17:47:00 +0000119template <class ELFT> StringRef InputSection<ELFT>::getSectionName() const {
Michael J. Spencer67bc8d62015-08-27 23:15:56 +0000120 ErrorOr<StringRef> Name = File->getObj()->getSectionName(Header);
Rafael Espindola5d83ccd2015-08-13 19:18:30 +0000121 error(Name);
122 return *Name;
123}
124
Michael J. Spencer84487f12015-07-24 21:03:07 +0000125namespace lld {
126namespace elf2 {
Rafael Espindola53d5cea2015-09-21 17:47:00 +0000127template class InputSection<object::ELF32LE>;
128template class InputSection<object::ELF32BE>;
129template class InputSection<object::ELF64LE>;
130template class InputSection<object::ELF64BE>;
Michael J. Spencer84487f12015-07-24 21:03:07 +0000131}
132}