blob: 9a8864df5ab100b996a24f05ebf4be0b03fa588e [file] [log] [blame]
Rui Ueyama6dc7fcb2016-11-01 20:28:21 +00001//===- SyntheticSections.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// This file contains linker-synthesized sections. Currently,
11// synthetic sections are created either output sections or input sections,
12// but we are rewriting code so that all synthetic sections are created as
13// input sections.
14//
15//===----------------------------------------------------------------------===//
16
17#include "SyntheticSections.h"
18#include "Config.h"
19#include "Error.h"
20#include "InputFiles.h"
Rui Ueyamae288eef2016-11-02 18:58:44 +000021#include "Memory.h"
Rui Ueyama6dc7fcb2016-11-01 20:28:21 +000022#include "OutputSections.h"
23#include "Strings.h"
Rui Ueyamae8a61022016-11-05 23:05:47 +000024#include "SymbolTable.h"
Rui Ueyama6dc7fcb2016-11-01 20:28:21 +000025
George Rimar364b59e22016-11-06 07:42:55 +000026#include "lld/Core/Parallel.h"
Rui Ueyama6dc7fcb2016-11-01 20:28:21 +000027#include "llvm/Support/Endian.h"
28#include "llvm/Support/MD5.h"
29#include "llvm/Support/RandomNumberGenerator.h"
30#include "llvm/Support/SHA1.h"
31#include "llvm/Support/xxhash.h"
32
33using namespace llvm;
34using namespace llvm::ELF;
35using namespace llvm::object;
36using namespace llvm::support;
37using namespace llvm::support::endian;
38
39using namespace lld;
40using namespace lld::elf;
41
Rui Ueyamae8a61022016-11-05 23:05:47 +000042template <class ELFT> static std::vector<DefinedCommon *> getCommonSymbols() {
43 std::vector<DefinedCommon *> V;
44 for (Symbol *S : Symtab<ELFT>::X->getSymbols())
45 if (auto *B = dyn_cast<DefinedCommon>(S->body()))
46 V.push_back(B);
47 return V;
48}
49
50// Find all common symbols and allocate space for them.
Rafael Espindola682a5bc2016-11-08 14:42:34 +000051template <class ELFT> InputSection<ELFT> *elf::createCommonSection() {
52 auto *Ret = make<InputSection<ELFT>>(SHF_ALLOC | SHF_WRITE, SHT_NOBITS, 1,
53 ArrayRef<uint8_t>(), "COMMON");
54 Ret->Live = true;
Rui Ueyamae8a61022016-11-05 23:05:47 +000055
56 // Sort the common symbols by alignment as an heuristic to pack them better.
57 std::vector<DefinedCommon *> Syms = getCommonSymbols<ELFT>();
58 std::stable_sort(Syms.begin(), Syms.end(),
59 [](const DefinedCommon *A, const DefinedCommon *B) {
60 return A->Alignment > B->Alignment;
61 });
62
63 // Assign offsets to symbols.
64 size_t Size = 0;
65 size_t Alignment = 1;
66 for (DefinedCommon *Sym : Syms) {
Rui Ueyama1c786822016-11-05 23:14:54 +000067 Alignment = std::max<size_t>(Alignment, Sym->Alignment);
Rui Ueyamae8a61022016-11-05 23:05:47 +000068 Size = alignTo(Size, Sym->Alignment);
69
70 // Compute symbol offset relative to beginning of input section.
71 Sym->Offset = Size;
72 Size += Sym->Size;
73 }
Rafael Espindola682a5bc2016-11-08 14:42:34 +000074 Ret->Alignment = Alignment;
75 Ret->Data = makeArrayRef<uint8_t>(nullptr, Size);
76 return Ret;
Rui Ueyamae8a61022016-11-05 23:05:47 +000077}
78
Rui Ueyamae288eef2016-11-02 18:58:44 +000079static ArrayRef<uint8_t> createInterp() {
80 // StringSaver guarantees that the returned string ends with '\0'.
81 StringRef S = Saver.save(Config->DynamicLinker);
Rui Ueyama6294a242016-11-04 17:41:29 +000082 return {(const uint8_t *)S.data(), S.size() + 1};
Rui Ueyamae288eef2016-11-02 18:58:44 +000083}
84
Rafael Espindolac0e47fb2016-11-08 14:56:27 +000085template <class ELFT> InputSection<ELFT> *elf::createInterpSection() {
86 auto *Ret = make<InputSection<ELFT>>(SHF_ALLOC, SHT_PROGBITS, 1,
87 createInterp(), ".interp");
88 Ret->Live = true;
89 return Ret;
Rui Ueyamaa9ee8d62016-11-04 22:25:39 +000090}
Rui Ueyamae288eef2016-11-02 18:58:44 +000091
Rui Ueyama6dc7fcb2016-11-01 20:28:21 +000092template <class ELFT>
93BuildIdSection<ELFT>::BuildIdSection(size_t HashSize)
94 : InputSection<ELFT>(SHF_ALLOC, SHT_NOTE, 1, ArrayRef<uint8_t>(),
George Rimar364b59e22016-11-06 07:42:55 +000095 ".note.gnu.build-id"),
96 HashSize(HashSize) {
Rui Ueyamaa9ee8d62016-11-04 22:25:39 +000097 this->Live = true;
98
Rafael Espindola1a541122016-11-08 14:47:16 +000099 Buf.resize(16 + HashSize);
Rui Ueyama6dc7fcb2016-11-01 20:28:21 +0000100 const endianness E = ELFT::TargetEndianness;
Rafael Espindola1a541122016-11-08 14:47:16 +0000101 write32<E>(Buf.data(), 4); // Name size
102 write32<E>(Buf.data() + 4, HashSize); // Content size
103 write32<E>(Buf.data() + 8, NT_GNU_BUILD_ID); // Type
104 memcpy(Buf.data() + 12, "GNU", 4); // Name string
105 this->Data = ArrayRef<uint8_t>(Buf);
Rui Ueyama6dc7fcb2016-11-01 20:28:21 +0000106}
107
108template <class ELFT>
109uint8_t *BuildIdSection<ELFT>::getOutputLoc(uint8_t *Start) const {
Rafael Espindola04a2e342016-11-09 01:42:41 +0000110 return Start + this->OutSec->Offset + this->OutSecOff;
Rui Ueyama6dc7fcb2016-11-01 20:28:21 +0000111}
112
George Rimar364b59e22016-11-06 07:42:55 +0000113static std::vector<ArrayRef<uint8_t>> split(ArrayRef<uint8_t> Arr,
114 size_t ChunkSize) {
115 std::vector<ArrayRef<uint8_t>> Ret;
116 while (Arr.size() > ChunkSize) {
117 Ret.push_back(Arr.take_front(ChunkSize));
118 Arr = Arr.drop_front(ChunkSize);
119 }
120 if (!Arr.empty())
121 Ret.push_back(Arr);
122 return Ret;
123}
124
125template <class ELFT>
126void BuildIdSection<ELFT>::computeHash(
George Rimar828787a2016-11-06 08:39:46 +0000127 llvm::MutableArrayRef<uint8_t> Data,
George Rimar364b59e22016-11-06 07:42:55 +0000128 std::function<void(ArrayRef<uint8_t> Arr, uint8_t *Hash)> Hash) {
129 std::vector<ArrayRef<uint8_t>> Chunks = split(Data, 1024 * 1024);
130 std::vector<uint8_t> HashList(Chunks.size() * HashSize);
131
132 if (Config->Threads)
133 parallel_for_each(Chunks.begin(), Chunks.end(),
134 [&](ArrayRef<uint8_t> &Chunk) {
135 size_t Id = &Chunk - Chunks.data();
136 Hash(Chunk, HashList.data() + Id * HashSize);
137 });
138 else
139 std::for_each(Chunks.begin(), Chunks.end(), [&](ArrayRef<uint8_t> &Chunk) {
140 size_t Id = &Chunk - Chunks.data();
141 Hash(Chunk, HashList.data() + Id * HashSize);
142 });
143
George Rimar828787a2016-11-06 08:39:46 +0000144 Hash(HashList, this->getOutputLoc(Data.begin()) + 16);
George Rimar364b59e22016-11-06 07:42:55 +0000145}
146
Rui Ueyama6dc7fcb2016-11-01 20:28:21 +0000147template <class ELFT>
148void BuildIdFastHash<ELFT>::writeBuildId(MutableArrayRef<uint8_t> Buf) {
George Rimar50209712016-11-06 08:26:53 +0000149 this->computeHash(Buf, [](ArrayRef<uint8_t> Arr, uint8_t *Dest) {
George Rimar364b59e22016-11-06 07:42:55 +0000150 uint64_t Hash = xxHash64(toStringRef(Arr));
151 write64<ELFT::TargetEndianness>(Dest, Hash);
152 });
Rui Ueyama6dc7fcb2016-11-01 20:28:21 +0000153}
154
155template <class ELFT>
156void BuildIdMd5<ELFT>::writeBuildId(MutableArrayRef<uint8_t> Buf) {
George Rimar50209712016-11-06 08:26:53 +0000157 this->computeHash(Buf, [&](ArrayRef<uint8_t> Arr, uint8_t *Dest) {
George Rimar364b59e22016-11-06 07:42:55 +0000158 MD5 Hash;
159 Hash.update(Arr);
160 MD5::MD5Result Res;
161 Hash.final(Res);
George Rimar50209712016-11-06 08:26:53 +0000162 memcpy(Dest, Res, this->HashSize);
George Rimar364b59e22016-11-06 07:42:55 +0000163 });
Rui Ueyama6dc7fcb2016-11-01 20:28:21 +0000164}
165
166template <class ELFT>
167void BuildIdSha1<ELFT>::writeBuildId(MutableArrayRef<uint8_t> Buf) {
George Rimar50209712016-11-06 08:26:53 +0000168 this->computeHash(Buf, [&](ArrayRef<uint8_t> Arr, uint8_t *Dest) {
George Rimar364b59e22016-11-06 07:42:55 +0000169 SHA1 Hash;
170 Hash.update(Arr);
George Rimar50209712016-11-06 08:26:53 +0000171 memcpy(Dest, Hash.final().data(), this->HashSize);
George Rimar364b59e22016-11-06 07:42:55 +0000172 });
Rui Ueyama6dc7fcb2016-11-01 20:28:21 +0000173}
174
175template <class ELFT>
176void BuildIdUuid<ELFT>::writeBuildId(MutableArrayRef<uint8_t> Buf) {
177 if (getRandomBytes(this->getOutputLoc(Buf.begin()) + 16, 16))
178 error("entropy source failure");
179}
180
181template <class ELFT>
182BuildIdHexstring<ELFT>::BuildIdHexstring()
183 : BuildIdSection<ELFT>(Config->BuildIdVector.size()) {}
184
185template <class ELFT>
186void BuildIdHexstring<ELFT>::writeBuildId(MutableArrayRef<uint8_t> Buf) {
187 memcpy(this->getOutputLoc(Buf.begin()) + 16, Config->BuildIdVector.data(),
188 Config->BuildIdVector.size());
189}
190
Rafael Espindola682a5bc2016-11-08 14:42:34 +0000191template InputSection<ELF32LE> *elf::createCommonSection();
192template InputSection<ELF32BE> *elf::createCommonSection();
193template InputSection<ELF64LE> *elf::createCommonSection();
194template InputSection<ELF64BE> *elf::createCommonSection();
Rui Ueyamae8a61022016-11-05 23:05:47 +0000195
Rafael Espindolac0e47fb2016-11-08 14:56:27 +0000196template InputSection<ELF32LE> *elf::createInterpSection();
197template InputSection<ELF32BE> *elf::createInterpSection();
198template InputSection<ELF64LE> *elf::createInterpSection();
199template InputSection<ELF64BE> *elf::createInterpSection();
Rui Ueyamae288eef2016-11-02 18:58:44 +0000200
Rui Ueyama6dc7fcb2016-11-01 20:28:21 +0000201template class elf::BuildIdSection<ELF32LE>;
202template class elf::BuildIdSection<ELF32BE>;
203template class elf::BuildIdSection<ELF64LE>;
204template class elf::BuildIdSection<ELF64BE>;
205
206template class elf::BuildIdFastHash<ELF32LE>;
207template class elf::BuildIdFastHash<ELF32BE>;
208template class elf::BuildIdFastHash<ELF64LE>;
209template class elf::BuildIdFastHash<ELF64BE>;
210
211template class elf::BuildIdMd5<ELF32LE>;
212template class elf::BuildIdMd5<ELF32BE>;
213template class elf::BuildIdMd5<ELF64LE>;
214template class elf::BuildIdMd5<ELF64BE>;
215
216template class elf::BuildIdSha1<ELF32LE>;
217template class elf::BuildIdSha1<ELF32BE>;
218template class elf::BuildIdSha1<ELF64LE>;
219template class elf::BuildIdSha1<ELF64BE>;
220
221template class elf::BuildIdUuid<ELF32LE>;
222template class elf::BuildIdUuid<ELF32BE>;
223template class elf::BuildIdUuid<ELF64LE>;
224template class elf::BuildIdUuid<ELF64BE>;
225
226template class elf::BuildIdHexstring<ELF32LE>;
227template class elf::BuildIdHexstring<ELF32BE>;
228template class elf::BuildIdHexstring<ELF64LE>;
229template class elf::BuildIdHexstring<ELF64BE>;