[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