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