blob: aff6cdedcd2290f689ae794712e6d3d551b4c3b3 [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 Espindola4ea00212015-09-21 22:01:00 +000029template <bool isRela>
30void InputSection<ELFT>::relocate(
Hal Finkel87bbd5f2015-10-12 21:19:18 +000031 uint8_t *Buf, uint8_t *BufEnd,
32 iterator_range<const Elf_Rel_Impl<ELFT, isRela> *> Rels,
Rui Ueyama15ef5e12015-10-07 19:18:16 +000033 const ObjectFile<ELFT> &File, uintX_t BaseAddr) {
Rafael Espindola4ea00212015-09-21 22:01:00 +000034 typedef Elf_Rel_Impl<ELFT, isRela> RelType;
Rafael Espindolae1901cc2015-09-24 15:11:50 +000035 bool IsMips64EL = File.getObj().isMips64EL();
Rafael Espindola4ea00212015-09-21 22:01:00 +000036 for (const RelType &RI : Rels) {
37 uint32_t SymIndex = RI.getSymbol(IsMips64EL);
38 uint32_t Type = RI.getType(IsMips64EL);
Rafael Espindola4ea00212015-09-21 22:01:00 +000039
40 // Handle relocations for local symbols -- they never get
41 // resolved so we don't allocate a SymbolBody.
42 const Elf_Shdr *SymTab = File.getSymbolTable();
43 if (SymIndex < SymTab->sh_info) {
Rui Ueyamabb3c3362015-10-12 20:28:23 +000044 uintX_t SymVA = getLocalRelTarget(File, RI);
Hal Finkel87bbd5f2015-10-12 21:19:18 +000045 Target->relocateOne(Buf, BufEnd, reinterpret_cast<const void *>(&RI),
46 Type, BaseAddr, SymVA);
Rui Ueyamabb3c3362015-10-12 20:28:23 +000047 continue;
Rafael Espindola4ea00212015-09-21 22:01:00 +000048 }
49
Rui Ueyamabb3c3362015-10-12 20:28:23 +000050 SymbolBody &Body = *File.getSymbolBody(SymIndex)->repl();
51 uintX_t SymVA = getSymVA<ELFT>(Body);
52 if (Target->relocNeedsPlt(Type, Body)) {
53 SymVA = Out<ELFT>::Plt->getEntryAddr(Body);
Rafael Espindola227556e2015-10-14 16:15:46 +000054 Type = Target->getPLTRefReloc(Type);
Rui Ueyamabb3c3362015-10-12 20:28:23 +000055 } else if (Target->relocNeedsGot(Type, Body)) {
56 SymVA = Out<ELFT>::Got->getEntryAddr(Body);
57 Type = Target->getGotRefReloc();
58 } else if (Target->relocPointsToGot(Type)) {
59 SymVA = Out<ELFT>::Got->getVA();
60 Type = Target->getPCRelReloc();
61 } else if (isa<SharedSymbol<ELFT>>(Body)) {
62 continue;
63 }
Hal Finkel87bbd5f2015-10-12 21:19:18 +000064 Target->relocateOne(Buf, BufEnd, reinterpret_cast<const void *>(&RI), Type,
Rui Ueyamaaf21d922015-10-08 20:06:07 +000065 BaseAddr, SymVA);
Rafael Espindola4ea00212015-09-21 22:01:00 +000066 }
67}
68
Rui Ueyama15ef5e12015-10-07 19:18:16 +000069template <class ELFT> void InputSection<ELFT>::writeTo(uint8_t *Buf) {
Michael J. Spencer84487f12015-07-24 21:03:07 +000070 if (Header->sh_type == SHT_NOBITS)
71 return;
72 // Copy section contents from source object file to output file.
Rafael Espindolae1901cc2015-09-24 15:11:50 +000073 ArrayRef<uint8_t> Data = *File->getObj().getSectionContents(Header);
Rui Ueyama55c3f892015-10-15 01:58:40 +000074 memcpy(Buf + OutSecOff, Data.data(), Data.size());
Rafael Espindola4ea00212015-09-21 22:01:00 +000075
Rafael Espindolae1901cc2015-09-24 15:11:50 +000076 ELFFile<ELFT> &EObj = File->getObj();
Rui Ueyama55c3f892015-10-15 01:58:40 +000077 uint8_t *Base = Buf + OutSecOff;
78 uintX_t BaseAddr = OutSec->getVA() + OutSecOff;
Rafael Espindola4ea00212015-09-21 22:01:00 +000079 // Iterate over all relocation sections that apply to this section.
80 for (const Elf_Shdr *RelSec : RelocSections) {
81 if (RelSec->sh_type == SHT_RELA)
Hal Finkel87bbd5f2015-10-12 21:19:18 +000082 relocate(Base, Base + Data.size(), EObj.relas(RelSec), *File, BaseAddr);
Rafael Espindola4ea00212015-09-21 22:01:00 +000083 else
Hal Finkel87bbd5f2015-10-12 21:19:18 +000084 relocate(Base, Base + Data.size(), EObj.rels(RelSec), *File, BaseAddr);
Rafael Espindola4ea00212015-09-21 22:01:00 +000085 }
Michael J. Spencer84487f12015-07-24 21:03:07 +000086}
87
Rafael Espindola53d5cea2015-09-21 17:47:00 +000088template <class ELFT> StringRef InputSection<ELFT>::getSectionName() const {
Rafael Espindolae1901cc2015-09-24 15:11:50 +000089 ErrorOr<StringRef> Name = File->getObj().getSectionName(Header);
Rafael Espindola5d83ccd2015-08-13 19:18:30 +000090 error(Name);
91 return *Name;
92}
93
Michael J. Spencer84487f12015-07-24 21:03:07 +000094namespace lld {
95namespace elf2 {
Rafael Espindola53d5cea2015-09-21 17:47:00 +000096template class InputSection<object::ELF32LE>;
97template class InputSection<object::ELF32BE>;
98template class InputSection<object::ELF64LE>;
99template class InputSection<object::ELF64BE>;
Michael J. Spencer84487f12015-07-24 21:03:07 +0000100}
101}