blob: 7aa9e7ea560f203c356fbc37d28c95a7b7a20ef8 [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 Espindola551dfd82015-09-25 19:24:57 +000011#include "Config.h"
Rafael Espindola192e1fa2015-08-06 15:08:23 +000012#include "Error.h"
Michael J. Spencer67bc8d62015-08-27 23:15:56 +000013#include "InputFiles.h"
Rafael Espindola4ea00212015-09-21 22:01:00 +000014#include "OutputSections.h"
Rafael Espindola01205f72015-09-22 18:19:46 +000015#include "Target.h"
Rafael Espindola4ea00212015-09-21 22:01:00 +000016
Michael J. Spencer84487f12015-07-24 21:03:07 +000017using namespace llvm;
18using namespace llvm::ELF;
Rafael Espindola4ea00212015-09-21 22:01:00 +000019using namespace llvm::object;
Michael J. Spencer84487f12015-07-24 21:03:07 +000020
21using namespace lld;
22using namespace lld::elf2;
23
24template <class ELFT>
Rafael Espindola53d5cea2015-09-21 17:47:00 +000025InputSection<ELFT>::InputSection(ObjectFile<ELFT> *F, const Elf_Shdr *Header)
Michael J. Spencer67bc8d62015-08-27 23:15:56 +000026 : File(F), Header(Header) {}
Michael J. Spencer84487f12015-07-24 21:03:07 +000027
Rafael Espindola4ea00212015-09-21 22:01:00 +000028template <class ELFT>
Rafael Espindolaaa197082015-10-15 15:52:12 +000029void 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
36template <class ELFT>
37void InputSection<ELFT>::relocateOne(uint8_t *Buf, uint8_t *BufEnd,
38 const Elf_Rela &Rel, uint32_t Type,
39 uintX_t BaseAddr, uintX_t SymVA) {
Rafael Espindolaaa197082015-10-15 15:52:12 +000040 Target->relocateOne(Buf, BufEnd, reinterpret_cast<const void *>(&Rel), Type,
Rui Ueyama66072272015-10-15 19:52:27 +000041 BaseAddr, SymVA + Rel.r_addend);
Rafael Espindolaaa197082015-10-15 15:52:12 +000042}
43
44template <class ELFT>
Rafael Espindola4ea00212015-09-21 22:01:00 +000045template <bool isRela>
46void InputSection<ELFT>::relocate(
Hal Finkel87bbd5f2015-10-12 21:19:18 +000047 uint8_t *Buf, uint8_t *BufEnd,
48 iterator_range<const Elf_Rel_Impl<ELFT, isRela> *> Rels,
Rui Ueyama15ef5e12015-10-07 19:18:16 +000049 const ObjectFile<ELFT> &File, uintX_t BaseAddr) {
Rafael Espindola4ea00212015-09-21 22:01:00 +000050 typedef Elf_Rel_Impl<ELFT, isRela> RelType;
Rafael Espindola4ea00212015-09-21 22:01:00 +000051 for (const RelType &RI : Rels) {
Rui Ueyama64558522015-10-16 22:51:43 +000052 uint32_t SymIndex = RI.getSymbol(Config->Mips64EL);
53 uint32_t Type = RI.getType(Config->Mips64EL);
Rafael Espindola4ea00212015-09-21 22:01:00 +000054
55 // Handle relocations for local symbols -- they never get
56 // resolved so we don't allocate a SymbolBody.
57 const Elf_Shdr *SymTab = File.getSymbolTable();
58 if (SymIndex < SymTab->sh_info) {
Hal Finkel230c5c52015-10-16 22:37:32 +000059 uintX_t SymVA = getLocalRelTarget(File, RI);
Rafael Espindolaaa197082015-10-15 15:52:12 +000060 relocateOne(Buf, BufEnd, RI, Type, BaseAddr, SymVA);
Rui Ueyamabb3c3362015-10-12 20:28:23 +000061 continue;
Rafael Espindola4ea00212015-09-21 22:01:00 +000062 }
63
Rui Ueyamabb3c3362015-10-12 20:28:23 +000064 SymbolBody &Body = *File.getSymbolBody(SymIndex)->repl();
65 uintX_t SymVA = getSymVA<ELFT>(Body);
66 if (Target->relocNeedsPlt(Type, Body)) {
67 SymVA = Out<ELFT>::Plt->getEntryAddr(Body);
Rafael Espindola227556e2015-10-14 16:15:46 +000068 Type = Target->getPLTRefReloc(Type);
Rui Ueyamabb3c3362015-10-12 20:28:23 +000069 } else if (Target->relocNeedsGot(Type, Body)) {
70 SymVA = Out<ELFT>::Got->getEntryAddr(Body);
71 Type = Target->getGotRefReloc();
72 } else if (Target->relocPointsToGot(Type)) {
73 SymVA = Out<ELFT>::Got->getVA();
74 Type = Target->getPCRelReloc();
75 } else if (isa<SharedSymbol<ELFT>>(Body)) {
76 continue;
77 }
Rafael Espindolaaa197082015-10-15 15:52:12 +000078 relocateOne(Buf, BufEnd, RI, Type, BaseAddr, SymVA);
Rafael Espindola4ea00212015-09-21 22:01:00 +000079 }
80}
81
Rui Ueyama15ef5e12015-10-07 19:18:16 +000082template <class ELFT> void InputSection<ELFT>::writeTo(uint8_t *Buf) {
Michael J. Spencer84487f12015-07-24 21:03:07 +000083 if (Header->sh_type == SHT_NOBITS)
84 return;
85 // Copy section contents from source object file to output file.
Rafael Espindolae1901cc2015-09-24 15:11:50 +000086 ArrayRef<uint8_t> Data = *File->getObj().getSectionContents(Header);
Rui Ueyama55c3f892015-10-15 01:58:40 +000087 memcpy(Buf + OutSecOff, Data.data(), Data.size());
Rafael Espindola4ea00212015-09-21 22:01:00 +000088
Rafael Espindolae1901cc2015-09-24 15:11:50 +000089 ELFFile<ELFT> &EObj = File->getObj();
Rui Ueyama55c3f892015-10-15 01:58:40 +000090 uint8_t *Base = Buf + OutSecOff;
91 uintX_t BaseAddr = OutSec->getVA() + OutSecOff;
Rafael Espindola4ea00212015-09-21 22:01:00 +000092 // Iterate over all relocation sections that apply to this section.
93 for (const Elf_Shdr *RelSec : RelocSections) {
94 if (RelSec->sh_type == SHT_RELA)
Hal Finkel87bbd5f2015-10-12 21:19:18 +000095 relocate(Base, Base + Data.size(), EObj.relas(RelSec), *File, BaseAddr);
Rafael Espindola4ea00212015-09-21 22:01:00 +000096 else
Hal Finkel87bbd5f2015-10-12 21:19:18 +000097 relocate(Base, Base + Data.size(), EObj.rels(RelSec), *File, BaseAddr);
Rafael Espindola4ea00212015-09-21 22:01:00 +000098 }
Michael J. Spencer84487f12015-07-24 21:03:07 +000099}
100
Rafael Espindola53d5cea2015-09-21 17:47:00 +0000101template <class ELFT> StringRef InputSection<ELFT>::getSectionName() const {
Rafael Espindolae1901cc2015-09-24 15:11:50 +0000102 ErrorOr<StringRef> Name = File->getObj().getSectionName(Header);
Rafael Espindola5d83ccd2015-08-13 19:18:30 +0000103 error(Name);
104 return *Name;
105}
106
Michael J. Spencer84487f12015-07-24 21:03:07 +0000107namespace lld {
108namespace elf2 {
Rafael Espindola53d5cea2015-09-21 17:47:00 +0000109template class InputSection<object::ELF32LE>;
110template class InputSection<object::ELF32BE>;
111template class InputSection<object::ELF64LE>;
112template class InputSection<object::ELF64BE>;
Michael J. Spencer84487f12015-07-24 21:03:07 +0000113}
114}