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 isTlsLocalDynamicRel(unsigned Type) const; 26 virtual bool isTlsGlobalDynamicRel(unsigned Type) const; 27 virtual unsigned getDynRel(unsigned Type) const { return Type; } 28 virtual bool isTlsDynRel(unsigned Type, const SymbolBody &S) const; 29 virtual unsigned getTlsGotRel(unsigned Type) const { return TlsGotRel; } 30 virtual void writeGotHeader(uint8_t *Buf) const {} 31 virtual void writeGotPltHeader(uint8_t *Buf) const {} 32 virtual void writeGotPlt(uint8_t *Buf, uint64_t Plt) const {}; 33 34 // If lazy binding is supported, the first entry of the PLT has code 35 // to call the dynamic linker to resolve PLT entries the first time 36 // they are called. This function writes that code. 37 virtual void writePltZero(uint8_t *Buf) const {} 38 39 virtual void writePlt(uint8_t *Buf, uint64_t GotEntryAddr, 40 uint64_t PltEntryAddr, int32_t Index, 41 unsigned RelOff) const {} 42 43 // Returns true if a relocation is just a hint for linker to make for example 44 // some code optimization. Such relocations should not be handled as a regular 45 // ones and lead to dynamic relocation creation etc. 46 virtual bool isHintRel(uint32_t Type) const; 47 48 // Returns true if a relocation is relative to the place being relocated, 49 // such as relocations used for PC-relative instructions. Such relocations 50 // need not be fixed up if an image is loaded to a different address than 51 // the link-time address. So we don't have to emit a relocation for the 52 // dynamic linker if isRelRelative returns true. 53 virtual bool isRelRelative(uint32_t Type) const; 54 55 virtual bool isSizeRel(uint32_t Type) const; 56 virtual bool needsDynRelative(unsigned Type) const { return false; } 57 virtual bool needsGot(uint32_t Type, SymbolBody &S) const; 58 virtual bool refersToGotEntry(uint32_t Type) const; 59 60 enum PltNeed { Plt_No, Plt_Explicit, Plt_Implicit }; 61 template <class ELFT> 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 virtual bool canRelaxTls(unsigned Type, const SymbolBody *S) const; 69 template <class ELFT> 70 bool needsCopyRel(uint32_t Type, const SymbolBody &S) const; 71 virtual unsigned relaxTls(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, 72 uint64_t P, 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 unsigned CopyRel; 86 unsigned GotRel; 87 unsigned PltRel; 88 unsigned RelativeRel; 89 unsigned IRelativeRel; 90 unsigned TlsGotRel = 0; 91 unsigned TlsModuleIndexRel; 92 unsigned 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 104 uint64_t getPPC64TocBase(); 105 106 template <class ELFT> 107 typename llvm::object::ELFFile<ELFT>::uintX_t getMipsGpAddr(); 108 109 template <class ELFT> bool isGnuIFunc(const SymbolBody &S); 110 111 extern TargetInfo *Target; 112 TargetInfo *createTarget(); 113 } 114 } 115 116 #endif 117