[PATCH] D34690: [LLD][ELF] Introduce target specific inBranchRange() function
Peter Smith via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Mon Jul 17 09:55:29 PDT 2017
This revision was automatically updated to reflect the committed changes.
Closed by commit rL308188: [ELF] Introduce target specific inBranchRange() function (authored by psmith).
Changed prior to commit:
https://reviews.llvm.org/D34690?vs=104165&id=106895#toc
Repository:
rL LLVM
https://reviews.llvm.org/D34690
Files:
lld/trunk/ELF/Arch/ARM.cpp
lld/trunk/ELF/Target.cpp
lld/trunk/ELF/Target.h
Index: lld/trunk/ELF/Arch/ARM.cpp
===================================================================
--- lld/trunk/ELF/Arch/ARM.cpp
+++ lld/trunk/ELF/Arch/ARM.cpp
@@ -40,6 +40,8 @@
void addPltHeaderSymbols(InputSectionBase *ISD) const override;
bool needsThunk(RelExpr Expr, uint32_t RelocType, const InputFile *File,
const SymbolBody &S) const override;
+ bool inBranchRange(uint32_t RelocType, uint64_t Src,
+ uint64_t Dst) const override;
void relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const override;
};
} // namespace
@@ -218,6 +220,49 @@
return false;
}
+bool ARM::inBranchRange(uint32_t RelocType, uint64_t Src, uint64_t Dst) const {
+ uint64_t Range;
+ uint64_t InstrSize;
+
+ switch (RelocType) {
+ case R_ARM_PC24:
+ case R_ARM_PLT32:
+ case R_ARM_JUMP24:
+ case R_ARM_CALL:
+ Range = 0x2000000;
+ InstrSize = 4;
+ break;
+ case R_ARM_THM_JUMP19:
+ Range = 0x100000;
+ InstrSize = 2;
+ break;
+ case R_ARM_THM_JUMP24:
+ case R_ARM_THM_CALL:
+ Range = 0x1000000;
+ InstrSize = 2;
+ break;
+ default:
+ return true;
+ }
+ // PC at Src is 2 instructions ahead, immediate of branch is signed
+ if (Src > Dst)
+ Range -= 2 * InstrSize;
+ else
+ Range += InstrSize;
+
+ if ((Dst & 0x1) == 0)
+ // Destination is ARM, if ARM caller then Src is already 4-byte aligned.
+ // If Thumb Caller (BLX) the Src address has bottom 2 bits cleared to ensure
+ // destination will be 4 byte aligned.
+ Src &= ~0x3;
+ else
+ // Bit 0 == 1 denotes Thumb state, it is not part of the range
+ Dst &= ~0x1;
+
+ uint64_t Distance = (Src > Dst) ? Src - Dst : Dst - Src;
+ return Distance <= Range;
+}
+
void ARM::relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const {
switch (Type) {
case R_ARM_ABS32:
Index: lld/trunk/ELF/Target.cpp
===================================================================
--- lld/trunk/ELF/Target.cpp
+++ lld/trunk/ELF/Target.cpp
@@ -128,6 +128,11 @@
return false;
}
+bool TargetInfo::inBranchRange(uint32_t RelocType, uint64_t Src,
+ uint64_t Dst) const {
+ return true;
+}
+
void TargetInfo::writeIgotPlt(uint8_t *Buf, const SymbolBody &S) const {
writeGotPlt(Buf, S);
}
Index: lld/trunk/ELF/Target.h
===================================================================
--- lld/trunk/ELF/Target.h
+++ lld/trunk/ELF/Target.h
@@ -51,6 +51,9 @@
// targeting S.
virtual bool needsThunk(RelExpr Expr, uint32_t RelocType,
const InputFile *File, const SymbolBody &S) const;
+ // Return true if we can reach Dst from Src with Relocation RelocType
+ virtual bool inBranchRange(uint32_t RelocType, uint64_t Src,
+ uint64_t Dst) const;
virtual RelExpr getRelExpr(uint32_t Type, const SymbolBody &S,
const uint8_t *Loc) const = 0;
virtual void relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const = 0;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D34690.106895.patch
Type: text/x-patch
Size: 3013 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170717/367d3e78/attachment.bin>
More information about the llvm-commits
mailing list