1 //===- Target.h -------------------------------------------------*- C++ -*-===// 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 #ifndef LLD_ELF_TARGET_H 11 #define LLD_ELF_TARGET_H 12 13 #include "llvm/ADT/StringRef.h" 14 #include "llvm/Object/ELF.h" 15 16 #include <memory> 17 18 namespace lld { 19 namespace elf { 20 class SymbolBody; 21 22 class TargetInfo { 23 public: 24 uint64_t getVAStart() const; 25 virtual bool isTlsInitialExecRel(uint32_t Type) const; 26 virtual bool pointsToLocalDynamicGotEntry(uint32_t Type) const; 27 virtual bool isTlsLocalDynamicRel(uint32_t Type) const; 28 virtual bool isTlsGlobalDynamicRel(uint32_t Type) const; 29 virtual uint32_t getDynRel(uint32_t Type) const { return Type; } 30 virtual uint32_t getTlsGotRel(uint32_t Type) const { return TlsGotRel; } 31 virtual void writeGotHeader(uint8_t *Buf) const {} 32 virtual void writeGotPltHeader(uint8_t *Buf) const {} 33 virtual void writeGotPlt(uint8_t *Buf, uint64_t Plt) const {}; 34 35 // If lazy binding is supported, the first entry of the PLT has code 36 // to call the dynamic linker to resolve PLT entries the first time 37 // they are called. This function writes that code. 38 virtual void writePltZero(uint8_t *Buf) const {} 39 40 virtual void writePlt(uint8_t *Buf, uint64_t GotEntryAddr, 41 uint64_t PltEntryAddr, int32_t Index, 42 unsigned RelOff) const {} 43 44 // Returns true if a relocation is just a hint for linker to make for example 45 // some code optimization. Such relocations should not be handled as a regular 46 // ones and lead to dynamic relocation creation etc. 47 virtual bool isHintRel(uint32_t Type) const; 48 49 // Returns true if a relocation is relative to the place being relocated, 50 // such as relocations used for PC-relative instructions. Such relocations 51 // need not be fixed up if an image is loaded to a different address than 52 // the link-time address. So we don't have to emit a relocation for the 53 // dynamic linker if isRelRelative returns true. 54 virtual bool isRelRelative(uint32_t Type) const; 55 56 virtual bool isSizeRel(uint32_t Type) const; 57 virtual bool needsDynRelative(uint32_t Type) const { return false; } 58 virtual bool needsGot(uint32_t Type, SymbolBody &S) const; 59 virtual bool refersToGotEntry(uint32_t Type) const; 60 61 enum PltNeed { Plt_No, Plt_Explicit, Plt_Implicit }; 62 PltNeed needsPlt(uint32_t Type, const SymbolBody &S) const; 63 64 virtual void relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, 65 uint64_t P, uint64_t SA, uint64_t ZA = 0, 66 uint8_t *PairedLoc = nullptr) const = 0; 67 virtual bool isGotRelative(uint32_t Type) const; 68 bool canRelaxTls(uint32_t Type, const SymbolBody *S) const; 69 template <class ELFT> 70 bool needsCopyRel(uint32_t Type, const SymbolBody &S) const; 71 size_t relaxTls(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P, 72 uint64_t SA, const SymbolBody &S) const; 73 virtual ~TargetInfo(); 74 75 unsigned PageSize = 4096; 76 77 // On freebsd x86_64 the first page cannot be mmaped. 78 // On linux that is controled by vm.mmap_min_addr. At least on some x86_64 79 // installs that is 65536, so the first 15 pages cannot be used. 80 // Given that, the smallest value that can be used in here is 0x10000. 81 // If using 2MB pages, the smallest page aligned address that works is 82 // 0x200000, but it looks like every OS uses 4k pages for executables. 83 uint64_t VAStart = 0x10000; 84 85 uint32_t CopyRel; 86 uint32_t GotRel; 87 uint32_t PltRel; 88 uint32_t RelativeRel; 89 uint32_t IRelativeRel; 90 uint32_t TlsGotRel = 0; 91 uint32_t TlsModuleIndexRel; 92 uint32_t TlsOffsetRel; 93 unsigned PltEntrySize = 8; 94 unsigned PltZeroSize = 0; 95 unsigned GotHeaderEntriesNum = 0; 96 unsigned GotPltHeaderEntriesNum = 3; 97 bool UseLazyBinding = false; 98 99 private: 100 virtual bool needsCopyRelImpl(uint32_t Type) const; 101 virtual bool needsPltImpl(uint32_t Type) const; 102 103 virtual size_t relaxTlsGdToIe(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, 104 uint64_t P, uint64_t SA) const; 105 virtual size_t relaxTlsGdToLe(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, 106 uint64_t P, uint64_t SA) const; 107 virtual size_t relaxTlsIeToLe(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, 108 uint64_t P, uint64_t SA) const; 109 virtual size_t relaxTlsLdToLe(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, 110 uint64_t P, uint64_t SA) const; 111 }; 112 113 uint64_t getPPC64TocBase(); 114 115 template <class ELFT> typename ELFT::uint getMipsGpAddr(); 116 117 extern TargetInfo *Target; 118 TargetInfo *createTarget(); 119 } 120 } 121 122 #endif 123