[lld] r340160 - [ELF] Add support for Armv5 and Armv6 compatible Thunks

Peter Smith via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 20 02:37:50 PDT 2018


Author: psmith
Date: Mon Aug 20 02:37:50 2018
New Revision: 340160

URL: http://llvm.org/viewvc/llvm-project?rev=340160&view=rev
Log:
[ELF] Add support for Armv5 and Armv6 compatible Thunks

Older Arm architectures do not support the MOVT and MOVW instructions so we
must use an alternative sequence of instructions to transfer control to the
destination.

Assuming at least Armv5 this patch adds support for Thunks that load or add
to the program counter. Note that there are no Armv5 Thumb Thunks as there
is no Thumb branch instruction in Armv5 that supports Thunks. These thunks
will not work for Armv4t (arm7tdmi) as this architecture cannot change state
from using the LDR or ADD instruction.

Differential Revision: https://reviews.llvm.org/D50077

Added:
    lld/trunk/test/ELF/arm-thumb-interwork-thunk-v5.s
    lld/trunk/test/ELF/arm-thumb-nov6thunk.s
    lld/trunk/test/ELF/arm-v5-reloc-error.s
Modified:
    lld/trunk/ELF/AArch64ErrataFix.cpp
    lld/trunk/ELF/Arch/AArch64.cpp
    lld/trunk/ELF/Arch/ARM.cpp
    lld/trunk/ELF/Driver.cpp
    lld/trunk/ELF/Relocations.cpp
    lld/trunk/ELF/Target.h
    lld/trunk/ELF/Thunks.cpp
    lld/trunk/ELF/Writer.cpp
    lld/trunk/test/ELF/arm-bl-v6.s
    lld/trunk/test/ELF/arm-blx-v4t.s
    lld/trunk/test/ELF/arm-branch-rangethunk.s
    lld/trunk/test/ELF/arm-branch-undef-weak-plt-thunk.s
    lld/trunk/test/ELF/arm-long-thunk-converge.s
    lld/trunk/test/ELF/arm-thumb-branch-rangethunk.s
    lld/trunk/test/ELF/arm-thumb-interwork-shared.s
    lld/trunk/test/ELF/arm-thumb-interwork-thunk-range.s
    lld/trunk/test/ELF/arm-thumb-interwork-thunk.s
    lld/trunk/test/ELF/arm-thumb-thunk-symbols.s
    lld/trunk/test/ELF/arm-thunk-edgecase.s
    lld/trunk/test/ELF/arm-thunk-linkerscript-dotexpr.s
    lld/trunk/test/ELF/arm-thunk-linkerscript-orphan.s
    lld/trunk/test/ELF/arm-thunk-linkerscript.s
    lld/trunk/test/ELF/arm-thunk-re-add.s

Modified: lld/trunk/ELF/AArch64ErrataFix.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/AArch64ErrataFix.cpp?rev=340160&r1=340159&r2=340160&view=diff
==============================================================================
--- lld/trunk/ELF/AArch64ErrataFix.cpp (original)
+++ lld/trunk/ELF/AArch64ErrataFix.cpp Mon Aug 20 02:37:50 2018
@@ -487,7 +487,7 @@ void AArch64Err843419Patcher::insertPatc
     InputSectionDescription &ISD, std::vector<Patch843419Section *> &Patches) {
   uint64_t ISLimit;
   uint64_t PrevISLimit = ISD.Sections.front()->OutSecOff;
-  uint64_t PatchUpperBound = PrevISLimit + Target->ThunkSectionSpacing;
+  uint64_t PatchUpperBound = PrevISLimit + Target->getThunkSectionSpacing();
 
   // Set the OutSecOff of patches to the place where we want to insert them.
   // We use a similar strategy to Thunk placement. Place patches roughly
@@ -503,7 +503,7 @@ void AArch64Err843419Patcher::insertPatc
         (*PatchIt)->OutSecOff = PrevISLimit;
         ++PatchIt;
       }
-      PatchUpperBound = PrevISLimit + Target->ThunkSectionSpacing;
+      PatchUpperBound = PrevISLimit + Target->getThunkSectionSpacing();
     }
     PrevISLimit = ISLimit;
   }

Modified: lld/trunk/ELF/Arch/AArch64.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Arch/AArch64.cpp?rev=340160&r1=340159&r2=340160&view=diff
==============================================================================
--- lld/trunk/ELF/Arch/AArch64.cpp (original)
+++ lld/trunk/ELF/Arch/AArch64.cpp Mon Aug 20 02:37:50 2018
@@ -41,6 +41,7 @@ public:
                 int32_t Index, unsigned RelOff) const override;
   bool needsThunk(RelExpr Expr, RelType Type, const InputFile *File,
                   uint64_t BranchAddr, const Symbol &S) const override;
+  uint32_t getThunkSectionSpacing() const override;
   bool inBranchRange(RelType Type, uint64_t Src, uint64_t Dst) const override;
   bool usesOnlyLowPageBits(RelType Type) const override;
   void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override;
