blob: 00a244a2a46b26207ad8bc91e3eff0e720592fdc [file] [log] [blame]
Rafael Espindola5805c4f2015-09-21 21:38:08 +00001//===- OutputSections.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 "OutputSections.h"
11#include "Config.h"
Rafael Espindola5805c4f2015-09-21 21:38:08 +000012#include "SymbolTable.h"
Rafael Espindola01205f72015-09-22 18:19:46 +000013#include "Target.h"
Rafael Espindola5805c4f2015-09-21 21:38:08 +000014
Rafael Espindola5805c4f2015-09-21 21:38:08 +000015using namespace llvm;
16using namespace llvm::object;
Rafael Espindolaa6627382015-10-06 23:56:53 +000017using namespace llvm::support::endian;
Rafael Espindola5805c4f2015-09-21 21:38:08 +000018using namespace llvm::ELF;
19
20using namespace lld;
21using namespace lld::elf2;
22
23template <bool Is64Bits>
24OutputSectionBase<Is64Bits>::OutputSectionBase(StringRef Name, uint32_t sh_type,
25 uintX_t sh_flags)
26 : Name(Name) {
27 memset(&Header, 0, sizeof(HeaderT));
28 Header.sh_type = sh_type;
29 Header.sh_flags = sh_flags;
30}
31
Rafael Espindola35c6af32015-09-25 17:19:10 +000032template <class ELFT>
Rafael Espindolaa6627382015-10-06 23:56:53 +000033GotSection<ELFT>::GotSection(const OutputSection<ELFT> &BssSec)
Rafael Espindola35c6af32015-09-25 17:19:10 +000034 : OutputSectionBase<ELFT::Is64Bits>(".got", llvm::ELF::SHT_PROGBITS,
35 llvm::ELF::SHF_ALLOC |
Rafael Espindolaa6627382015-10-06 23:56:53 +000036 llvm::ELF::SHF_WRITE),
37 BssSec(BssSec) {
Rafael Espindola35c6af32015-09-25 17:19:10 +000038 this->Header.sh_addralign = this->getAddrSize();
39}
40
Rafael Espindola5805c4f2015-09-21 21:38:08 +000041template <class ELFT> void GotSection<ELFT>::addEntry(SymbolBody *Sym) {
42 Sym->setGotIndex(Entries.size());
43 Entries.push_back(Sym);
44}
45
46template <class ELFT>
47typename GotSection<ELFT>::uintX_t
48GotSection<ELFT>::getEntryAddr(const SymbolBody &B) const {
49 return this->getVA() + B.getGotIndex() * this->getAddrSize();
50}
51
Rafael Espindolaa6627382015-10-06 23:56:53 +000052template <class ELFT> void GotSection<ELFT>::writeTo(uint8_t *Buf) {
53 for (const SymbolBody *B : Entries) {
Rafael Espindolae782f672015-10-07 03:56:05 +000054 uint8_t *Entry = Buf;
55 Buf += sizeof(uintX_t);
Rafael Espindolaa6627382015-10-06 23:56:53 +000056 if (canBePreempted(B))
57 continue; // The dynamic linker will take care of it.
58 uintX_t VA = getSymVA(*B, BssSec);
Rafael Espindolae782f672015-10-07 03:56:05 +000059 write<uintX_t, ELFT::TargetEndianness, sizeof(uintX_t)>(Entry, VA);
Rafael Espindolaa6627382015-10-06 23:56:53 +000060 }
61}
62
Rafael Espindola35c6af32015-09-25 17:19:10 +000063template <class ELFT>
64PltSection<ELFT>::PltSection(const GotSection<ELFT> &GotSec)
65 : OutputSectionBase<ELFT::Is64Bits>(".plt", llvm::ELF::SHT_PROGBITS,
66 llvm::ELF::SHF_ALLOC |
67 llvm::ELF::SHF_EXECINSTR),
68 GotSec(GotSec) {
69 this->Header.sh_addralign = 16;
70}
71
Rafael Espindola5805c4f2015-09-21 21:38:08 +000072template <class ELFT> void PltSection<ELFT>::writeTo(uint8_t *Buf) {
73 uintptr_t Start = reinterpret_cast<uintptr_t>(Buf);
Rafael Espindola5805c4f2015-09-21 21:38:08 +000074 for (const SymbolBody *E : Entries) {
Rafael Espindola01205f72015-09-22 18:19:46 +000075 uint64_t GotEntryAddr = GotSec.getEntryAddr(*E);
Rafael Espindola5805c4f2015-09-21 21:38:08 +000076 uintptr_t InstPos = reinterpret_cast<uintptr_t>(Buf);
Rafael Espindola01205f72015-09-22 18:19:46 +000077 uint64_t PltEntryAddr = (InstPos - Start) + this->getVA();
78 Target->writePltEntry(Buf, GotEntryAddr, PltEntryAddr);
79 Buf += 8;
Rafael Espindola5805c4f2015-09-21 21:38:08 +000080 }
81}
82
83template <class ELFT> void PltSection<ELFT>::addEntry(SymbolBody *Sym) {
84 Sym->setPltIndex(Entries.size());
85 Entries.push_back(Sym);
86}
87
88template <class ELFT>
89typename PltSection<ELFT>::uintX_t
90PltSection<ELFT>::getEntryAddr(const SymbolBody &B) const {
91 return this->getVA() + B.getPltIndex() * EntrySize;
92}
93
Rafael Espindola35c6af32015-09-25 17:19:10 +000094template <class ELFT>
95RelocationSection<ELFT>::RelocationSection(SymbolTableSection<ELFT> &DynSymSec,
96 const GotSection<ELFT> &GotSec,
Rafael Espindola9c3e4d22015-10-05 21:23:08 +000097 const OutputSection<ELFT> &BssSec,
Rafael Espindola35c6af32015-09-25 17:19:10 +000098 bool IsRela)
99 : OutputSectionBase<ELFT::Is64Bits>(IsRela ? ".rela.dyn" : ".rel.dyn",
100 IsRela ? llvm::ELF::SHT_RELA
101 : llvm::ELF::SHT_REL,
102 llvm::ELF::SHF_ALLOC),
Rafael Espindola9c3e4d22015-10-05 21:23:08 +0000103 DynSymSec(DynSymSec), GotSec(GotSec), BssSec(BssSec), IsRela(IsRela) {
Rafael Espindola35c6af32015-09-25 17:19:10 +0000104 this->Header.sh_entsize = IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel);
105 this->Header.sh_addralign = ELFT::Is64Bits ? 8 : 4;
106}
107
Rafael Espindola5805c4f2015-09-21 21:38:08 +0000108template <class ELFT> void RelocationSection<ELFT>::writeTo(uint8_t *Buf) {
Rafael Espindola50534c22015-09-22 17:49:38 +0000109 const unsigned EntrySize = IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel);
Rafael Espindolae1901cc2015-09-24 15:11:50 +0000110 bool IsMips64EL = Relocs[0].C.getFile()->getObj().isMips64EL();
Rafael Espindola5805c4f2015-09-21 21:38:08 +0000111 for (const DynamicReloc<ELFT> &Rel : Relocs) {
Rafael Espindola50534c22015-09-22 17:49:38 +0000112 auto *P = reinterpret_cast<Elf_Rel *>(Buf);
113 Buf += EntrySize;
114
Rafael Espindola5805c4f2015-09-21 21:38:08 +0000115 const InputSection<ELFT> &C = Rel.C;
116 const Elf_Rel &RI = Rel.RI;
Rui Ueyamab4908762015-10-07 17:04:18 +0000117 OutputSection<ELFT> *OutSec = C.getOutputSection();
Rafael Espindola5805c4f2015-09-21 21:38:08 +0000118 uint32_t SymIndex = RI.getSymbol(IsMips64EL);
Rafael Espindola41127ad2015-10-05 22:49:16 +0000119 const ObjectFile<ELFT> &File = *C.getFile();
120 const SymbolBody *Body = File.getSymbolBody(SymIndex);
121 const ELFFile<ELFT> &Obj = File.getObj();
122
Rafael Espindola5805c4f2015-09-21 21:38:08 +0000123 uint32_t Type = RI.getType(IsMips64EL);
Rafael Espindola52dca342015-10-07 00:58:20 +0000124
125 bool CanBePreempted = canBePreempted(Body);
126 uintX_t Addend = 0;
127 if (!CanBePreempted) {
128 if (IsRela) {
129 if (Body)
130 Addend += getSymVA(cast<ELFSymbolBody<ELFT>>(*Body), BssSec);
131 else
132 Addend += getLocalSymVA(
133 Obj.getRelocationSymbol(&RI, File.getSymbolTable()), File);
134 }
135 P->setSymbolAndType(0, Target->getRelativeReloc(), IsMips64EL);
136 }
137
Rafael Espindolaae244002015-10-05 19:30:12 +0000138 if (Body && Target->relocNeedsGot(Type, *Body)) {
Rafael Espindola5805c4f2015-09-21 21:38:08 +0000139 P->r_offset = GotSec.getEntryAddr(*Body);
Rafael Espindola52dca342015-10-07 00:58:20 +0000140 if (CanBePreempted)
141 P->setSymbolAndType(Body->getDynamicSymbolTableIndex(),
142 Target->getGotReloc(), IsMips64EL);
Rafael Espindola5805c4f2015-09-21 21:38:08 +0000143 } else {
Rafael Espindola3c83e2b2015-10-05 21:09:37 +0000144 if (IsRela)
Rafael Espindola52dca342015-10-07 00:58:20 +0000145 Addend += static_cast<const Elf_Rela &>(RI).r_addend;
Rui Ueyamab4908762015-10-07 17:04:18 +0000146 P->r_offset = RI.r_offset + C.getOutputSectionOff() + OutSec->getVA();
Rafael Espindola52dca342015-10-07 00:58:20 +0000147 if (CanBePreempted)
Rafael Espindolaae244002015-10-05 19:30:12 +0000148 P->setSymbolAndType(Body->getDynamicSymbolTableIndex(), Type,
149 IsMips64EL);
Rafael Espindola5805c4f2015-09-21 21:38:08 +0000150 }
Rafael Espindola52dca342015-10-07 00:58:20 +0000151
152 if (IsRela)
153 static_cast<Elf_Rela *>(P)->r_addend = Addend;
Rafael Espindola5805c4f2015-09-21 21:38:08 +0000154 }
155}
156
157template <class ELFT> void RelocationSection<ELFT>::finalize() {
158 this->Header.sh_link = DynSymSec.getSectionIndex();
159 this->Header.sh_size = Relocs.size() * this->Header.sh_entsize;
160}
161
162template <bool Is64Bits>
163InterpSection<Is64Bits>::InterpSection()
164 : OutputSectionBase<Is64Bits>(".interp", llvm::ELF::SHT_PROGBITS,
165 llvm::ELF::SHF_ALLOC) {
166 this->Header.sh_size = Config->DynamicLinker.size() + 1;
167 this->Header.sh_addralign = 1;
168}
169
170template <bool Is64Bits>
171template <endianness E>
172void OutputSectionBase<Is64Bits>::writeHeaderTo(
173 typename ELFFile<ELFType<E, Is64Bits>>::Elf_Shdr *SHdr) {
174 SHdr->sh_name = Header.sh_name;
175 SHdr->sh_type = Header.sh_type;
176 SHdr->sh_flags = Header.sh_flags;
177 SHdr->sh_addr = Header.sh_addr;
178 SHdr->sh_offset = Header.sh_offset;
179 SHdr->sh_size = Header.sh_size;
180 SHdr->sh_link = Header.sh_link;
181 SHdr->sh_info = Header.sh_info;
182 SHdr->sh_addralign = Header.sh_addralign;
183 SHdr->sh_entsize = Header.sh_entsize;
184}
185
186template <bool Is64Bits> void InterpSection<Is64Bits>::writeTo(uint8_t *Buf) {
187 memcpy(Buf, Config->DynamicLinker.data(), Config->DynamicLinker.size());
188}
189
Rafael Espindola35c6af32015-09-25 17:19:10 +0000190template <class ELFT>
191HashTableSection<ELFT>::HashTableSection(SymbolTableSection<ELFT> &DynSymSec)
192 : OutputSectionBase<ELFT::Is64Bits>(".hash", llvm::ELF::SHT_HASH,
193 llvm::ELF::SHF_ALLOC),
194 DynSymSec(DynSymSec) {
195 this->Header.sh_entsize = sizeof(Elf_Word);
196 this->Header.sh_addralign = sizeof(Elf_Word);
197}
198
Rafael Espindola5805c4f2015-09-21 21:38:08 +0000199template <class ELFT> void HashTableSection<ELFT>::addSymbol(SymbolBody *S) {
200 StringRef Name = S->getName();
201 DynSymSec.addSymbol(Name);
202 Hashes.push_back(hash(Name));
203 S->setDynamicSymbolTableIndex(Hashes.size());
204}
205
Rui Ueyama0db335f2015-10-07 16:58:54 +0000206template <class ELFT> void HashTableSection<ELFT>::finalize() {
207 this->Header.sh_link = DynSymSec.getSectionIndex();
208
209 assert(DynSymSec.getNumSymbols() == Hashes.size() + 1);
210 unsigned NumEntries = 2; // nbucket and nchain.
211 NumEntries += DynSymSec.getNumSymbols(); // The chain entries.
212
213 // Create as many buckets as there are symbols.
214 // FIXME: This is simplistic. We can try to optimize it, but implementing
215 // support for SHT_GNU_HASH is probably even more profitable.
216 NumEntries += DynSymSec.getNumSymbols();
217 this->Header.sh_size = NumEntries * sizeof(Elf_Word);
218}
219
220template <class ELFT> void HashTableSection<ELFT>::writeTo(uint8_t *Buf) {
221 unsigned NumSymbols = DynSymSec.getNumSymbols();
222 auto *P = reinterpret_cast<Elf_Word *>(Buf);
223 *P++ = NumSymbols; // nbucket
224 *P++ = NumSymbols; // nchain
225
226 Elf_Word *Buckets = P;
227 Elf_Word *Chains = P + NumSymbols;
228
229 for (unsigned I = 1; I < NumSymbols; ++I) {
230 uint32_t Hash = Hashes[I - 1] % NumSymbols;
231 Chains[I] = Buckets[Hash];
232 Buckets[Hash] = I;
233 }
234}
235
Rafael Espindola35c6af32015-09-25 17:19:10 +0000236template <class ELFT>
237DynamicSection<ELFT>::DynamicSection(SymbolTable &SymTab,
238 HashTableSection<ELFT> &HashSec,
Igor Kudrinb1f2b512015-10-05 10:29:46 +0000239 RelocationSection<ELFT> &RelaDynSec,
240 const OutputSection<ELFT> &BssSec)
Rafael Espindola35c6af32015-09-25 17:19:10 +0000241 : OutputSectionBase<ELFT::Is64Bits>(".dynamic", llvm::ELF::SHT_DYNAMIC,
242 llvm::ELF::SHF_ALLOC |
243 llvm::ELF::SHF_WRITE),
244 HashSec(HashSec), DynSymSec(HashSec.getDynSymSec()),
245 DynStrSec(DynSymSec.getStrTabSec()), RelaDynSec(RelaDynSec),
Igor Kudrinb1f2b512015-10-05 10:29:46 +0000246 BssSec(BssSec), SymTab(SymTab) {
Rafael Espindola35c6af32015-09-25 17:19:10 +0000247 typename Base::HeaderT &Header = this->Header;
248 Header.sh_addralign = ELFT::Is64Bits ? 8 : 4;
249 Header.sh_entsize = ELFT::Is64Bits ? 16 : 8;
250}
251
Rafael Espindola5805c4f2015-09-21 21:38:08 +0000252template <class ELFT> void DynamicSection<ELFT>::finalize() {
Michael J. Spencer52bf0eb2015-10-01 21:15:02 +0000253 if (this->Header.sh_size)
254 return; // Already finalized.
255
Rafael Espindola5805c4f2015-09-21 21:38:08 +0000256 typename Base::HeaderT &Header = this->Header;
257 Header.sh_link = DynStrSec.getSectionIndex();
258
259 unsigned NumEntries = 0;
260 if (RelaDynSec.hasRelocs()) {
261 ++NumEntries; // DT_RELA / DT_REL
Rui Ueyama2dfd74f2015-09-30 21:57:53 +0000262 ++NumEntries; // DT_RELASZ / DT_RELSZ
263 ++NumEntries; // DT_RELAENT / DT_RELENT
Rafael Espindola5805c4f2015-09-21 21:38:08 +0000264 }
265 ++NumEntries; // DT_SYMTAB
Rui Ueyama2dfd74f2015-09-30 21:57:53 +0000266 ++NumEntries; // DT_SYMENT
Rafael Espindola5805c4f2015-09-21 21:38:08 +0000267 ++NumEntries; // DT_STRTAB
268 ++NumEntries; // DT_STRSZ
269 ++NumEntries; // DT_HASH
270
Rui Ueyama7de3f372015-10-01 19:36:04 +0000271 if (!Config->RPath.empty()) {
Davide Italianoc39c75d2015-10-06 16:20:00 +0000272 ++NumEntries; // DT_RUNPATH / DT_RPATH
Rui Ueyama7de3f372015-10-01 19:36:04 +0000273 DynStrSec.add(Config->RPath);
274 }
275
276 if (!Config->SoName.empty()) {
277 ++NumEntries; // DT_SONAME
278 DynStrSec.add(Config->SoName);
Rafael Espindola5805c4f2015-09-21 21:38:08 +0000279 }
280
Rafael Espindola77572242015-10-02 19:37:55 +0000281 if (PreInitArraySec)
282 NumEntries += 2;
283 if (InitArraySec)
284 NumEntries += 2;
285 if (FiniArraySec)
286 NumEntries += 2;
287
Rafael Espindola5805c4f2015-09-21 21:38:08 +0000288 const std::vector<std::unique_ptr<SharedFileBase>> &SharedFiles =
289 SymTab.getSharedFiles();
290 for (const std::unique_ptr<SharedFileBase> &File : SharedFiles)
Rafael Espindolac8b15812015-10-01 15:47:50 +0000291 DynStrSec.add(File->getSoName());
Rafael Espindola5805c4f2015-09-21 21:38:08 +0000292 NumEntries += SharedFiles.size();
293
Igor Kudrinb1f2b512015-10-05 10:29:46 +0000294 if (Symbol *S = SymTab.getSymbols().lookup(Config->Init))
295 InitSym = dyn_cast<ELFSymbolBody<ELFT>>(S->Body);
296 if (Symbol *S = SymTab.getSymbols().lookup(Config->Fini))
297 FiniSym = dyn_cast<ELFSymbolBody<ELFT>>(S->Body);
Igor Kudrinb1f2b512015-10-05 10:29:46 +0000298 if (InitSym)
299 ++NumEntries; // DT_INIT
300 if (FiniSym)
301 ++NumEntries; // DT_FINI
George Rimar97aad172015-10-07 15:00:21 +0000302 if (Config->ZNow)
303 ++NumEntries; // DT_FLAGS_1
Igor Kudrinb1f2b512015-10-05 10:29:46 +0000304
Rafael Espindola5805c4f2015-09-21 21:38:08 +0000305 ++NumEntries; // DT_NULL
306
307 Header.sh_size = NumEntries * Header.sh_entsize;
308}
309
310template <class ELFT> void DynamicSection<ELFT>::writeTo(uint8_t *Buf) {
Rafael Espindola5805c4f2015-09-21 21:38:08 +0000311 auto *P = reinterpret_cast<Elf_Dyn *>(Buf);
312
Rui Ueyama8c205d52015-10-02 01:33:31 +0000313 auto WritePtr = [&](int32_t Tag, uint64_t Val) {
314 P->d_tag = Tag;
315 P->d_un.d_ptr = Val;
316 ++P;
317 };
318
319 auto WriteVal = [&](int32_t Tag, uint32_t Val) {
320 P->d_tag = Tag;
321 P->d_un.d_val = Val;
322 ++P;
323 };
324
Rafael Espindola5805c4f2015-09-21 21:38:08 +0000325 if (RelaDynSec.hasRelocs()) {
326 bool IsRela = RelaDynSec.isRela();
Rui Ueyama8c205d52015-10-02 01:33:31 +0000327 WritePtr(IsRela ? DT_RELA : DT_REL, RelaDynSec.getVA());
328 WriteVal(IsRela ? DT_RELASZ : DT_RELSZ, RelaDynSec.getSize());
329 WriteVal(IsRela ? DT_RELAENT : DT_RELENT,
330 IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel));
Rafael Espindola5805c4f2015-09-21 21:38:08 +0000331 }
332
Rui Ueyama8c205d52015-10-02 01:33:31 +0000333 WritePtr(DT_SYMTAB, DynSymSec.getVA());
334 WritePtr(DT_SYMENT, sizeof(Elf_Sym));
335 WritePtr(DT_STRTAB, DynStrSec.getVA());
336 WriteVal(DT_STRSZ, DynStrSec.data().size());
337 WritePtr(DT_HASH, HashSec.getVA());
Rafael Espindola5805c4f2015-09-21 21:38:08 +0000338
Rui Ueyama8c205d52015-10-02 01:33:31 +0000339 if (!Config->RPath.empty())
Davide Italianoc39c75d2015-10-06 16:20:00 +0000340
341 // If --enable-new-dtags is set lld emits DT_RUNPATH
342 // instead of DT_RPATH. The two tags are functionally
343 // equivalent except for the following:
344 // - DT_RUNPATH is searched after LD_LIBRARY_PATH, while
345 // DT_RPATH is searched before.
346 // - DT_RUNPATH is used only to search for direct
347 // dependencies of the object it's contained in, while
348 // DT_RPATH is used for indirect dependencies as well.
349 WriteVal(Config->EnableNewDtags ? DT_RUNPATH : DT_RPATH,
350 DynStrSec.getFileOff(Config->RPath));
Rui Ueyama2dfd74f2015-09-30 21:57:53 +0000351
Rui Ueyama8c205d52015-10-02 01:33:31 +0000352 if (!Config->SoName.empty())
353 WriteVal(DT_SONAME, DynStrSec.getFileOff(Config->SoName));
Rafael Espindola5805c4f2015-09-21 21:38:08 +0000354
Rafael Espindola77572242015-10-02 19:37:55 +0000355 auto WriteArray = [&](int32_t T1, int32_t T2,
356 const OutputSection<ELFT> *Sec) {
357 if (!Sec)
358 return;
359 WritePtr(T1, Sec->getVA());
360 WriteVal(T2, Sec->getSize());
361 };
362 WriteArray(DT_PREINIT_ARRAY, DT_PREINIT_ARRAYSZ, PreInitArraySec);
363 WriteArray(DT_INIT_ARRAY, DT_INIT_ARRAYSZ, InitArraySec);
364 WriteArray(DT_FINI_ARRAY, DT_FINI_ARRAYSZ, FiniArraySec);
365
Rafael Espindola5805c4f2015-09-21 21:38:08 +0000366 const std::vector<std::unique_ptr<SharedFileBase>> &SharedFiles =
367 SymTab.getSharedFiles();
Rui Ueyama8c205d52015-10-02 01:33:31 +0000368 for (const std::unique_ptr<SharedFileBase> &File : SharedFiles)
369 WriteVal(DT_NEEDED, DynStrSec.getFileOff(File->getSoName()));
Rafael Espindola5805c4f2015-09-21 21:38:08 +0000370
Igor Kudrinb1f2b512015-10-05 10:29:46 +0000371 if (InitSym)
372 WritePtr(DT_INIT, getSymVA(*InitSym, BssSec));
373 if (FiniSym)
374 WritePtr(DT_FINI, getSymVA(*FiniSym, BssSec));
375
George Rimar97aad172015-10-07 15:00:21 +0000376 if (Config->ZNow)
377 WriteVal(DT_FLAGS_1, DF_1_NOW);
378
Rui Ueyama8c205d52015-10-02 01:33:31 +0000379 WriteVal(DT_NULL, 0);
Rafael Espindola5805c4f2015-09-21 21:38:08 +0000380}
381
382template <class ELFT>
Rafael Espindola35c6af32015-09-25 17:19:10 +0000383OutputSection<ELFT>::OutputSection(const PltSection<ELFT> &PltSec,
384 const GotSection<ELFT> &GotSec,
385 const OutputSection<ELFT> &BssSec,
386 StringRef Name, uint32_t sh_type,
387 uintX_t sh_flags)
388 : OutputSectionBase<ELFT::Is64Bits>(Name, sh_type, sh_flags),
389 PltSec(PltSec), GotSec(GotSec), BssSec(BssSec) {}
390
391template <class ELFT>
Rafael Espindola71675852015-09-22 00:16:19 +0000392void OutputSection<ELFT>::addSection(InputSection<ELFT> *C) {
393 Sections.push_back(C);
Rafael Espindola5805c4f2015-09-21 21:38:08 +0000394 C->setOutputSection(this);
395 uint32_t Align = C->getAlign();
396 if (Align > this->Header.sh_addralign)
397 this->Header.sh_addralign = Align;
398
399 uintX_t Off = this->Header.sh_size;
400 Off = RoundUpToAlignment(Off, Align);
401 C->setOutputSectionOff(Off);
402 Off += C->getSize();
403 this->Header.sh_size = Off;
404}
405
406template <class ELFT>
Rafael Espindola5805c4f2015-09-21 21:38:08 +0000407typename ELFFile<ELFT>::uintX_t
Rafael Espindola8614c562015-10-06 14:33:58 +0000408lld::elf2::getSymVA(const SymbolBody &S, const OutputSection<ELFT> &BssSec) {
Rafael Espindolacd076f02015-09-25 18:19:03 +0000409 switch (S.kind()) {
Rafael Espindola8614c562015-10-06 14:33:58 +0000410 case SymbolBody::DefinedSyntheticKind: {
411 auto &D = cast<DefinedSynthetic<ELFT>>(S);
412 return D.Section.getVA() + D.Sym.st_value;
413 }
Rafael Espindolacd076f02015-09-25 18:19:03 +0000414 case SymbolBody::DefinedAbsoluteKind:
Rafael Espindola8614c562015-10-06 14:33:58 +0000415 return cast<DefinedAbsolute<ELFT>>(S).Sym.st_value;
Rafael Espindolacd076f02015-09-25 18:19:03 +0000416 case SymbolBody::DefinedRegularKind: {
417 const auto &DR = cast<DefinedRegular<ELFT>>(S);
418 const InputSection<ELFT> *SC = &DR.Section;
419 OutputSection<ELFT> *OS = SC->getOutputSection();
420 return OS->getVA() + SC->getOutputSectionOff() + DR.Sym.st_value;
421 }
422 case SymbolBody::DefinedCommonKind:
423 return BssSec.getVA() + cast<DefinedCommon<ELFT>>(S).OffsetInBSS;
424 case SymbolBody::SharedKind:
425 case SymbolBody::UndefinedKind:
426 return 0;
427 case SymbolBody::LazyKind:
Rafael Espindola8614c562015-10-06 14:33:58 +0000428 assert(S.isUsedInRegularObj() && "Lazy symbol reached writer");
429 return 0;
Rafael Espindolacd076f02015-09-25 18:19:03 +0000430 }
Denis Protivensky92aa1c02015-10-07 08:21:34 +0000431 llvm_unreachable("Invalid symbol kind");
Rafael Espindola5805c4f2015-09-21 21:38:08 +0000432}
433
434template <class ELFT>
435typename ELFFile<ELFT>::uintX_t
436lld::elf2::getLocalSymVA(const typename ELFFile<ELFT>::Elf_Sym *Sym,
437 const ObjectFile<ELFT> &File) {
438 uint32_t SecIndex = Sym->st_shndx;
439
440 if (SecIndex == SHN_XINDEX)
Rafael Espindolae1901cc2015-09-24 15:11:50 +0000441 SecIndex = File.getObj().getExtendedSymbolTableIndex(
Rafael Espindola5805c4f2015-09-21 21:38:08 +0000442 Sym, File.getSymbolTable(), File.getSymbolTableShndx());
Rafael Espindola71675852015-09-22 00:16:19 +0000443 ArrayRef<InputSection<ELFT> *> Sections = File.getSections();
444 InputSection<ELFT> *Section = Sections[SecIndex];
Rui Ueyamab4908762015-10-07 17:04:18 +0000445 OutputSection<ELFT> *OutSec = Section->getOutputSection();
446 return OutSec->getVA() + Section->getOutputSectionOff() + Sym->st_value;
Rafael Espindola5805c4f2015-09-21 21:38:08 +0000447}
448
Rafael Espindolaa6627382015-10-06 23:56:53 +0000449bool lld::elf2::canBePreempted(const SymbolBody *Body) {
450 if (!Body)
451 return false;
Rafael Espindolacea0b3b2015-10-07 04:22:55 +0000452 if (Body->isShared())
453 return true;
454 if (Body->isUndefined() && !Body->isWeak())
Rafael Espindolaa6627382015-10-06 23:56:53 +0000455 return true;
456 if (!Config->Shared)
457 return false;
Rafael Espindola52dca342015-10-07 00:58:20 +0000458 return Body->getMostConstrainingVisibility() == STV_DEFAULT;
Rafael Espindolaa6627382015-10-06 23:56:53 +0000459}
460
Rafael Espindola5805c4f2015-09-21 21:38:08 +0000461template <class ELFT> void OutputSection<ELFT>::writeTo(uint8_t *Buf) {
Rafael Espindola71675852015-09-22 00:16:19 +0000462 for (InputSection<ELFT> *C : Sections)
Rafael Espindolac2d21192015-09-23 18:25:05 +0000463 C->writeTo(Buf, BssSec, PltSec, GotSec);
Rafael Espindola5805c4f2015-09-21 21:38:08 +0000464}
465
466template <bool Is64Bits>
Rafael Espindola35c6af32015-09-25 17:19:10 +0000467StringTableSection<Is64Bits>::StringTableSection(bool Dynamic)
468 : OutputSectionBase<Is64Bits>(Dynamic ? ".dynstr" : ".strtab",
469 llvm::ELF::SHT_STRTAB,
470 Dynamic ? (uintX_t)llvm::ELF::SHF_ALLOC : 0),
471 Dynamic(Dynamic) {
472 this->Header.sh_addralign = 1;
473}
474
475template <bool Is64Bits>
Rafael Espindola5805c4f2015-09-21 21:38:08 +0000476void StringTableSection<Is64Bits>::writeTo(uint8_t *Buf) {
477 StringRef Data = StrTabBuilder.data();
478 memcpy(Buf, Data.data(), Data.size());
479}
480
Rafael Espindola4f674ed2015-10-05 15:24:04 +0000481template <class ELFT> bool lld::elf2::includeInSymtab(const SymbolBody &B) {
Rafael Espindola5805c4f2015-09-21 21:38:08 +0000482 if (!B.isUsedInRegularObj())
483 return false;
Rafael Espindola4f674ed2015-10-05 15:24:04 +0000484
485 // Don't include synthetic symbols like __init_array_start in every output.
486 if (auto *U = dyn_cast<DefinedAbsolute<ELFT>>(&B))
487 if (&U->Sym == &DefinedAbsolute<ELFT>::IgnoreUndef)
488 return false;
489
Rafael Espindola5805c4f2015-09-21 21:38:08 +0000490 return true;
491}
492
Rafael Espindola05a3dd22015-09-22 23:38:23 +0000493bool lld::elf2::includeInDynamicSymtab(const SymbolBody &B) {
Rafael Espindola4f674ed2015-10-05 15:24:04 +0000494 uint8_t V = B.getMostConstrainingVisibility();
495 if (V != STV_DEFAULT && V != STV_PROTECTED)
496 return false;
497
Rafael Espindola05a3dd22015-09-22 23:38:23 +0000498 if (Config->ExportDynamic || Config->Shared)
499 return true;
500 return B.isUsedInDynamicReloc();
501}
502
Rafael Espindolad1cf4212015-10-05 16:25:43 +0000503template <class ELFT>
504bool lld::elf2::shouldKeepInSymtab(StringRef SymName,
505 const typename ELFFile<ELFT>::Elf_Sym &Sym) {
506 if (Sym.getType() == STT_SECTION)
507 return false;
508
Davide Italiano6993ba42015-09-26 00:47:56 +0000509 if (Config->DiscardNone)
510 return true;
511
512 // ELF defines dynamic locals as symbols which name starts with ".L".
513 return !(Config->DiscardLocals && SymName.startswith(".L"));
514}
515
Rafael Espindola35c6af32015-09-25 17:19:10 +0000516template <class ELFT>
517SymbolTableSection<ELFT>::SymbolTableSection(
518 SymbolTable &Table, StringTableSection<ELFT::Is64Bits> &StrTabSec,
519 const OutputSection<ELFT> &BssSec)
520 : OutputSectionBase<ELFT::Is64Bits>(
521 StrTabSec.isDynamic() ? ".dynsym" : ".symtab",
522 StrTabSec.isDynamic() ? llvm::ELF::SHT_DYNSYM : llvm::ELF::SHT_SYMTAB,
523 StrTabSec.isDynamic() ? (uintX_t)llvm::ELF::SHF_ALLOC : 0),
524 Table(Table), StrTabSec(StrTabSec), BssSec(BssSec) {
525 typedef OutputSectionBase<ELFT::Is64Bits> Base;
526 typename Base::HeaderT &Header = this->Header;
527
528 Header.sh_entsize = sizeof(Elf_Sym);
529 Header.sh_addralign = ELFT::Is64Bits ? 8 : 4;
530}
531
Rui Ueyama0db335f2015-10-07 16:58:54 +0000532template <class ELFT> void SymbolTableSection<ELFT>::finalize() {
533 this->Header.sh_size = getNumSymbols() * sizeof(Elf_Sym);
534 this->Header.sh_link = StrTabSec.getSectionIndex();
535 this->Header.sh_info = NumLocals + 1;
536}
537
538template <class ELFT>
539void SymbolTableSection<ELFT>::addSymbol(StringRef Name, bool isLocal) {
540 StrTabSec.add(Name);
541 ++NumVisible;
542 if (isLocal)
543 ++NumLocals;
544}
545
Rafael Espindola5805c4f2015-09-21 21:38:08 +0000546template <class ELFT> void SymbolTableSection<ELFT>::writeTo(uint8_t *Buf) {
Rafael Espindola5805c4f2015-09-21 21:38:08 +0000547 Buf += sizeof(Elf_Sym);
548
549 // All symbols with STB_LOCAL binding precede the weak and global symbols.
550 // .dynsym only contains global symbols.
Rui Ueyama8ddfa812015-09-30 00:32:10 +0000551 if (!Config->DiscardAll && !StrTabSec.isDynamic())
552 writeLocalSymbols(Buf);
553
554 writeGlobalSymbols(Buf);
555}
556
557template <class ELFT>
558void SymbolTableSection<ELFT>::writeLocalSymbols(uint8_t *&Buf) {
559 // Iterate over all input object files to copy their local symbols
560 // to the output symbol table pointed by Buf.
561 for (const std::unique_ptr<ObjectFileBase> &FileB : Table.getObjectFiles()) {
562 auto &File = cast<ObjectFile<ELFT>>(*FileB);
563 Elf_Sym_Range Syms = File.getLocalSymbols();
564 for (const Elf_Sym &Sym : Syms) {
Rui Ueyama8ddfa812015-09-30 00:32:10 +0000565 ErrorOr<StringRef> SymName = Sym.getName(File.getStringTable());
Rafael Espindolad1cf4212015-10-05 16:25:43 +0000566 if (SymName && !shouldKeepInSymtab<ELFT>(*SymName, Sym))
Rui Ueyama8ddfa812015-09-30 00:32:10 +0000567 continue;
Rui Ueyamac55733e2015-09-30 00:54:29 +0000568 auto *ESym = reinterpret_cast<Elf_Sym *>(Buf);
569 Buf += sizeof(*ESym);
Rui Ueyama8ddfa812015-09-30 00:32:10 +0000570 ESym->st_name = (SymName) ? StrTabSec.getFileOff(*SymName) : 0;
571 ESym->st_size = Sym.st_size;
572 ESym->setBindingAndType(Sym.getBinding(), Sym.getType());
573 uint32_t SecIndex = Sym.st_shndx;
574 uintX_t VA = Sym.st_value;
575 if (SecIndex == SHN_ABS) {
576 ESym->st_shndx = SHN_ABS;
577 } else {
578 if (SecIndex == SHN_XINDEX)
579 SecIndex = File.getObj().getExtendedSymbolTableIndex(
580 &Sym, File.getSymbolTable(), File.getSymbolTableShndx());
581 ArrayRef<InputSection<ELFT> *> Sections = File.getSections();
582 const InputSection<ELFT> *Section = Sections[SecIndex];
Rui Ueyamab4908762015-10-07 17:04:18 +0000583 const OutputSection<ELFT> *OutSec = Section->getOutputSection();
584 ESym->st_shndx = OutSec->getSectionIndex();
585 VA += OutSec->getVA() + Section->getOutputSectionOff();
Rafael Espindola5805c4f2015-09-21 21:38:08 +0000586 }
Rui Ueyama8ddfa812015-09-30 00:32:10 +0000587 ESym->st_value = VA;
Rafael Espindola5805c4f2015-09-21 21:38:08 +0000588 }
589 }
Rui Ueyama8ddfa812015-09-30 00:32:10 +0000590}
Rafael Espindola5805c4f2015-09-21 21:38:08 +0000591
Rui Ueyama8ddfa812015-09-30 00:32:10 +0000592template <class ELFT>
593void SymbolTableSection<ELFT>::writeGlobalSymbols(uint8_t *&Buf) {
594 // Write the internal symbol table contents to the output symbol table
595 // pointed by Buf.
Rafael Espindola4f674ed2015-10-05 15:24:04 +0000596 uint8_t *Start = Buf;
Rui Ueyama8ddfa812015-09-30 00:32:10 +0000597 for (const std::pair<StringRef, Symbol *> &P : Table.getSymbols()) {
Rafael Espindola5805c4f2015-09-21 21:38:08 +0000598 StringRef Name = P.first;
599 Symbol *Sym = P.second;
600 SymbolBody *Body = Sym->Body;
Rafael Espindola4f674ed2015-10-05 15:24:04 +0000601 if (!includeInSymtab<ELFT>(*Body))
Rafael Espindola5805c4f2015-09-21 21:38:08 +0000602 continue;
Rafael Espindola05a3dd22015-09-22 23:38:23 +0000603 if (StrTabSec.isDynamic() && !includeInDynamicSymtab(*Body))
604 continue;
Rafael Espindola5805c4f2015-09-21 21:38:08 +0000605
606 auto *ESym = reinterpret_cast<Elf_Sym *>(Buf);
Rui Ueyamac55733e2015-09-30 00:54:29 +0000607 Buf += sizeof(*ESym);
Rafael Espindola8614c562015-10-06 14:33:58 +0000608
Rafael Espindola5805c4f2015-09-21 21:38:08 +0000609 ESym->st_name = StrTabSec.getFileOff(Name);
610
Rui Ueyamab4908762015-10-07 17:04:18 +0000611 const OutputSection<ELFT> *OutSec = nullptr;
Rafael Espindola25b0acb2015-09-25 17:32:37 +0000612 const InputSection<ELFT> *Section = nullptr;
Rafael Espindola5805c4f2015-09-21 21:38:08 +0000613
Rafael Espindola8614c562015-10-06 14:33:58 +0000614 switch (Body->kind()) {
Rafael Espindola0e604f92015-09-25 18:56:53 +0000615 case SymbolBody::DefinedSyntheticKind:
Rui Ueyamab4908762015-10-07 17:04:18 +0000616 OutSec = &cast<DefinedSynthetic<ELFT>>(Body)->Section;
Rafael Espindola0e604f92015-09-25 18:56:53 +0000617 break;
Rafael Espindola5805c4f2015-09-21 21:38:08 +0000618 case SymbolBody::DefinedRegularKind:
Rafael Espindola8614c562015-10-06 14:33:58 +0000619 Section = &cast<DefinedRegular<ELFT>>(Body)->Section;
Rafael Espindola5805c4f2015-09-21 21:38:08 +0000620 break;
621 case SymbolBody::DefinedCommonKind:
Rui Ueyamab4908762015-10-07 17:04:18 +0000622 OutSec = &BssSec;
Rafael Espindola5805c4f2015-09-21 21:38:08 +0000623 break;
624 case SymbolBody::UndefinedKind:
625 case SymbolBody::DefinedAbsoluteKind:
626 case SymbolBody::SharedKind:
Rafael Espindola5805c4f2015-09-21 21:38:08 +0000627 case SymbolBody::LazyKind:
Rafael Espindola8614c562015-10-06 14:33:58 +0000628 break;
Rafael Espindola5805c4f2015-09-21 21:38:08 +0000629 }
630
Rafael Espindola8614c562015-10-06 14:33:58 +0000631 unsigned char Binding = Body->isWeak() ? STB_WEAK : STB_GLOBAL;
632 unsigned char Type = STT_NOTYPE;
633 uintX_t Size = 0;
634 if (const auto *EBody = dyn_cast<ELFSymbolBody<ELFT>>(Body)) {
635 const Elf_Sym &InputSym = EBody->Sym;
636 Binding = InputSym.getBinding();
637 Type = InputSym.getType();
638 Size = InputSym.st_size;
639 }
640
641 unsigned char Visibility = Body->getMostConstrainingVisibility();
Rafael Espindola4f674ed2015-10-05 15:24:04 +0000642 if (Visibility != STV_DEFAULT && Visibility != STV_PROTECTED)
643 Binding = STB_LOCAL;
644
Rafael Espindola8614c562015-10-06 14:33:58 +0000645 ESym->setBindingAndType(Binding, Type);
646 ESym->st_size = Size;
Rafael Espindola4f674ed2015-10-05 15:24:04 +0000647 ESym->setVisibility(Visibility);
Rafael Espindola8614c562015-10-06 14:33:58 +0000648 ESym->st_value = getSymVA(*Body, BssSec);
Rafael Espindola5805c4f2015-09-21 21:38:08 +0000649
650 if (Section)
Rui Ueyamab4908762015-10-07 17:04:18 +0000651 OutSec = Section->getOutputSection();
Rafael Espindola5805c4f2015-09-21 21:38:08 +0000652
Rafael Espindola8614c562015-10-06 14:33:58 +0000653 if (isa<DefinedAbsolute<ELFT>>(Body))
Rafael Espindola6f4bd532015-10-06 14:17:53 +0000654 ESym->st_shndx = SHN_ABS;
Rui Ueyamab4908762015-10-07 17:04:18 +0000655 else if (OutSec)
656 ESym->st_shndx = OutSec->getSectionIndex();
Rafael Espindola5805c4f2015-09-21 21:38:08 +0000657 }
Rafael Espindola4f674ed2015-10-05 15:24:04 +0000658 if (!StrTabSec.isDynamic())
659 std::stable_sort(
660 reinterpret_cast<Elf_Sym *>(Start), reinterpret_cast<Elf_Sym *>(Buf),
661 [](const Elf_Sym &A, const Elf_Sym &B) -> bool {
662 return A.getBinding() == STB_LOCAL && B.getBinding() != STB_LOCAL;
663 });
Rafael Espindola5805c4f2015-09-21 21:38:08 +0000664}
665
666namespace lld {
667namespace elf2 {
668template class OutputSectionBase<false>;
669template class OutputSectionBase<true>;
670
671template void OutputSectionBase<false>::writeHeaderTo<support::little>(
Rafael Espindolaf68b7072015-09-21 22:21:46 +0000672 ELFFile<ELFType<support::little, false>>::Elf_Shdr *SHdr);
Rafael Espindola5805c4f2015-09-21 21:38:08 +0000673template void OutputSectionBase<true>::writeHeaderTo<support::little>(
Rafael Espindolaf68b7072015-09-21 22:21:46 +0000674 ELFFile<ELFType<support::little, true>>::Elf_Shdr *SHdr);
Rafael Espindola5805c4f2015-09-21 21:38:08 +0000675template void OutputSectionBase<false>::writeHeaderTo<support::big>(
Rafael Espindolaf68b7072015-09-21 22:21:46 +0000676 ELFFile<ELFType<support::big, false>>::Elf_Shdr *SHdr);
Rafael Espindola5805c4f2015-09-21 21:38:08 +0000677template void OutputSectionBase<true>::writeHeaderTo<support::big>(
Rafael Espindolaf68b7072015-09-21 22:21:46 +0000678 ELFFile<ELFType<support::big, true>>::Elf_Shdr *SHdr);
Rafael Espindola5805c4f2015-09-21 21:38:08 +0000679
680template class GotSection<ELF32LE>;
681template class GotSection<ELF32BE>;
682template class GotSection<ELF64LE>;
683template class GotSection<ELF64BE>;
684
685template class PltSection<ELF32LE>;
686template class PltSection<ELF32BE>;
687template class PltSection<ELF64LE>;
688template class PltSection<ELF64BE>;
689
690template class RelocationSection<ELF32LE>;
691template class RelocationSection<ELF32BE>;
692template class RelocationSection<ELF64LE>;
693template class RelocationSection<ELF64BE>;
694
695template class InterpSection<false>;
696template class InterpSection<true>;
697
698template class HashTableSection<ELF32LE>;
699template class HashTableSection<ELF32BE>;
700template class HashTableSection<ELF64LE>;
701template class HashTableSection<ELF64BE>;
702
703template class DynamicSection<ELF32LE>;
704template class DynamicSection<ELF32BE>;
705template class DynamicSection<ELF64LE>;
706template class DynamicSection<ELF64BE>;
707
708template class OutputSection<ELF32LE>;
709template class OutputSection<ELF32BE>;
710template class OutputSection<ELF64LE>;
711template class OutputSection<ELF64BE>;
712
713template class StringTableSection<false>;
714template class StringTableSection<true>;
715
716template class SymbolTableSection<ELF32LE>;
717template class SymbolTableSection<ELF32BE>;
718template class SymbolTableSection<ELF64LE>;
719template class SymbolTableSection<ELF64BE>;
720
Rafael Espindola8614c562015-10-06 14:33:58 +0000721template ELFFile<ELF32LE>::uintX_t getSymVA(const SymbolBody &,
722 const OutputSection<ELF32LE> &);
723template ELFFile<ELF32BE>::uintX_t getSymVA(const SymbolBody &,
724 const OutputSection<ELF32BE> &);
725template ELFFile<ELF64LE>::uintX_t getSymVA(const SymbolBody &,
726 const OutputSection<ELF64LE> &);
727template ELFFile<ELF64BE>::uintX_t getSymVA(const SymbolBody &,
728 const OutputSection<ELF64BE> &);
Rafael Espindola4ea00212015-09-21 22:01:00 +0000729
Rafael Espindola56f965f2015-09-21 22:48:12 +0000730template ELFFile<ELF32LE>::uintX_t
Rui Ueyamab189b5c2015-09-30 00:43:22 +0000731getLocalSymVA(const ELFFile<ELF32LE>::Elf_Sym *, const ObjectFile<ELF32LE> &);
Rafael Espindola4ea00212015-09-21 22:01:00 +0000732
Rafael Espindola56f965f2015-09-21 22:48:12 +0000733template ELFFile<ELF32BE>::uintX_t
Rui Ueyamab189b5c2015-09-30 00:43:22 +0000734getLocalSymVA(const ELFFile<ELF32BE>::Elf_Sym *, const ObjectFile<ELF32BE> &);
Rafael Espindola4ea00212015-09-21 22:01:00 +0000735
Rafael Espindola56f965f2015-09-21 22:48:12 +0000736template ELFFile<ELF64LE>::uintX_t
Rui Ueyamab189b5c2015-09-30 00:43:22 +0000737getLocalSymVA(const ELFFile<ELF64LE>::Elf_Sym *, const ObjectFile<ELF64LE> &);
Rafael Espindola4ea00212015-09-21 22:01:00 +0000738
Rafael Espindola56f965f2015-09-21 22:48:12 +0000739template ELFFile<ELF64BE>::uintX_t
Rui Ueyamab189b5c2015-09-30 00:43:22 +0000740getLocalSymVA(const ELFFile<ELF64BE>::Elf_Sym *, const ObjectFile<ELF64BE> &);
Rafael Espindola4f674ed2015-10-05 15:24:04 +0000741
742template bool includeInSymtab<ELF32LE>(const SymbolBody &);
743template bool includeInSymtab<ELF32BE>(const SymbolBody &);
744template bool includeInSymtab<ELF64LE>(const SymbolBody &);
745template bool includeInSymtab<ELF64BE>(const SymbolBody &);
Rafael Espindolad1cf4212015-10-05 16:25:43 +0000746
747template bool shouldKeepInSymtab<ELF32LE>(StringRef,
748 const ELFFile<ELF32LE>::Elf_Sym &);
749template bool shouldKeepInSymtab<ELF32BE>(StringRef,
750 const ELFFile<ELF32BE>::Elf_Sym &);
751template bool shouldKeepInSymtab<ELF64LE>(StringRef,
752 const ELFFile<ELF64LE>::Elf_Sym &);
753template bool shouldKeepInSymtab<ELF64BE>(StringRef,
754 const ELFFile<ELF64BE>::Elf_Sym &);
Rafael Espindola5805c4f2015-09-21 21:38:08 +0000755}
756}