diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2020-07-26 19:36:28 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2020-07-26 19:36:28 +0000 |
commit | cfca06d7963fa0909f90483b42a6d7d194d01e08 (patch) | |
tree | 209fb2a2d68f8f277793fc8df46c753d31bc853b /lld/ELF/Target.h | |
parent | 706b4fc47bbc608932d3b491ae19a3b9cde9497b (diff) |
Notes
Diffstat (limited to 'lld/ELF/Target.h')
-rw-r--r-- | lld/ELF/Target.h | 74 |
1 files changed, 46 insertions, 28 deletions
diff --git a/lld/ELF/Target.h b/lld/ELF/Target.h index 949a7bfdf64b..47905ae64a47 100644 --- a/lld/ELF/Target.h +++ b/lld/ELF/Target.h @@ -82,10 +82,27 @@ public: virtual bool inBranchRange(RelType type, uint64_t src, uint64_t dst) const; - virtual void relocateOne(uint8_t *loc, RelType type, uint64_t val) const = 0; + virtual void relocate(uint8_t *loc, const Relocation &rel, + uint64_t val) const = 0; + void relocateNoSym(uint8_t *loc, RelType type, uint64_t val) const { + relocate(loc, Relocation{R_NONE, type, 0, 0, nullptr}, val); + } + + virtual void applyJumpInstrMod(uint8_t *loc, JumpModType type, + JumpModType val) const {} virtual ~TargetInfo(); + // This deletes a jump insn at the end of the section if it is a fall thru to + // the next section. Further, if there is a conditional jump and a direct + // jump consecutively, it tries to flip the conditional jump to convert the + // direct jump into a fall thru and delete it. Returns true if a jump + // instruction can be deleted. + virtual bool deleteFallThruJmpInsn(InputSection &is, InputFile *file, + InputSection *nextIS) const { + return false; + } + unsigned defaultCommonPageSize = 4096; unsigned defaultMaxPageSize = 4096; @@ -122,6 +139,10 @@ public: // executable OutputSections. std::array<uint8_t, 4> trapInstr; + // Stores the NOP instructions of different sizes for the target and is used + // to pad sections that are relaxed. + llvm::Optional<std::vector<std::vector<uint8_t>>> nopInstrs; + // If a target needs to rewrite calls to __morestack to instead call // __morestack_non_split when a split-stack enabled caller calls a // non-split-stack callee this will return true. Otherwise returns false. @@ -129,11 +150,16 @@ public: virtual RelExpr adjustRelaxExpr(RelType type, const uint8_t *data, RelExpr expr) const; - virtual void relaxGot(uint8_t *loc, RelType type, uint64_t val) const; - virtual void relaxTlsGdToIe(uint8_t *loc, RelType type, uint64_t val) const; - virtual void relaxTlsGdToLe(uint8_t *loc, RelType type, uint64_t val) const; - virtual void relaxTlsIeToLe(uint8_t *loc, RelType type, uint64_t val) const; - virtual void relaxTlsLdToLe(uint8_t *loc, RelType type, uint64_t val) const; + virtual void relaxGot(uint8_t *loc, const Relocation &rel, + uint64_t val) const; + virtual void relaxTlsGdToIe(uint8_t *loc, const Relocation &rel, + uint64_t val) const; + virtual void relaxTlsGdToLe(uint8_t *loc, const Relocation &rel, + uint64_t val) const; + virtual void relaxTlsIeToLe(uint8_t *loc, const Relocation &rel, + uint64_t val) const; + virtual void relaxTlsLdToLe(uint8_t *loc, const Relocation &rel, + uint64_t val) const; protected: // On FreeBSD x86_64 the first page cannot be mmaped. @@ -171,8 +197,7 @@ static inline std::string getErrorLocation(const uint8_t *loc) { void writePPC32GlinkSection(uint8_t *buf, size_t numEntries); -bool tryRelaxPPC64TocIndirection(RelType type, const Relocation &rel, - uint8_t *bufLoc); +bool tryRelaxPPC64TocIndirection(const Relocation &rel, uint8_t *bufLoc); unsigned getPPCDFormOp(unsigned secondaryOp); // In the PowerPC64 Elf V2 abi a function can have 2 entry points. The first @@ -188,6 +213,7 @@ unsigned getPPC64GlobalEntryToLocalEntryOffset(uint8_t stOther); // the .toc section. bool isPPC64SmallCodeModelTocReloc(RelType type); +void addPPC64SaveRestore(); uint64_t getPPC64TocBase(); uint64_t getAArch64Page(uint64_t expr); @@ -196,44 +222,36 @@ TargetInfo *getTarget(); template <class ELFT> bool isMipsPIC(const Defined *sym); -static inline void reportRangeError(uint8_t *loc, RelType type, const Twine &v, - int64_t min, uint64_t max) { - ErrorPlace errPlace = getErrorPlace(loc); - StringRef hint; - if (errPlace.isec && errPlace.isec->name.startswith(".debug")) - hint = "; consider recompiling with -fdebug-types-section to reduce size " - "of debug sections"; - - errorOrWarn(errPlace.loc + "relocation " + lld::toString(type) + - " out of range: " + v.str() + " is not in [" + Twine(min).str() + - ", " + Twine(max).str() + "]" + hint); -} +void reportRangeError(uint8_t *loc, const Relocation &rel, const Twine &v, + int64_t min, uint64_t max); // Make sure that V can be represented as an N bit signed integer. -inline void checkInt(uint8_t *loc, int64_t v, int n, RelType type) { +inline void checkInt(uint8_t *loc, int64_t v, int n, const Relocation &rel) { if (v != llvm::SignExtend64(v, n)) - reportRangeError(loc, type, Twine(v), llvm::minIntN(n), llvm::maxIntN(n)); + reportRangeError(loc, rel, Twine(v), llvm::minIntN(n), llvm::maxIntN(n)); } // Make sure that V can be represented as an N bit unsigned integer. -inline void checkUInt(uint8_t *loc, uint64_t v, int n, RelType type) { +inline void checkUInt(uint8_t *loc, uint64_t v, int n, const Relocation &rel) { if ((v >> n) != 0) - reportRangeError(loc, type, Twine(v), 0, llvm::maxUIntN(n)); + reportRangeError(loc, rel, Twine(v), 0, llvm::maxUIntN(n)); } // Make sure that V can be represented as an N bit signed or unsigned integer. -inline void checkIntUInt(uint8_t *loc, uint64_t v, int n, RelType type) { +inline void checkIntUInt(uint8_t *loc, uint64_t v, int n, + const Relocation &rel) { // For the error message we should cast V to a signed integer so that error // messages show a small negative value rather than an extremely large one if (v != (uint64_t)llvm::SignExtend64(v, n) && (v >> n) != 0) - reportRangeError(loc, type, Twine((int64_t)v), llvm::minIntN(n), + reportRangeError(loc, rel, Twine((int64_t)v), llvm::minIntN(n), llvm::maxUIntN(n)); } -inline void checkAlignment(uint8_t *loc, uint64_t v, int n, RelType type) { +inline void checkAlignment(uint8_t *loc, uint64_t v, int n, + const Relocation &rel) { if ((v & (n - 1)) != 0) error(getErrorLocation(loc) + "improper alignment for relocation " + - lld::toString(type) + ": 0x" + llvm::utohexstr(v) + + lld::toString(rel.type) + ": 0x" + llvm::utohexstr(v) + " is not aligned to " + Twine(n) + " bytes"); } |