xref: /llvm-project-15.0.7/lld/ELF/Target.cpp (revision 0a2899ca)
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 namespace {
46 class X86TargetInfo final : public TargetInfo {
47 public:
48   X86TargetInfo();
49   void writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const override;
50   void writePltZeroEntry(uint8_t *Buf, uint64_t GotEntryAddr,
51                          uint64_t PltEntryAddr) const override;
52   void writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr,
53                      uint64_t PltEntryAddr, int32_t Index) const override;
54   bool relocNeedsGot(uint32_t Type, const SymbolBody &S) const override;
55   bool relocPointsToGot(uint32_t Type) const override;
56   bool relocNeedsPlt(uint32_t Type, const SymbolBody &S) const override;
57   void relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P,
58                    uint64_t SA) const override;
59 };
60 
61 class X86_64TargetInfo final : public TargetInfo {
62 public:
63   X86_64TargetInfo();
64   unsigned getPltRefReloc(unsigned Type) const override;
65   void writeGotPltHeaderEntries(uint8_t *Buf) const override;
66   void writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const override;
67   void writePltZeroEntry(uint8_t *Buf, uint64_t GotEntryAddr,
68                          uint64_t PltEntryAddr) const override;
69   void writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr,
70                      uint64_t PltEntryAddr, int32_t Index) const override;
71   bool relocNeedsCopy(uint32_t Type, const SymbolBody &S) const override;
72   bool relocNeedsGot(uint32_t Type, const SymbolBody &S) const override;
73   bool relocNeedsPlt(uint32_t Type, const SymbolBody &S) const override;
74   void relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P,
75                    uint64_t SA) const override;
76   bool isRelRelative(uint32_t Type) const override;
77   bool isTlsOptimized(unsigned Type, const SymbolBody &S) const override;
78   void relocateTlsOptimize(uint8_t *Loc, uint8_t *BufEnd, uint64_t P,
79                            uint64_t SA) const override;
80 };
81 
82 class PPC64TargetInfo final : public TargetInfo {
83 public:
84   PPC64TargetInfo();
85   void writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const override;
86   void writePltZeroEntry(uint8_t *Buf, uint64_t GotEntryAddr,
87                          uint64_t PltEntryAddr) const override;
88   void writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr,
89                      uint64_t PltEntryAddr, int32_t Index) const override;
90   bool relocNeedsGot(uint32_t Type, const SymbolBody &S) const override;
91   bool relocNeedsPlt(uint32_t Type, const SymbolBody &S) const override;
92   void relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P,
93                    uint64_t SA) const override;
94   bool isRelRelative(uint32_t Type) const override;
95 };
96 
97 class AArch64TargetInfo final : public TargetInfo {
98 public:
99   AArch64TargetInfo();
100   unsigned getGotRefReloc(unsigned Type) const override;
101   unsigned getPltRefReloc(unsigned Type) const override;
102   void writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const override;
103   void writePltZeroEntry(uint8_t *Buf, uint64_t GotEntryAddr,
104                          uint64_t PltEntryAddr) const override;
105   void writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr,
106                      uint64_t PltEntryAddr, int32_t Index) const override;
107   bool relocNeedsGot(uint32_t Type, const SymbolBody &S) const override;
108   bool relocNeedsPlt(uint32_t Type, const SymbolBody &S) const override;
109   void relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P,
110                    uint64_t SA) const override;
111 };
112 
113 template <class ELFT> class MipsTargetInfo final : public TargetInfo {
114 public:
115   MipsTargetInfo();
116   void writeGotHeaderEntries(uint8_t *Buf) const override;
117   void writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const override;
118   void writePltZeroEntry(uint8_t *Buf, uint64_t GotEntryAddr,
119                          uint64_t PltEntryAddr) const override;
120   void writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr,
121                      uint64_t PltEntryAddr, int32_t Index) const override;
122   bool relocNeedsGot(uint32_t Type, const SymbolBody &S) const override;
123   bool relocNeedsPlt(uint32_t Type, const SymbolBody &S) const override;
124   void relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P,
125                    uint64_t SA) const override;
126 };
127 } // anonymous namespace
128 
129 TargetInfo *createTarget() {
130   switch (Config->EMachine) {
131   case EM_386:
132     return new X86TargetInfo();
133   case EM_AARCH64:
134     return new AArch64TargetInfo();
135   case EM_MIPS:
136     switch (Config->EKind) {
137     case ELF32LEKind:
138       return new MipsTargetInfo<ELF32LE>();
139     case ELF32BEKind:
140       return new MipsTargetInfo<ELF32BE>();
141     default:
142       error("Unsupported MIPS target");
143     }
144   case EM_PPC64:
145     return new PPC64TargetInfo();
146   case EM_X86_64:
147     return new X86_64TargetInfo();
148   }
149   error("Unknown target machine");
150 }
151 
152 TargetInfo::~TargetInfo() {}
153 
154 bool TargetInfo::isTlsOptimized(unsigned Type, const SymbolBody &S) const {
155   return false;
156 }
157 
158 uint64_t TargetInfo::getVAStart() const { return Config->Shared ? 0 : VAStart; }
159 
160 bool TargetInfo::relocNeedsCopy(uint32_t Type, const SymbolBody &S) const {
161   return false;
162 }
163 
164 unsigned TargetInfo::getGotRefReloc(unsigned Type) const { return GotRefReloc; }
165 
166 unsigned TargetInfo::getPltRefReloc(unsigned Type) const { return PCRelReloc; }
167 
168 bool TargetInfo::relocPointsToGot(uint32_t Type) const { return false; }
169 
170 bool TargetInfo::isRelRelative(uint32_t Type) const { return true; }
171 
172 void TargetInfo::relocateTlsOptimize(uint8_t *Loc, uint8_t *BufEnd, uint64_t P,
173                                      uint64_t SA) const {}
174 
175 void TargetInfo::writeGotHeaderEntries(uint8_t *Buf) const {}
176 
177 void TargetInfo::writeGotPltHeaderEntries(uint8_t *Buf) const {}
178 
179 X86TargetInfo::X86TargetInfo() {
180   PCRelReloc = R_386_PC32;
181   GotReloc = R_386_GLOB_DAT;
182   GotRefReloc = R_386_GOT32;
183   PltReloc = R_386_JUMP_SLOT;
184 }
185 
186 void X86TargetInfo::writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const {}
187 void X86TargetInfo::writePltZeroEntry(uint8_t *Buf, uint64_t GotEntryAddr,
188                                       uint64_t PltEntryAddr) const {}
189 
190 void X86TargetInfo::writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr,
191                                   uint64_t PltEntryAddr, int32_t Index) const {
192   // jmpl *val; nop; nop
193   const uint8_t Inst[] = {0xff, 0x25, 0, 0, 0, 0, 0x90, 0x90};
194   memcpy(Buf, Inst, sizeof(Inst));
195   assert(isUInt<32>(GotEntryAddr));
196   write32le(Buf + 2, GotEntryAddr);
197 }
198 
199 bool X86TargetInfo::relocNeedsGot(uint32_t Type, const SymbolBody &S) const {
200   return Type == R_386_GOT32 || relocNeedsPlt(Type, S);
201 }
202 
203 bool X86TargetInfo::relocPointsToGot(uint32_t Type) const {
204   return Type == R_386_GOTPC;
205 }
206 
207 bool X86TargetInfo::relocNeedsPlt(uint32_t Type, const SymbolBody &S) const {
208   return Type == R_386_PLT32 || (Type == R_386_PC32 && S.isShared());
209 }
210 
211 void X86TargetInfo::relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type,
212                                 uint64_t P, uint64_t SA) const {
213   switch (Type) {
214   case R_386_GOT32:
215     add32le(Loc, SA - Out<ELF32LE>::Got->getVA());
216     break;
217   case R_386_PC32:
218     add32le(Loc, SA - P);
219     break;
220   case R_386_32:
221     add32le(Loc, SA);
222     break;
223   default:
224     error("unrecognized reloc " + Twine(Type));
225   }
226 }
227 
228 X86_64TargetInfo::X86_64TargetInfo() {
229   CopyReloc = R_X86_64_COPY;
230   PCRelReloc = R_X86_64_PC32;
231   GotReloc = R_X86_64_GLOB_DAT;
232   GotRefReloc = R_X86_64_PC32;
233   PltReloc = R_X86_64_JUMP_SLOT;
234   RelativeReloc = R_X86_64_RELATIVE;
235   TlsGotReloc = R_X86_64_TPOFF64;
236   TlsLocalDynamicReloc = R_X86_64_TLSLD;
237   TlsGlobalDynamicReloc = R_X86_64_TLSGD;
238   TlsModuleIndexReloc = R_X86_64_DTPMOD64;
239   TlsOffsetReloc = R_X86_64_DTPOFF64;
240   TlsPcRelGotReloc = R_X86_64_GOTTPOFF;
241   LazyRelocations = true;
242   PltEntrySize = 16;
243   PltZeroEntrySize = 16;
244 }
245 
246 void X86_64TargetInfo::writeGotPltHeaderEntries(uint8_t *Buf) const {
247   write64le(Buf, Out<ELF64LE>::Dynamic->getVA());
248 }
249 
250 void X86_64TargetInfo::writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const {
251   // Skip 6 bytes of "jmpq *got(%rip)"
252   write32le(Buf, Plt + 6);
253 }
254 
255 void X86_64TargetInfo::writePltZeroEntry(uint8_t *Buf, uint64_t GotEntryAddr,
256                                          uint64_t PltEntryAddr) const {
257   const uint8_t PltData[] = {
258       0xff, 0x35, 0x00, 0x00, 0x00, 0x00, // pushq GOT+8(%rip)
259       0xff, 0x25, 0x00, 0x00, 0x00, 0x00, // jmp *GOT+16(%rip)
260       0x0f, 0x1f, 0x40, 0x00              // nopl 0x0(rax)
261   };
262   memcpy(Buf, PltData, sizeof(PltData));
263   write32le(Buf + 2, GotEntryAddr - PltEntryAddr + 2); // GOT+8
264   write32le(Buf + 8, GotEntryAddr - PltEntryAddr + 4); // GOT+16
265 }
266 
267 void X86_64TargetInfo::writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr,
268                                      uint64_t PltEntryAddr,
269                                      int32_t Index) const {
270   const uint8_t Inst[] = {
271       0xff, 0x25, 0x00, 0x00, 0x00, 0x00, // jmpq *got(%rip)
272       0x68, 0x00, 0x00, 0x00, 0x00,       // pushq <relocation index>
273       0xe9, 0x00, 0x00, 0x00, 0x00        // jmpq plt[0]
274   };
275   memcpy(Buf, Inst, sizeof(Inst));
276 
277   write32le(Buf + 2, GotEntryAddr - PltEntryAddr - 6);
278   write32le(Buf + 7, Index);
279   write32le(Buf + 12, -Index * PltEntrySize - PltZeroEntrySize - 16);
280 }
281 
282 bool X86_64TargetInfo::relocNeedsCopy(uint32_t Type,
283                                       const SymbolBody &S) const {
284   if (Type == R_X86_64_32S || Type == R_X86_64_32 || Type == R_X86_64_PC32 ||
285       Type == R_X86_64_64)
286     if (auto *SS = dyn_cast<SharedSymbol<ELF64LE>>(&S))
287       return SS->Sym.getType() == STT_OBJECT;
288   return false;
289 }
290 
291 bool X86_64TargetInfo::relocNeedsGot(uint32_t Type, const SymbolBody &S) const {
292   if (Type == R_X86_64_GOTTPOFF)
293     return !isTlsOptimized(Type, S);
294   return Type == R_X86_64_GOTTPOFF || Type == R_X86_64_GOTPCREL ||
295          relocNeedsPlt(Type, S);
296 }
297 
298 unsigned X86_64TargetInfo::getPltRefReloc(unsigned Type) const {
299   if (Type == R_X86_64_PLT32)
300     return R_X86_64_PC32;
301   return Type;
302 }
303 
304 bool X86_64TargetInfo::relocNeedsPlt(uint32_t Type, const SymbolBody &S) const {
305   if (relocNeedsCopy(Type, S))
306     return false;
307 
308   switch (Type) {
309   default:
310     return false;
311   case R_X86_64_32:
312   case R_X86_64_64:
313   case R_X86_64_PC32:
314     // This relocation is defined to have a value of (S + A - P).
315     // The problems start when a non PIC program calls a function in a shared
316     // library.
317     // In an ideal world, we could just report an error saying the relocation
318     // can overflow at runtime.
319     // In the real world with glibc, crt1.o has a R_X86_64_PC32 pointing to
320     // libc.so.
321     //
322     // The general idea on how to handle such cases is to create a PLT entry
323     // and use that as the function value.
324     //
325     // For the static linking part, we just return true and everything else
326     // will use the the PLT entry as the address.
327     //
328     // The remaining (unimplemented) problem is making sure pointer equality
329     // still works. We need the help of the dynamic linker for that. We
330     // let it know that we have a direct reference to a so symbol by creating
331     // an undefined symbol with a non zero st_value. Seeing that, the
332     // dynamic linker resolves the symbol to the value of the symbol we created.
333     // This is true even for got entries, so pointer equality is maintained.
334     // To avoid an infinite loop, the only entry that points to the
335     // real function is a dedicated got entry used by the plt. That is
336     // identified by special relocation types (R_X86_64_JUMP_SLOT,
337     // R_386_JMP_SLOT, etc).
338     return S.isShared();
339   case R_X86_64_PLT32:
340     return canBePreempted(&S, true);
341   }
342 }
343 
344 bool X86_64TargetInfo::isRelRelative(uint32_t Type) const {
345   switch (Type) {
346   default:
347     return false;
348   case R_X86_64_PC64:
349   case R_X86_64_PC32:
350   case R_X86_64_PC16:
351   case R_X86_64_PC8:
352   case R_X86_64_PLT32:
353   case R_X86_64_DTPOFF32:
354   case R_X86_64_DTPOFF64:
355     return true;
356   }
357 }
358 
359 bool X86_64TargetInfo::isTlsOptimized(unsigned Type,
360                                       const SymbolBody &S) const {
361   if (Config->Shared || !S.isTLS())
362     return false;
363   return Type == R_X86_64_GOTTPOFF && !canBePreempted(&S, true);
364 }
365 
366 // In some conditions, R_X86_64_GOTTPOFF relocation can be optimized to
367 // R_X86_64_TPOFF32 so that R_X86_64_TPOFF32 so that it does not use GOT.
368 // This function does that. Read "ELF Handling For Thread-Local Storage,
369 // 5.5 x86-x64 linker optimizations" (http://www.akkadia.org/drepper/tls.pdf)
370 // by Ulrich Drepper for details.
371 void X86_64TargetInfo::relocateTlsOptimize(uint8_t *Loc, uint8_t *BufEnd,
372                                            uint64_t P, uint64_t SA) const {
373   // Ulrich's document section 6.5 says that @gottpoff(%rip) must be
374   // used in MOVQ or ADDQ instructions only.
375   // "MOVQ foo@GOTTPOFF(%RIP), %REG" is transformed to "MOVQ $foo, %REG".
376   // "ADDQ foo@GOTTPOFF(%RIP), %REG" is transformed to "LEAQ foo(%REG), %REG"
377   // (if the register is not RSP/R12) or "ADDQ $foo, %RSP".
378   // Opcodes info can be found at http://ref.x86asm.net/coder64.html#x48.
379   uint8_t *Prefix = Loc - 3;
380   uint8_t *Inst = Loc - 2;
381   uint8_t *RegSlot = Loc - 1;
382   uint8_t Reg = Loc[-1] >> 3;
383   bool IsMov = *Inst == 0x8b;
384   bool RspAdd = !IsMov && Reg == 4;
385   // r12 and rsp registers requires special handling.
386   // Problem is that for other registers, for example leaq 0xXXXXXXXX(%r11),%r11
387   // result out is 7 bytes: 4d 8d 9b XX XX XX XX,
388   // but leaq 0xXXXXXXXX(%r12),%r12 is 8 bytes: 4d 8d a4 24 XX XX XX XX.
389   // The same true for rsp. So we convert to addq for them, saving 1 byte that
390   // we dont have.
391   if (RspAdd)
392     *Inst = 0x81;
393   else
394     *Inst = IsMov ? 0xc7 : 0x8d;
395   if (*Prefix == 0x4c)
396     *Prefix = (IsMov || RspAdd) ? 0x49 : 0x4d;
397   *RegSlot = (IsMov || RspAdd) ? (0xc0 | Reg) : (0x80 | Reg | (Reg << 3));
398   relocateOne(Loc, BufEnd, R_X86_64_TPOFF32, P, SA);
399 }
400 
401 void X86_64TargetInfo::relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type,
402                                    uint64_t P, uint64_t SA) const {
403   switch (Type) {
404   case R_X86_64_PC32:
405   case R_X86_64_GOTPCREL:
406   case R_X86_64_PLT32:
407   case R_X86_64_TLSLD:
408   case R_X86_64_TLSGD:
409   case R_X86_64_TPOFF64:
410     write32le(Loc, SA - P);
411     break;
412   case R_X86_64_64:
413   case R_X86_64_DTPOFF64:
414     write64le(Loc, SA);
415     break;
416   case R_X86_64_32:
417   case R_X86_64_32S:
418     if (Type == R_X86_64_32 && !isUInt<32>(SA))
419       error("R_X86_64_32 out of range");
420     else if (!isInt<32>(SA))
421       error("R_X86_64_32S out of range");
422     write32le(Loc, SA);
423     break;
424   case R_X86_64_DTPOFF32:
425     write32le(Loc, SA);
426     break;
427   case R_X86_64_TPOFF32: {
428     uint64_t Val = SA - Out<ELF64LE>::TlsPhdr->p_memsz;
429     if (!isInt<32>(Val))
430       error("R_X86_64_TPOFF32 out of range");
431     write32le(Loc, Val);
432     break;
433   }
434   default:
435     error("unrecognized reloc " + Twine(Type));
436   }
437 }
438 
439 // Relocation masks following the #lo(value), #hi(value), #ha(value),
440 // #higher(value), #highera(value), #highest(value), and #highesta(value)
441 // macros defined in section 4.5.1. Relocation Types of the PPC-elf64abi
442 // document.
443 static uint16_t applyPPCLo(uint64_t V) { return V; }
444 static uint16_t applyPPCHi(uint64_t V) { return V >> 16; }
445 static uint16_t applyPPCHa(uint64_t V) { return (V + 0x8000) >> 16; }
446 static uint16_t applyPPCHigher(uint64_t V) { return V >> 32; }
447 static uint16_t applyPPCHighera(uint64_t V) { return (V + 0x8000) >> 32; }
448 static uint16_t applyPPCHighest(uint64_t V) { return V >> 48; }
449 static uint16_t applyPPCHighesta(uint64_t V) { return (V + 0x8000) >> 48; }
450 
451 PPC64TargetInfo::PPC64TargetInfo() {
452   PCRelReloc = R_PPC64_REL24;
453   GotReloc = R_PPC64_GLOB_DAT;
454   GotRefReloc = R_PPC64_REL64;
455   RelativeReloc = R_PPC64_RELATIVE;
456   PltEntrySize = 32;
457 
458   // We need 64K pages (at least under glibc/Linux, the loader won't
459   // set different permissions on a finer granularity than that).
460   PageSize = 65536;
461 
462   // The PPC64 ELF ABI v1 spec, says:
463   //
464   //   It is normally desirable to put segments with different characteristics
465   //   in separate 256 Mbyte portions of the address space, to give the
466   //   operating system full paging flexibility in the 64-bit address space.
467   //
468   // And because the lowest non-zero 256M boundary is 0x10000000, PPC64 linkers
469   // use 0x10000000 as the starting address.
470   VAStart = 0x10000000;
471 }
472 
473 uint64_t getPPC64TocBase() {
474   // The TOC consists of sections .got, .toc, .tocbss, .plt in that
475   // order. The TOC starts where the first of these sections starts.
476 
477   // FIXME: This obviously does not do the right thing when there is no .got
478   // section, but there is a .toc or .tocbss section.
479   uint64_t TocVA = Out<ELF64BE>::Got->getVA();
480   if (!TocVA)
481     TocVA = Out<ELF64BE>::Plt->getVA();
482 
483   // Per the ppc64-elf-linux ABI, The TOC base is TOC value plus 0x8000
484   // thus permitting a full 64 Kbytes segment. Note that the glibc startup
485   // code (crt1.o) assumes that you can get from the TOC base to the
486   // start of the .toc section with only a single (signed) 16-bit relocation.
487   return TocVA + 0x8000;
488 }
489 
490 void PPC64TargetInfo::writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const {}
491 void PPC64TargetInfo::writePltZeroEntry(uint8_t *Buf, uint64_t GotEntryAddr,
492                                         uint64_t PltEntryAddr) const {}
493 void PPC64TargetInfo::writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr,
494                                     uint64_t PltEntryAddr, int32_t Index) const {
495   uint64_t Off = GotEntryAddr - getPPC64TocBase();
496 
497   // FIXME: What we should do, in theory, is get the offset of the function
498   // descriptor in the .opd section, and use that as the offset from %r2 (the
499   // TOC-base pointer). Instead, we have the GOT-entry offset, and that will
500   // be a pointer to the function descriptor in the .opd section. Using
501   // this scheme is simpler, but requires an extra indirection per PLT dispatch.
502 
503   write32be(Buf,      0xf8410028);                   // std %r2, 40(%r1)
504   write32be(Buf + 4,  0x3d620000 | applyPPCHa(Off)); // addis %r11, %r2, X@ha
505   write32be(Buf + 8,  0xe98b0000 | applyPPCLo(Off)); // ld %r12, X@l(%r11)
506   write32be(Buf + 12, 0xe96c0000);                   // ld %r11,0(%r12)
507   write32be(Buf + 16, 0x7d6903a6);                   // mtctr %r11
508   write32be(Buf + 20, 0xe84c0008);                   // ld %r2,8(%r12)
509   write32be(Buf + 24, 0xe96c0010);                   // ld %r11,16(%r12)
510   write32be(Buf + 28, 0x4e800420);                   // bctr
511 }
512 
513 bool PPC64TargetInfo::relocNeedsGot(uint32_t Type, const SymbolBody &S) const {
514   if (relocNeedsPlt(Type, S))
515     return true;
516 
517   switch (Type) {
518   default: return false;
519   case R_PPC64_GOT16:
520   case R_PPC64_GOT16_LO:
521   case R_PPC64_GOT16_HI:
522   case R_PPC64_GOT16_HA:
523   case R_PPC64_GOT16_DS:
524   case R_PPC64_GOT16_LO_DS:
525     return true;
526   }
527 }
528 
529 bool PPC64TargetInfo::relocNeedsPlt(uint32_t Type, const SymbolBody &S) const {
530   // These are function calls that need to be redirected through a PLT stub.
531   return Type == R_PPC64_REL24 && canBePreempted(&S, false);
532 }
533 
534 bool PPC64TargetInfo::isRelRelative(uint32_t Type) const {
535   switch (Type) {
536   default:
537     return true;
538   case R_PPC64_TOC:
539   case R_PPC64_ADDR64:
540     return false;
541   }
542 }
543 
544 void PPC64TargetInfo::relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type,
545                                   uint64_t P, uint64_t SA) const {
546   uint64_t TB = getPPC64TocBase();
547 
548   // For a TOC-relative relocation, adjust the addend and proceed in terms of
549   // the corresponding ADDR16 relocation type.
550   switch (Type) {
551   case R_PPC64_TOC16:       Type = R_PPC64_ADDR16;       SA -= TB; break;
552   case R_PPC64_TOC16_DS:    Type = R_PPC64_ADDR16_DS;    SA -= TB; break;
553   case R_PPC64_TOC16_LO:    Type = R_PPC64_ADDR16_LO;    SA -= TB; break;
554   case R_PPC64_TOC16_LO_DS: Type = R_PPC64_ADDR16_LO_DS; SA -= TB; break;
555   case R_PPC64_TOC16_HI:    Type = R_PPC64_ADDR16_HI;    SA -= TB; break;
556   case R_PPC64_TOC16_HA:    Type = R_PPC64_ADDR16_HA;    SA -= TB; break;
557   default: break;
558   }
559 
560   switch (Type) {
561   case R_PPC64_ADDR16:
562     if (!isInt<16>(SA))
563       error("Relocation R_PPC64_ADDR16 overflow");
564     write16be(Loc, SA);
565     break;
566   case R_PPC64_ADDR16_DS:
567     if (!isInt<16>(SA))
568       error("Relocation R_PPC64_ADDR16_DS overflow");
569     write16be(Loc, (read16be(Loc) & 3) | (SA & ~3));
570     break;
571   case R_PPC64_ADDR16_LO:
572     write16be(Loc, applyPPCLo(SA));
573     break;
574   case R_PPC64_ADDR16_LO_DS:
575     write16be(Loc, (read16be(Loc) & 3) | (applyPPCLo(SA) & ~3));
576     break;
577   case R_PPC64_ADDR16_HI:
578     write16be(Loc, applyPPCHi(SA));
579     break;
580   case R_PPC64_ADDR16_HA:
581     write16be(Loc, applyPPCHa(SA));
582     break;
583   case R_PPC64_ADDR16_HIGHER:
584     write16be(Loc, applyPPCHigher(SA));
585     break;
586   case R_PPC64_ADDR16_HIGHERA:
587     write16be(Loc, applyPPCHighera(SA));
588     break;
589   case R_PPC64_ADDR16_HIGHEST:
590     write16be(Loc, applyPPCHighest(SA));
591     break;
592   case R_PPC64_ADDR16_HIGHESTA:
593     write16be(Loc, applyPPCHighesta(SA));
594     break;
595   case R_PPC64_ADDR14: {
596     if ((SA & 3) != 0)
597       error("Improper alignment for relocation R_PPC64_ADDR14");
598 
599     // Preserve the AA/LK bits in the branch instruction
600     uint8_t AALK = Loc[3];
601     write16be(Loc + 2, (AALK & 3) | (SA & 0xfffc));
602     break;
603   }
604   case R_PPC64_REL16_LO:
605     write16be(Loc, applyPPCLo(SA - P));
606     break;
607   case R_PPC64_REL16_HI:
608     write16be(Loc, applyPPCHi(SA - P));
609     break;
610   case R_PPC64_REL16_HA:
611     write16be(Loc, applyPPCHa(SA - P));
612     break;
613   case R_PPC64_ADDR32:
614     if (!isInt<32>(SA))
615       error("Relocation R_PPC64_ADDR32 overflow");
616     write32be(Loc, SA);
617     break;
618   case R_PPC64_REL24: {
619     // If we have an undefined weak symbol, we might get here with a symbol
620     // address of zero. That could overflow, but the code must be unreachable,
621     // so don't bother doing anything at all.
622     if (!SA)
623       break;
624 
625     uint64_t PltStart = Out<ELF64BE>::Plt->getVA();
626     uint64_t PltEnd = PltStart + Out<ELF64BE>::Plt->getSize();
627     bool InPlt = PltStart <= SA && SA < PltEnd;
628 
629     if (!InPlt && Out<ELF64BE>::Opd) {
630       // If this is a local call, and we currently have the address of a
631       // function-descriptor, get the underlying code address instead.
632       uint64_t OpdStart = Out<ELF64BE>::Opd->getVA();
633       uint64_t OpdEnd = OpdStart + Out<ELF64BE>::Opd->getSize();
634       bool InOpd = OpdStart <= SA && SA < OpdEnd;
635 
636       if (InOpd)
637         SA = read64be(&Out<ELF64BE>::OpdBuf[SA - OpdStart]);
638     }
639 
640     uint32_t Mask = 0x03FFFFFC;
641     if (!isInt<24>(SA - P))
642       error("Relocation R_PPC64_REL24 overflow");
643     write32be(Loc, (read32be(Loc) & ~Mask) | ((SA - P) & Mask));
644 
645     uint32_t Nop = 0x60000000;
646     if (InPlt && Loc + 8 <= BufEnd && read32be(Loc + 4) == Nop)
647       write32be(Loc + 4, 0xe8410028); // ld %r2, 40(%r1)
648     break;
649   }
650   case R_PPC64_REL32:
651     if (!isInt<32>(SA - P))
652       error("Relocation R_PPC64_REL32 overflow");
653     write32be(Loc, SA - P);
654     break;
655   case R_PPC64_REL64:
656     write64be(Loc, SA - P);
657     break;
658   case R_PPC64_ADDR64:
659   case R_PPC64_TOC:
660     write64be(Loc, SA);
661     break;
662   default:
663     error("unrecognized reloc " + Twine(Type));
664   }
665 }
666 
667 AArch64TargetInfo::AArch64TargetInfo() {
668   GotReloc = R_AARCH64_GLOB_DAT;
669   PltReloc = R_AARCH64_JUMP_SLOT;
670   LazyRelocations = true;
671   PltEntrySize = 16;
672   PltZeroEntrySize = 32;
673 }
674 
675 unsigned AArch64TargetInfo::getGotRefReloc(unsigned Type) const { return Type; }
676 
677 unsigned AArch64TargetInfo::getPltRefReloc(unsigned Type) const { return Type; }
678 
679 void AArch64TargetInfo::writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const {
680   write64le(Buf, Out<ELF64LE>::Plt->getVA());
681 }
682 
683 void AArch64TargetInfo::writePltZeroEntry(uint8_t *Buf, uint64_t GotEntryAddr,
684                                           uint64_t PltEntryAddr) const {
685   const uint8_t PltData[] = {
686       0xf0, 0x7b, 0xbf, 0xa9, // stp	x16, x30, [sp,#-16]!
687       0x10, 0x00, 0x00, 0x90, // adrp	x16, Page(&(.plt.got[2]))
688       0x11, 0x02, 0x40, 0xf9, // ldr	x17, [x16, Offset(&(.plt.got[2]))]
689       0x10, 0x02, 0x00, 0x91, // add	x16, x16, Offset(&(.plt.got[2]))
690       0x20, 0x02, 0x1f, 0xd6, // br	x17
691       0x1f, 0x20, 0x03, 0xd5, // nop
692       0x1f, 0x20, 0x03, 0xd5, // nop
693       0x1f, 0x20, 0x03, 0xd5  // nop
694   };
695   memcpy(Buf, PltData, sizeof(PltData));
696 
697   relocateOne(Buf + 4, Buf + 8, R_AARCH64_ADR_PREL_PG_HI21, PltEntryAddr + 4,
698               GotEntryAddr + 16);
699   relocateOne(Buf + 8, Buf + 12, R_AARCH64_LDST64_ABS_LO12_NC, PltEntryAddr + 8,
700               GotEntryAddr + 16);
701   relocateOne(Buf + 12, Buf + 16, R_AARCH64_ADD_ABS_LO12_NC, PltEntryAddr + 12,
702               GotEntryAddr + 16);
703 }
704 
705 void AArch64TargetInfo::writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr,
706                                       uint64_t PltEntryAddr,
707                                       int32_t Index) const {
708   const uint8_t Inst[] = {
709       0x10, 0x00, 0x00, 0x90, // adrp x16, Page(&(.plt.got[n]))
710       0x11, 0x02, 0x40, 0xf9, // ldr  x17, [x16, Offset(&(.plt.got[n]))]
711       0x10, 0x02, 0x00, 0x91, // add  x16, x16, Offset(&(.plt.got[n]))
712       0x20, 0x02, 0x1f, 0xd6  // br   x17
713   };
714   memcpy(Buf, Inst, sizeof(Inst));
715 
716   relocateOne(Buf, Buf + 4, R_AARCH64_ADR_PREL_PG_HI21, PltEntryAddr,
717               GotEntryAddr);
718   relocateOne(Buf + 4, Buf + 8, R_AARCH64_LDST64_ABS_LO12_NC, PltEntryAddr + 4,
719               GotEntryAddr);
720   relocateOne(Buf + 8, Buf + 12, R_AARCH64_ADD_ABS_LO12_NC, PltEntryAddr + 8,
721               GotEntryAddr);
722 }
723 
724 bool AArch64TargetInfo::relocNeedsGot(uint32_t Type,
725                                       const SymbolBody &S) const {
726   return Type == R_AARCH64_ADR_GOT_PAGE || Type == R_AARCH64_LD64_GOT_LO12_NC ||
727          relocNeedsPlt(Type, S);
728 }
729 
730 bool AArch64TargetInfo::relocNeedsPlt(uint32_t Type,
731                                       const SymbolBody &S) const {
732   switch (Type) {
733   default:
734     return false;
735   case R_AARCH64_JUMP26:
736   case R_AARCH64_CALL26:
737     return canBePreempted(&S, true);
738   }
739 }
740 
741 static void updateAArch64Adr(uint8_t *L, uint64_t Imm) {
742   uint32_t ImmLo = (Imm & 0x3) << 29;
743   uint32_t ImmHi = ((Imm & 0x1FFFFC) >> 2) << 5;
744   uint64_t Mask = (0x3 << 29) | (0x7FFFF << 5);
745   write32le(L, (read32le(L) & ~Mask) | ImmLo | ImmHi);
746 }
747 
748 // Page(Expr) is the page address of the expression Expr, defined
749 // as (Expr & ~0xFFF). (This applies even if the machine page size
750 // supported by the platform has a different value.)
751 static uint64_t getAArch64Page(uint64_t Expr) {
752   return Expr & (~static_cast<uint64_t>(0xFFF));
753 }
754 
755 template <unsigned N>
756 static void checkAArch64OutOfRange(int64_t X, uint32_t Type) {
757   if (!isInt<N>(X))
758     error("Relocation " + getELFRelocationTypeName(EM_AARCH64, Type) +
759           " out of range");
760 }
761 
762 void AArch64TargetInfo::relocateOne(uint8_t *Loc, uint8_t *BufEnd,
763                                     uint32_t Type, uint64_t P,
764                                     uint64_t SA) const {
765   switch (Type) {
766   case R_AARCH64_ABS16:
767     checkAArch64OutOfRange<16>(SA, Type);
768     write16le(Loc, SA);
769     break;
770   case R_AARCH64_ABS32:
771     checkAArch64OutOfRange<32>(SA, Type);
772     write32le(Loc, SA);
773     break;
774   case R_AARCH64_ABS64:
775     // No overflow check needed.
776     write64le(Loc, SA);
777     break;
778   case R_AARCH64_ADD_ABS_LO12_NC:
779     // No overflow check needed.
780     // This relocation stores 12 bits and there's no instruction
781     // to do it. Instead, we do a 32 bits store of the value
782     // of r_addend bitwise-or'ed Loc. This assumes that the addend
783     // bits in Loc are zero.
784     or32le(Loc, (SA & 0xFFF) << 10);
785     break;
786   case R_AARCH64_ADR_PREL_LO21: {
787     uint64_t X = SA - P;
788     checkAArch64OutOfRange<21>(X, Type);
789     updateAArch64Adr(Loc, X & 0x1FFFFF);
790     break;
791   }
792   case R_AARCH64_ADR_GOT_PAGE:
793   case R_AARCH64_ADR_PREL_PG_HI21: {
794     uint64_t X = getAArch64Page(SA) - getAArch64Page(P);
795     checkAArch64OutOfRange<33>(X, Type);
796     updateAArch64Adr(Loc, (X >> 12) & 0x1FFFFF); // X[32:12]
797     break;
798   }
799   case R_AARCH64_JUMP26:
800   case R_AARCH64_CALL26: {
801     uint64_t X = SA - P;
802     checkAArch64OutOfRange<28>(X, Type);
803     or32le(Loc, (X & 0x0FFFFFFC) >> 2);
804     break;
805   }
806   case R_AARCH64_LDST32_ABS_LO12_NC:
807     // No overflow check needed.
808     or32le(Loc, (SA & 0xFFC) << 8);
809     break;
810   case R_AARCH64_LD64_GOT_LO12_NC:
811     if (SA & 0x7)
812       error("Relocation R_AARCH64_LD64_GOT_LO12_NC not aligned");
813     // No overflow check needed.
814     or32le(Loc, (SA & 0xFF8) << 7);
815     break;
816   case R_AARCH64_LDST64_ABS_LO12_NC:
817     // No overflow check needed.
818     or32le(Loc, (SA & 0xFF8) << 7);
819     break;
820   case R_AARCH64_LDST8_ABS_LO12_NC:
821     // No overflow check needed.
822     or32le(Loc, (SA & 0xFFF) << 10);
823     break;
824   case R_AARCH64_PREL16:
825     checkAArch64OutOfRange<16>(SA - P, Type);
826     write16le(Loc, SA - P);
827     break;
828   case R_AARCH64_PREL32:
829     checkAArch64OutOfRange<32>(SA - P, Type);
830     write32le(Loc, SA - P);
831     break;
832   case R_AARCH64_PREL64:
833     // No overflow check needed.
834     write64le(Loc, SA - P);
835     break;
836   default:
837     error("unrecognized reloc " + Twine(Type));
838   }
839 }
840 
841 template <class ELFT> MipsTargetInfo<ELFT>::MipsTargetInfo() {
842   PageSize = 65536;
843   GotRefReloc = R_MIPS_GOT16;
844   GotHeaderEntriesNum = 2;
845 }
846 
847 template <class ELFT>
848 void MipsTargetInfo<ELFT>::writeGotHeaderEntries(uint8_t *Buf) const {
849   typedef typename llvm::object::ELFFile<ELFT>::Elf_Off Elf_Off;
850   auto *P = reinterpret_cast<Elf_Off *>(Buf);
851   // Module pointer
852   P[1] = ELFT::Is64Bits ? 0x8000000000000000 : 0x80000000;
853 }
854 
855 template <class ELFT>
856 void MipsTargetInfo<ELFT>::writeGotPltEntry(uint8_t *Buf, uint64_t Plt) const {}
857 template <class ELFT>
858 void MipsTargetInfo<ELFT>::writePltZeroEntry(uint8_t *Buf, uint64_t GotEntryAddr,
859                                        uint64_t PltEntryAddr) const {}
860 template <class ELFT>
861 void MipsTargetInfo<ELFT>::writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr,
862                                          uint64_t PltEntryAddr, int32_t Index) const {}
863 
864 template <class ELFT>
865 bool MipsTargetInfo<ELFT>::relocNeedsGot(uint32_t Type,
866                                          const SymbolBody &S) const {
867   return Type == R_MIPS_GOT16;
868 }
869 
870 template <class ELFT>
871 bool MipsTargetInfo<ELFT>::relocNeedsPlt(uint32_t Type,
872                                          const SymbolBody &S) const {
873   return false;
874 }
875 
876 template <class ELFT>
877 void MipsTargetInfo<ELFT>::relocateOne(uint8_t *Loc, uint8_t *BufEnd,
878                                        uint32_t Type, uint64_t P,
879                                        uint64_t SA) const {
880   const endianness E = ELFT::TargetEndianness;
881   switch (Type) {
882   case R_MIPS_32:
883     add32<E>(Loc, SA);
884     break;
885   case R_MIPS_GOT16: {
886     int64_t V = SA - getMipsGpAddr<ELFT>();
887     if (!isInt<16>(V))
888       error("Relocation R_MIPS_GOT16 out of range");
889     write32<E>(Loc, (read32<E>(Loc) & 0xffff0000) | (V & 0xffff));
890     break;
891   }
892   default:
893     error("unrecognized reloc " + Twine(Type));
894   }
895 }
896 
897 template <class ELFT>
898 typename llvm::object::ELFFile<ELFT>::uintX_t getMipsGpAddr() {
899   const unsigned GPOffset = 0x7ff0;
900   return Out<ELFT>::Got->getVA() ? (Out<ELFT>::Got->getVA() + GPOffset) : 0;
901 }
902 
903 template uint32_t getMipsGpAddr<ELF32LE>();
904 template uint32_t getMipsGpAddr<ELF32BE>();
905 template uint64_t getMipsGpAddr<ELF64LE>();
906 template uint64_t getMipsGpAddr<ELF64BE>();
907 }
908 }
909