Rui Ueyama | 6dc7fcb | 2016-11-01 20:28:21 +0000 | [diff] [blame] | 1 | //===- 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 Ueyama | e288eef | 2016-11-02 18:58:44 +0000 | [diff] [blame] | 21 | #include "Memory.h" |
Rui Ueyama | 6dc7fcb | 2016-11-01 20:28:21 +0000 | [diff] [blame] | 22 | #include "OutputSections.h" |
| 23 | #include "Strings.h" |
Rui Ueyama | e8a6102 | 2016-11-05 23:05:47 +0000 | [diff] [blame] | 24 | #include "SymbolTable.h" |
Simon Atanasyan | ce02cf0 | 2016-11-09 21:36:56 +0000 | [diff] [blame] | 25 | #include "Target.h" |
Simon Atanasyan | fa03b0f | 2016-11-09 21:37:06 +0000 | [diff] [blame] | 26 | #include "Writer.h" |
Rui Ueyama | 6dc7fcb | 2016-11-01 20:28:21 +0000 | [diff] [blame] | 27 | |
Rui Ueyama | 3da3f06 | 2016-11-10 20:20:37 +0000 | [diff] [blame] | 28 | #include "lld/Config/Version.h" |
George Rimar | 364b59e2 | 2016-11-06 07:42:55 +0000 | [diff] [blame] | 29 | #include "lld/Core/Parallel.h" |
Rui Ueyama | 6dc7fcb | 2016-11-01 20:28:21 +0000 | [diff] [blame] | 30 | #include "llvm/Support/Endian.h" |
| 31 | #include "llvm/Support/MD5.h" |
| 32 | #include "llvm/Support/RandomNumberGenerator.h" |
| 33 | #include "llvm/Support/SHA1.h" |
| 34 | #include "llvm/Support/xxhash.h" |
Rui Ueyama | 3da3f06 | 2016-11-10 20:20:37 +0000 | [diff] [blame] | 35 | #include <cstdlib> |
Rui Ueyama | 6dc7fcb | 2016-11-01 20:28:21 +0000 | [diff] [blame] | 36 | |
| 37 | using namespace llvm; |
| 38 | using namespace llvm::ELF; |
| 39 | using namespace llvm::object; |
| 40 | using namespace llvm::support; |
| 41 | using namespace llvm::support::endian; |
| 42 | |
| 43 | using namespace lld; |
| 44 | using namespace lld::elf; |
| 45 | |
Rui Ueyama | e8a6102 | 2016-11-05 23:05:47 +0000 | [diff] [blame] | 46 | template <class ELFT> static std::vector<DefinedCommon *> getCommonSymbols() { |
| 47 | std::vector<DefinedCommon *> V; |
| 48 | for (Symbol *S : Symtab<ELFT>::X->getSymbols()) |
| 49 | if (auto *B = dyn_cast<DefinedCommon>(S->body())) |
| 50 | V.push_back(B); |
| 51 | return V; |
| 52 | } |
| 53 | |
| 54 | // Find all common symbols and allocate space for them. |
Rafael Espindola | 682a5bc | 2016-11-08 14:42:34 +0000 | [diff] [blame] | 55 | template <class ELFT> InputSection<ELFT> *elf::createCommonSection() { |
| 56 | auto *Ret = make<InputSection<ELFT>>(SHF_ALLOC | SHF_WRITE, SHT_NOBITS, 1, |
| 57 | ArrayRef<uint8_t>(), "COMMON"); |
| 58 | Ret->Live = true; |
Rui Ueyama | e8a6102 | 2016-11-05 23:05:47 +0000 | [diff] [blame] | 59 | |
| 60 | // Sort the common symbols by alignment as an heuristic to pack them better. |
| 61 | std::vector<DefinedCommon *> Syms = getCommonSymbols<ELFT>(); |
| 62 | std::stable_sort(Syms.begin(), Syms.end(), |
| 63 | [](const DefinedCommon *A, const DefinedCommon *B) { |
| 64 | return A->Alignment > B->Alignment; |
| 65 | }); |
| 66 | |
| 67 | // Assign offsets to symbols. |
| 68 | size_t Size = 0; |
| 69 | size_t Alignment = 1; |
| 70 | for (DefinedCommon *Sym : Syms) { |
Rui Ueyama | 1c78682 | 2016-11-05 23:14:54 +0000 | [diff] [blame] | 71 | Alignment = std::max<size_t>(Alignment, Sym->Alignment); |
Rui Ueyama | e8a6102 | 2016-11-05 23:05:47 +0000 | [diff] [blame] | 72 | Size = alignTo(Size, Sym->Alignment); |
| 73 | |
| 74 | // Compute symbol offset relative to beginning of input section. |
| 75 | Sym->Offset = Size; |
| 76 | Size += Sym->Size; |
| 77 | } |
Rafael Espindola | 682a5bc | 2016-11-08 14:42:34 +0000 | [diff] [blame] | 78 | Ret->Alignment = Alignment; |
| 79 | Ret->Data = makeArrayRef<uint8_t>(nullptr, Size); |
| 80 | return Ret; |
Rui Ueyama | e8a6102 | 2016-11-05 23:05:47 +0000 | [diff] [blame] | 81 | } |
| 82 | |
Rui Ueyama | 3da3f06 | 2016-11-10 20:20:37 +0000 | [diff] [blame] | 83 | // Returns an LLD version string. |
| 84 | static ArrayRef<uint8_t> getVersion() { |
| 85 | // Check LLD_VERSION first for ease of testing. |
| 86 | // You can get consitent output by using the environment variable. |
| 87 | // This is only for testing. |
| 88 | StringRef S = getenv("LLD_VERSION"); |
| 89 | if (S.empty()) |
| 90 | S = Saver.save(Twine("Linker: ") + getLLDVersion()); |
| 91 | |
| 92 | // +1 to include the terminating '\0'. |
| 93 | return {(const uint8_t *)S.data(), S.size() + 1}; |
Davide Italiano | b69f38f | 2016-11-11 00:05:41 +0000 | [diff] [blame] | 94 | } |
Rui Ueyama | 3da3f06 | 2016-11-10 20:20:37 +0000 | [diff] [blame] | 95 | |
| 96 | // Creates a .comment section containing LLD version info. |
| 97 | // With this feature, you can identify LLD-generated binaries easily |
| 98 | // by "objdump -s -j .comment <file>". |
| 99 | // The returned object is a mergeable string section. |
| 100 | template <class ELFT> MergeInputSection<ELFT> *elf::createCommentSection() { |
| 101 | typename ELFT::Shdr Hdr = {}; |
| 102 | Hdr.sh_flags = SHF_MERGE | SHF_STRINGS; |
| 103 | Hdr.sh_type = SHT_PROGBITS; |
| 104 | Hdr.sh_entsize = 1; |
| 105 | Hdr.sh_addralign = 1; |
| 106 | |
| 107 | auto *Ret = make<MergeInputSection<ELFT>>(/*file=*/nullptr, &Hdr, ".comment"); |
| 108 | Ret->Data = getVersion(); |
| 109 | Ret->splitIntoPieces(); |
| 110 | return Ret; |
| 111 | } |
| 112 | |
Simon Atanasyan | ce02cf0 | 2016-11-09 21:36:56 +0000 | [diff] [blame] | 113 | // Iterate over sections of the specified type. For each section call |
| 114 | // provided function. After that "kill" the section by turning off |
| 115 | // "Live" flag, so that they won't be included in the final output. |
| 116 | template <class ELFT> |
| 117 | static void iterateSectionContents( |
| 118 | uint32_t Type, |
Simon Atanasyan | 93214b7 | 2016-11-09 21:46:42 +0000 | [diff] [blame] | 119 | std::function<void(elf::ObjectFile<ELFT> *, ArrayRef<uint8_t>)> F) { |
Simon Atanasyan | ce02cf0 | 2016-11-09 21:36:56 +0000 | [diff] [blame] | 120 | for (InputSectionBase<ELFT> *Sec : Symtab<ELFT>::X->Sections) { |
| 121 | if (Sec && Sec->Live && Sec->Type == Type) { |
| 122 | Sec->Live = false; |
| 123 | F(Sec->getFile(), Sec->Data); |
| 124 | } |
| 125 | } |
| 126 | } |
| 127 | |
Simon Atanasyan | fa03b0f | 2016-11-09 21:37:06 +0000 | [diff] [blame] | 128 | // .MIPS.abiflags section. |
| 129 | template <class ELFT> |
| 130 | MipsAbiFlagsSection<ELFT>::MipsAbiFlagsSection() |
| 131 | : InputSection<ELFT>(SHF_ALLOC, SHT_MIPS_ABIFLAGS, 8, ArrayRef<uint8_t>(), |
| 132 | ".MIPS.abiflags") { |
| 133 | auto Func = [this](ObjectFile<ELFT> *F, ArrayRef<uint8_t> D) { |
| 134 | if (D.size() != sizeof(Elf_Mips_ABIFlags)) { |
| 135 | error(getFilename(F) + ": invalid size of .MIPS.abiflags section"); |
| 136 | return; |
| 137 | } |
| 138 | auto *S = reinterpret_cast<const Elf_Mips_ABIFlags *>(D.data()); |
| 139 | if (S->version != 0) { |
| 140 | error(getFilename(F) + ": unexpected .MIPS.abiflags version " + |
| 141 | Twine(S->version)); |
| 142 | return; |
| 143 | } |
| 144 | // LLD checks ISA compatibility in getMipsEFlags(). Here we just |
| 145 | // select the highest number of ISA/Rev/Ext. |
| 146 | Flags.isa_level = std::max(Flags.isa_level, S->isa_level); |
| 147 | Flags.isa_rev = std::max(Flags.isa_rev, S->isa_rev); |
| 148 | Flags.isa_ext = std::max(Flags.isa_ext, S->isa_ext); |
| 149 | Flags.gpr_size = std::max(Flags.gpr_size, S->gpr_size); |
| 150 | Flags.cpr1_size = std::max(Flags.cpr1_size, S->cpr1_size); |
| 151 | Flags.cpr2_size = std::max(Flags.cpr2_size, S->cpr2_size); |
| 152 | Flags.ases |= S->ases; |
| 153 | Flags.flags1 |= S->flags1; |
| 154 | Flags.flags2 |= S->flags2; |
| 155 | Flags.fp_abi = |
| 156 | elf::getMipsFpAbiFlag(Flags.fp_abi, S->fp_abi, getFilename(F)); |
| 157 | }; |
| 158 | iterateSectionContents<ELFT>(SHT_MIPS_ABIFLAGS, Func); |
| 159 | |
| 160 | this->Data = ArrayRef<uint8_t>((const uint8_t *)&Flags, sizeof(Flags)); |
| 161 | this->Live = true; |
| 162 | } |
| 163 | |
Simon Atanasyan | ce02cf0 | 2016-11-09 21:36:56 +0000 | [diff] [blame] | 164 | // .MIPS.options section. |
| 165 | template <class ELFT> |
| 166 | MipsOptionsSection<ELFT>::MipsOptionsSection() |
| 167 | : InputSection<ELFT>(SHF_ALLOC, SHT_MIPS_OPTIONS, 8, ArrayRef<uint8_t>(), |
| 168 | ".MIPS.options") { |
| 169 | Buf.resize(sizeof(Elf_Mips_Options) + sizeof(Elf_Mips_RegInfo)); |
| 170 | getOptions()->kind = ODK_REGINFO; |
| 171 | getOptions()->size = Buf.size(); |
| 172 | auto Func = [this](ObjectFile<ELFT> *F, ArrayRef<uint8_t> D) { |
| 173 | while (!D.empty()) { |
| 174 | if (D.size() < sizeof(Elf_Mips_Options)) { |
| 175 | error(getFilename(F) + ": invalid size of .MIPS.options section"); |
| 176 | break; |
| 177 | } |
| 178 | auto *O = reinterpret_cast<const Elf_Mips_Options *>(D.data()); |
| 179 | if (O->kind == ODK_REGINFO) { |
| 180 | if (Config->Relocatable && O->getRegInfo().ri_gp_value) |
| 181 | error(getFilename(F) + ": unsupported non-zero ri_gp_value"); |
| 182 | getOptions()->getRegInfo().ri_gprmask |= O->getRegInfo().ri_gprmask; |
| 183 | F->MipsGp0 = O->getRegInfo().ri_gp_value; |
| 184 | break; |
| 185 | } |
| 186 | if (!O->size) |
| 187 | fatal(getFilename(F) + ": zero option descriptor size"); |
| 188 | D = D.slice(O->size); |
| 189 | } |
| 190 | }; |
| 191 | iterateSectionContents<ELFT>(SHT_MIPS_OPTIONS, Func); |
| 192 | |
| 193 | this->Data = ArrayRef<uint8_t>(Buf); |
| 194 | // Section should be alive for N64 ABI only. |
| 195 | this->Live = ELFT::Is64Bits; |
| 196 | } |
| 197 | |
| 198 | template <class ELFT> void MipsOptionsSection<ELFT>::finalize() { |
| 199 | if (!Config->Relocatable) |
| 200 | getOptions()->getRegInfo().ri_gp_value = |
Eugene Leviant | ad4439e | 2016-11-11 11:33:32 +0000 | [diff] [blame] | 201 | In<ELFT>::Got->getVA() + MipsGPOffset; |
Simon Atanasyan | ce02cf0 | 2016-11-09 21:36:56 +0000 | [diff] [blame] | 202 | } |
| 203 | |
| 204 | // MIPS .reginfo section. |
| 205 | template <class ELFT> |
| 206 | MipsReginfoSection<ELFT>::MipsReginfoSection() |
| 207 | : InputSection<ELFT>(SHF_ALLOC, SHT_MIPS_REGINFO, 4, ArrayRef<uint8_t>(), |
| 208 | ".reginfo") { |
| 209 | auto Func = [this](ObjectFile<ELFT> *F, ArrayRef<uint8_t> D) { |
| 210 | if (D.size() != sizeof(Elf_Mips_RegInfo)) { |
| 211 | error(getFilename(F) + ": invalid size of .reginfo section"); |
| 212 | return; |
| 213 | } |
| 214 | auto *R = reinterpret_cast<const Elf_Mips_RegInfo *>(D.data()); |
| 215 | if (Config->Relocatable && R->ri_gp_value) |
| 216 | error(getFilename(F) + ": unsupported non-zero ri_gp_value"); |
| 217 | Reginfo.ri_gprmask |= R->ri_gprmask; |
| 218 | F->MipsGp0 = R->ri_gp_value; |
| 219 | }; |
| 220 | iterateSectionContents<ELFT>(SHT_MIPS_REGINFO, Func); |
| 221 | |
| 222 | this->Data = ArrayRef<uint8_t>((const uint8_t *)&Reginfo, sizeof(Reginfo)); |
| 223 | // Section should be alive for O32 and N32 ABIs only. |
| 224 | this->Live = !ELFT::Is64Bits; |
| 225 | } |
| 226 | |
| 227 | template <class ELFT> void MipsReginfoSection<ELFT>::finalize() { |
| 228 | if (!Config->Relocatable) |
Eugene Leviant | ad4439e | 2016-11-11 11:33:32 +0000 | [diff] [blame] | 229 | Reginfo.ri_gp_value = In<ELFT>::Got->getVA() + MipsGPOffset; |
Simon Atanasyan | ce02cf0 | 2016-11-09 21:36:56 +0000 | [diff] [blame] | 230 | } |
| 231 | |
Rui Ueyama | e288eef | 2016-11-02 18:58:44 +0000 | [diff] [blame] | 232 | static ArrayRef<uint8_t> createInterp() { |
| 233 | // StringSaver guarantees that the returned string ends with '\0'. |
| 234 | StringRef S = Saver.save(Config->DynamicLinker); |
Rui Ueyama | 6294a24 | 2016-11-04 17:41:29 +0000 | [diff] [blame] | 235 | return {(const uint8_t *)S.data(), S.size() + 1}; |
Rui Ueyama | e288eef | 2016-11-02 18:58:44 +0000 | [diff] [blame] | 236 | } |
| 237 | |
Rafael Espindola | c0e47fb | 2016-11-08 14:56:27 +0000 | [diff] [blame] | 238 | template <class ELFT> InputSection<ELFT> *elf::createInterpSection() { |
| 239 | auto *Ret = make<InputSection<ELFT>>(SHF_ALLOC, SHT_PROGBITS, 1, |
| 240 | createInterp(), ".interp"); |
| 241 | Ret->Live = true; |
| 242 | return Ret; |
Rui Ueyama | a9ee8d6 | 2016-11-04 22:25:39 +0000 | [diff] [blame] | 243 | } |
Rui Ueyama | e288eef | 2016-11-02 18:58:44 +0000 | [diff] [blame] | 244 | |
Rui Ueyama | 6dc7fcb | 2016-11-01 20:28:21 +0000 | [diff] [blame] | 245 | template <class ELFT> |
| 246 | BuildIdSection<ELFT>::BuildIdSection(size_t HashSize) |
| 247 | : InputSection<ELFT>(SHF_ALLOC, SHT_NOTE, 1, ArrayRef<uint8_t>(), |
George Rimar | 364b59e2 | 2016-11-06 07:42:55 +0000 | [diff] [blame] | 248 | ".note.gnu.build-id"), |
| 249 | HashSize(HashSize) { |
Rui Ueyama | a9ee8d6 | 2016-11-04 22:25:39 +0000 | [diff] [blame] | 250 | this->Live = true; |
| 251 | |
Rafael Espindola | 0e876cf | 2016-11-10 15:41:34 +0000 | [diff] [blame] | 252 | Buf.resize(HeaderSize + HashSize); |
Rui Ueyama | 6dc7fcb | 2016-11-01 20:28:21 +0000 | [diff] [blame] | 253 | const endianness E = ELFT::TargetEndianness; |
Rafael Espindola | 1a54112 | 2016-11-08 14:47:16 +0000 | [diff] [blame] | 254 | write32<E>(Buf.data(), 4); // Name size |
| 255 | write32<E>(Buf.data() + 4, HashSize); // Content size |
| 256 | write32<E>(Buf.data() + 8, NT_GNU_BUILD_ID); // Type |
| 257 | memcpy(Buf.data() + 12, "GNU", 4); // Name string |
| 258 | this->Data = ArrayRef<uint8_t>(Buf); |
Rui Ueyama | 6dc7fcb | 2016-11-01 20:28:21 +0000 | [diff] [blame] | 259 | } |
| 260 | |
Rui Ueyama | 35e0075 | 2016-11-10 00:12:28 +0000 | [diff] [blame] | 261 | // Returns the location of the build-id hash value in the output. |
Rui Ueyama | 6dc7fcb | 2016-11-01 20:28:21 +0000 | [diff] [blame] | 262 | template <class ELFT> |
| 263 | uint8_t *BuildIdSection<ELFT>::getOutputLoc(uint8_t *Start) const { |
Rafael Espindola | 0e876cf | 2016-11-10 15:41:34 +0000 | [diff] [blame] | 264 | return Start + this->OutSec->Offset + this->OutSecOff + HeaderSize; |
Rui Ueyama | 6dc7fcb | 2016-11-01 20:28:21 +0000 | [diff] [blame] | 265 | } |
| 266 | |
Rui Ueyama | 35e0075 | 2016-11-10 00:12:28 +0000 | [diff] [blame] | 267 | // Split one uint8 array into small pieces of uint8 arrays. |
George Rimar | 364b59e2 | 2016-11-06 07:42:55 +0000 | [diff] [blame] | 268 | static std::vector<ArrayRef<uint8_t>> split(ArrayRef<uint8_t> Arr, |
| 269 | size_t ChunkSize) { |
| 270 | std::vector<ArrayRef<uint8_t>> Ret; |
| 271 | while (Arr.size() > ChunkSize) { |
| 272 | Ret.push_back(Arr.take_front(ChunkSize)); |
| 273 | Arr = Arr.drop_front(ChunkSize); |
| 274 | } |
| 275 | if (!Arr.empty()) |
| 276 | Ret.push_back(Arr); |
| 277 | return Ret; |
| 278 | } |
| 279 | |
Rui Ueyama | 35e0075 | 2016-11-10 00:12:28 +0000 | [diff] [blame] | 280 | // Computes a hash value of Data using a given hash function. |
| 281 | // In order to utilize multiple cores, we first split data into 1MB |
| 282 | // chunks, compute a hash for each chunk, and then compute a hash value |
| 283 | // of the hash values. |
George Rimar | 364b59e2 | 2016-11-06 07:42:55 +0000 | [diff] [blame] | 284 | template <class ELFT> |
| 285 | void BuildIdSection<ELFT>::computeHash( |
George Rimar | 828787a | 2016-11-06 08:39:46 +0000 | [diff] [blame] | 286 | llvm::MutableArrayRef<uint8_t> Data, |
Rui Ueyama | 35e0075 | 2016-11-10 00:12:28 +0000 | [diff] [blame] | 287 | std::function<void(ArrayRef<uint8_t> Arr, uint8_t *Dest)> HashFn) { |
George Rimar | 364b59e2 | 2016-11-06 07:42:55 +0000 | [diff] [blame] | 288 | std::vector<ArrayRef<uint8_t>> Chunks = split(Data, 1024 * 1024); |
| 289 | std::vector<uint8_t> HashList(Chunks.size() * HashSize); |
| 290 | |
Rui Ueyama | 35e0075 | 2016-11-10 00:12:28 +0000 | [diff] [blame] | 291 | auto Fn = [&](ArrayRef<uint8_t> &Chunk) { |
| 292 | size_t Idx = &Chunk - Chunks.data(); |
| 293 | HashFn(Chunk, HashList.data() + Idx * HashSize); |
| 294 | }; |
George Rimar | 364b59e2 | 2016-11-06 07:42:55 +0000 | [diff] [blame] | 295 | |
Rui Ueyama | 35e0075 | 2016-11-10 00:12:28 +0000 | [diff] [blame] | 296 | if (Config->Threads) |
| 297 | parallel_for_each(Chunks.begin(), Chunks.end(), Fn); |
| 298 | else |
| 299 | std::for_each(Chunks.begin(), Chunks.end(), Fn); |
| 300 | |
| 301 | HashFn(HashList, this->getOutputLoc(Data.begin())); |
George Rimar | 364b59e2 | 2016-11-06 07:42:55 +0000 | [diff] [blame] | 302 | } |
| 303 | |
Rui Ueyama | 6dc7fcb | 2016-11-01 20:28:21 +0000 | [diff] [blame] | 304 | template <class ELFT> |
| 305 | void BuildIdFastHash<ELFT>::writeBuildId(MutableArrayRef<uint8_t> Buf) { |
George Rimar | 5020971 | 2016-11-06 08:26:53 +0000 | [diff] [blame] | 306 | this->computeHash(Buf, [](ArrayRef<uint8_t> Arr, uint8_t *Dest) { |
Rui Ueyama | 35e0075 | 2016-11-10 00:12:28 +0000 | [diff] [blame] | 307 | write64le(Dest, xxHash64(toStringRef(Arr))); |
George Rimar | 364b59e2 | 2016-11-06 07:42:55 +0000 | [diff] [blame] | 308 | }); |
Rui Ueyama | 6dc7fcb | 2016-11-01 20:28:21 +0000 | [diff] [blame] | 309 | } |
| 310 | |
| 311 | template <class ELFT> |
| 312 | void BuildIdMd5<ELFT>::writeBuildId(MutableArrayRef<uint8_t> Buf) { |
Rui Ueyama | 35e0075 | 2016-11-10 00:12:28 +0000 | [diff] [blame] | 313 | this->computeHash(Buf, [](ArrayRef<uint8_t> Arr, uint8_t *Dest) { |
George Rimar | 364b59e2 | 2016-11-06 07:42:55 +0000 | [diff] [blame] | 314 | MD5 Hash; |
| 315 | Hash.update(Arr); |
| 316 | MD5::MD5Result Res; |
| 317 | Hash.final(Res); |
Rui Ueyama | 35e0075 | 2016-11-10 00:12:28 +0000 | [diff] [blame] | 318 | memcpy(Dest, Res, 16); |
George Rimar | 364b59e2 | 2016-11-06 07:42:55 +0000 | [diff] [blame] | 319 | }); |
Rui Ueyama | 6dc7fcb | 2016-11-01 20:28:21 +0000 | [diff] [blame] | 320 | } |
| 321 | |
| 322 | template <class ELFT> |
| 323 | void BuildIdSha1<ELFT>::writeBuildId(MutableArrayRef<uint8_t> Buf) { |
Rui Ueyama | 35e0075 | 2016-11-10 00:12:28 +0000 | [diff] [blame] | 324 | this->computeHash(Buf, [](ArrayRef<uint8_t> Arr, uint8_t *Dest) { |
George Rimar | 364b59e2 | 2016-11-06 07:42:55 +0000 | [diff] [blame] | 325 | SHA1 Hash; |
| 326 | Hash.update(Arr); |
Rui Ueyama | 35e0075 | 2016-11-10 00:12:28 +0000 | [diff] [blame] | 327 | memcpy(Dest, Hash.final().data(), 20); |
George Rimar | 364b59e2 | 2016-11-06 07:42:55 +0000 | [diff] [blame] | 328 | }); |
Rui Ueyama | 6dc7fcb | 2016-11-01 20:28:21 +0000 | [diff] [blame] | 329 | } |
| 330 | |
| 331 | template <class ELFT> |
| 332 | void BuildIdUuid<ELFT>::writeBuildId(MutableArrayRef<uint8_t> Buf) { |
Rui Ueyama | 35e0075 | 2016-11-10 00:12:28 +0000 | [diff] [blame] | 333 | if (getRandomBytes(this->getOutputLoc(Buf.data()), this->HashSize)) |
Rui Ueyama | 6dc7fcb | 2016-11-01 20:28:21 +0000 | [diff] [blame] | 334 | error("entropy source failure"); |
| 335 | } |
| 336 | |
| 337 | template <class ELFT> |
| 338 | BuildIdHexstring<ELFT>::BuildIdHexstring() |
| 339 | : BuildIdSection<ELFT>(Config->BuildIdVector.size()) {} |
| 340 | |
| 341 | template <class ELFT> |
| 342 | void BuildIdHexstring<ELFT>::writeBuildId(MutableArrayRef<uint8_t> Buf) { |
Rui Ueyama | 35e0075 | 2016-11-10 00:12:28 +0000 | [diff] [blame] | 343 | memcpy(this->getOutputLoc(Buf.data()), Config->BuildIdVector.data(), |
Rui Ueyama | 6dc7fcb | 2016-11-01 20:28:21 +0000 | [diff] [blame] | 344 | Config->BuildIdVector.size()); |
| 345 | } |
| 346 | |
Eugene Leviant | 41ca327 | 2016-11-10 09:48:29 +0000 | [diff] [blame] | 347 | template <class ELFT> |
Eugene Leviant | ad4439e | 2016-11-11 11:33:32 +0000 | [diff] [blame] | 348 | GotSection<ELFT>::GotSection() |
| 349 | : SyntheticSection<ELFT>(SHF_ALLOC | SHF_WRITE, SHT_PROGBITS, |
| 350 | Target->GotEntrySize, ".got") { |
| 351 | if (Config->EMachine == EM_MIPS) |
| 352 | this->Flags |= SHF_MIPS_GPREL; |
| 353 | } |
| 354 | |
| 355 | template <class ELFT> void GotSection<ELFT>::addEntry(SymbolBody &Sym) { |
| 356 | Sym.GotIndex = Entries.size(); |
| 357 | Entries.push_back(&Sym); |
| 358 | } |
| 359 | |
| 360 | template <class ELFT> |
| 361 | void GotSection<ELFT>::addMipsEntry(SymbolBody &Sym, uintX_t Addend, |
| 362 | RelExpr Expr) { |
| 363 | // For "true" local symbols which can be referenced from the same module |
| 364 | // only compiler creates two instructions for address loading: |
| 365 | // |
| 366 | // lw $8, 0($gp) # R_MIPS_GOT16 |
| 367 | // addi $8, $8, 0 # R_MIPS_LO16 |
| 368 | // |
| 369 | // The first instruction loads high 16 bits of the symbol address while |
| 370 | // the second adds an offset. That allows to reduce number of required |
| 371 | // GOT entries because only one global offset table entry is necessary |
| 372 | // for every 64 KBytes of local data. So for local symbols we need to |
| 373 | // allocate number of GOT entries to hold all required "page" addresses. |
| 374 | // |
| 375 | // All global symbols (hidden and regular) considered by compiler uniformly. |
| 376 | // It always generates a single `lw` instruction and R_MIPS_GOT16 relocation |
| 377 | // to load address of the symbol. So for each such symbol we need to |
| 378 | // allocate dedicated GOT entry to store its address. |
| 379 | // |
| 380 | // If a symbol is preemptible we need help of dynamic linker to get its |
| 381 | // final address. The corresponding GOT entries are allocated in the |
| 382 | // "global" part of GOT. Entries for non preemptible global symbol allocated |
| 383 | // in the "local" part of GOT. |
| 384 | // |
| 385 | // See "Global Offset Table" in Chapter 5: |
| 386 | // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf |
| 387 | if (Expr == R_MIPS_GOT_LOCAL_PAGE) { |
| 388 | // At this point we do not know final symbol value so to reduce number |
| 389 | // of allocated GOT entries do the following trick. Save all output |
| 390 | // sections referenced by GOT relocations. Then later in the `finalize` |
| 391 | // method calculate number of "pages" required to cover all saved output |
| 392 | // section and allocate appropriate number of GOT entries. |
| 393 | auto *OutSec = cast<DefinedRegular<ELFT>>(&Sym)->Section->OutSec; |
| 394 | MipsOutSections.insert(OutSec); |
| 395 | return; |
| 396 | } |
| 397 | if (Sym.isTls()) { |
| 398 | // GOT entries created for MIPS TLS relocations behave like |
| 399 | // almost GOT entries from other ABIs. They go to the end |
| 400 | // of the global offset table. |
| 401 | Sym.GotIndex = Entries.size(); |
| 402 | Entries.push_back(&Sym); |
| 403 | return; |
| 404 | } |
| 405 | auto AddEntry = [&](SymbolBody &S, uintX_t A, MipsGotEntries &Items) { |
| 406 | if (S.isInGot() && !A) |
| 407 | return; |
| 408 | size_t NewIndex = Items.size(); |
| 409 | if (!MipsGotMap.insert({{&S, A}, NewIndex}).second) |
| 410 | return; |
| 411 | Items.emplace_back(&S, A); |
| 412 | if (!A) |
| 413 | S.GotIndex = NewIndex; |
| 414 | }; |
| 415 | if (Sym.isPreemptible()) { |
| 416 | // Ignore addends for preemptible symbols. They got single GOT entry anyway. |
| 417 | AddEntry(Sym, 0, MipsGlobal); |
| 418 | Sym.IsInGlobalMipsGot = true; |
| 419 | } else if (Expr == R_MIPS_GOT_OFF32) { |
| 420 | AddEntry(Sym, Addend, MipsLocal32); |
| 421 | Sym.Is32BitMipsGot = true; |
| 422 | } else { |
| 423 | // Hold local GOT entries accessed via a 16-bit index separately. |
| 424 | // That allows to write them in the beginning of the GOT and keep |
| 425 | // their indexes as less as possible to escape relocation's overflow. |
| 426 | AddEntry(Sym, Addend, MipsLocal); |
| 427 | } |
| 428 | } |
| 429 | |
| 430 | template <class ELFT> bool GotSection<ELFT>::addDynTlsEntry(SymbolBody &Sym) { |
| 431 | if (Sym.GlobalDynIndex != -1U) |
| 432 | return false; |
| 433 | Sym.GlobalDynIndex = Entries.size(); |
| 434 | // Global Dynamic TLS entries take two GOT slots. |
| 435 | Entries.push_back(nullptr); |
| 436 | Entries.push_back(&Sym); |
| 437 | return true; |
| 438 | } |
| 439 | |
| 440 | // Reserves TLS entries for a TLS module ID and a TLS block offset. |
| 441 | // In total it takes two GOT slots. |
| 442 | template <class ELFT> bool GotSection<ELFT>::addTlsIndex() { |
| 443 | if (TlsIndexOff != uint32_t(-1)) |
| 444 | return false; |
| 445 | TlsIndexOff = Entries.size() * sizeof(uintX_t); |
| 446 | Entries.push_back(nullptr); |
| 447 | Entries.push_back(nullptr); |
| 448 | return true; |
| 449 | } |
| 450 | |
| 451 | template <class ELFT> |
| 452 | typename GotSection<ELFT>::uintX_t |
| 453 | GotSection<ELFT>::getMipsLocalPageOffset(uintX_t EntryValue) { |
| 454 | // Initialize the entry by the %hi(EntryValue) expression |
| 455 | // but without right-shifting. |
| 456 | EntryValue = (EntryValue + 0x8000) & ~0xffff; |
| 457 | // Take into account MIPS GOT header. |
| 458 | // See comment in the GotSection::writeTo. |
| 459 | size_t NewIndex = MipsLocalGotPos.size() + 2; |
| 460 | auto P = MipsLocalGotPos.insert(std::make_pair(EntryValue, NewIndex)); |
| 461 | assert(!P.second || MipsLocalGotPos.size() <= MipsPageEntries); |
| 462 | return (uintX_t)P.first->second * sizeof(uintX_t) - MipsGPOffset; |
| 463 | } |
| 464 | |
| 465 | template <class ELFT> |
| 466 | typename GotSection<ELFT>::uintX_t |
| 467 | GotSection<ELFT>::getMipsGotOffset(const SymbolBody &B, uintX_t Addend) const { |
| 468 | // Calculate offset of the GOT entries block: TLS, global, local. |
| 469 | uintX_t GotBlockOff; |
| 470 | if (B.isTls()) |
| 471 | GotBlockOff = getMipsTlsOffset(); |
| 472 | else if (B.IsInGlobalMipsGot) |
| 473 | GotBlockOff = getMipsLocalEntriesNum() * sizeof(uintX_t); |
| 474 | else if (B.Is32BitMipsGot) |
| 475 | GotBlockOff = (MipsPageEntries + MipsLocal.size()) * sizeof(uintX_t); |
| 476 | else |
| 477 | GotBlockOff = MipsPageEntries * sizeof(uintX_t); |
| 478 | // Calculate index of the GOT entry in the block. |
| 479 | uintX_t GotIndex; |
| 480 | if (B.isInGot()) |
| 481 | GotIndex = B.GotIndex; |
| 482 | else { |
| 483 | auto It = MipsGotMap.find({&B, Addend}); |
| 484 | assert(It != MipsGotMap.end()); |
| 485 | GotIndex = It->second; |
| 486 | } |
| 487 | return GotBlockOff + GotIndex * sizeof(uintX_t) - MipsGPOffset; |
| 488 | } |
| 489 | |
| 490 | template <class ELFT> |
| 491 | typename GotSection<ELFT>::uintX_t GotSection<ELFT>::getMipsTlsOffset() const { |
| 492 | return (getMipsLocalEntriesNum() + MipsGlobal.size()) * sizeof(uintX_t); |
| 493 | } |
| 494 | |
| 495 | template <class ELFT> |
| 496 | typename GotSection<ELFT>::uintX_t |
| 497 | GotSection<ELFT>::getGlobalDynAddr(const SymbolBody &B) const { |
| 498 | return this->getVA() + B.GlobalDynIndex * sizeof(uintX_t); |
| 499 | } |
| 500 | |
| 501 | template <class ELFT> |
| 502 | typename GotSection<ELFT>::uintX_t |
| 503 | GotSection<ELFT>::getGlobalDynOffset(const SymbolBody &B) const { |
| 504 | return B.GlobalDynIndex * sizeof(uintX_t); |
| 505 | } |
| 506 | |
| 507 | template <class ELFT> |
| 508 | const SymbolBody *GotSection<ELFT>::getMipsFirstGlobalEntry() const { |
| 509 | return MipsGlobal.empty() ? nullptr : MipsGlobal.front().first; |
| 510 | } |
| 511 | |
| 512 | template <class ELFT> |
| 513 | unsigned GotSection<ELFT>::getMipsLocalEntriesNum() const { |
| 514 | return MipsPageEntries + MipsLocal.size() + MipsLocal32.size(); |
| 515 | } |
| 516 | |
| 517 | template <class ELFT> void GotSection<ELFT>::finalize() { |
| 518 | size_t EntriesNum = Entries.size(); |
| 519 | if (Config->EMachine == EM_MIPS) { |
| 520 | // Take into account MIPS GOT header. |
| 521 | // See comment in the GotSection::writeTo. |
| 522 | MipsPageEntries += 2; |
| 523 | for (const OutputSectionBase *OutSec : MipsOutSections) { |
| 524 | // Calculate an upper bound of MIPS GOT entries required to store page |
| 525 | // addresses of local symbols. We assume the worst case - each 64kb |
| 526 | // page of the output section has at least one GOT relocation against it. |
| 527 | // Add 0x8000 to the section's size because the page address stored |
| 528 | // in the GOT entry is calculated as (value + 0x8000) & ~0xffff. |
| 529 | MipsPageEntries += (OutSec->Size + 0x8000 + 0xfffe) / 0xffff; |
| 530 | } |
| 531 | EntriesNum += getMipsLocalEntriesNum() + MipsGlobal.size(); |
| 532 | } |
| 533 | Size = EntriesNum * sizeof(uintX_t); |
| 534 | } |
| 535 | |
| 536 | template <class ELFT> |
| 537 | static void writeUint(uint8_t *Buf, typename ELFT::uint Val) { |
| 538 | typedef typename ELFT::uint uintX_t; |
| 539 | write<uintX_t, ELFT::TargetEndianness, sizeof(uintX_t)>(Buf, Val); |
| 540 | } |
| 541 | |
| 542 | template <class ELFT> void GotSection<ELFT>::writeMipsGot(uint8_t *Buf) { |
| 543 | // Set the MSB of the second GOT slot. This is not required by any |
| 544 | // MIPS ABI documentation, though. |
| 545 | // |
| 546 | // There is a comment in glibc saying that "The MSB of got[1] of a |
| 547 | // gnu object is set to identify gnu objects," and in GNU gold it |
| 548 | // says "the second entry will be used by some runtime loaders". |
| 549 | // But how this field is being used is unclear. |
| 550 | // |
| 551 | // We are not really willing to mimic other linkers behaviors |
| 552 | // without understanding why they do that, but because all files |
| 553 | // generated by GNU tools have this special GOT value, and because |
| 554 | // we've been doing this for years, it is probably a safe bet to |
| 555 | // keep doing this for now. We really need to revisit this to see |
| 556 | // if we had to do this. |
| 557 | auto *P = reinterpret_cast<typename ELFT::Off *>(Buf); |
| 558 | P[1] = uintX_t(1) << (ELFT::Is64Bits ? 63 : 31); |
| 559 | // Write 'page address' entries to the local part of the GOT. |
| 560 | for (std::pair<uintX_t, size_t> &L : MipsLocalGotPos) { |
| 561 | uint8_t *Entry = Buf + L.second * sizeof(uintX_t); |
| 562 | writeUint<ELFT>(Entry, L.first); |
| 563 | } |
| 564 | Buf += MipsPageEntries * sizeof(uintX_t); |
| 565 | auto AddEntry = [&](const MipsGotEntry &SA) { |
| 566 | uint8_t *Entry = Buf; |
| 567 | Buf += sizeof(uintX_t); |
| 568 | const SymbolBody *Body = SA.first; |
| 569 | uintX_t VA = Body->template getVA<ELFT>(SA.second); |
| 570 | writeUint<ELFT>(Entry, VA); |
| 571 | }; |
| 572 | std::for_each(std::begin(MipsLocal), std::end(MipsLocal), AddEntry); |
| 573 | std::for_each(std::begin(MipsLocal32), std::end(MipsLocal32), AddEntry); |
| 574 | std::for_each(std::begin(MipsGlobal), std::end(MipsGlobal), AddEntry); |
| 575 | // Initialize TLS-related GOT entries. If the entry has a corresponding |
| 576 | // dynamic relocations, leave it initialized by zero. Write down adjusted |
| 577 | // TLS symbol's values otherwise. To calculate the adjustments use offsets |
| 578 | // for thread-local storage. |
| 579 | // https://www.linux-mips.org/wiki/NPTL |
| 580 | if (TlsIndexOff != -1U && !Config->Pic) |
| 581 | writeUint<ELFT>(Buf + TlsIndexOff, 1); |
| 582 | for (const SymbolBody *B : Entries) { |
| 583 | if (!B || B->isPreemptible()) |
| 584 | continue; |
| 585 | uintX_t VA = B->getVA<ELFT>(); |
| 586 | if (B->GotIndex != -1U) { |
| 587 | uint8_t *Entry = Buf + B->GotIndex * sizeof(uintX_t); |
| 588 | writeUint<ELFT>(Entry, VA - 0x7000); |
| 589 | } |
| 590 | if (B->GlobalDynIndex != -1U) { |
| 591 | uint8_t *Entry = Buf + B->GlobalDynIndex * sizeof(uintX_t); |
| 592 | writeUint<ELFT>(Entry, 1); |
| 593 | Entry += sizeof(uintX_t); |
| 594 | writeUint<ELFT>(Entry, VA - 0x8000); |
| 595 | } |
| 596 | } |
| 597 | } |
| 598 | |
| 599 | template <class ELFT> void GotSection<ELFT>::writeTo(uint8_t *Buf) { |
| 600 | if (Config->EMachine == EM_MIPS) { |
| 601 | writeMipsGot(Buf); |
| 602 | return; |
| 603 | } |
| 604 | for (const SymbolBody *B : Entries) { |
| 605 | uint8_t *Entry = Buf; |
| 606 | Buf += sizeof(uintX_t); |
| 607 | if (!B) |
| 608 | continue; |
| 609 | if (B->isPreemptible()) |
| 610 | continue; // The dynamic linker will take care of it. |
| 611 | uintX_t VA = B->getVA<ELFT>(); |
| 612 | writeUint<ELFT>(Entry, VA); |
| 613 | } |
| 614 | } |
| 615 | |
| 616 | template <class ELFT> |
Eugene Leviant | 41ca327 | 2016-11-10 09:48:29 +0000 | [diff] [blame] | 617 | GotPltSection<ELFT>::GotPltSection() |
| 618 | : SyntheticSection<ELFT>(SHF_ALLOC | SHF_WRITE, SHT_PROGBITS, |
George Rimar | d8b2776 | 2016-11-14 10:14:18 +0000 | [diff] [blame] | 619 | Target->GotPltEntrySize, ".got.plt") {} |
Eugene Leviant | 41ca327 | 2016-11-10 09:48:29 +0000 | [diff] [blame] | 620 | |
| 621 | template <class ELFT> void GotPltSection<ELFT>::addEntry(SymbolBody &Sym) { |
| 622 | Sym.GotPltIndex = Target->GotPltHeaderEntriesNum + Entries.size(); |
| 623 | Entries.push_back(&Sym); |
| 624 | } |
| 625 | |
| 626 | template <class ELFT> bool GotPltSection<ELFT>::empty() const { |
| 627 | return Entries.empty(); |
| 628 | } |
| 629 | |
| 630 | template <class ELFT> size_t GotPltSection<ELFT>::getSize() const { |
| 631 | return (Target->GotPltHeaderEntriesNum + Entries.size()) * |
| 632 | Target->GotPltEntrySize; |
| 633 | } |
| 634 | |
| 635 | template <class ELFT> void GotPltSection<ELFT>::writeTo(uint8_t *Buf) { |
| 636 | Target->writeGotPltHeader(Buf); |
| 637 | Buf += Target->GotPltHeaderEntriesNum * Target->GotPltEntrySize; |
| 638 | for (const SymbolBody *B : Entries) { |
| 639 | Target->writeGotPlt(Buf, *B); |
| 640 | Buf += sizeof(uintX_t); |
| 641 | } |
| 642 | } |
| 643 | |
Eugene Leviant | 22eb026 | 2016-11-14 09:16:00 +0000 | [diff] [blame] | 644 | template <class ELFT> |
| 645 | StringTableSection<ELFT>::StringTableSection(StringRef Name, bool Dynamic) |
| 646 | : SyntheticSection<ELFT>(Dynamic ? (uintX_t)SHF_ALLOC : 0, SHT_STRTAB, 1, |
| 647 | Name), |
| 648 | Dynamic(Dynamic) {} |
| 649 | |
| 650 | // Adds a string to the string table. If HashIt is true we hash and check for |
| 651 | // duplicates. It is optional because the name of global symbols are already |
| 652 | // uniqued and hashing them again has a big cost for a small value: uniquing |
| 653 | // them with some other string that happens to be the same. |
| 654 | template <class ELFT> |
| 655 | unsigned StringTableSection<ELFT>::addString(StringRef S, bool HashIt) { |
| 656 | if (HashIt) { |
| 657 | auto R = StringMap.insert(std::make_pair(S, this->Size)); |
| 658 | if (!R.second) |
| 659 | return R.first->second; |
| 660 | } |
| 661 | unsigned Ret = this->Size; |
| 662 | this->Size = this->Size + S.size() + 1; |
| 663 | Strings.push_back(S); |
| 664 | return Ret; |
| 665 | } |
| 666 | |
| 667 | template <class ELFT> void StringTableSection<ELFT>::writeTo(uint8_t *Buf) { |
| 668 | // ELF string tables start with NUL byte, so advance the pointer by one. |
| 669 | ++Buf; |
| 670 | for (StringRef S : Strings) { |
| 671 | memcpy(Buf, S.data(), S.size()); |
| 672 | Buf += S.size() + 1; |
| 673 | } |
| 674 | } |
| 675 | |
Eugene Leviant | 6380ce2 | 2016-11-15 12:26:55 +0000 | [diff] [blame] | 676 | static unsigned getVerDefNum() { return Config->VersionDefinitions.size() + 1; } |
| 677 | |
| 678 | template <class ELFT> |
| 679 | DynamicSection<ELFT>::DynamicSection() |
| 680 | : SyntheticSection<ELFT>(SHF_ALLOC | SHF_WRITE, SHT_DYNAMIC, |
| 681 | sizeof(uintX_t), ".dynamic") { |
| 682 | this->Entsize = ELFT::Is64Bits ? 16 : 8; |
| 683 | // .dynamic section is not writable on MIPS. |
| 684 | // See "Special Section" in Chapter 4 in the following document: |
| 685 | // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf |
| 686 | if (Config->EMachine == EM_MIPS) |
| 687 | this->Flags = SHF_ALLOC; |
| 688 | |
| 689 | addEntries(); |
| 690 | } |
| 691 | |
| 692 | // There are some dynamic entries that don't depend on other sections. |
| 693 | // Such entries can be set early. |
| 694 | template <class ELFT> void DynamicSection<ELFT>::addEntries() { |
| 695 | // Add strings to .dynstr early so that .dynstr's size will be |
| 696 | // fixed early. |
| 697 | for (StringRef S : Config->AuxiliaryList) |
| 698 | Add({DT_AUXILIARY, In<ELFT>::DynStrTab->addString(S)}); |
| 699 | if (!Config->RPath.empty()) |
| 700 | Add({Config->EnableNewDtags ? DT_RUNPATH : DT_RPATH, |
| 701 | In<ELFT>::DynStrTab->addString(Config->RPath)}); |
| 702 | for (SharedFile<ELFT> *F : Symtab<ELFT>::X->getSharedFiles()) |
| 703 | if (F->isNeeded()) |
| 704 | Add({DT_NEEDED, In<ELFT>::DynStrTab->addString(F->getSoName())}); |
| 705 | if (!Config->SoName.empty()) |
| 706 | Add({DT_SONAME, In<ELFT>::DynStrTab->addString(Config->SoName)}); |
| 707 | |
| 708 | // Set DT_FLAGS and DT_FLAGS_1. |
| 709 | uint32_t DtFlags = 0; |
| 710 | uint32_t DtFlags1 = 0; |
| 711 | if (Config->Bsymbolic) |
| 712 | DtFlags |= DF_SYMBOLIC; |
| 713 | if (Config->ZNodelete) |
| 714 | DtFlags1 |= DF_1_NODELETE; |
| 715 | if (Config->ZNow) { |
| 716 | DtFlags |= DF_BIND_NOW; |
| 717 | DtFlags1 |= DF_1_NOW; |
| 718 | } |
| 719 | if (Config->ZOrigin) { |
| 720 | DtFlags |= DF_ORIGIN; |
| 721 | DtFlags1 |= DF_1_ORIGIN; |
| 722 | } |
| 723 | |
| 724 | if (DtFlags) |
| 725 | Add({DT_FLAGS, DtFlags}); |
| 726 | if (DtFlags1) |
| 727 | Add({DT_FLAGS_1, DtFlags1}); |
| 728 | |
| 729 | if (!Config->Entry.empty()) |
| 730 | Add({DT_DEBUG, (uint64_t)0}); |
| 731 | } |
| 732 | |
| 733 | // Add remaining entries to complete .dynamic contents. |
| 734 | template <class ELFT> void DynamicSection<ELFT>::finalize() { |
| 735 | if (this->Size) |
| 736 | return; // Already finalized. |
| 737 | |
| 738 | this->Link = In<ELFT>::DynStrTab->OutSec->SectionIndex; |
| 739 | |
Eugene Leviant | a96d902 | 2016-11-16 10:02:27 +0000 | [diff] [blame^] | 740 | if (In<ELFT>::RelaDyn->hasRelocs()) { |
Eugene Leviant | 6380ce2 | 2016-11-15 12:26:55 +0000 | [diff] [blame] | 741 | bool IsRela = Config->Rela; |
Eugene Leviant | a96d902 | 2016-11-16 10:02:27 +0000 | [diff] [blame^] | 742 | Add({IsRela ? DT_RELA : DT_REL, In<ELFT>::RelaDyn}); |
| 743 | Add({IsRela ? DT_RELASZ : DT_RELSZ, In<ELFT>::RelaDyn->getSize()}); |
Eugene Leviant | 6380ce2 | 2016-11-15 12:26:55 +0000 | [diff] [blame] | 744 | Add({IsRela ? DT_RELAENT : DT_RELENT, |
| 745 | uintX_t(IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel))}); |
| 746 | |
| 747 | // MIPS dynamic loader does not support RELCOUNT tag. |
| 748 | // The problem is in the tight relation between dynamic |
| 749 | // relocations and GOT. So do not emit this tag on MIPS. |
| 750 | if (Config->EMachine != EM_MIPS) { |
Eugene Leviant | a96d902 | 2016-11-16 10:02:27 +0000 | [diff] [blame^] | 751 | size_t NumRelativeRels = In<ELFT>::RelaDyn->getRelativeRelocCount(); |
Eugene Leviant | 6380ce2 | 2016-11-15 12:26:55 +0000 | [diff] [blame] | 752 | if (Config->ZCombreloc && NumRelativeRels) |
| 753 | Add({IsRela ? DT_RELACOUNT : DT_RELCOUNT, NumRelativeRels}); |
| 754 | } |
| 755 | } |
Eugene Leviant | a96d902 | 2016-11-16 10:02:27 +0000 | [diff] [blame^] | 756 | if (In<ELFT>::RelaPlt->hasRelocs()) { |
| 757 | Add({DT_JMPREL, In<ELFT>::RelaPlt}); |
| 758 | Add({DT_PLTRELSZ, In<ELFT>::RelaPlt->getSize()}); |
Eugene Leviant | 6380ce2 | 2016-11-15 12:26:55 +0000 | [diff] [blame] | 759 | Add({Config->EMachine == EM_MIPS ? DT_MIPS_PLTGOT : DT_PLTGOT, |
| 760 | In<ELFT>::GotPlt}); |
| 761 | Add({DT_PLTREL, uint64_t(Config->Rela ? DT_RELA : DT_REL)}); |
| 762 | } |
| 763 | |
| 764 | Add({DT_SYMTAB, Out<ELFT>::DynSymTab}); |
| 765 | Add({DT_SYMENT, sizeof(Elf_Sym)}); |
| 766 | Add({DT_STRTAB, In<ELFT>::DynStrTab}); |
| 767 | Add({DT_STRSZ, In<ELFT>::DynStrTab->getSize()}); |
| 768 | if (Out<ELFT>::GnuHashTab) |
| 769 | Add({DT_GNU_HASH, Out<ELFT>::GnuHashTab}); |
| 770 | if (Out<ELFT>::HashTab) |
| 771 | Add({DT_HASH, Out<ELFT>::HashTab}); |
| 772 | |
| 773 | if (Out<ELFT>::PreinitArray) { |
| 774 | Add({DT_PREINIT_ARRAY, Out<ELFT>::PreinitArray}); |
| 775 | Add({DT_PREINIT_ARRAYSZ, Out<ELFT>::PreinitArray, Entry::SecSize}); |
| 776 | } |
| 777 | if (Out<ELFT>::InitArray) { |
| 778 | Add({DT_INIT_ARRAY, Out<ELFT>::InitArray}); |
| 779 | Add({DT_INIT_ARRAYSZ, Out<ELFT>::InitArray, Entry::SecSize}); |
| 780 | } |
| 781 | if (Out<ELFT>::FiniArray) { |
| 782 | Add({DT_FINI_ARRAY, Out<ELFT>::FiniArray}); |
| 783 | Add({DT_FINI_ARRAYSZ, Out<ELFT>::FiniArray, Entry::SecSize}); |
| 784 | } |
| 785 | |
| 786 | if (SymbolBody *B = Symtab<ELFT>::X->find(Config->Init)) |
| 787 | Add({DT_INIT, B}); |
| 788 | if (SymbolBody *B = Symtab<ELFT>::X->find(Config->Fini)) |
| 789 | Add({DT_FINI, B}); |
| 790 | |
| 791 | bool HasVerNeed = Out<ELFT>::VerNeed->getNeedNum() != 0; |
| 792 | if (HasVerNeed || Out<ELFT>::VerDef) |
| 793 | Add({DT_VERSYM, Out<ELFT>::VerSym}); |
| 794 | if (Out<ELFT>::VerDef) { |
| 795 | Add({DT_VERDEF, Out<ELFT>::VerDef}); |
| 796 | Add({DT_VERDEFNUM, getVerDefNum()}); |
| 797 | } |
| 798 | if (HasVerNeed) { |
| 799 | Add({DT_VERNEED, Out<ELFT>::VerNeed}); |
| 800 | Add({DT_VERNEEDNUM, Out<ELFT>::VerNeed->getNeedNum()}); |
| 801 | } |
| 802 | |
| 803 | if (Config->EMachine == EM_MIPS) { |
| 804 | Add({DT_MIPS_RLD_VERSION, 1}); |
| 805 | Add({DT_MIPS_FLAGS, RHF_NOTPOT}); |
| 806 | Add({DT_MIPS_BASE_ADDRESS, Config->ImageBase}); |
| 807 | Add({DT_MIPS_SYMTABNO, Out<ELFT>::DynSymTab->getNumSymbols()}); |
| 808 | Add({DT_MIPS_LOCAL_GOTNO, In<ELFT>::Got->getMipsLocalEntriesNum()}); |
| 809 | if (const SymbolBody *B = In<ELFT>::Got->getMipsFirstGlobalEntry()) |
| 810 | Add({DT_MIPS_GOTSYM, B->DynsymIndex}); |
| 811 | else |
| 812 | Add({DT_MIPS_GOTSYM, Out<ELFT>::DynSymTab->getNumSymbols()}); |
| 813 | Add({DT_PLTGOT, In<ELFT>::Got}); |
| 814 | if (Out<ELFT>::MipsRldMap) |
| 815 | Add({DT_MIPS_RLD_MAP, Out<ELFT>::MipsRldMap}); |
| 816 | } |
| 817 | |
| 818 | this->OutSec->Entsize = this->Entsize; |
| 819 | this->OutSec->Link = this->Link; |
| 820 | |
| 821 | // +1 for DT_NULL |
| 822 | this->Size = (Entries.size() + 1) * this->Entsize; |
| 823 | } |
| 824 | |
| 825 | template <class ELFT> void DynamicSection<ELFT>::writeTo(uint8_t *Buf) { |
| 826 | auto *P = reinterpret_cast<Elf_Dyn *>(Buf); |
| 827 | |
| 828 | for (const Entry &E : Entries) { |
| 829 | P->d_tag = E.Tag; |
| 830 | switch (E.Kind) { |
| 831 | case Entry::SecAddr: |
| 832 | P->d_un.d_ptr = E.OutSec->Addr; |
| 833 | break; |
| 834 | case Entry::InSecAddr: |
| 835 | P->d_un.d_ptr = E.InSec->OutSec->Addr + E.InSec->OutSecOff; |
| 836 | break; |
| 837 | case Entry::SecSize: |
| 838 | P->d_un.d_val = E.OutSec->Size; |
| 839 | break; |
| 840 | case Entry::SymAddr: |
| 841 | P->d_un.d_ptr = E.Sym->template getVA<ELFT>(); |
| 842 | break; |
| 843 | case Entry::PlainInt: |
| 844 | P->d_un.d_val = E.Val; |
| 845 | break; |
| 846 | } |
| 847 | ++P; |
| 848 | } |
| 849 | } |
| 850 | |
Eugene Leviant | a96d902 | 2016-11-16 10:02:27 +0000 | [diff] [blame^] | 851 | template <class ELFT> |
| 852 | typename ELFT::uint DynamicReloc<ELFT>::getOffset() const { |
| 853 | if (OutputSec) |
| 854 | return OutputSec->Addr + OffsetInSec; |
| 855 | return InputSec->OutSec->Addr + InputSec->getOffset(OffsetInSec); |
| 856 | } |
| 857 | |
| 858 | template <class ELFT> |
| 859 | typename ELFT::uint DynamicReloc<ELFT>::getAddend() const { |
| 860 | if (UseSymVA) |
| 861 | return Sym->getVA<ELFT>(Addend); |
| 862 | return Addend; |
| 863 | } |
| 864 | |
| 865 | template <class ELFT> uint32_t DynamicReloc<ELFT>::getSymIndex() const { |
| 866 | if (Sym && !UseSymVA) |
| 867 | return Sym->DynsymIndex; |
| 868 | return 0; |
| 869 | } |
| 870 | |
| 871 | template <class ELFT> |
| 872 | RelocationSection<ELFT>::RelocationSection(StringRef Name, bool Sort) |
| 873 | : SyntheticSection<ELFT>(SHF_ALLOC, Config->Rela ? SHT_RELA : SHT_REL, |
| 874 | sizeof(uintX_t), Name), |
| 875 | Sort(Sort) { |
| 876 | this->Entsize = Config->Rela ? sizeof(Elf_Rela) : sizeof(Elf_Rel); |
| 877 | } |
| 878 | |
| 879 | template <class ELFT> |
| 880 | void RelocationSection<ELFT>::addReloc(const DynamicReloc<ELFT> &Reloc) { |
| 881 | if (Reloc.Type == Target->RelativeRel) |
| 882 | ++NumRelativeRelocs; |
| 883 | Relocs.push_back(Reloc); |
| 884 | } |
| 885 | |
| 886 | template <class ELFT, class RelTy> |
| 887 | static bool compRelocations(const RelTy &A, const RelTy &B) { |
| 888 | bool AIsRel = A.getType(Config->Mips64EL) == Target->RelativeRel; |
| 889 | bool BIsRel = B.getType(Config->Mips64EL) == Target->RelativeRel; |
| 890 | if (AIsRel != BIsRel) |
| 891 | return AIsRel; |
| 892 | |
| 893 | return A.getSymbol(Config->Mips64EL) < B.getSymbol(Config->Mips64EL); |
| 894 | } |
| 895 | |
| 896 | template <class ELFT> void RelocationSection<ELFT>::writeTo(uint8_t *Buf) { |
| 897 | uint8_t *BufBegin = Buf; |
| 898 | for (const DynamicReloc<ELFT> &Rel : Relocs) { |
| 899 | auto *P = reinterpret_cast<Elf_Rela *>(Buf); |
| 900 | Buf += Config->Rela ? sizeof(Elf_Rela) : sizeof(Elf_Rel); |
| 901 | |
| 902 | if (Config->Rela) |
| 903 | P->r_addend = Rel.getAddend(); |
| 904 | P->r_offset = Rel.getOffset(); |
| 905 | if (Config->EMachine == EM_MIPS && Rel.getInputSec() == In<ELFT>::Got) |
| 906 | // Dynamic relocation against MIPS GOT section make deal TLS entries |
| 907 | // allocated in the end of the GOT. We need to adjust the offset to take |
| 908 | // in account 'local' and 'global' GOT entries. |
| 909 | P->r_offset += In<ELFT>::Got->getMipsTlsOffset(); |
| 910 | P->setSymbolAndType(Rel.getSymIndex(), Rel.Type, Config->Mips64EL); |
| 911 | } |
| 912 | |
| 913 | if (Sort) { |
| 914 | if (Config->Rela) |
| 915 | std::stable_sort((Elf_Rela *)BufBegin, |
| 916 | (Elf_Rela *)BufBegin + Relocs.size(), |
| 917 | compRelocations<ELFT, Elf_Rela>); |
| 918 | else |
| 919 | std::stable_sort((Elf_Rel *)BufBegin, (Elf_Rel *)BufBegin + Relocs.size(), |
| 920 | compRelocations<ELFT, Elf_Rel>); |
| 921 | } |
| 922 | } |
| 923 | |
| 924 | template <class ELFT> unsigned RelocationSection<ELFT>::getRelocOffset() { |
| 925 | return this->Entsize * Relocs.size(); |
| 926 | } |
| 927 | |
| 928 | template <class ELFT> void RelocationSection<ELFT>::finalize() { |
| 929 | this->Link = Out<ELFT>::DynSymTab ? Out<ELFT>::DynSymTab->SectionIndex |
| 930 | : Out<ELFT>::SymTab->SectionIndex; |
| 931 | |
| 932 | // Set required output section properties. |
| 933 | this->OutSec->Link = this->Link; |
| 934 | this->OutSec->Entsize = this->Entsize; |
| 935 | } |
| 936 | |
Rafael Espindola | 682a5bc | 2016-11-08 14:42:34 +0000 | [diff] [blame] | 937 | template InputSection<ELF32LE> *elf::createCommonSection(); |
| 938 | template InputSection<ELF32BE> *elf::createCommonSection(); |
| 939 | template InputSection<ELF64LE> *elf::createCommonSection(); |
| 940 | template InputSection<ELF64BE> *elf::createCommonSection(); |
Rui Ueyama | e8a6102 | 2016-11-05 23:05:47 +0000 | [diff] [blame] | 941 | |
Rafael Espindola | c0e47fb | 2016-11-08 14:56:27 +0000 | [diff] [blame] | 942 | template InputSection<ELF32LE> *elf::createInterpSection(); |
| 943 | template InputSection<ELF32BE> *elf::createInterpSection(); |
| 944 | template InputSection<ELF64LE> *elf::createInterpSection(); |
| 945 | template InputSection<ELF64BE> *elf::createInterpSection(); |
Rui Ueyama | e288eef | 2016-11-02 18:58:44 +0000 | [diff] [blame] | 946 | |
Rui Ueyama | 3da3f06 | 2016-11-10 20:20:37 +0000 | [diff] [blame] | 947 | template MergeInputSection<ELF32LE> *elf::createCommentSection(); |
| 948 | template MergeInputSection<ELF32BE> *elf::createCommentSection(); |
| 949 | template MergeInputSection<ELF64LE> *elf::createCommentSection(); |
| 950 | template MergeInputSection<ELF64BE> *elf::createCommentSection(); |
| 951 | |
Simon Atanasyan | fa03b0f | 2016-11-09 21:37:06 +0000 | [diff] [blame] | 952 | template class elf::MipsAbiFlagsSection<ELF32LE>; |
| 953 | template class elf::MipsAbiFlagsSection<ELF32BE>; |
| 954 | template class elf::MipsAbiFlagsSection<ELF64LE>; |
| 955 | template class elf::MipsAbiFlagsSection<ELF64BE>; |
| 956 | |
Simon Atanasyan | ce02cf0 | 2016-11-09 21:36:56 +0000 | [diff] [blame] | 957 | template class elf::MipsOptionsSection<ELF32LE>; |
| 958 | template class elf::MipsOptionsSection<ELF32BE>; |
| 959 | template class elf::MipsOptionsSection<ELF64LE>; |
| 960 | template class elf::MipsOptionsSection<ELF64BE>; |
| 961 | |
| 962 | template class elf::MipsReginfoSection<ELF32LE>; |
| 963 | template class elf::MipsReginfoSection<ELF32BE>; |
| 964 | template class elf::MipsReginfoSection<ELF64LE>; |
| 965 | template class elf::MipsReginfoSection<ELF64BE>; |
| 966 | |
Rui Ueyama | 6dc7fcb | 2016-11-01 20:28:21 +0000 | [diff] [blame] | 967 | template class elf::BuildIdSection<ELF32LE>; |
| 968 | template class elf::BuildIdSection<ELF32BE>; |
| 969 | template class elf::BuildIdSection<ELF64LE>; |
| 970 | template class elf::BuildIdSection<ELF64BE>; |
| 971 | |
| 972 | template class elf::BuildIdFastHash<ELF32LE>; |
| 973 | template class elf::BuildIdFastHash<ELF32BE>; |
| 974 | template class elf::BuildIdFastHash<ELF64LE>; |
| 975 | template class elf::BuildIdFastHash<ELF64BE>; |
| 976 | |
| 977 | template class elf::BuildIdMd5<ELF32LE>; |
| 978 | template class elf::BuildIdMd5<ELF32BE>; |
| 979 | template class elf::BuildIdMd5<ELF64LE>; |
| 980 | template class elf::BuildIdMd5<ELF64BE>; |
| 981 | |
| 982 | template class elf::BuildIdSha1<ELF32LE>; |
| 983 | template class elf::BuildIdSha1<ELF32BE>; |
| 984 | template class elf::BuildIdSha1<ELF64LE>; |
| 985 | template class elf::BuildIdSha1<ELF64BE>; |
| 986 | |
| 987 | template class elf::BuildIdUuid<ELF32LE>; |
| 988 | template class elf::BuildIdUuid<ELF32BE>; |
| 989 | template class elf::BuildIdUuid<ELF64LE>; |
| 990 | template class elf::BuildIdUuid<ELF64BE>; |
| 991 | |
| 992 | template class elf::BuildIdHexstring<ELF32LE>; |
| 993 | template class elf::BuildIdHexstring<ELF32BE>; |
| 994 | template class elf::BuildIdHexstring<ELF64LE>; |
| 995 | template class elf::BuildIdHexstring<ELF64BE>; |
Eugene Leviant | 41ca327 | 2016-11-10 09:48:29 +0000 | [diff] [blame] | 996 | |
Eugene Leviant | ad4439e | 2016-11-11 11:33:32 +0000 | [diff] [blame] | 997 | template class elf::GotSection<ELF32LE>; |
| 998 | template class elf::GotSection<ELF32BE>; |
| 999 | template class elf::GotSection<ELF64LE>; |
| 1000 | template class elf::GotSection<ELF64BE>; |
| 1001 | |
Eugene Leviant | 41ca327 | 2016-11-10 09:48:29 +0000 | [diff] [blame] | 1002 | template class elf::GotPltSection<ELF32LE>; |
| 1003 | template class elf::GotPltSection<ELF32BE>; |
| 1004 | template class elf::GotPltSection<ELF64LE>; |
| 1005 | template class elf::GotPltSection<ELF64BE>; |
Eugene Leviant | 22eb026 | 2016-11-14 09:16:00 +0000 | [diff] [blame] | 1006 | |
| 1007 | template class elf::StringTableSection<ELF32LE>; |
| 1008 | template class elf::StringTableSection<ELF32BE>; |
| 1009 | template class elf::StringTableSection<ELF64LE>; |
| 1010 | template class elf::StringTableSection<ELF64BE>; |
Eugene Leviant | 6380ce2 | 2016-11-15 12:26:55 +0000 | [diff] [blame] | 1011 | |
| 1012 | template class elf::DynamicSection<ELF32LE>; |
| 1013 | template class elf::DynamicSection<ELF32BE>; |
| 1014 | template class elf::DynamicSection<ELF64LE>; |
| 1015 | template class elf::DynamicSection<ELF64BE>; |
Eugene Leviant | a96d902 | 2016-11-16 10:02:27 +0000 | [diff] [blame^] | 1016 | |
| 1017 | template class elf::RelocationSection<ELF32LE>; |
| 1018 | template class elf::RelocationSection<ELF32BE>; |
| 1019 | template class elf::RelocationSection<ELF64LE>; |
| 1020 | template class elf::RelocationSection<ELF64BE>; |