@@ -70,11 +71,6 @@ AArch64::AArch64() {
   // 1 of the tls structures and the tcb size is 16.
   TcbSize = 16;
   NeedsThunks = true;
-
-  // See comment in Arch/ARM.cpp for a more detailed explanation of
-  // ThunkSectionSpacing. For AArch64 the only branches we are permitted to
-  // Thunk have a range of +/- 128 MiB
-  ThunkSectionSpacing = (128 * 1024 * 1024) - 0x30000;
 }
 
 RelExpr AArch64::getRelExpr(RelType Type, const Symbol &S,
@@ -208,6 +204,13 @@ bool AArch64::needsThunk(RelExpr Expr, R
   return !inBranchRange(Type, BranchAddr, Dst);
 }
 
+uint32_t AArch64::getThunkSectionSpacing() const {
+  // See comment in Arch/ARM.cpp for a more detailed explanation of
+  // getThunkSectionSpacing(). For AArch64 the only branches we are permitted to
+  // Thunk have a range of +/- 128 MiB
+  return (128 * 1024 * 1024) - 0x30000;
+}
+
 bool AArch64::inBranchRange(RelType Type, uint64_t Src, uint64_t Dst) const {
   if (Type != R_AARCH64_CALL26 && Type != R_AARCH64_JUMP26)
     return true;

Modified: lld/trunk/ELF/Arch/ARM.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Arch/ARM.cpp?rev=340160&r1=340159&r2=340160&view=diff
==============================================================================
--- lld/trunk/ELF/Arch/ARM.cpp (original)
+++ lld/trunk/ELF/Arch/ARM.cpp Mon Aug 20 02:37:50 2018
@@ -40,6 +40,7 @@ public:
   void addPltHeaderSymbols(InputSection &ISD) const override;
   bool needsThunk(RelExpr Expr, RelType Type, const InputFile *File,
                   uint64_t BranchAddr, const Symbol &S) const override;
+  uint32_t getThunkSectionSpacing() const override;
   bool inBranchRange(RelType Type, uint64_t Src, uint64_t Dst) const override;
   void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override;
 };
@@ -63,37 +64,6 @@ ARM::ARM() {
   // ARM uses Variant 1 TLS
   TcbSize = 8;
   NeedsThunks = true;
-
-  // The placing of pre-created ThunkSections is controlled by the
-  // ThunkSectionSpacing parameter. The aim is to place the
-  // ThunkSection such that all branches from the InputSections prior to the
-  // ThunkSection can reach a Thunk placed at the end of the ThunkSection.
-  // Graphically:
-  // | up to ThunkSectionSpacing .text input sections |
-  // | ThunkSection                                   |
-  // | up to ThunkSectionSpacing .text input sections |
-  // | ThunkSection                                   |
-
-  // Pre-created ThunkSections are spaced roughly 16MiB apart on ARM. This is to
-  // match the most common expected case of a Thumb 2 encoded BL, BLX or B.W
-  // ARM B, BL, BLX range +/- 32MiB
-  // Thumb B.W, BL, BLX range +/- 16MiB
-  // Thumb B<cc>.W range +/- 1MiB
-  // If a branch cannot reach a pre-created ThunkSection a new one will be
-  // created so we can handle the rare cases of a Thumb 2 conditional branch.
-  // We intentionally use a lower size for ThunkSectionSpacing than the maximum
-  // branch range so the end of the ThunkSection is more likely to be within
-  // range of the branch instruction that is furthest away. The value we shorten
-  // ThunkSectionSpacing by is set conservatively to allow us to create 16,384
-  // 12 byte Thunks at any offset in a ThunkSection without risk of a branch to
-  // one of the Thunks going out of range.
-
-  // FIXME: lld assumes that the Thumb BL and BLX encoding permits the J1 and
-  // J2 bits to be used to extend the branch range. On earlier Architectures
-  // such as ARMv4, ARMv5 and ARMv6 (except ARMv6T2) the range is +/- 4MiB. If
-  // support for the earlier encodings is added then when they are used the
-  // ThunkSectionSpacing will need lowering.
-  ThunkSectionSpacing = 0x1000000 - 0x30000;
 }
 
 uint32_t ARM::calcEFlags() const {
@@ -324,6 +294,40 @@ bool ARM::needsThunk(RelExpr Expr, RelTy
   return false;
 }
 
+uint32_t ARM::getThunkSectionSpacing() const {
+  // The placing of pre-created ThunkSections is controlled by the value
+  // ThunkSectionSpacing returned by getThunkSectionSpacing(). The aim is to
+  // place the ThunkSection such that all branches from the InputSections
+  // prior to the ThunkSection can reach a Thunk placed at the end of the
+  // ThunkSection. Graphically:
+  // | up to ThunkSectionSpacing .text input sections |
+  // | ThunkSection                                   |
+  // | up to ThunkSectionSpacing .text input sections |
+  // | ThunkSection                                   |
+
+  // Pre-created ThunkSections are spaced roughly 16MiB apart on ARMv7. This
+  // is to match the most common expected case of a Thumb 2 encoded BL, BLX or
+  // B.W:
+  // ARM B, BL, BLX range +/- 32MiB
+  // Thumb B.W, BL, BLX range +/- 16MiB
+  // Thumb B<cc>.W range +/- 1MiB
+  // If a branch cannot reach a pre-created ThunkSection a new one will be
+  // created so we can handle the rare cases of a Thumb 2 conditional branch.
+  // We intentionally use a lower size for ThunkSectionSpacing than the maximum
+  // branch range so the end of the ThunkSection is more likely to be within
+  // range of the branch instruction that is furthest away. The value we shorten
+  // ThunkSectionSpacing by is set conservatively to allow us to create 16,384
+  // 12 byte Thunks at any offset in a ThunkSection without risk of a branch to
+  // one of the Thunks going out of range.
+
+  // On Arm the ThunkSectionSpacing depends on the range of the Thumb Branch
+  // range. On earlier Architectures such as ARMv4, ARMv5 and ARMv6 (except
+  // ARMv6T2) the range is +/- 4MiB.
+
+  return (Config->ARMJ1J2BranchEncoding) ? 0x1000000 - 0x30000
+                                         : 0x400000 - 0x7500;
+}
+
 bool ARM::inBranchRange(RelType Type, uint64_t Src, uint64_t Dst) const {
   uint64_t Range;
   uint64_t InstrSize;

Modified: lld/trunk/ELF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=340160&r1=340159&r2=340160&view=diff
==============================================================================
--- lld/trunk/ELF/Driver.cpp (original)
+++ lld/trunk/ELF/Driver.cpp Mon Aug 20 02:37:50 2018
@@ -1504,9 +1504,6 @@ template <class ELFT> void LinkerDriver:
     if (Config->ARMHasBlx == false)
       warn("lld uses blx instruction, no object with architecture supporting "
            "feature detected.");
-    if (Config->ARMHasMovtMovw == false)
-      warn("lld may use movt/movw, no object with architecture supporting "
-           "feature detected.");
   }
 
   // This adds a .comment section containing a version string. We have to add it

Modified: lld/trunk/ELF/Relocations.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Relocations.cpp?rev=340160&r1=340159&r2=340160&view=diff
==============================================================================
--- lld/trunk/ELF/Relocations.cpp (original)
+++ lld/trunk/ELF/Relocations.cpp Mon Aug 20 02:37:50 2018
@@ -1268,6 +1268,7 @@ ThunkSection *ThunkCreator::getISThunkSe
 // allow for the creation of a short thunk.
 void ThunkCreator::createInitialThunkSections(
     ArrayRef<OutputSection *> OutputSections) {
+  uint32_t ThunkSectionSpacing = Target->getThunkSectionSpacing();
   forEachInputSectionDescription(
       OutputSections, [&](OutputSection *OS, InputSectionDescription *ISD) {
         if (ISD->Sections.empty())
@@ -1276,18 +1277,18 @@ void ThunkCreator::createInitialThunkSec
         uint32_t ISDEnd =
             ISD->Sections.back()->OutSecOff + ISD->Sections.back()->getSize();
         uint32_t LastThunkLowerBound = -1;
-        if (ISDEnd - ISDBegin > Target->ThunkSectionSpacing * 2)
-          LastThunkLowerBound = ISDEnd - Target->ThunkSectionSpacing;
+        if (ISDEnd - ISDBegin > ThunkSectionSpacing * 2)
+          LastThunkLowerBound = ISDEnd - ThunkSectionSpacing;
 
         uint32_t ISLimit;
         uint32_t PrevISLimit = ISDBegin;
-        uint32_t ThunkUpperBound = ISDBegin + Target->ThunkSectionSpacing;
+        uint32_t ThunkUpperBound = ISDBegin + ThunkSectionSpacing;
 
         for (const InputSection *IS : ISD->Sections) {
           ISLimit = IS->OutSecOff + IS->getSize();
           if (ISLimit > ThunkUpperBound) {
             addThunkSection(OS, ISD, PrevISLimit);
-            ThunkUpperBound = PrevISLimit + Target->ThunkSectionSpacing;
+            ThunkUpperBound = PrevISLimit + ThunkSectionSpacing;
           }
           if (ISLimit > LastThunkLowerBound)
             break;
@@ -1382,7 +1383,7 @@ bool ThunkCreator::normalizeExistingThun
 // relocation out of range error.
 bool ThunkCreator::createThunks(ArrayRef<OutputSection *> OutputSections) {
   bool AddressesChanged = false;
-  if (Pass == 0 && Target->ThunkSectionSpacing)
+  if (Pass == 0 && Target->getThunkSectionSpacing())
     createInitialThunkSections(OutputSections);
   else if (Pass == 10)
     // With Thunk Size much smaller than branch range we expect to

Modified: lld/trunk/ELF/Target.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.h?rev=340160&r1=340159&r2=340160&view=diff
==============================================================================
--- lld/trunk/ELF/Target.h (original)
+++ lld/trunk/ELF/Target.h Mon Aug 20 02:37:50 2018
@@ -61,6 +61,11 @@ public:
                           const InputFile *File, uint64_t BranchAddr,
                           const Symbol &S) const;
 
+  // On systems with range extensions we place collections of Thunks at
+  // regular spacings that enable the majority of branches reach the Thunks.
+  // a value of 0 means range extension thunks are not supported.
+  virtual uint32_t getThunkSectionSpacing() const { return 0; }
+
   // The function with a prologue starting at Loc was compiled with
   // -fsplit-stack and it calls a function compiled without. Adjust the prologue
   // to do the right thing. See https://gcc.gnu.org/wiki/SplitStacks.
@@ -88,10 +93,6 @@ public:
   // True if _GLOBAL_OFFSET_TABLE_ is relative to .got.plt, false if .got.
   bool GotBaseSymInGotPlt = true;
 
-  // On systems with range extensions we place collections of Thunks at
-  // regular spacings that enable the majority of branches reach the Thunks.
-  uint32_t ThunkSectionSpacing = 0;
-
   RelType CopyRel;
   RelType GotRel;
   RelType PltRel;

Modified: lld/trunk/ELF/Thunks.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Thunks.cpp?rev=340160&r1=340159&r2=340160&view=diff
==============================================================================
--- lld/trunk/ELF/Thunks.cpp (original)
+++ lld/trunk/ELF/Thunks.cpp Mon Aug 20 02:37:50 2018
@@ -159,6 +159,31 @@ public:
   void addSymbols(ThunkSection &IS) override;
 };
 
+// Implementations of Thunks for older Arm architectures that do not support
+// the movt/movw instructions. These thunks require at least Architecture v5
+// as used on processors such as the Arm926ej-s. There are no Thumb entry
+// points as there is no Thumb branch instruction on these architecture that
+// can result in a thunk
+class ARMV5ABSLongThunk final : public ARMThunk {
+public:
+  ARMV5ABSLongThunk(Symbol &Dest) : ARMThunk(Dest) {}
+
+  uint32_t sizeLong() override { return 8; }
+  void writeLong(uint8_t *Buf) override;
+  void addSymbols(ThunkSection &IS) override;
+  bool isCompatibleWith(uint32_t RelocType) const override;
+};
+
+class ARMV5PILongThunk final : public ARMThunk {
+public:
+  ARMV5PILongThunk(Symbol &Dest) : ARMThunk(Dest) {}
+
+  uint32_t sizeLong() override { return 16; }
+  void writeLong(uint8_t *Buf) override;
+  void addSymbols(ThunkSection &IS) override;
+  bool isCompatibleWith(uint32_t RelocType) const override;
+};
+
 // MIPS LA25 thunk
 class MipsThunk final : public Thunk {
 public:
@@ -433,6 +458,52 @@ void ThumbV7PILongThunk::addSymbols(Thun
   addSymbol("$t", STT_NOTYPE, 0, IS);
 }
 
+void ARMV5ABSLongThunk::writeLong(uint8_t *Buf) {
+  const uint8_t Data[] = {
+      0x04, 0xf0, 0x1f, 0xe5, //     ldr pc, [pc,#-4] ; L1
+      0x00, 0x00, 0x00, 0x00, // L1: .word S
+  };
+  memcpy(Buf, Data, sizeof(Data));
+  Target->relocateOne(Buf + 4, R_ARM_ABS32, getARMThunkDestVA(Destination));
+}
+
+void ARMV5ABSLongThunk::addSymbols(ThunkSection &IS) {
+  addSymbol(Saver.save("__ARMv5ABSLongThunk_" + Destination.getName()),
+            STT_FUNC, 0, IS);
+  addSymbol("$a", STT_NOTYPE, 0, IS);
+  addSymbol("$d", STT_NOTYPE, 4, IS);
+}
+
+bool ARMV5ABSLongThunk::isCompatibleWith(uint32_t RelocType) const {
+  // Thumb branch relocations can't use BLX
+  return RelocType != R_ARM_THM_JUMP19 && RelocType != R_ARM_THM_JUMP24;
+}
+
+void ARMV5PILongThunk::writeLong(uint8_t *Buf) {
+  const uint8_t Data[] = {
+      0x04, 0xc0, 0x9f, 0xe5, // P:  ldr ip, [pc,#4] ; L2
+      0x0c, 0xc0, 0x8f, 0xe0, // L1: add ip, pc, ip
+      0x1c, 0xff, 0x2f, 0xe1, //     bx ip
+      0x00, 0x00, 0x00, 0x00, // L2: .word S - (P + (L1 - P) + 8)
+  };
+  uint64_t S = getARMThunkDestVA(Destination);
+  uint64_t P = getThunkTargetSym()->getVA() & ~0x1;
+  memcpy(Buf, Data, sizeof(Data));
+  Target->relocateOne(Buf + 12, R_ARM_REL32, S - P - 12);
+}
+
+void ARMV5PILongThunk::addSymbols(ThunkSection &IS) {
+  addSymbol(Saver.save("__ARMV5PILongThunk_" + Destination.getName()), STT_FUNC,
+            0, IS);
+  addSymbol("$a", STT_NOTYPE, 0, IS);
+  addSymbol("$d", STT_NOTYPE, 12, IS);
+}
+
+bool ARMV5PILongThunk::isCompatibleWith(uint32_t RelocType) const {
+  // Thumb branch relocations can't use BLX
+  return RelocType != R_ARM_THM_JUMP19 && RelocType != R_ARM_THM_JUMP24;
+}
+
 // Write MIPS LA25 thunk code to call PIC function from the non-PIC one.
 void MipsThunk::writeTo(uint8_t *Buf) {
   uint64_t S = Destination.getVA();
@@ -534,10 +605,49 @@ static Thunk *addThunkAArch64(RelType Ty
 }
 
 // Creates a thunk for Thumb-ARM interworking.
+// Arm Architectures v5 and v6 do not support Thumb2 technology. This means
+// - MOVT and MOVW instructions cannot be used
+// - Only Thumb relocation that can generate a Thunk is a BL, this can always
+//   be transformed into a BLX
+static Thunk *addThunkPreArmv7(RelType Reloc, Symbol &S) {
+  switch (Reloc) {
+  case R_ARM_PC24:
+  case R_ARM_PLT32:
+  case R_ARM_JUMP24:
+  case R_ARM_CALL:
+  case R_ARM_THM_CALL:
+    if (Config->Pic)
+      return make<ARMV5PILongThunk>(S);
+    return make<ARMV5ABSLongThunk>(S);
+  }
+  fatal("relocation " + toString(Reloc) + " to " + toString(S) +
+        " not supported for Armv5 or Armv6 targets");
+}
+
+// Creates a thunk for Thumb-ARM interworking or branch range extension.
 static Thunk *addThunkArm(RelType Reloc, Symbol &S) {
-  // ARM relocations need ARM to Thumb interworking Thunks.
-  // Thumb relocations need Thumb to ARM relocations.
-  // Use position independent Thunks if we require position independent code.
+  // Decide which Thunk is needed based on:
+  // Available instruction set
+  // - An Arm Thunk can only be used if Arm state is available.
+  // - A Thumb Thunk can only be used if Thumb state is available.
+  // - Can only use a Thunk if it uses instructions that the Target supports.
+  // Relocation is branch or branch and link
+  // - Branch instructions cannot change state, can only select Thunk that
+  //   starts in the same state as the caller.
+  // - Branch and link relocations can change state, can select Thunks from
+  //   either Arm or Thumb.
+  // Position independent Thunks if we require position independent code.
+
+  if (!Config->ARMHasMovtMovw) {
+    if (!Config->ARMJ1J2BranchEncoding)
+      return addThunkPreArmv7(Reloc, S);
+    else
+      // The Armv6-m architecture (Cortex-M0) does not have Arm instructions or
+      // support the MOVT MOVW instructions so it cannot use any of the Thunks
+      // currently implemented.
+      fatal("thunks not supported for architecture Armv6-m");
+  }
+
   switch (Reloc) {
   case R_ARM_PC24:
   case R_ARM_PLT32:

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=340160&r1=340159&r2=340160&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Mon Aug 20 02:37:50 2018
@@ -1166,7 +1166,7 @@ sortISDBySectionOrder(InputSectionDescri
   // we effectively double the amount of code that could potentially call into
   // the hot code without a thunk.
   size_t InsPt = 0;
-  if (Target->ThunkSectionSpacing && !OrderedSections.empty()) {
+  if (Target->getThunkSectionSpacing() && !OrderedSections.empty()) {
     uint64_t UnorderedPos = 0;
     for (; InsPt != UnorderedSections.size(); ++InsPt) {
       UnorderedPos += UnorderedSections[InsPt]->getSize();

Modified: lld/trunk/test/ELF/arm-bl-v6.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/arm-bl-v6.s?rev=340160&r1=340159&r2=340160&view=diff
==============================================================================
--- lld/trunk/test/ELF/arm-bl-v6.s (original)
+++ lld/trunk/test/ELF/arm-bl-v6.s Mon Aug 20 02:37:50 2018
@@ -1,15 +1,18 @@
 // REQUIRES: arm
 // RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv6-none-linux-gnueabi %s -o %t
-// RUN: ld.lld %t -o /dev/null 2>&1 | FileCheck %s
+// RUN: ld.lld %t -o %t2 2>&1
+// RUN: llvm-objdump -d -triple=armv6-none-linux-gnueabi -start-address=69632 -stop-address=69640 %t2 | FileCheck -check-prefix=CHECK-ARM1 %s
+// RUN: llvm-objdump -d -triple=thumbv6-none-linux-gnueabi %t2 -start-address=69640 -stop-address=69644 | FileCheck -check-prefix=CHECK-THUMB1 %s
+// RUN: llvm-objdump -d -triple=armv6-none-linux-gnueabi -start-address=2166796 -stop-address=2166804 %t2 | FileCheck -check-prefix=CHECK-ARM2 %s
+// RUN: llvm-objdump -d -triple=thumbv6-none-linux-gnueabi %t2 -start-address=6365184 -stop-address=6365186 | FileCheck -check-prefix=CHECK-THUMB2 %s
 
 // On Arm v6 the range of a Thumb BL instruction is only 4 megabytes as the
 // extended range encoding is not supported. The following example has a Thumb
 // BL that is out of range on ARM v6 and requires a range extension thunk.
 // As v6 does not support MOVT or MOVW instructions the Thunk must not
-// use these instructions either. At present we don't support v6 so we give a
-// warning for unsupported features.
+// use these instructions either.
+
 
-// CHECK: warning: lld may use movt/movw, no object with architecture supporting feature detected.
 // ARM v6 supports blx so we shouldn't see the blx not supported warning.
 // CHECK-NOT: warning: lld uses blx instruction, no object with architecture supporting feature detected.
  .text
@@ -22,6 +25,10 @@ _start:
   bl thumbfunc
   bx lr
 
+// CHECK-ARM1: Disassembly of section .text:
+// CHECK-ARM1-NEXT: _start:
+// CHECK-ARM1-NEXT:    11000:   00 00 00 fa     blx     #0 <thumbfunc>
+// CHECK-ARM1-NEXT:    11004:   1e ff 2f e1     bx      lr
  .thumb
  .section .text.2, "ax", %progbits
  .globl thumbfunc
@@ -29,11 +36,17 @@ _start:
 thumbfunc:
  bl farthumbfunc
 
-// 6 Megabytes, enough to make farthumbfunc out of range of caller on a v6
-// Arm, but not on a v7 Arm.
+// CHECK-THUMB1: thumbfunc:
+// CHECK-THUMB1-NEXT:    11008:	00 f2 00 e8 	blx	#2097152
+// 6 Megabytes, enough to make farthumbfunc out of range of caller
+// on a v6 Arm, but not on a v7 Arm.
+
  .section .text.3, "ax", %progbits
  .space 0x200000
-
+// CHECK-ARM2: __ARMv5ABSLongThunk_farthumbfunc:
+// CHECK-ARM2-NEXT:   21100c:   04 f0 1f e5     ldr     pc, [pc, #-4]
+// CHECK-ARM2: $d:
+// CHECK-ARM2-NEXT:   211010:   01 20 61 00     .word   0x00612001
  .section .text.4, "ax", %progbits
  .space 0x200000
 
@@ -47,3 +60,5 @@ thumbfunc:
  .type farthumbfunc,%function
 farthumbfunc:
  bx lr
+// CHECK-THUMB2: farthumbfunc:
+// CHECK-THUMB2-NEXT:   612000:        70 47   bx      lr

Modified: lld/trunk/test/ELF/arm-blx-v4t.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/arm-blx-v4t.s?rev=340160&r1=340159&r2=340160&view=diff
==============================================================================
--- lld/trunk/test/ELF/arm-blx-v4t.s (original)
+++ lld/trunk/test/ELF/arm-blx-v4t.s Mon Aug 20 02:37:50 2018
@@ -7,7 +7,6 @@
 // features.
 
 // CHECK: warning: lld uses blx instruction, no object with architecture supporting feature detected.
-// CHECK-NEXT: warning: lld may use movt/movw, no object with architecture supporting feature detected.
 
  .text
  .syntax unified

Modified: lld/trunk/test/ELF/arm-branch-rangethunk.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/arm-branch-rangethunk.s?rev=340160&r1=340159&r2=340160&view=diff
==============================================================================
--- lld/trunk/test/ELF/arm-branch-rangethunk.s (original)
+++ lld/trunk/test/ELF/arm-branch-rangethunk.s Mon Aug 20 02:37:50 2018
@@ -1,9 +1,9 @@
 // REQUIRES: arm
-// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
-// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/far-arm-abs.s -o %tfar
+// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
+// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/far-arm-abs.s -o %tfar
 // RUN: ld.lld  %t %tfar -o %t2 2>&1
 // RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t2 | FileCheck --check-prefix=SHORT %s
-// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/far-long-arm-abs.s -o %tfarlong
+// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/far-long-arm-abs.s -o %tfarlong
 // RUN: ld.lld  %t %tfarlong -o %t3 2>&1
 // RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t3 | FileCheck --check-prefix=LONG %s
  .syntax unified

Modified: lld/trunk/test/ELF/arm-branch-undef-weak-plt-thunk.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/arm-branch-undef-weak-plt-thunk.s?rev=340160&r1=340159&r2=340160&view=diff
==============================================================================
--- lld/trunk/test/ELF/arm-branch-undef-weak-plt-thunk.s (original)
+++ lld/trunk/test/ELF/arm-branch-undef-weak-plt-thunk.s Mon Aug 20 02:37:50 2018
@@ -1,7 +1,7 @@
 // REQUIRES: arm
-// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/arm-shared.s -o %t
+// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/arm-shared.s -o %t
 // RUN: ld.lld %t --shared -o %t.so
-// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t2
+// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t2
 // RUN: ld.lld %t2 %t.so -o %t3
 // RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi -start-address=69632 -stop-address=69664 %t3 | FileCheck %s
 

Modified: lld/trunk/test/ELF/arm-long-thunk-converge.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/arm-long-thunk-converge.s?rev=340160&r1=340159&r2=340160&view=diff
==============================================================================
--- lld/trunk/test/ELF/arm-long-thunk-converge.s (original)
+++ lld/trunk/test/ELF/arm-long-thunk-converge.s Mon Aug 20 02:37:50 2018
@@ -1,5 +1,5 @@
 // REQUIRES: arm
-// RUN: llvm-mc -triple armv7-unknown-gnu -filetype=obj -o %t %s
+// RUN: llvm-mc -triple armv7-unknown-gnu -arm-add-build-attributes -filetype=obj -o %t %s
 // RUN: ld.lld %t %S/Inputs/arm-long-thunk-converge.lds -o %t2
 // RUN: llvm-objdump -d -start-address=0x00000000 -stop-address=0x00000010 -triple=armv7a-linux-gnueabihf %t2 | FileCheck --check-prefix=CHECK1 %s
 // RUN: llvm-objdump -d -start-address=0x02000000 -stop-address=0x02000010 -triple=armv7a-linux-gnueabihf %t2 | FileCheck --check-prefix=CHECK2 %s

Modified: lld/trunk/test/ELF/arm-thumb-branch-rangethunk.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/arm-thumb-branch-rangethunk.s?rev=340160&r1=340159&r2=340160&view=diff
==============================================================================
--- lld/trunk/test/ELF/arm-thumb-branch-rangethunk.s (original)
+++ lld/trunk/test/ELF/arm-thumb-branch-rangethunk.s Mon Aug 20 02:37:50 2018
@@ -1,6 +1,6 @@
 // REQUIRES: arm
-// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
-// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %S/Inputs/far-arm-thumb-abs.s -o %tfar
+// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
+// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=thumbv7a-none-linux-gnueabi %S/Inputs/far-arm-thumb-abs.s -o %tfar
 // RUN: ld.lld  %t %tfar -o %t2 2>&1
 // RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi %t2
  .syntax unified

Modified: lld/trunk/test/ELF/arm-thumb-interwork-shared.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/arm-thumb-interwork-shared.s?rev=340160&r1=340159&r2=340160&view=diff
==============================================================================
--- lld/trunk/test/ELF/arm-thumb-interwork-shared.s (original)
+++ lld/trunk/test/ELF/arm-thumb-interwork-shared.s Mon Aug 20 02:37:50 2018
@@ -1,5 +1,5 @@
 // REQUIRES: arm
-// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
+// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
 // RUN: ld.lld %t --shared -o %t.so
 // RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi %t.so | FileCheck %s
 // RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t.so | FileCheck %s -check-prefix=PLT

Modified: lld/trunk/test/ELF/arm-thumb-interwork-thunk-range.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/arm-thumb-interwork-thunk-range.s?rev=340160&r1=340159&r2=340160&view=diff
==============================================================================
--- lld/trunk/test/ELF/arm-thumb-interwork-thunk-range.s (original)
+++ lld/trunk/test/ELF/arm-thumb-interwork-thunk-range.s Mon Aug 20 02:37:50 2018
@@ -1,5 +1,5 @@
 // REQUIRES: arm
-// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o
+// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o
 // RUN: ld.lld %t.o -o /dev/null -image-base=0x80000000
 
 // Test that when the thunk is at a high address we don't get confused with it

Added: lld/trunk/test/ELF/arm-thumb-interwork-thunk-v5.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/arm-thumb-interwork-thunk-v5.s?rev=340160&view=auto
==============================================================================
--- lld/trunk/test/ELF/arm-thumb-interwork-thunk-v5.s (added)
+++ lld/trunk/test/ELF/arm-thumb-interwork-thunk-v5.s Mon Aug 20 02:37:50 2018
@@ -0,0 +1,66 @@
+// REQUIRES: arm
+// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv5-none-linux-gnueabi %s -o %t
+// RUN: ld.lld %t -o %t2
+// RUN: llvm-objdump -d %t2 -triple=armv5-none-linux-gnueabi | FileCheck -check-prefix=CHECK-ARM %s
+// RUN: llvm-objdump -d %t2 -triple=thumbv5-none-linux-gnueabi | FileCheck -check-prefix=CHECK-THUMB %s
+// RUN: ld.lld %t -o %t3 --shared
+// RUN: llvm-objdump -d %t3 -triple=armv5-none-linux-gnueabi | FileCheck -check-prefix=CHECK-ARM-PI %s
+// RUN: llvm-objdump -d %t3 -triple=thumbv5-none-linux-gnueabi | FileCheck -check-prefix=CHECK-THUMB-PI %s
+
+// Test ARM Thumb Interworking on older Arm architectures using Thunks that do
+// not use MOVT/MOVW instructions.
+// For pure interworking (not considering range extension) there is only the
+// case of an Arm B to a Thumb Symbol to consider as in older Arm architectures
+// there is no Thumb B.w that we can intercept with a Thunk and we still assume
+// support for the blx instruction for Thumb BL and BLX to an Arm symbol.
+        .arm
+        .text
+        .syntax unified
+        .cpu    arm10tdmi
+
+        .text
+        .globl _start
+        .type _start, %function
+        .balign 0x1000
+_start:
+        b thumb_func
+        bl thumb_func
+        blx thumb_func
+        bx lr
+
+// CHECK-ARM: _start:
+// CHECK-ARM-NEXT: 11000: 03 00 00 ea     b       #12 <__ARMv5ABSLongThunk_thumb_func>
+// CHECK-ARM-NEXT: 11004: 01 00 00 fa     blx     #4 <thumb_func>
+// CHECK-ARM-NEXT: 11008: 00 00 00 fa     blx     #0 <thumb_func>
+// CHECK-ARM-NEXT: 1100c: 1e ff 2f e1     bx      lr
+
+// CHECK-THUMB: thumb_func:
+// CHECK-THUMB-NEXT: 11010: 70 47   bx      lr
+
+// CHECK-ARM: __ARMv5ABSLongThunk_thumb_func:
+// CHECK-ARM-NEXT: 11014: 04 f0 1f e5     ldr     pc, [pc, #-4]
+// CHECK-ARM: $d:
+// CHECK-ARM-NEXT: 11018: 11 10 01 00     .word   0x00011011
+
+// CHECK-ARM-PI: _start:
+// CHECK-ARM-PI-NEXT: 1000: 03 00 00 ea     b       #12 <__ARMV5PILongThunk_thumb_func>
+// CHECK-ARM-PI-NEXT: 1004: 01 00 00 fa     blx     #4 <thumb_func>
+// CHECK-ARM-PI-NEXT: 1008: 00 00 00 fa     blx     #0 <thumb_func>
+// CHECK-ARM-PI-NEXT: 100c: 1e ff 2f e1     bx      lr
+
+// CHECK-THUMB-PI: thumb_func:
+// CHECK-THUMB-PI-NEXT: 1010: 70 47   bx      lr
+
+// CHECK-ARM-PI: __ARMV5PILongThunk_thumb_func:
+// CHECK-ARM-PI-NEXT: 1014: 04 c0 9f e5     ldr     r12, [pc, #4]
+// CHECK-ARM-PI-NEXT: 1018: 0c c0 8f e0     add     r12, pc, r12
+// CHECK-ARM-PI-NEXT: 101c: 1c ff 2f e1     bx      r12
+// CHECK-ARM-PI: $d:
+// CHECK-ARM-PI-NEXT: 1020: f1 ff ff ff     .word   0xfffffff1
+
+        .section .text.1, "ax", %progbits
+        .thumb
+        .hidden thumb_func
+        .type thumb_func, %function
+thumb_func:
+        bx lr

Modified: lld/trunk/test/ELF/arm-thumb-interwork-thunk.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/arm-thumb-interwork-thunk.s?rev=340160&r1=340159&r2=340160&view=diff
==============================================================================
--- lld/trunk/test/ELF/arm-thumb-interwork-thunk.s (original)
+++ lld/trunk/test/ELF/arm-thumb-interwork-thunk.s Mon Aug 20 02:37:50 2018
@@ -1,5 +1,5 @@
 // REQUIRES: arm
-// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
+// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
 // RUN: echo "SECTIONS { \
 // RUN:       . = SIZEOF_HEADERS; \
 // RUN:       .R_ARM_JUMP24_callee_1 : { *(.R_ARM_JUMP24_callee_low) } \

Added: lld/trunk/test/ELF/arm-thumb-nov6thunk.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/arm-thumb-nov6thunk.s?rev=340160&view=auto
==============================================================================
--- lld/trunk/test/ELF/arm-thumb-nov6thunk.s (added)
+++ lld/trunk/test/ELF/arm-thumb-nov6thunk.s Mon Aug 20 02:37:50 2018
@@ -0,0 +1,39 @@
+// REQUIRES: arm
+// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv6m-none-eabi %s -o %t
+// RUN: echo "SECTIONS { \
+// RUN:       . = SIZEOF_HEADERS; \
+// RUN:       .text_low : { *(.text_low) *(.text_low2) } \
+// RUN:       .text_high 0x2000000 : { *(.text_high) *(.text_high2) } \
+// RUN:       } " > %t.script
+// RUN: not ld.lld --script %t.script %t -o %t2 2>&1 | FileCheck %s
+
+// CHECK:  error: thunks not supported for architecture Armv6-m
+
+// Range extension thunks are not currently supported on Armv6-m due to a
+// combination of Armv6-m being aimed at low-end microcontrollers that typically
+// have < 512 Kilobytes of memory, and the restrictions of the instruction set
+// that make thunks inefficient. The main restriction is that the
+// interprocedural scratch register r12 (ip) cannot be accessed from many
+// instructions so we must use the stack to avoid corrupting the program.
+//
+// A v6-m Thunk would look like
+//     push {r0, r1} ; Make 8-bytes of stack for restoring r0, and destination
+//     ldr r0, [pc, #4] ; L1
+//     str r0, [sp, #4] ; store destination address into sp + 4
+//     pop {r0, pc} ; restore r0 and load pc with destination
+// L1: .word destination
+
+ .syntax unified
+ .section .text_low, "ax", %progbits
+ .thumb
+ .type _start, %function
+ .globl _start
+_start:
+ bl far
+
+ .section .text_high, "ax", %progbits
+ .globl far
+ .type far, %function
+far:
+ bx lr
+

Modified: lld/trunk/test/ELF/arm-thumb-thunk-symbols.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/arm-thumb-thunk-symbols.s?rev=340160&r1=340159&r2=340160&view=diff
==============================================================================
--- lld/trunk/test/ELF/arm-thumb-thunk-symbols.s (original)
+++ lld/trunk/test/ELF/arm-thumb-thunk-symbols.s Mon Aug 20 02:37:50 2018
@@ -1,5 +1,5 @@
 // REQUIRES: arm
-// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
+// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
 // RUN: ld.lld %t -o %t2 2>&1
 // RUN: llvm-readobj --symbols %t2 | FileCheck %s
 // RUN: ld.lld --shared %t -o %t3 2>&1

Modified: lld/trunk/test/ELF/arm-thunk-edgecase.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/arm-thunk-edgecase.s?rev=340160&r1=340159&r2=340160&view=diff
==============================================================================
--- lld/trunk/test/ELF/arm-thunk-edgecase.s (original)
+++ lld/trunk/test/ELF/arm-thunk-edgecase.s Mon Aug 20 02:37:50 2018
@@ -1,5 +1,5 @@
 // REQUIRES: arm
-// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o
+// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o
 // RUN: echo "SECTIONS { \
 // RUN:           .text_armfunc 0x1000 : { *(.text_armfunc) } \
 // RUN:           .text_thumbfunc 0x11010 : { *(.text_thumbfunc) } \

Modified: lld/trunk/test/ELF/arm-thunk-linkerscript-dotexpr.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/arm-thunk-linkerscript-dotexpr.s?rev=340160&r1=340159&r2=340160&view=diff
==============================================================================
--- lld/trunk/test/ELF/arm-thunk-linkerscript-dotexpr.s (original)
+++ lld/trunk/test/ELF/arm-thunk-linkerscript-dotexpr.s Mon Aug 20 02:37:50 2018
@@ -1,5 +1,5 @@
 // REQUIRES: arm
-// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
+// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
 // RUN: echo "SECTIONS { \
 // RUN:       . = SIZEOF_HEADERS; \
 // RUN:       .text_low : { *(.text_low) *(.text_low2) . = . + 0x2000000 ; *(.text_high) *(.text_high2) } \

Modified: lld/trunk/test/ELF/arm-thunk-linkerscript-orphan.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/arm-thunk-linkerscript-orphan.s?rev=340160&r1=340159&r2=340160&view=diff
==============================================================================
--- lld/trunk/test/ELF/arm-thunk-linkerscript-orphan.s (original)
+++ lld/trunk/test/ELF/arm-thunk-linkerscript-orphan.s Mon Aug 20 02:37:50 2018
@@ -1,5 +1,5 @@
 // REQUIRES: arm
-// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
+// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
 // RUN: echo "SECTIONS { \
 // RUN:       .text_low 0x100000 : { *(.text_low) } \
 // RUN:       .text_high 0x2000000 : { *(.text_high) } \

Modified: lld/trunk/test/ELF/arm-thunk-linkerscript.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/arm-thunk-linkerscript.s?rev=340160&r1=340159&r2=340160&view=diff
==============================================================================
--- lld/trunk/test/ELF/arm-thunk-linkerscript.s (original)
+++ lld/trunk/test/ELF/arm-thunk-linkerscript.s Mon Aug 20 02:37:50 2018
@@ -1,5 +1,5 @@
 // REQUIRES: arm
-// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
+// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
 // RUN: echo "SECTIONS { \
 // RUN:       . = SIZEOF_HEADERS; \
 // RUN:       .text_low : { *(.text_low) *(.text_low2) } \

Modified: lld/trunk/test/ELF/arm-thunk-re-add.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/arm-thunk-re-add.s?rev=340160&r1=340159&r2=340160&view=diff
==============================================================================
--- lld/trunk/test/ELF/arm-thunk-re-add.s (original)
+++ lld/trunk/test/ELF/arm-thunk-re-add.s Mon Aug 20 02:37:50 2018
@@ -1,5 +1,5 @@
 // REQUIRES: arm
-// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
+// RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
 // RUN: ld.lld %t --shared -o %t.so
 // The output file is large, most of it zeroes. We dissassemble only the
 // parts we need to speed up the test and avoid a large output file

Added: lld/trunk/test/ELF/arm-v5-reloc-error.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/arm-v5-reloc-error.s?rev=340160&view=auto
==============================================================================
--- lld/trunk/test/ELF/arm-v5-reloc-error.s (added)
+++ lld/trunk/test/ELF/arm-v5-reloc-error.s Mon Aug 20 02:37:50 2018
@@ -0,0 +1,31 @@
+// REQUIRES: arm
+// RUN: llvm-mc -filetype=obj -triple=armv7a-linux-gnueabi %s -o %t
+// RUN: echo "SECTIONS { \
+// RUN:       . = SIZEOF_HEADERS; \
+// RUN:       .text_low : { *(.text_low) *(.text_low2) } \
+// RUN:       .text_high 0x2000000 : { *(.text_high) *(.text_high2) } \
+// RUN:       } " > %t.script
+// RUN: not ld.lld --script %t.script %t -o %t2 2>&1 | FileCheck %s
+
+// CHECK: error: relocation R_ARM_THM_JUMP24 to far not supported for Armv5 or Armv6 targets
+
+// Lie about our build attributes. Our triple is armv7a-linux-gnueabi but
+// we are claiming to be Armv5. This can also happen with llvm-mc when we
+// don't have any .eabi_attribute directives in the file or the
+// --arm-add-build-attributes command line isn't used to add them from the
+// triple.
+ .eabi_attribute 6, 5           // Tag_cpu_arch 5 = v5TEJ
+ .thumb
+ .syntax unified
+ .section .text_low, "ax", %progbits
+ .thumb
+ .globl _start
+ .type _start, %function
+_start:
+ b.w far // Will produce relocation not supported in Armv5.
+
+ .section .text_high, "ax", %progbits
+ .globl far
+ .type far, %function
+far:
+ bx lr




More information about the llvm-commits mailing list