1 //===- Target.h -------------------------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLD_ELF_TARGET_H 10 #define LLD_ELF_TARGET_H 11 12 #include "InputSection.h" 13 #include "lld/Common/ErrorHandler.h" 14 #include "llvm/Object/ELF.h" 15 #include "llvm/Support/MathExtras.h" 16 #include <array> 17 18 namespace lld { 19 std::string toString(elf::RelType type); 20 21 namespace elf { 22 class Defined; 23 class InputFile; 24 class Symbol; 25 26 class TargetInfo { 27 public: 28 virtual uint32_t calcEFlags() const { return 0; } 29 virtual RelExpr getRelExpr(RelType type, const Symbol &s, 30 const uint8_t *loc) const = 0; 31 virtual RelType getDynRel(RelType type) const { return 0; } 32 virtual void writeGotPltHeader(uint8_t *buf) const {} 33 virtual void writeGotHeader(uint8_t *buf) const {} 34 virtual void writeGotPlt(uint8_t *buf, const Symbol &s) const {}; 35 virtual void writeIgotPlt(uint8_t *buf, const Symbol &s) const; 36 virtual int64_t getImplicitAddend(const uint8_t *buf, RelType type) const; 37 virtual int getTlsGdRelaxSkip(RelType type) const { return 1; } 38 39 // If lazy binding is supported, the first entry of the PLT has code 40 // to call the dynamic linker to resolve PLT entries the first time 41 // they are called. This function writes that code. 42 virtual void writePltHeader(uint8_t *buf) const {} 43 44 virtual void writePlt(uint8_t *buf, uint64_t gotEntryAddr, 45 uint64_t pltEntryAddr, int32_t index, 46 unsigned relOff) const {} 47 virtual void addPltHeaderSymbols(InputSection &isec) const {} 48 virtual void addPltSymbols(InputSection &isec, uint64_t off) const {} 49 50 // Returns true if a relocation only uses the low bits of a value such that 51 // all those bits are in the same page. For example, if the relocation 52 // only uses the low 12 bits in a system with 4k pages. If this is true, the 53 // bits will always have the same value at runtime and we don't have to emit 54 // a dynamic relocation. 55 virtual bool usesOnlyLowPageBits(RelType type) const; 56 57 // Decide whether a Thunk is needed for the relocation from File 58 // targeting S. 59 virtual bool needsThunk(RelExpr expr, RelType relocType, 60 const InputFile *file, uint64_t branchAddr, 61 const Symbol &s) const; 62 63 // On systems with range extensions we place collections of Thunks at 64 // regular spacings that enable the majority of branches reach the Thunks. 65 // a value of 0 means range extension thunks are not supported. 66 virtual uint32_t getThunkSectionSpacing() const { return 0; } 67 68 // The function with a prologue starting at Loc was compiled with 69 // -fsplit-stack and it calls a function compiled without. Adjust the prologue 70 // to do the right thing. See https://gcc.gnu.org/wiki/SplitStacks. 71 // The symbols st_other flags are needed on PowerPC64 for determining the 72 // offset to the split-stack prologue. 73 virtual bool adjustPrologueForCrossSplitStack(uint8_t *loc, uint8_t *end, 74 uint8_t stOther) const; 75 76 // Return true if we can reach dst from src with RelType type. 77 virtual bool inBranchRange(RelType type, uint64_t src, 78 uint64_t dst) const; 79 80 virtual void relocateOne(uint8_t *loc, RelType type, uint64_t val) const = 0; 81 82 virtual ~TargetInfo(); 83 84 unsigned defaultCommonPageSize = 4096; 85 unsigned defaultMaxPageSize = 4096; 86 87 uint64_t getImageBase() const; 88 89 // True if _GLOBAL_OFFSET_TABLE_ is relative to .got.plt, false if .got. 90 bool gotBaseSymInGotPlt = true; 91 92 RelType copyRel; 93 RelType gotRel; 94 RelType noneRel; 95 RelType pltRel; 96 RelType relativeRel; 97 RelType iRelativeRel; 98 RelType symbolicRel; 99 RelType tlsDescRel; 100 RelType tlsGotRel; 101 RelType tlsModuleIndexRel; 102 RelType tlsOffsetRel; 103 unsigned pltEntrySize; 104 unsigned pltHeaderSize; 105 106 // At least on x86_64 positions 1 and 2 are used by the first plt entry 107 // to support lazy loading. 108 unsigned gotPltHeaderEntriesNum = 3; 109 110 // On PPC ELF V2 abi, the first entry in the .got is the .TOC. 111 unsigned gotHeaderEntriesNum = 0; 112 113 bool needsThunks = false; 114 115 // A 4-byte field corresponding to one or more trap instructions, used to pad 116 // executable OutputSections. 117 std::array<uint8_t, 4> trapInstr; 118 119 // If a target needs to rewrite calls to __morestack to instead call 120 // __morestack_non_split when a split-stack enabled caller calls a 121 // non-split-stack callee this will return true. Otherwise returns false. 122 bool needsMoreStackNonSplit = true; 123 124 virtual RelExpr adjustRelaxExpr(RelType type, const uint8_t *data, 125 RelExpr expr) const; 126 virtual void relaxGot(uint8_t *loc, RelType type, uint64_t val) const; 127 virtual void relaxTlsGdToIe(uint8_t *loc, RelType type, uint64_t val) const; 128 virtual void relaxTlsGdToLe(uint8_t *loc, RelType type, uint64_t val) const; 129 virtual void relaxTlsIeToLe(uint8_t *loc, RelType type, uint64_t val) const; 130 virtual void relaxTlsLdToLe(uint8_t *loc, RelType type, uint64_t val) const; 131 132 protected: 133 // On FreeBSD x86_64 the first page cannot be mmaped. 134 // On Linux that is controled by vm.mmap_min_addr. At least on some x86_64 135 // installs that is 65536, so the first 15 pages cannot be used. 136 // Given that, the smallest value that can be used in here is 0x10000. 137 uint64_t defaultImageBase = 0x10000; 138 }; 139 140 TargetInfo *getAArch64TargetInfo(); 141 TargetInfo *getAMDGPUTargetInfo(); 142 TargetInfo *getARMTargetInfo(); 143 TargetInfo *getAVRTargetInfo(); 144 TargetInfo *getHexagonTargetInfo(); 145 TargetInfo *getMSP430TargetInfo(); 146 TargetInfo *getPPC64TargetInfo(); 147 TargetInfo *getPPCTargetInfo(); 148 TargetInfo *getRISCVTargetInfo(); 149 TargetInfo *getSPARCV9TargetInfo(); 150 TargetInfo *getX86TargetInfo(); 151 TargetInfo *getX86_64TargetInfo(); 152 template <class ELFT> TargetInfo *getMipsTargetInfo(); 153 154 struct ErrorPlace { 155 InputSectionBase *isec; 156 std::string loc; 157 }; 158 159 // Returns input section and corresponding source string for the given location. 160 ErrorPlace getErrorPlace(const uint8_t *loc); 161 162 static inline std::string getErrorLocation(const uint8_t *loc) { 163 return getErrorPlace(loc).loc; 164 } 165 166 void writePPC32GlinkSection(uint8_t *buf, size_t numEntries); 167 168 bool tryRelaxPPC64TocIndirection(RelType type, const Relocation &rel, 169 uint8_t *bufLoc); 170 unsigned getPPCDFormOp(unsigned secondaryOp); 171 172 // In the PowerPC64 Elf V2 abi a function can have 2 entry points. The first 173 // is a global entry point (GEP) which typically is used to initialize the TOC 174 // pointer in general purpose register 2. The second is a local entry 175 // point (LEP) which bypasses the TOC pointer initialization code. The 176 // offset between GEP and LEP is encoded in a function's st_other flags. 177 // This function will return the offset (in bytes) from the global entry-point 178 // to the local entry-point. 179 unsigned getPPC64GlobalEntryToLocalEntryOffset(uint8_t stOther); 180 181 // Returns true if a relocation is a small code model relocation that accesses 182 // the .toc section. 183 bool isPPC64SmallCodeModelTocReloc(RelType type); 184 185 uint64_t getPPC64TocBase(); 186 uint64_t getAArch64Page(uint64_t expr); 187 188 extern const TargetInfo *target; 189 TargetInfo *getTarget(); 190 191 template <class ELFT> bool isMipsPIC(const Defined *sym); 192 193 static inline void reportRangeError(uint8_t *loc, RelType type, const Twine &v, 194 int64_t min, uint64_t max) { 195 ErrorPlace errPlace = getErrorPlace(loc); 196 StringRef hint; 197 if (errPlace.isec && errPlace.isec->name.startswith(".debug")) 198 hint = "; consider recompiling with -fdebug-types-section to reduce size " 199 "of debug sections"; 200 201 errorOrWarn(errPlace.loc + "relocation " + lld::toString(type) + 202 " out of range: " + v.str() + " is not in [" + Twine(min).str() + 203 ", " + Twine(max).str() + "]" + hint); 204 } 205 206 // Make sure that V can be represented as an N bit signed integer. 207 inline void checkInt(uint8_t *loc, int64_t v, int n, RelType type) { 208 if (v != llvm::SignExtend64(v, n)) 209 reportRangeError(loc, type, Twine(v), llvm::minIntN(n), llvm::maxIntN(n)); 210 } 211 212 // Make sure that V can be represented as an N bit unsigned integer. 213 inline void checkUInt(uint8_t *loc, uint64_t v, int n, RelType type) { 214 if ((v >> n) != 0) 215 reportRangeError(loc, type, Twine(v), 0, llvm::maxUIntN(n)); 216 } 217 218 // Make sure that V can be represented as an N bit signed or unsigned integer. 219 inline void checkIntUInt(uint8_t *loc, uint64_t v, int n, RelType type) { 220 // For the error message we should cast V to a signed integer so that error 221 // messages show a small negative value rather than an extremely large one 222 if (v != (uint64_t)llvm::SignExtend64(v, n) && (v >> n) != 0) 223 reportRangeError(loc, type, Twine((int64_t)v), llvm::minIntN(n), 224 llvm::maxUIntN(n)); 225 } 226 227 inline void checkAlignment(uint8_t *loc, uint64_t v, int n, RelType type) { 228 if ((v & (n - 1)) != 0) 229 error(getErrorLocation(loc) + "improper alignment for relocation " + 230 lld::toString(type) + ": 0x" + llvm::utohexstr(v) + 231 " is not aligned to " + Twine(n) + " bytes"); 232 } 233 234 // Endianness-aware read/write. 235 inline uint16_t read16(const void *p) { 236 return llvm::support::endian::read16(p, config->endianness); 237 } 238 239 inline uint32_t read32(const void *p) { 240 return llvm::support::endian::read32(p, config->endianness); 241 } 242 243 inline uint64_t read64(const void *p) { 244 return llvm::support::endian::read64(p, config->endianness); 245 } 246 247 inline void write16(void *p, uint16_t v) { 248 llvm::support::endian::write16(p, v, config->endianness); 249 } 250 251 inline void write32(void *p, uint32_t v) { 252 llvm::support::endian::write32(p, v, config->endianness); 253 } 254 255 inline void write64(void *p, uint64_t v) { 256 llvm::support::endian::write64(p, v, config->endianness); 257 } 258 } // namespace elf 259 } // namespace lld 260 261 #endif 262