xref: /llvm-project-15.0.7/lld/ELF/Target.cpp (revision b3eef01e)
1 //===- Target.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 // Machine-specific things, such as applying relocations, creation of
11 // GOT or PLT entries, etc., are handled in this file.
12 //
13 // Refer the ELF spec for the single letter varaibles, S, A or P, used
14 // in this file. SA is S+A.
15 //
16 //===----------------------------------------------------------------------===//
17 
18 #include "Target.h"
19 #include "Error.h"
20 #include "OutputSections.h"
21 #include "Symbols.h"
22 
23 #include "llvm/ADT/ArrayRef.h"
24 #include "llvm/Object/ELF.h"
25 #include "llvm/Support/Endian.h"
26 #include "llvm/Support/ELF.h"
27 
28 using namespace llvm;
29 using namespace llvm::object;
30 using namespace llvm::support::endian;
31 using namespace llvm::ELF;
32 
33 namespace lld {
34 namespace elf2 {
35 
36 std::unique_ptr<TargetInfo> Target;
37 
38 template <endianness E> static void add32(void *P, int32_t V) {
39   write32<E>(P, read32<E>(P) + V);
40 }
41 
42 static void add32le(uint8_t *P, int32_t V) { add32<support::little>(P, V); }
43 static void or32le(uint8_t *P, int32_t V) { write32le(P, read32le(P) | V); }
44 
45 template <unsigned N> static void checkInt(int64_t V, uint32_t Type) {
46   if (isInt<N>(V))
47     return;
48   StringRef S = getELFRelocationTypeName(Config->EMachine, Type);
49   error("Relocation " + S + " out of range");
50 }
51 
52 template <unsigned N> static void checkUInt(uint64_t V, uint32_t Type) {
53   if (isUInt<N>(V))
54     return;
55   StringRef S = getELFRelocationTypeName(Config->EMachine, Type);
56   error("Relocation " + S + " out of range");
57 }
58 
59 template <unsigned N> static void checkIntUInt(uint64_t V, uint32_t Type) {
60   if (isInt<N>(V) || isUInt<N>(V))
61     return;
62   StringRef S = getELFRelocationTypeName(Config->EMachine, Type);
63   error("Relocation " + S + " out of range");
64 }
65 
66 template <unsigned N> static void checkAlignment(uint64_t V, uint32_t Type) {
67   if ((V & (N - 1)) == 0)
68     return;
69   StringRef S = getELFRelocationTypeName(Config->EMachine, Type);
70   error("Improper alignment for relocation " + S);
71 }
72 
73 namespace {
74 class X86TargetInfo final : public TargetInfo {
75 public:
76   X86TargetInfo();
77   void writeGotPltHeaderEntries(uint8_t *Buf) const override;
78   unsigned getDynReloc(unsigned Type) const override;
79   bool isTlsDynReloc(unsigned Type) const override;
80   void writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const override;
81   void writePltZeroEntry(uint8_t *Buf, uint64_t GotEntryAddr,
82                          uint64_t PltEntryAddr) const override;
83   void writePltEntry(uint8_t *Buf, uint64_t GotAddr, uint64_t GotEntryAddr,
84                      uint64_t PltEntryAddr, int32_t Index,
85                      unsigned RelOff) const override;
86   bool relocNeedsCopy(uint32_t Type, const SymbolBody &S) const override;
87   bool relocNeedsGot(uint32_t Type, const SymbolBody &S) const override;
88   bool relocNeedsPlt(uint32_t Type, const SymbolBody &S) const override;
89   void relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P,
90                    uint64_t SA, uint8_t *PairedLoc = nullptr) const override;
91 };
92 
93 class X86_64TargetInfo final : public TargetInfo {
94 public:
95   X86_64TargetInfo();
96   unsigned getPltRefReloc(unsigned Type) const override;
97   bool isTlsDynReloc(unsigned Type) const override;
98   void writeGotPltHeaderEntries(uint8_t *Buf) const override;
99   void writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const override;
100   void writePltZeroEntry(uint8_t *Buf, uint64_t GotEntryAddr,
101                          uint64_t PltEntryAddr) const override;
102   void writePltEntry(uint8_t *Buf, uint64_t GotAddr, uint64_t GotEntryAddr,
103                      uint64_t PltEntryAddr, int32_t Index,
104                      unsigned RelOff) const override;
105   bool relocNeedsCopy(uint32_t Type, const SymbolBody &S) const override;
106   bool relocNeedsGot(uint32_t Type, const SymbolBody &S) const override;
107   bool relocNeedsPlt(uint32_t Type, const SymbolBody &S) const override;
108   void relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P,
109                    uint64_t SA, uint8_t *PairedLoc = nullptr) const override;
110   bool isRelRelative(uint32_t Type) const override;
111   bool isTlsOptimized(unsigned Type, const SymbolBody *S) const override;
112   unsigned relocateTlsOptimize(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type,
113                                uint64_t P, uint64_t SA,
114                                const SymbolBody &S) const override;
115 
116 private:
117   void relocateTlsLdToLe(uint8_t *Loc, uint8_t *BufEnd, uint64_t P,
118                          uint64_t SA) const;
119   void relocateTlsGdToLe(uint8_t *Loc, uint8_t *BufEnd, uint64_t P,
120                          uint64_t SA) const;
121   void relocateTlsGdToIe(uint8_t *Loc, uint8_t *BufEnd, uint64_t P,
122                          uint64_t SA) const;
123   void relocateTlsIeToLe(uint8_t *Loc, uint8_t *BufEnd, uint64_t P,
124                          uint64_t SA) const;
125 };
126 
127 class PPC64TargetInfo final : public TargetInfo {
128 public:
129   PPC64TargetInfo();
130   void writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const override;
131   void writePltZeroEntry(uint8_t *Buf, uint64_t GotEntryAddr,
132                          uint64_t PltEntryAddr) const override;
133   void writePltEntry(uint8_t *Buf, uint64_t GotAddr, uint64_t GotEntryAddr,
134                      uint64_t PltEntryAddr, int32_t Index,
135                      unsigned RelOff) const override;
136   bool relocNeedsGot(uint32_t Type, const SymbolBody &S) const override;
137   bool relocNeedsPlt(uint32_t Type, const SymbolBody &S) const override;
138   void relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P,
139                    uint64_t SA, uint8_t *PairedLoc = nullptr) const override;
140   bool isRelRelative(uint32_t Type) const override;
141 };
142 
143 class AArch64TargetInfo final : public TargetInfo {
144 public:
145   AArch64TargetInfo();
146   unsigned getPltRefReloc(unsigned Type) const override;
147   void writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const override;
148   void writePltZeroEntry(uint8_t *Buf, uint64_t GotEntryAddr,
149                          uint64_t PltEntryAddr) const override;
150   void writePltEntry(uint8_t *Buf, uint64_t GotAddr, uint64_t GotEntryAddr,
151                      uint64_t PltEntryAddr, int32_t Index,
152                      unsigned RelOff) const override;
153   bool relocNeedsCopy(uint32_t Type, const SymbolBody &S) const override;
154   bool relocNeedsGot(uint32_t Type, const SymbolBody &S) const override;
155   bool relocNeedsPlt(uint32_t Type, const SymbolBody &S) const override;
156   void relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P,
157                    uint64_t SA, uint8_t *PairedLoc = nullptr) const override;
158 };
159 
160 template <class ELFT> class MipsTargetInfo final : public TargetInfo {
161 public:
162   MipsTargetInfo();
163   void writeGotHeaderEntries(uint8_t *Buf) const override;
164   void writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const override;
165   void writePltZeroEntry(uint8_t *Buf, uint64_t GotEntryAddr,
166                          uint64_t PltEntryAddr) const override;
167   void writePltEntry(uint8_t *Buf, uint64_t GotAddr, uint64_t GotEntryAddr,
168                      uint64_t PltEntryAddr, int32_t Index,
169                      unsigned RelOff) const override;
170   bool relocNeedsGot(uint32_t Type, const SymbolBody &S) const override;
171   bool relocNeedsPlt(uint32_t Type, const SymbolBody &S) const override;
172   void relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P,
173                    uint64_t SA, uint8_t *PairedLoc = nullptr) const override;
174 };
175 } // anonymous namespace
176 
177 TargetInfo *createTarget() {
178   switch (Config->EMachine) {
179   case EM_386:
180     return new X86TargetInfo();
181   case EM_AARCH64:
182     return new AArch64TargetInfo();
183   case EM_MIPS:
184     switch (Config->EKind) {
185     case ELF32LEKind:
186       return new MipsTargetInfo<ELF32LE>();
187     case ELF32BEKind:
188       return new MipsTargetInfo<ELF32BE>();
189     default:
190       error("Unsupported MIPS target");
191     }
192   case EM_PPC64:
193     return new PPC64TargetInfo();
194   case EM_X86_64:
195     return new X86_64TargetInfo();
196   }
197   error("Unknown target machine");
198 }
199 
200 TargetInfo::~TargetInfo() {}
201 
202 bool TargetInfo::isTlsOptimized(unsigned Type, const SymbolBody *S) const {
203   return false;
204 }
205 
206 uint64_t TargetInfo::getVAStart() const { return Config->Shared ? 0 : VAStart; }
207 
208 bool TargetInfo::relocNeedsCopy(uint32_t Type, const SymbolBody &S) const {
209   return false;
210 }
211 
212 unsigned TargetInfo::getPltRefReloc(unsigned Type) const { return PCRelReloc; }
213 
214 bool TargetInfo::isRelRelative(uint32_t Type) const { return true; }
215 
216 unsigned TargetInfo::relocateTlsOptimize(uint8_t *Loc, uint8_t *BufEnd,
217                                          uint32_t Type, uint64_t P, uint64_t SA,
218                                          const SymbolBody &S) const {
219   return 0;
220 }
221 
222 void TargetInfo::writeGotHeaderEntries(uint8_t *Buf) const {}
223 
224 void TargetInfo::writeGotPltHeaderEntries(uint8_t *Buf) const {}
225 
226 X86TargetInfo::X86TargetInfo() {
227   CopyReloc = R_386_COPY;
228   PCRelReloc = R_386_PC32;
229   GotReloc = R_386_GLOB_DAT;
230   PltReloc = R_386_JUMP_SLOT;
231   TlsGotReloc = R_386_TLS_TPOFF;
232   TlsGlobalDynamicReloc = R_386_TLS_GD;
233   TlsLocalDynamicReloc = R_386_TLS_LDM;
234   TlsModuleIndexReloc = R_386_TLS_DTPMOD32;
235   TlsOffsetReloc = R_386_TLS_DTPOFF32;
236   LazyRelocations = true;
237   PltEntrySize = 16;
238   PltZeroEntrySize = 16;
239 }
240 
241 void X86TargetInfo::writeGotPltHeaderEntries(uint8_t *Buf) const {
242   write32le(Buf, Out<ELF32LE>::Dynamic->getVA());
243 }
244 
245 void X86TargetInfo::writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const {
246   // Skip 6 bytes of "pushl (GOT+4)"
247   write32le(Buf, Plt + 6);
248 }
249 
250 unsigned X86TargetInfo::getDynReloc(unsigned Type) const {
251   if (Type == R_386_TLS_LE)
252     return R_386_TLS_TPOFF;
253   if (Type == R_386_TLS_LE_32)
254     return R_386_TLS_TPOFF32;
255   return Type;
256 }
257 
258 bool X86TargetInfo::isTlsDynReloc(unsigned Type) const {
259   if (Type == R_386_TLS_LE || Type == R_386_TLS_LE_32 ||
260       Type == R_386_TLS_GOTIE)
261     return Config->Shared;
262   return false;
263 }
264 
265 void X86TargetInfo::writePltZeroEntry(uint8_t *Buf, uint64_t GotEntryAddr,
266                                       uint64_t PltEntryAddr) const {
267   // Executable files and shared object files have
268   // separate procedure linkage tables.
269   if (Config->Shared) {
270     const uint8_t V[] = {
271         0xff, 0xb3, 0x04, 0x00, 0x00, 0x00, // pushl 4(%ebx
272         0xff, 0xa3, 0x08, 0x00, 0x00, 0x00, // jmp *8(%ebx)
273         0x90, 0x90, 0x90, 0x90              // nop;nop;nop;nop
274     };
275     memcpy(Buf, V, sizeof(V));
276     return;
277   }
278 
279   const uint8_t PltData[] = {
280       0xff, 0x35, 0x00, 0x00, 0x00, 0x00, // pushl (GOT+4)
281       0xff, 0x25, 0x00, 0x00, 0x00, 0x00, // jmp *(GOT+8)
282       0x90, 0x90, 0x90, 0x90              // nop;nop;nop;nop
283   };
284   memcpy(Buf, PltData, sizeof(PltData));
285   write32le(Buf + 2, GotEntryAddr + 4); // GOT+4
286   write32le(Buf + 8, GotEntryAddr + 8); // GOT+8
287 }
288 
289 void X86TargetInfo::writePltEntry(uint8_t *Buf, uint64_t GotAddr,
290                                   uint64_t GotEntryAddr, uint64_t PltEntryAddr,
291                                   int32_t Index, unsigned RelOff) const {
292   const uint8_t Inst[] = {
293       0xff, 0x00, 0x00, 0x00, 0x00, 0x00, // jmp *foo_in_GOT|*foo@GOT(%ebx)
294       0x68, 0x00, 0x00, 0x00, 0x00,       // pushl $reloc_offset
295       0xe9, 0x00, 0x00, 0x00, 0x00        // jmp .PLT0@PC
296   };
297   memcpy(Buf, Inst, sizeof(Inst));
298   // jmp *foo@GOT(%ebx) or jmp *foo_in_GOT
299   Buf[1] = Config->Shared ? 0xa3 : 0x25;
300   write32le(Buf + 2, Config->Shared ? (GotEntryAddr - GotAddr) : GotEntryAddr);
301   write32le(Buf + 7, RelOff);
302   write32le(Buf + 12, -Index * PltEntrySize - PltZeroEntrySize - 16);
303 }
304 
305 bool X86TargetInfo::relocNeedsCopy(uint32_t Type, const SymbolBody &S) const {
306   if (Type == R_386_32 || Type == R_386_16 || Type == R_386_8)
307     if (auto *SS = dyn_cast<SharedSymbol<ELF32LE>>(&S))
308       return SS->Sym.getType() == STT_OBJECT;
309   return false;
310 }
311 
312 bool X86TargetInfo::relocNeedsGot(uint32_t Type, const SymbolBody &S) const {
313   return Type == R_386_TLS_GOTIE || Type == R_386_GOT32 ||
314          relocNeedsPlt(Type, S);
315 }
316 
317 bool X86TargetInfo::relocNeedsPlt(uint32_t Type, const SymbolBody &S) const {
318   return Type == R_386_PLT32 || (Type == R_386_PC32 && S.isShared());
319 }
320 
321 void X86TargetInfo::relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type,
322                                 uint64_t P, uint64_t SA,
323                                 uint8_t *PairedLoc) const {
324   switch (Type) {
325   case R_386_32:
326     add32le(Loc, SA);
327     break;
328   case R_386_GOT32:
329     add32le(Loc, SA - Out<ELF32LE>::Got->getVA());
330     break;
331   case R_386_GOTPC:
332     add32le(Loc, SA + Out<ELF32LE>::Got->getVA() - P);
333     break;
334   case R_386_PC32:
335     add32le(Loc, SA - P);
336     break;
337   case R_386_TLS_GD:
338   case R_386_TLS_LDM:
339   case R_386_TLS_TPOFF: {
340     uint64_t V = SA - Out<ELF32LE>::Got->getVA() -
341                  Out<ELF32LE>::Got->getNumEntries() * 4;
342     checkInt<32>(V, Type);
343     write32le(Loc, V);
344     break;
345   }
346   case R_386_TLS_LDO_32:
347     write32le(Loc, SA);
348     break;
349   case R_386_TLS_LE:
350     write32le(Loc, SA - Out<ELF32LE>::TlsPhdr->p_memsz);
351     break;
352   case R_386_TLS_LE_32:
353     write32le(Loc, Out<ELF32LE>::TlsPhdr->p_memsz - SA);
354     break;
355   default:
356     error("unrecognized reloc " + Twine(Type));
357   }
358 }
359 
360 X86_64TargetInfo::X86_64TargetInfo() {
361   CopyReloc = R_X86_64_COPY;
362   PCRelReloc = R_X86_64_PC32;
363   GotReloc = R_X86_64_GLOB_DAT;
364   PltReloc = R_X86_64_JUMP_SLOT;
365   RelativeReloc = R_X86_64_RELATIVE;
366   TlsGotReloc = R_X86_64_TPOFF64;
367   TlsLocalDynamicReloc = R_X86_64_TLSLD;
368   TlsGlobalDynamicReloc = R_X86_64_TLSGD;
369   TlsModuleIndexReloc = R_X86_64_DTPMOD64;
370   TlsOffsetReloc = R_X86_64_DTPOFF64;
371   LazyRelocations = true;
372   PltEntrySize = 16;
373   PltZeroEntrySize = 16;
374 }
375 
376 void X86_64TargetInfo::writeGotPltHeaderEntries(uint8_t *Buf) const {
377   write64le(Buf, Out<ELF64LE>::Dynamic->getVA());
378 }
379 
380 void X86_64TargetInfo::writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const {
381   // Skip 6 bytes of "jmpq *got(%rip)"
382   write32le(Buf, Plt + 6);
383 }
384 
385 void X86_64TargetInfo::writePltZeroEntry(uint8_t *Buf, uint64_t GotEntryAddr,
386                                          uint64_t PltEntryAddr) const {
387   const uint8_t PltData[] = {
388       0xff, 0x35, 0x00, 0x00, 0x00, 0x00, // pushq GOT+8(%rip)
389       0xff, 0x25, 0x00, 0x00, 0x00, 0x00, // jmp *GOT+16(%rip)
390       0x0f, 0x1f, 0x40, 0x00              // nopl 0x0(rax)
391   };
392   memcpy(Buf, PltData, sizeof(PltData));
393   write32le(Buf + 2, GotEntryAddr - PltEntryAddr + 2); // GOT+8
394   write32le(Buf + 8, GotEntryAddr - PltEntryAddr + 4); // GOT+16
395 }
396 
397 void X86_64TargetInfo::writePltEntry(uint8_t *Buf, uint64_t GotAddr,
398                                      uint64_t GotEntryAddr,
399                                      uint64_t PltEntryAddr, int32_t Index,
400                                      unsigned RelOff) const {
401   const uint8_t Inst[] = {
402       0xff, 0x25, 0x00, 0x00, 0x00, 0x00, // jmpq *got(%rip)
403       0x68, 0x00, 0x00, 0x00, 0x00,       // pushq <relocation index>
404       0xe9, 0x00, 0x00, 0x00, 0x00        // jmpq plt[0]
405   };
406   memcpy(Buf, Inst, sizeof(Inst));
407 
408   write32le(Buf + 2, GotEntryAddr - PltEntryAddr - 6);
409   write32le(Buf + 7, Index);
410   write32le(Buf + 12, -Index * PltEntrySize - PltZeroEntrySize - 16);
411 }
412 
413 bool X86_64TargetInfo::relocNeedsCopy(uint32_t Type,
414                                       const SymbolBody &S) const {
415   if (Type == R_X86_64_32S || Type == R_X86_64_32 || Type == R_X86_64_PC32 ||
416       Type == R_X86_64_64)
417     if (auto *SS = dyn_cast<SharedSymbol<ELF64LE>>(&S))
418       return SS->Sym.getType() == STT_OBJECT;
419   return false;
420 }
421 
422 bool X86_64TargetInfo::relocNeedsGot(uint32_t Type, const SymbolBody &S) const {
423   if (Type == R_X86_64_TLSGD)
424     return Target->isTlsOptimized(Type, &S) && canBePreempted(&S, true);
425   if (Type == R_X86_64_GOTTPOFF)
426     return !isTlsOptimized(Type, &S);
427   return Type == R_X86_64_GOTPCREL || relocNeedsPlt(Type, S);
428 }
429 
430 bool X86_64TargetInfo::isTlsDynReloc(unsigned Type) const {
431   return Type == R_X86_64_GOTTPOFF || Type == R_X86_64_TLSGD;
432 }
433 
434 unsigned X86_64TargetInfo::getPltRefReloc(unsigned Type) const {
435   if (Type == R_X86_64_PLT32)
436     return R_X86_64_PC32;
437   return Type;
438 }
439 
440 bool X86_64TargetInfo::relocNeedsPlt(uint32_t Type, const SymbolBody &S) const {
441   if (relocNeedsCopy(Type, S))
442     return false;
443 
444   switch (Type) {
445   default:
446     return false;
447   case R_X86_64_32:
448   case R_X86_64_64:
449   case R_X86_64_PC32:
450     // This relocation is defined to have a value of (S + A - P).
451     // The problems start when a non PIC program calls a function in a shared
452     // library.
453     // In an ideal world, we could just report an error saying the relocation
454     // can overflow at runtime.
455     // In the real world with glibc, crt1.o has a R_X86_64_PC32 pointing to
456     // libc.so.
457     //
458     // The general idea on how to handle such cases is to create a PLT entry
459     // and use that as the function value.
460     //
461     // For the static linking part, we just return true and everything else
462     // will use the the PLT entry as the address.
463     //
464     // The remaining (unimplemented) problem is making sure pointer equality
465     // still works. We need the help of the dynamic linker for that. We
466     // let it know that we have a direct reference to a so symbol by creating
467     // an undefined symbol with a non zero st_value. Seeing that, the
468     // dynamic linker resolves the symbol to the value of the symbol we created.
469     // This is true even for got entries, so pointer equality is maintained.
470     // To avoid an infinite loop, the only entry that points to the
471     // real function is a dedicated got entry used by the plt. That is
472     // identified by special relocation types (R_X86_64_JUMP_SLOT,
473     // R_386_JMP_SLOT, etc).
474     return S.isShared();
475   case R_X86_64_PLT32:
476     return canBePreempted(&S, true);
477   }
478 }
479 
480 bool X86_64TargetInfo::isRelRelative(uint32_t Type) const {
481   switch (Type) {
482   default:
483     return false;
484   case R_X86_64_DTPOFF32:
485   case R_X86_64_DTPOFF64:
486   case R_X86_64_PC8:
487   case R_X86_64_PC16:
488   case R_X86_64_PC32:
489   case R_X86_64_PC64:
490   case R_X86_64_PLT32:
491     return true;
492   }
493 }
494 
495 bool X86_64TargetInfo::isTlsOptimized(unsigned Type,
496                                       const SymbolBody *S) const {
497   if (Config->Shared || (S && !S->isTLS()))
498     return false;
499   return Type == R_X86_64_TLSGD || Type == R_X86_64_TLSLD ||
500          Type == R_X86_64_DTPOFF32 ||
501          (Type == R_X86_64_GOTTPOFF && !canBePreempted(S, true));
502 }
503 
504 // "Ulrich Drepper, ELF Handling For Thread-Local Storage" (5.5
505 // x86-x64 linker optimizations, http://www.akkadia.org/drepper/tls.pdf) shows
506 // how LD can be optimized to LE:
507 //   leaq bar@tlsld(%rip), %rdi
508 //   callq __tls_get_addr@PLT
509 //   leaq bar@dtpoff(%rax), %rcx
510 // Is converted to:
511 //  .word 0x6666
512 //  .byte 0x66
513 //  mov %fs:0,%rax
514 //  leaq bar@tpoff(%rax), %rcx
515 void X86_64TargetInfo::relocateTlsLdToLe(uint8_t *Loc, uint8_t *BufEnd,
516                                          uint64_t P, uint64_t SA) const {
517   const uint8_t Inst[] = {
518       0x66, 0x66,                                          //.word 0x6666
519       0x66,                                                //.byte 0x66
520       0x64, 0x48, 0x8b, 0x04, 0x25, 0x00, 0x00, 0x00, 0x00 // mov %fs:0,%rax
521   };
522   memcpy(Loc - 3, Inst, sizeof(Inst));
523 }
524 
525 // "Ulrich Drepper, ELF Handling For Thread-Local Storage" (5.5
526 // x86-x64 linker optimizations, http://www.akkadia.org/drepper/tls.pdf) shows
527 // how GD can be optimized to LE:
528 //  .byte 0x66
529 //  leaq x@tlsgd(%rip), %rdi
530 //  .word 0x6666
531 //  rex64
532 //  call __tls_get_addr@plt
533 // Is converted to:
534 //  mov %fs:0x0,%rax
535 //  lea x@tpoff,%rax
536 void X86_64TargetInfo::relocateTlsGdToLe(uint8_t *Loc, uint8_t *BufEnd,
537                                          uint64_t P, uint64_t SA) const {
538   const uint8_t Inst[] = {
539       0x64, 0x48, 0x8b, 0x04, 0x25, 0x00, 0x00, 0x00, 0x00, // mov %fs:0x0,%rax
540       0x48, 0x8d, 0x80, 0x00, 0x00, 0x00, 0x00              // lea x@tpoff,%rax
541   };
542   memcpy(Loc - 4, Inst, sizeof(Inst));
543   relocateOne(Loc + 8, BufEnd, R_X86_64_TPOFF32, P, SA);
544 }
545 
546 // "Ulrich Drepper, ELF Handling For Thread-Local Storage" (5.5
547 // x86-x64 linker optimizations, http://www.akkadia.org/drepper/tls.pdf) shows
548 // how GD can be optimized to IE:
549 //  .byte 0x66
550 //  leaq x@tlsgd(%rip), %rdi
551 //  .word 0x6666
552 //  rex64
553 //  call __tls_get_addr@plt
554 // Is converted to:
555 //  mov %fs:0x0,%rax
556 //  addq x@tpoff,%rax
557 void X86_64TargetInfo::relocateTlsGdToIe(uint8_t *Loc, uint8_t *BufEnd,
558                                          uint64_t P, uint64_t SA) const {
559   const uint8_t Inst[] = {
560       0x64, 0x48, 0x8b, 0x04, 0x25, 0x00, 0x00, 0x00, 0x00, // mov %fs:0x0,%rax
561       0x48, 0x03, 0x05, 0x00, 0x00, 0x00, 0x00              // addq x@tpoff,%rax
562   };
563   memcpy(Loc - 4, Inst, sizeof(Inst));
564   relocateOne(Loc + 8, BufEnd, R_X86_64_TPOFF64, P + 12, SA);
565 }
566 
567 // In some conditions, R_X86_64_GOTTPOFF relocation can be optimized to
568 // R_X86_64_TPOFF32 so that R_X86_64_TPOFF32 so that it does not use GOT.
569 // This function does that. Read "ELF Handling For Thread-Local Storage,
570 // 5.5 x86-x64 linker optimizations" (http://www.akkadia.org/drepper/tls.pdf)
571 // by Ulrich Drepper for details.
572 void X86_64TargetInfo::relocateTlsIeToLe(uint8_t *Loc, uint8_t *BufEnd,
573                                          uint64_t P, uint64_t SA) const {
574   // Ulrich's document section 6.5 says that @gottpoff(%rip) must be
575   // used in MOVQ or ADDQ instructions only.
576   // "MOVQ foo@GOTTPOFF(%RIP), %REG" is transformed to "MOVQ $foo, %REG".
577   // "ADDQ foo@GOTTPOFF(%RIP), %REG" is transformed to "LEAQ foo(%REG), %REG"
578   // (if the register is not RSP/R12) or "ADDQ $foo, %RSP".
579   // Opcodes info can be found at http://ref.x86asm.net/coder64.html#x48.
580   uint8_t *Prefix = Loc - 3;
581   uint8_t *Inst = Loc - 2;
582   uint8_t *RegSlot = Loc - 1;
583   uint8_t Reg = Loc[-1] >> 3;
584   bool IsMov = *Inst == 0x8b;
585   bool RspAdd = !IsMov && Reg == 4;
586   // r12 and rsp registers requires special handling.
587   // Problem is that for other registers, for example leaq 0xXXXXXXXX(%r11),%r11
588   // result out is 7 bytes: 4d 8d 9b XX XX XX XX,
589   // but leaq 0xXXXXXXXX(%r12),%r12 is 8 bytes: 4d 8d a4 24 XX XX XX XX.
590   // The same true for rsp. So we convert to addq for them, saving 1 byte that
591   // we dont have.
592   if (RspAdd)
593     *Inst = 0x81;
594   else
595     *Inst = IsMov ? 0xc7 : 0x8d;
596   if (*Prefix == 0x4c)
597     *Prefix = (IsMov || RspAdd) ? 0x49 : 0x4d;
598   *RegSlot = (IsMov || RspAdd) ? (0xc0 | Reg) : (0x80 | Reg | (Reg << 3));
599   relocateOne(Loc, BufEnd, R_X86_64_TPOFF32, P, SA);
600 }
601 
602 // This function applies a TLS relocation with an optimization as described
603 // in the Ulrich's document. As a result of rewriting instructions at the
604 // relocation target, relocations immediately follow the TLS relocation (which
605 // would be applied to rewritten instructions) may have to be skipped.
606 // This function returns a number of relocations that need to be skipped.
607 unsigned X86_64TargetInfo::relocateTlsOptimize(uint8_t *Loc, uint8_t *BufEnd,
608                                                uint32_t Type, uint64_t P,
609                                                uint64_t SA,
610                                                const SymbolBody &S) const {
611   switch (Type) {
612   case R_X86_64_DTPOFF32:
613     relocateOne(Loc, BufEnd, R_X86_64_TPOFF32, P, SA);
614     return 0;
615   case R_X86_64_GOTTPOFF:
616     relocateTlsIeToLe(Loc, BufEnd, P, SA);
617     return 0;
618   case R_X86_64_TLSGD: {
619     if (canBePreempted(&S, true))
620       relocateTlsGdToIe(Loc, BufEnd, P, SA);
621     else
622       relocateTlsGdToLe(Loc, BufEnd, P, SA);
623     // The next relocation should be against __tls_get_addr, so skip it
624     return 1;
625   }
626   case R_X86_64_TLSLD:
627     relocateTlsLdToLe(Loc, BufEnd, P, SA);
628     // The next relocation should be against __tls_get_addr, so skip it
629     return 1;
630   }
631   llvm_unreachable("Unknown TLS optimization");
632 }
633 
634 void X86_64TargetInfo::relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type,
635                                    uint64_t P, uint64_t SA,
636                                    uint8_t *PairedLoc) const {
637   switch (Type) {
638   case R_X86_64_32:
639     checkUInt<32>(SA, Type);
640     write32le(Loc, SA);
641     break;
642   case R_X86_64_32S:
643     checkInt<32>(SA, Type);
644     write32le(Loc, SA);
645     break;
646   case R_X86_64_64:
647     write64le(Loc, SA);
648     break;
649   case R_X86_64_DTPOFF32:
650     write32le(Loc, SA);
651     break;
652   case R_X86_64_DTPOFF64:
653     write64le(Loc, SA);
654     break;
655   case R_X86_64_GOTPCREL:
656   case R_X86_64_PC32:
657   case R_X86_64_PLT32:
658   case R_X86_64_TLSGD:
659   case R_X86_64_TLSLD:
660     write32le(Loc, SA - P);
661     break;
662   case R_X86_64_TPOFF32: {
663     uint64_t Val = SA - Out<ELF64LE>::TlsPhdr->p_memsz;
664     checkInt<32>(Val, Type);
665     write32le(Loc, Val);
666     break;
667   }
668   case R_X86_64_TPOFF64:
669     write32le(Loc, SA - P);
670     break;
671   default:
672     error("unrecognized reloc " + Twine(Type));
673   }
674 }
675 
676 // Relocation masks following the #lo(value), #hi(value), #ha(value),
677 // #higher(value), #highera(value), #highest(value), and #highesta(value)
678 // macros defined in section 4.5.1. Relocation Types of the PPC-elf64abi
679 // document.
680 static uint16_t applyPPCLo(uint64_t V) { return V; }
681 static uint16_t applyPPCHi(uint64_t V) { return V >> 16; }
682 static uint16_t applyPPCHa(uint64_t V) { return (V + 0x8000) >> 16; }
683 static uint16_t applyPPCHigher(uint64_t V) { return V >> 32; }
684 static uint16_t applyPPCHighera(uint64_t V) { return (V + 0x8000) >> 32; }
685 static uint16_t applyPPCHighest(uint64_t V) { return V >> 48; }
686 static uint16_t applyPPCHighesta(uint64_t V) { return (V + 0x8000) >> 48; }
687 
688 PPC64TargetInfo::PPC64TargetInfo() {
689   PCRelReloc = R_PPC64_REL24;
690   GotReloc = R_PPC64_GLOB_DAT;
691   RelativeReloc = R_PPC64_RELATIVE;
692   PltEntrySize = 32;
693 
694   // We need 64K pages (at least under glibc/Linux, the loader won't
695   // set different permissions on a finer granularity than that).
696   PageSize = 65536;
697 
698   // The PPC64 ELF ABI v1 spec, says:
699   //
700   //   It is normally desirable to put segments with different characteristics
701   //   in separate 256 Mbyte portions of the address space, to give the
702   //   operating system full paging flexibility in the 64-bit address space.
703   //
704   // And because the lowest non-zero 256M boundary is 0x10000000, PPC64 linkers
705   // use 0x10000000 as the starting address.
706   VAStart = 0x10000000;
707 }
708 
709 uint64_t getPPC64TocBase() {
710   // The TOC consists of sections .got, .toc, .tocbss, .plt in that
711   // order. The TOC starts where the first of these sections starts.
712 
713   // FIXME: This obviously does not do the right thing when there is no .got
714   // section, but there is a .toc or .tocbss section.
715   uint64_t TocVA = Out<ELF64BE>::Got->getVA();
716   if (!TocVA)
717     TocVA = Out<ELF64BE>::Plt->getVA();
718 
719   // Per the ppc64-elf-linux ABI, The TOC base is TOC value plus 0x8000
720   // thus permitting a full 64 Kbytes segment. Note that the glibc startup
721   // code (crt1.o) assumes that you can get from the TOC base to the
722   // start of the .toc section with only a single (signed) 16-bit relocation.
723   return TocVA + 0x8000;
724 }
725 
726 void PPC64TargetInfo::writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const {}
727 void PPC64TargetInfo::writePltZeroEntry(uint8_t *Buf, uint64_t GotEntryAddr,
728                                         uint64_t PltEntryAddr) const {}
729 void PPC64TargetInfo::writePltEntry(uint8_t *Buf, uint64_t GotAddr,
730                                     uint64_t GotEntryAddr,
731                                     uint64_t PltEntryAddr, int32_t Index,
732                                     unsigned RelOff) const {
733   uint64_t Off = GotEntryAddr - getPPC64TocBase();
734 
735   // FIXME: What we should do, in theory, is get the offset of the function
736   // descriptor in the .opd section, and use that as the offset from %r2 (the
737   // TOC-base pointer). Instead, we have the GOT-entry offset, and that will
738   // be a pointer to the function descriptor in the .opd section. Using
739   // this scheme is simpler, but requires an extra indirection per PLT dispatch.
740 
741   write32be(Buf,      0xf8410028);                   // std %r2, 40(%r1)
742   write32be(Buf + 4,  0x3d620000 | applyPPCHa(Off)); // addis %r11, %r2, X@ha
743   write32be(Buf + 8,  0xe98b0000 | applyPPCLo(Off)); // ld %r12, X@l(%r11)
744   write32be(Buf + 12, 0xe96c0000);                   // ld %r11,0(%r12)
745   write32be(Buf + 16, 0x7d6903a6);                   // mtctr %r11
746   write32be(Buf + 20, 0xe84c0008);                   // ld %r2,8(%r12)
747   write32be(Buf + 24, 0xe96c0010);                   // ld %r11,16(%r12)
748   write32be(Buf + 28, 0x4e800420);                   // bctr
749 }
750 
751 bool PPC64TargetInfo::relocNeedsGot(uint32_t Type, const SymbolBody &S) const {
752   if (relocNeedsPlt(Type, S))
753     return true;
754 
755   switch (Type) {
756   default: return false;
757   case R_PPC64_GOT16:
758   case R_PPC64_GOT16_DS:
759   case R_PPC64_GOT16_HA:
760   case R_PPC64_GOT16_HI:
761   case R_PPC64_GOT16_LO:
762   case R_PPC64_GOT16_LO_DS:
763     return true;
764   }
765 }
766 
767 bool PPC64TargetInfo::relocNeedsPlt(uint32_t Type, const SymbolBody &S) const {
768   // These are function calls that need to be redirected through a PLT stub.
769   return Type == R_PPC64_REL24 && canBePreempted(&S, false);
770 }
771 
772 bool PPC64TargetInfo::isRelRelative(uint32_t Type) const {
773   switch (Type) {
774   default:
775     return true;
776   case R_PPC64_ADDR64:
777   case R_PPC64_TOC:
778     return false;
779   }
780 }
781 
782 void PPC64TargetInfo::relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type,
783                                   uint64_t P, uint64_t SA,
784                                   uint8_t *PairedLoc) const {
785   uint64_t TB = getPPC64TocBase();
786 
787   // For a TOC-relative relocation, adjust the addend and proceed in terms of
788   // the corresponding ADDR16 relocation type.
789   switch (Type) {
790   case R_PPC64_TOC16:       Type = R_PPC64_ADDR16;       SA -= TB; break;
791   case R_PPC64_TOC16_DS:    Type = R_PPC64_ADDR16_DS;    SA -= TB; break;
792   case R_PPC64_TOC16_HA:    Type = R_PPC64_ADDR16_HA;    SA -= TB; break;
793   case R_PPC64_TOC16_HI:    Type = R_PPC64_ADDR16_HI;    SA -= TB; break;
794   case R_PPC64_TOC16_LO:    Type = R_PPC64_ADDR16_LO;    SA -= TB; break;
795   case R_PPC64_TOC16_LO_DS: Type = R_PPC64_ADDR16_LO_DS; SA -= TB; break;
796   default: break;
797   }
798 
799   switch (Type) {
800   case R_PPC64_ADDR14: {
801     checkAlignment<4>(SA, Type);
802     // Preserve the AA/LK bits in the branch instruction
803     uint8_t AALK = Loc[3];
804     write16be(Loc + 2, (AALK & 3) | (SA & 0xfffc));
805     break;
806   }
807   case R_PPC64_ADDR16:
808     checkInt<16>(SA, Type);
809     write16be(Loc, SA);
810     break;
811   case R_PPC64_ADDR16_DS:
812     checkInt<16>(SA, Type);
813     write16be(Loc, (read16be(Loc) & 3) | (SA & ~3));
814     break;
815   case R_PPC64_ADDR16_HA:
816     write16be(Loc, applyPPCHa(SA));
817     break;
818   case R_PPC64_ADDR16_HI:
819     write16be(Loc, applyPPCHi(SA));
820     break;
821   case R_PPC64_ADDR16_HIGHER:
822     write16be(Loc, applyPPCHigher(SA));
823     break;
824   case R_PPC64_ADDR16_HIGHERA:
825     write16be(Loc, applyPPCHighera(SA));
826     break;
827   case R_PPC64_ADDR16_HIGHEST:
828     write16be(Loc, applyPPCHighest(SA));
829     break;
830   case R_PPC64_ADDR16_HIGHESTA:
831     write16be(Loc, applyPPCHighesta(SA));
832     break;
833   case R_PPC64_ADDR16_LO:
834     write16be(Loc, applyPPCLo(SA));
835     break;
836   case R_PPC64_ADDR16_LO_DS:
837     write16be(Loc, (read16be(Loc) & 3) | (applyPPCLo(SA) & ~3));
838     break;
839   case R_PPC64_ADDR32:
840     checkInt<32>(SA, Type);
841     write32be(Loc, SA);
842     break;
843   case R_PPC64_ADDR64:
844     write64be(Loc, SA);
845     break;
846   case R_PPC64_REL16_HA:
847     write16be(Loc, applyPPCHa(SA - P));
848     break;
849   case R_PPC64_REL16_HI:
850     write16be(Loc, applyPPCHi(SA - P));
851     break;
852   case R_PPC64_REL16_LO:
853     write16be(Loc, applyPPCLo(SA - P));
854     break;
855   case R_PPC64_REL24: {
856     // If we have an undefined weak symbol, we might get here with a symbol
857     // address of zero. That could overflow, but the code must be unreachable,
858     // so don't bother doing anything at all.
859     if (!SA)
860       break;
861 
862     uint64_t PltStart = Out<ELF64BE>::Plt->getVA();
863     uint64_t PltEnd = PltStart + Out<ELF64BE>::Plt->getSize();
864     bool InPlt = PltStart <= SA && SA < PltEnd;
865 
866     if (!InPlt && Out<ELF64BE>::Opd) {
867       // If this is a local call, and we currently have the address of a
868       // function-descriptor, get the underlying code address instead.
869       uint64_t OpdStart = Out<ELF64BE>::Opd->getVA();
870       uint64_t OpdEnd = OpdStart + Out<ELF64BE>::Opd->getSize();
871       bool InOpd = OpdStart <= SA && SA < OpdEnd;
872 
873       if (InOpd)
874         SA = read64be(&Out<ELF64BE>::OpdBuf[SA - OpdStart]);
875     }
876 
877     uint32_t Mask = 0x03FFFFFC;
878     checkInt<24>(SA - P, Type);
879     write32be(Loc, (read32be(Loc) & ~Mask) | ((SA - P) & Mask));
880 
881     uint32_t Nop = 0x60000000;
882     if (InPlt && Loc + 8 <= BufEnd && read32be(Loc + 4) == Nop)
883       write32be(Loc + 4, 0xe8410028); // ld %r2, 40(%r1)
884     break;
885   }
886   case R_PPC64_REL32:
887     checkInt<32>(SA - P, Type);
888     write32be(Loc, SA - P);
889     break;
890   case R_PPC64_REL64:
891     write64be(Loc, SA - P);
892     break;
893   case R_PPC64_TOC:
894     write64be(Loc, SA);
895     break;
896   default:
897     error("unrecognized reloc " + Twine(Type));
898   }
899 }
900 
901 AArch64TargetInfo::AArch64TargetInfo() {
902   CopyReloc = R_AARCH64_COPY;
903   GotReloc = R_AARCH64_GLOB_DAT;
904   PltReloc = R_AARCH64_JUMP_SLOT;
905   LazyRelocations = true;
906   PltEntrySize = 16;
907   PltZeroEntrySize = 32;
908 }
909 
910 unsigned AArch64TargetInfo::getPltRefReloc(unsigned Type) const { return Type; }
911 
912 void AArch64TargetInfo::writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const {
913   write64le(Buf, Out<ELF64LE>::Plt->getVA());
914 }
915 
916 void AArch64TargetInfo::writePltZeroEntry(uint8_t *Buf, uint64_t GotEntryAddr,
917                                           uint64_t PltEntryAddr) const {
918   const uint8_t PltData[] = {
919       0xf0, 0x7b, 0xbf, 0xa9, // stp	x16, x30, [sp,#-16]!
920       0x10, 0x00, 0x00, 0x90, // adrp	x16, Page(&(.plt.got[2]))
921       0x11, 0x02, 0x40, 0xf9, // ldr	x17, [x16, Offset(&(.plt.got[2]))]
922       0x10, 0x02, 0x00, 0x91, // add	x16, x16, Offset(&(.plt.got[2]))
923       0x20, 0x02, 0x1f, 0xd6, // br	x17
924       0x1f, 0x20, 0x03, 0xd5, // nop
925       0x1f, 0x20, 0x03, 0xd5, // nop
926       0x1f, 0x20, 0x03, 0xd5  // nop
927   };
928   memcpy(Buf, PltData, sizeof(PltData));
929 
930   relocateOne(Buf + 4, Buf + 8, R_AARCH64_ADR_PREL_PG_HI21, PltEntryAddr + 4,
931               GotEntryAddr + 16);
932   relocateOne(Buf + 8, Buf + 12, R_AARCH64_LDST64_ABS_LO12_NC, PltEntryAddr + 8,
933               GotEntryAddr + 16);
934   relocateOne(Buf + 12, Buf + 16, R_AARCH64_ADD_ABS_LO12_NC, PltEntryAddr + 12,
935               GotEntryAddr + 16);
936 }
937 
938 void AArch64TargetInfo::writePltEntry(uint8_t *Buf, uint64_t GotAddr,
939                                       uint64_t GotEntryAddr,
940                                       uint64_t PltEntryAddr, int32_t Index,
941                                       unsigned RelOff) const {
942   const uint8_t Inst[] = {
943       0x10, 0x00, 0x00, 0x90, // adrp x16, Page(&(.plt.got[n]))
944       0x11, 0x02, 0x40, 0xf9, // ldr  x17, [x16, Offset(&(.plt.got[n]))]
945       0x10, 0x02, 0x00, 0x91, // add  x16, x16, Offset(&(.plt.got[n]))
946       0x20, 0x02, 0x1f, 0xd6  // br   x17
947   };
948   memcpy(Buf, Inst, sizeof(Inst));
949 
950   relocateOne(Buf, Buf + 4, R_AARCH64_ADR_PREL_PG_HI21, PltEntryAddr,
951               GotEntryAddr);
952   relocateOne(Buf + 4, Buf + 8, R_AARCH64_LDST64_ABS_LO12_NC, PltEntryAddr + 4,
953               GotEntryAddr);
954   relocateOne(Buf + 8, Buf + 12, R_AARCH64_ADD_ABS_LO12_NC, PltEntryAddr + 8,
955               GotEntryAddr);
956 }
957 
958 bool AArch64TargetInfo::relocNeedsCopy(uint32_t Type,
959                                        const SymbolBody &S) const {
960   if (Config->Shared)
961     return false;
962   switch (Type) {
963   default:
964     return false;
965   case R_AARCH64_ABS16:
966   case R_AARCH64_ABS32:
967   case R_AARCH64_ABS64:
968   case R_AARCH64_ADD_ABS_LO12_NC:
969   case R_AARCH64_ADR_PREL_LO21:
970   case R_AARCH64_ADR_PREL_PG_HI21:
971   case R_AARCH64_LDST8_ABS_LO12_NC:
972   case R_AARCH64_LDST32_ABS_LO12_NC:
973   case R_AARCH64_LDST64_ABS_LO12_NC:
974     if (auto *SS = dyn_cast<SharedSymbol<ELF64LE>>(&S))
975       return SS->Sym.getType() == STT_OBJECT;
976     return false;
977   }
978 }
979 
980 bool AArch64TargetInfo::relocNeedsGot(uint32_t Type,
981                                       const SymbolBody &S) const {
982   return Type == R_AARCH64_ADR_GOT_PAGE || Type == R_AARCH64_LD64_GOT_LO12_NC ||
983          relocNeedsPlt(Type, S);
984 }
985 
986 bool AArch64TargetInfo::relocNeedsPlt(uint32_t Type,
987                                       const SymbolBody &S) const {
988   switch (Type) {
989   default:
990     return false;
991   case R_AARCH64_CALL26:
992   case R_AARCH64_JUMP26:
993     return canBePreempted(&S, true);
994   }
995 }
996 
997 static void updateAArch64Adr(uint8_t *L, uint64_t Imm) {
998   uint32_t ImmLo = (Imm & 0x3) << 29;
999   uint32_t ImmHi = ((Imm & 0x1FFFFC) >> 2) << 5;
1000   uint64_t Mask = (0x3 << 29) | (0x7FFFF << 5);
1001   write32le(L, (read32le(L) & ~Mask) | ImmLo | ImmHi);
1002 }
1003 
1004 // Page(Expr) is the page address of the expression Expr, defined
1005 // as (Expr & ~0xFFF). (This applies even if the machine page size
1006 // supported by the platform has a different value.)
1007 static uint64_t getAArch64Page(uint64_t Expr) {
1008   return Expr & (~static_cast<uint64_t>(0xFFF));
1009 }
1010 
1011 void AArch64TargetInfo::relocateOne(uint8_t *Loc, uint8_t *BufEnd,
1012                                     uint32_t Type, uint64_t P, uint64_t SA,
1013                                     uint8_t *PairedLoc) const {
1014   switch (Type) {
1015   case R_AARCH64_ABS16:
1016     checkIntUInt<16>(SA, Type);
1017     write16le(Loc, SA);
1018     break;
1019   case R_AARCH64_ABS32:
1020     checkIntUInt<32>(SA, Type);
1021     write32le(Loc, SA);
1022     break;
1023   case R_AARCH64_ABS64:
1024     write64le(Loc, SA);
1025     break;
1026   case R_AARCH64_ADD_ABS_LO12_NC:
1027     // This relocation stores 12 bits and there's no instruction
1028     // to do it. Instead, we do a 32 bits store of the value
1029     // of r_addend bitwise-or'ed Loc. This assumes that the addend
1030     // bits in Loc are zero.
1031     or32le(Loc, (SA & 0xFFF) << 10);
1032     break;
1033   case R_AARCH64_ADR_GOT_PAGE: {
1034     uint64_t X = getAArch64Page(SA) - getAArch64Page(P);
1035     checkInt<33>(X, Type);
1036     updateAArch64Adr(Loc, (X >> 12) & 0x1FFFFF); // X[32:12]
1037     break;
1038   }
1039   case R_AARCH64_ADR_PREL_LO21: {
1040     uint64_t X = SA - P;
1041     checkInt<21>(X, Type);
1042     updateAArch64Adr(Loc, X & 0x1FFFFF);
1043     break;
1044   }
1045   case R_AARCH64_ADR_PREL_PG_HI21: {
1046     uint64_t X = getAArch64Page(SA) - getAArch64Page(P);
1047     checkInt<33>(X, Type);
1048     updateAArch64Adr(Loc, (X >> 12) & 0x1FFFFF); // X[32:12]
1049     break;
1050   }
1051   case R_AARCH64_CALL26:
1052   case R_AARCH64_JUMP26: {
1053     uint64_t X = SA - P;
1054     checkInt<28>(X, Type);
1055     or32le(Loc, (X & 0x0FFFFFFC) >> 2);
1056     break;
1057   }
1058   case R_AARCH64_LD64_GOT_LO12_NC:
1059     checkAlignment<8>(SA, Type);
1060     or32le(Loc, (SA & 0xFF8) << 7);
1061     break;
1062   case R_AARCH64_LDST8_ABS_LO12_NC:
1063     or32le(Loc, (SA & 0xFFF) << 10);
1064     break;
1065   case R_AARCH64_LDST32_ABS_LO12_NC:
1066     or32le(Loc, (SA & 0xFFC) << 8);
1067     break;
1068   case R_AARCH64_LDST64_ABS_LO12_NC:
1069     or32le(Loc, (SA & 0xFF8) << 7);
1070     break;
1071   case R_AARCH64_PREL16:
1072     checkIntUInt<16>(SA - P, Type);
1073     write16le(Loc, SA - P);
1074     break;
1075   case R_AARCH64_PREL32:
1076     checkIntUInt<32>(SA - P, Type);
1077     write32le(Loc, SA - P);
1078     break;
1079   case R_AARCH64_PREL64:
1080     write64le(Loc, SA - P);
1081     break;
1082   default:
1083     error("unrecognized reloc " + Twine(Type));
1084   }
1085 }
1086 
1087 template <class ELFT> MipsTargetInfo<ELFT>::MipsTargetInfo() {
1088   PageSize = 65536;
1089   GotHeaderEntriesNum = 2;
1090 }
1091 
1092 template <class ELFT>
1093 void MipsTargetInfo<ELFT>::writeGotHeaderEntries(uint8_t *Buf) const {
1094   typedef typename ELFFile<ELFT>::Elf_Off Elf_Off;
1095   auto *P = reinterpret_cast<Elf_Off *>(Buf);
1096   // Module pointer
1097   P[1] = ELFT::Is64Bits ? 0x8000000000000000 : 0x80000000;
1098 }
1099 
1100 template <class ELFT>
1101 void MipsTargetInfo<ELFT>::writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const {}
1102 template <class ELFT>
1103 void MipsTargetInfo<ELFT>::writePltZeroEntry(uint8_t *Buf, uint64_t GotEntryAddr,
1104                                        uint64_t PltEntryAddr) const {}
1105 template <class ELFT>
1106 void MipsTargetInfo<ELFT>::writePltEntry(uint8_t *Buf, uint64_t GotAddr,
1107                                          uint64_t GotEntryAddr,
1108                                          uint64_t PltEntryAddr, int32_t Index,
1109                                          unsigned RelOff) const {}
1110 
1111 template <class ELFT>
1112 bool MipsTargetInfo<ELFT>::relocNeedsGot(uint32_t Type,
1113                                          const SymbolBody &S) const {
1114   return Type == R_MIPS_GOT16 || Type == R_MIPS_CALL16;
1115 }
1116 
1117 template <class ELFT>
1118 bool MipsTargetInfo<ELFT>::relocNeedsPlt(uint32_t Type,
1119                                          const SymbolBody &S) const {
1120   return false;
1121 }
1122 
1123 template <class ELFT>
1124 void MipsTargetInfo<ELFT>::relocateOne(uint8_t *Loc, uint8_t *BufEnd,
1125                                        uint32_t Type, uint64_t P, uint64_t SA,
1126                                        uint8_t *PairedLoc) const {
1127   const endianness E = ELFT::TargetEndianness;
1128   switch (Type) {
1129   case R_MIPS_32:
1130     add32<E>(Loc, SA);
1131     break;
1132   case R_MIPS_CALL16:
1133   case R_MIPS_GOT16: {
1134     int64_t V = SA - getMipsGpAddr<ELFT>();
1135     if (Type == R_MIPS_GOT16)
1136       checkInt<16>(V, Type);
1137     write32<E>(Loc, (read32<E>(Loc) & 0xffff0000) | (V & 0xffff));
1138     break;
1139   }
1140   case R_MIPS_HI16: {
1141     uint32_t Instr = read32<E>(Loc);
1142     if (PairedLoc) {
1143       uint64_t AHL = ((Instr & 0xffff) << 16) +
1144                      SignExtend64<16>(read32<E>(PairedLoc) & 0xffff);
1145       write32<E>(Loc, (Instr & 0xffff0000) | (((SA + AHL) >> 16) & 0xffff));
1146     } else {
1147       warning("Can't find matching R_MIPS_LO16 relocation for R_MIPS_HI16");
1148       write32<E>(Loc, (Instr & 0xffff0000) | ((SA >> 16) & 0xffff));
1149     }
1150     break;
1151   }
1152   case R_MIPS_LO16: {
1153     uint32_t Instr = read32<E>(Loc);
1154     int64_t AHL = SignExtend64<16>(Instr & 0xffff);
1155     write32<E>(Loc, (Instr & 0xffff0000) | ((SA + AHL) & 0xffff));
1156     break;
1157   }
1158   default:
1159     error("unrecognized reloc " + Twine(Type));
1160   }
1161 }
1162 
1163 template <class ELFT> typename ELFFile<ELFT>::uintX_t getMipsGpAddr() {
1164   const unsigned GPOffset = 0x7ff0;
1165   return Out<ELFT>::Got->getVA() ? (Out<ELFT>::Got->getVA() + GPOffset) : 0;
1166 }
1167 
1168 template uint32_t getMipsGpAddr<ELF32LE>();
1169 template uint32_t getMipsGpAddr<ELF32BE>();
1170 template uint64_t getMipsGpAddr<ELF64LE>();
1171 template uint64_t getMipsGpAddr<ELF64BE>();
1172 }
1173 }
1174