[lld] 8cf8956 - [lld][Arm] Big Endian - Byte invariant support.

Simi Pallipurath via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 20 06:08:26 PDT 2023


Author: Simi Pallipurath
Date: 2023-06-20T14:08:21+01:00
New Revision: 8cf8956897ce9bca3176c6339077b1ca17b27abc

URL: https://github.com/llvm/llvm-project/commit/8cf8956897ce9bca3176c6339077b1ca17b27abc
DIFF: https://github.com/llvm/llvm-project/commit/8cf8956897ce9bca3176c6339077b1ca17b27abc.diff

LOG: [lld][Arm] Big Endian - Byte invariant support.

Arm has BE8 big endian configuration called a byte-invariant(every byte has the same address on little and big-endian systems).

When in BE8 mode:
  1. Instructions are big-endian in relocatable objects but
     little-endian in executables and shared objects.
  2. Data is big-endian.
  3. The data encoding of the ELF file is ELFDATA2MSB.

To support BE8 without an ABI break for relocatable objects,the linker takes on the responsibility of changing the endianness of instructions. At a high level the only difference between BE32 and BE8 in the linker is that for BE8:
  1. The linker sets the flag EF_ARM_BE8 in the ELF header.
  2. The linker endian reverses the instructions, but not data.

This patch adds BE8 big endian support for Arm. To endian reverse the instructions we'll need access to the mapping symbols. Code sections can contain a mix of Arm, Thumb and literal data. We need to endian reverse Arm instructions as words, Thumb instructions
as half-words and ignore literal data.The only way to find these transitions precisely is by using mapping symbols. The instruction reversal will need to take place after relocation. For Arm BE8 code sections (Section has SHF_EXECINSTR flag ) we inserted a step after relocation to endian reverse the instructions. The implementation strategy i have used here is to write all sections BE32  including SyntheticSections then endian reverse all code in InputSections via mapping symbols.

Reviewed By: peter.smith

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

Added: 
    

Modified: 
    lld/ELF/Arch/ARM.cpp
    lld/ELF/Config.h
    lld/ELF/Driver.cpp
    lld/ELF/Options.td
    lld/ELF/OutputSections.cpp
    lld/ELF/SyntheticSections.cpp
    lld/ELF/Target.h
    lld/ELF/Thunks.cpp
    lld/ELF/Writer.cpp
    lld/docs/ld.lld.1
    lld/test/ELF/arm-bl-v6.s
    lld/test/ELF/arm-data-relocs.s
    lld/test/ELF/arm-exidx-emit-relocs.s
    lld/test/ELF/arm-exidx-relocatable.s
    lld/test/ELF/arm-exidx-sentinel-norelocatable.s
    lld/test/ELF/arm-header.s
    lld/test/ELF/arm-mov-relocs.s
    lld/test/ELF/arm-plt-reloc.s
    lld/test/ELF/arm-thumb-plt-reloc.s
    lld/test/ELF/arm-thunk-arm-thumb-reuse.s
    lld/test/ELF/arm-thunk-edgecase.s
    lld/test/ELF/arm-thunk-largesection.s
    lld/test/ELF/arm-thunk-linkerscript-dotexpr.s
    lld/test/ELF/arm-thunk-linkerscript.s
    lld/test/ELF/arm-thunk-nosuitable.s
    lld/test/ELF/arm-thunk-re-add.s
    lld/test/ELF/arm-thunk-reuse.s
    lld/test/ELF/arm-thunk-section-too-large.s
    lld/test/ELF/arm-thunk-toolargesection.s
    lld/test/ELF/arm-v5-reloc-error.s
    lld/test/ELF/emulation-arm.s
    lld/test/ELF/target-specific-options.s

Removed: 
    


################################################################################
diff  --git a/lld/ELF/Arch/ARM.cpp b/lld/ELF/Arch/ARM.cpp
index 79635a22df4ec..cdab2a40e2183 100644
--- a/lld/ELF/Arch/ARM.cpp
+++ b/lld/ELF/Arch/ARM.cpp
@@ -6,6 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "InputFiles.h"
 #include "Symbols.h"
 #include "SyntheticSections.h"
 #include "Target.h"
@@ -44,8 +45,11 @@ class ARM final : public TargetInfo {
   void relocate(uint8_t *loc, const Relocation &rel,
                 uint64_t val) const override;
 };
+enum class CodeState { Data = 0, Thumb = 2, Arm = 4 };
 } // namespace
 
+static DenseMap<InputSection *, SmallVector<const Defined *, 0>> sectionMap;
+
 ARM::ARM() {
   copyRel = R_ARM_COPY;
   relativeRel = R_ARM_RELATIVE;
@@ -68,16 +72,24 @@ uint32_t ARM::calcEFlags() const {
   // The ABIFloatType is used by loaders to detect the floating point calling
   // convention.
   uint32_t abiFloatType = 0;
+
+  // Set the EF_ARM_BE8 flag in the ELF header, if ELF file is big-endian
+  // with BE-8 code.
+  uint32_t armBE8 = 0;
+
   if (config->armVFPArgs == ARMVFPArgKind::Base ||
       config->armVFPArgs == ARMVFPArgKind::Default)
     abiFloatType = EF_ARM_ABI_FLOAT_SOFT;
   else if (config->armVFPArgs == ARMVFPArgKind::VFP)
     abiFloatType = EF_ARM_ABI_FLOAT_HARD;
 
+  if (!config->isLE && config->armBe8)
+    armBE8 = EF_ARM_BE8;
+
   // We don't currently use any features incompatible with EF_ARM_EABI_VER5,
   // but we don't have any firm guarantees of conformance. Linux AArch64
   // kernels (as of 2016) require an EABI version to be set.
-  return EF_ARM_EABI_VER5 | abiFloatType;
+  return EF_ARM_EABI_VER5 | abiFloatType | armBE8;
 }
 
 RelExpr ARM::getRelExpr(RelType type, const Symbol &s,
@@ -910,6 +922,114 @@ int64_t ARM::getImplicitAddend(const uint8_t *buf, RelType type) const {
   }
 }
 
+static bool isArmMapSymbol(const Symbol *b) {
+  return b->getName() == "$a" || b->getName().startswith("$a.");
+}
+
+static bool isThumbMapSymbol(const Symbol *s) {
+  return s->getName() == "$t" || s->getName().startswith("$t.");
+}
+
+static bool isDataMapSymbol(const Symbol *b) {
+  return b->getName() == "$d" || b->getName().startswith("$d.");
+}
+
+void elf::sortArmMappingSymbols() {
+  // For each input section make sure the mapping symbols are sorted in
+  // ascending order.
+  for (auto &kv : sectionMap) {
+    SmallVector<const Defined *, 0> &mapSyms = kv.second;
+    llvm::stable_sort(mapSyms, [](const Defined *a, const Defined *b) {
+      return a->value < b->value;
+    });
+  }
+}
+
+void elf::addArmInputSectionMappingSymbols() {
+  // Collect mapping symbols for every executable input sections.
+  // The linker generated mapping symbols for all the synthetic
+  // sections are adding into the sectionmap through the function
+  // addArmSyntheitcSectionMappingSymbol.
+  for (ELFFileBase *file : ctx.objectFiles) {
+    for (Symbol *sym : file->getLocalSymbols()) {
+      auto *def = dyn_cast<Defined>(sym);
+      if (!def)
+        continue;
+      if (!isArmMapSymbol(def) && !isDataMapSymbol(def) &&
+          !isThumbMapSymbol(def))
+        continue;
+      if (auto *sec = cast_if_present<InputSection>(def->section))
+        if (sec->flags & SHF_EXECINSTR)
+          sectionMap[sec].push_back(def);
+    }
+  }
+}
+
+// Synthetic sections are not backed by an ELF file where we can access the
+// symbol table, instead mapping symbols added to synthetic sections are stored
+// in the synthetic symbol table. Due to the presence of strip (--strip-all),
+// we can not rely on the synthetic symbol table retaining the mapping symbols.
+// Instead we record the mapping symbols locally.
+void elf::addArmSyntheticSectionMappingSymbol(Defined *sym) {
+  if (!isArmMapSymbol(sym) && !isDataMapSymbol(sym) && !isThumbMapSymbol(sym))
+    return;
+  if (auto *sec = cast_if_present<InputSection>(sym->section))
+    if (sec->flags & SHF_EXECINSTR)
+      sectionMap[sec].push_back(sym);
+}
+
+static void toLittleEndianInstructions(uint8_t *buf, uint64_t start,
+                                       uint64_t end, uint64_t width) {
+  CodeState curState = static_cast<CodeState>(width);
+  if (curState == CodeState::Arm)
+    for (uint64_t i = start; i < end; i += width)
+      write32le(buf + i, read32(buf + i));
+
+  if (curState == CodeState::Thumb)
+    for (uint64_t i = start; i < end; i += width)
+      write16le(buf + i, read16(buf + i));
+}
+
+// Arm BE8 big endian format requires instructions to be little endian, with
+// the initial contents big-endian. Convert the big-endian instructions to
+// little endian leaving literal data untouched. We use mapping symbols to
+// identify half open intervals of Arm code [$a, non $a) and Thumb code
+// [$t, non $t) and convert these to little endian a word or half word at a
+// time respectively.
+void elf::convertArmInstructionstoBE8(InputSection *sec, uint8_t *buf) {
+  SmallVector<const Defined *, 0> &mapSyms = sectionMap[sec];
+
+  if (mapSyms.empty())
+    return;
+
+  CodeState curState = CodeState::Data;
+  uint64_t start = 0, width = 0, size = sec->getSize();
+  for (auto &msym : mapSyms) {
+    CodeState newState = CodeState::Data;
+    if (isThumbMapSymbol(msym))
+      newState = CodeState::Thumb;
+    else if (isArmMapSymbol(msym))
+      newState = CodeState::Arm;
+
+    if (newState == curState)
+      continue;
+
+    if (curState != CodeState::Data) {
+      width = static_cast<uint64_t>(curState);
+      toLittleEndianInstructions(buf, start, msym->value, width);
+    }
+    start = msym->value;
+    curState = newState;
+  }
+
+  // Passed last mapping symbol, may need to reverse
+  // up to end of section.
+  if (curState != CodeState::Data) {
+    width = static_cast<uint64_t>(curState);
+    toLittleEndianInstructions(buf, start, size, width);
+  }
+}
+
 TargetInfo *elf::getARMTargetInfo() {
   static ARM target;
   return ⌖

diff  --git a/lld/ELF/Config.h b/lld/ELF/Config.h
index 956530098c0f1..813102a9bd83a 100644
--- a/lld/ELF/Config.h
+++ b/lld/ELF/Config.h
@@ -201,6 +201,7 @@ struct Config {
   bool armHasMovtMovw = false;
   bool armJ1J2BranchEncoding = false;
   bool asNeeded = false;
+  bool armBe8 = false;
   BsymbolicKind bsymbolic = BsymbolicKind::None;
   bool callGraphProfileSort;
   bool checkSections;

diff  --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index 4eb10fc3c91e1..9c813f97bf57c 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -351,9 +351,12 @@ static void checkOptions() {
   if (config->fixCortexA8 && config->emachine != EM_ARM)
     error("--fix-cortex-a8 is only supported on ARM targets");
 
+  if (config->armBe8 && config->emachine != EM_ARM)
+    error("--be8 is only supported on ARM targets");
+
   if (config->fixCortexA8 && !config->isLE)
     error("--fix-cortex-a8 is not supported on big endian targets");
-  
+
   if (config->tocOptimize && config->emachine != EM_PPC64)
     error("--toc-optimize is only supported on PowerPC64 targets");
 
@@ -1115,6 +1118,7 @@ static void readConfigs(opt::InputArgList &args) {
                                             OPT_no_android_memtag_stack, false);
   config->androidMemtagMode = getMemtagMode(args);
   config->auxiliaryList = args::getStrings(args, OPT_auxiliary);
+  config->armBe8 = args.hasArg(OPT_be8);
   if (opt::Arg *arg =
           args.getLastArg(OPT_Bno_symbolic, OPT_Bsymbolic_non_weak_functions,
                           OPT_Bsymbolic_functions, OPT_Bsymbolic)) {

diff  --git a/lld/ELF/Options.td b/lld/ELF/Options.td
index 0c6884afe52d4..d878ae313fa2c 100644
--- a/lld/ELF/Options.td
+++ b/lld/ELF/Options.td
@@ -36,6 +36,8 @@ multiclass B<string name, string help1, string help2> {
 
 defm auxiliary: Eq<"auxiliary", "Set DT_AUXILIARY field to the specified name">;
 
+def be8: F<"be8">, HelpText<"write a Big Endian ELF file using BE8 format (AArch32 only)">;
+
 def Bno_symbolic: F<"Bno-symbolic">, HelpText<"Don't bind default visibility defined symbols locally for -shared (default)">;
 
 def Bsymbolic: F<"Bsymbolic">, HelpText<"Bind default visibility defined symbols locally for -shared">;

diff  --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp
index 05f9cdc20fd29..0b9b76e5b832f 100644
--- a/lld/ELF/OutputSections.cpp
+++ b/lld/ELF/OutputSections.cpp
@@ -496,6 +496,12 @@ void OutputSection::writeTo(uint8_t *buf, parallel::TaskGroup &tg) {
       else
         isec->writeTo<ELFT>(buf + isec->outSecOff);
 
+      // When in Arm BE8 mode, the linker has to convert the big-endian
+      // instructions to little-endian, leaving the data big-endian.
+      if (config->emachine == EM_ARM && !config->isLE && config->armBe8 &&
+          (flags & SHF_EXECINSTR))
+        convertArmInstructionstoBE8(isec, buf + isec->outSecOff);
+
       // Fill gaps between sections.
       if (nonZeroFiller) {
         uint8_t *start = buf + isec->outSecOff + isec->getSize();

diff  --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp
index 48f30123dcc00..0a52ad31ede05 100644
--- a/lld/ELF/SyntheticSections.cpp
+++ b/lld/ELF/SyntheticSections.cpp
@@ -271,6 +271,13 @@ Defined *elf::addSyntheticLocal(StringRef name, uint8_t type, uint64_t value,
                            value, size, &section);
   if (in.symTab)
     in.symTab->addSymbol(s);
+
+  if (config->emachine == EM_ARM && !config->isLE && config->armBe8 &&
+      (section.flags & SHF_EXECINSTR))
+    // Adding Linker generated mapping symbols to the arm specific mapping
+    // symbols list.
+    addArmSyntheticSectionMappingSymbol(s);
+
   return s;
 }
 

diff  --git a/lld/ELF/Target.h b/lld/ELF/Target.h
index 59534ab3256df..dd0ae392deab7 100644
--- a/lld/ELF/Target.h
+++ b/lld/ELF/Target.h
@@ -223,6 +223,10 @@ uint64_t getPPC64TocBase();
 uint64_t getAArch64Page(uint64_t expr);
 void riscvFinalizeRelax(int passes);
 void mergeRISCVAttributesSections();
+void addArmInputSectionMappingSymbols();
+void addArmSyntheticSectionMappingSymbol(Defined *);
+void sortArmMappingSymbols();
+void convertArmInstructionstoBE8(InputSection *sec, uint8_t *buf);
 
 LLVM_LIBRARY_VISIBILITY extern const TargetInfo *target;
 TargetInfo *getTarget();

diff  --git a/lld/ELF/Thunks.cpp b/lld/ELF/Thunks.cpp
index 331e28e8bf4e1..81140686cef2c 100644
--- a/lld/ELF/Thunks.cpp
+++ b/lld/ELF/Thunks.cpp
@@ -744,7 +744,8 @@ void ThumbV6MABSLongThunk::addSymbols(ThunkSection &isec) {
   addSymbol(saver().save("__Thumbv6MABSLongThunk_" + destination.getName()),
             STT_FUNC, 1, isec);
   addSymbol("$t", STT_NOTYPE, 0, isec);
-  addSymbol("$d", STT_NOTYPE, 8, isec);
+  if (!getMayUseShortThunk())
+    addSymbol("$d", STT_NOTYPE, 8, isec);
 }
 
 void ThumbV6MPILongThunk::writeLong(uint8_t *buf) {
@@ -767,7 +768,8 @@ void ThumbV6MPILongThunk::addSymbols(ThunkSection &isec) {
   addSymbol(saver().save("__Thumbv6MPILongThunk_" + destination.getName()),
             STT_FUNC, 1, isec);
   addSymbol("$t", STT_NOTYPE, 0, isec);
-  addSymbol("$d", STT_NOTYPE, 12, isec);
+  if (!getMayUseShortThunk())
+    addSymbol("$d", STT_NOTYPE, 12, isec);
 }
 
 void ARMV5LongLdrPcThunk::writeLong(uint8_t *buf) {
@@ -780,7 +782,8 @@ void ARMV5LongLdrPcThunk::addSymbols(ThunkSection &isec) {
   addSymbol(saver().save("__ARMv5LongLdrPcThunk_" + destination.getName()),
             STT_FUNC, 0, isec);
   addSymbol("$a", STT_NOTYPE, 0, isec);
-  addSymbol("$d", STT_NOTYPE, 4, isec);
+  if (!getMayUseShortThunk())
+    addSymbol("$d", STT_NOTYPE, 4, isec);
 }
 
 void ARMV4ABSLongBXThunk::writeLong(uint8_t *buf) {
@@ -794,7 +797,8 @@ void ARMV4ABSLongBXThunk::addSymbols(ThunkSection &isec) {
   addSymbol(saver().save("__ARMv4ABSLongBXThunk_" + destination.getName()),
             STT_FUNC, 0, isec);
   addSymbol("$a", STT_NOTYPE, 0, isec);
-  addSymbol("$d", STT_NOTYPE, 8, isec);
+  if (!getMayUseShortThunk())
+    addSymbol("$d", STT_NOTYPE, 8, isec);
 }
 
 void ThumbV4ABSLongBXThunk::writeLong(uint8_t *buf) {
@@ -810,7 +814,8 @@ void ThumbV4ABSLongBXThunk::addSymbols(ThunkSection &isec) {
             STT_FUNC, 1, isec);
   addSymbol("$t", STT_NOTYPE, 0, isec);
   addSymbol("$a", STT_NOTYPE, 4, isec);
-  addSymbol("$d", STT_NOTYPE, 8, isec);
+  if (!getMayUseShortThunk())
+    addSymbol("$d", STT_NOTYPE, 8, isec);
 }
 
 void ThumbV4ABSLongThunk::writeLong(uint8_t *buf) {
@@ -827,7 +832,8 @@ void ThumbV4ABSLongThunk::addSymbols(ThunkSection &isec) {
             STT_FUNC, 1, isec);
   addSymbol("$t", STT_NOTYPE, 0, isec);
   addSymbol("$a", STT_NOTYPE, 4, isec);
-  addSymbol("$d", STT_NOTYPE, 12, isec);
+  if (!getMayUseShortThunk())
+    addSymbol("$d", STT_NOTYPE, 12, isec);
 }
 
 void ARMV4PILongBXThunk::writeLong(uint8_t *buf) {
@@ -844,7 +850,8 @@ void ARMV4PILongBXThunk::addSymbols(ThunkSection &isec) {
   addSymbol(saver().save("__ARMv4PILongBXThunk_" + destination.getName()),
             STT_FUNC, 0, isec);
   addSymbol("$a", STT_NOTYPE, 0, isec);
-  addSymbol("$d", STT_NOTYPE, 12, isec);
+  if (!getMayUseShortThunk())
+    addSymbol("$d", STT_NOTYPE, 12, isec);
 }
 
 void ARMV4PILongThunk::writeLong(uint8_t *buf) {
@@ -860,7 +867,8 @@ void ARMV4PILongThunk::addSymbols(ThunkSection &isec) {
   addSymbol(saver().save("__ARMv4PILongThunk_" + destination.getName()),
             STT_FUNC, 0, isec);
   addSymbol("$a", STT_NOTYPE, 0, isec);
-  addSymbol("$d", STT_NOTYPE, 8, isec);
+  if (!getMayUseShortThunk())
+    addSymbol("$d", STT_NOTYPE, 8, isec);
 }
 
 void ThumbV4PILongBXThunk::writeLong(uint8_t *buf) {
@@ -879,7 +887,8 @@ void ThumbV4PILongBXThunk::addSymbols(ThunkSection &isec) {
             STT_FUNC, 1, isec);
   addSymbol("$t", STT_NOTYPE, 0, isec);
   addSymbol("$a", STT_NOTYPE, 4, isec);
-  addSymbol("$d", STT_NOTYPE, 12, isec);
+  if (!getMayUseShortThunk())
+    addSymbol("$d", STT_NOTYPE, 12, isec);
 }
 
 void ThumbV4PILongThunk::writeLong(uint8_t *buf) {
@@ -899,7 +908,8 @@ void ThumbV4PILongThunk::addSymbols(ThunkSection &isec) {
             STT_FUNC, 1, isec);
   addSymbol("$t", STT_NOTYPE, 0, isec);
   addSymbol("$a", STT_NOTYPE, 4, isec);
-  addSymbol("$d", STT_NOTYPE, 16, isec);
+  if (!getMayUseShortThunk())
+    addSymbol("$d", STT_NOTYPE, 16, isec);
 }
 
 // Use the long jump which covers a range up to 8MiB.

diff  --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index 3630b199714da..4396cf33c226d 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -2149,6 +2149,11 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
     sec->finalize();
 
   script->checkMemoryRegions();
+
+  if (config->emachine == EM_ARM && !config->isLE && config->armBe8) {
+    addArmInputSectionMappingSymbols();
+    sortArmMappingSymbols();
+  }
 }
 
 // Ensure data sections are not mixed with executable sections when

diff  --git a/lld/docs/ld.lld.1 b/lld/docs/ld.lld.1
index e3db3a20678d9..898ec30dfe6f3 100644
--- a/lld/docs/ld.lld.1
+++ b/lld/docs/ld.lld.1
@@ -88,6 +88,8 @@ Bind default visibility defined function symbols locally for
 .It Fl Bsymbolic-non-weak-functions
 Bind default visibility defined STB_GLOBAL function symbols locally for
 .Fl shared.
+.It Fl --be8
+Write a Big Endian ELF File using BE8 format(AArch32 only)
 .It Fl -build-id Ns = Ns Ar value
 Generate a build ID note.
 .Ar value

diff  --git a/lld/test/ELF/arm-bl-v6.s b/lld/test/ELF/arm-bl-v6.s
index 7666d6fb9e506..65f06207303c7 100644
--- a/lld/test/ELF/arm-bl-v6.s
+++ b/lld/test/ELF/arm-bl-v6.s
@@ -13,6 +13,12 @@
 // RUN: llvm-objdump --no-print-imm-hex -d --triple=armv6eb-none-linux-gnueabi --start-address=0x22100c --stop-address=0x221014 %t2 | FileCheck --check-prefix=CHECK-ARM2-EB %s
 // RUN: llvm-objdump --no-print-imm-hex -d --triple=thumbv6eb-none-linux-gnueabi %t2 --start-address=0x622000 --stop-address=0x622002 | FileCheck --check-prefix=CHECK-THUMB2 %s
 
+// RUN: ld.lld --be8 %t -o %t2
+// RUN: llvm-objdump --no-print-imm-hex -d --triple=armv6eb-none-linux-gnueabi --start-address=0x21000 --stop-address=0x21008 %t2 | FileCheck --check-prefix=CHECK-ARM1 %s
+// RUN: llvm-objdump --no-print-imm-hex -d --triple=thumbv6eb-none-linux-gnueabi %t2 --start-address=0x21008 --stop-address=0x2100c | FileCheck --check-prefix=CHECK-THUMB1 %s
+// RUN: llvm-objdump --no-print-imm-hex -d --triple=armv6eb-none-linux-gnueabi --start-address=0x22100c --stop-address=0x221014 %t2 | FileCheck --check-prefix=CHECK-ARM2-EB %s
+// RUN: llvm-objdump --no-print-imm-hex -d --triple=thumbv6eb-none-linux-gnueabi %t2 --start-address=0x622000 --stop-address=0x622002 | 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.

diff  --git a/lld/test/ELF/arm-data-relocs.s b/lld/test/ELF/arm-data-relocs.s
index 70335aa6d51ae..91037c8cebf9b 100644
--- a/lld/test/ELF/arm-data-relocs.s
+++ b/lld/test/ELF/arm-data-relocs.s
@@ -9,6 +9,9 @@
 // RUN: ld.lld %t.be.o %t256.be.o -o %t.be
 // RUN: llvm-objdump -s %t.be | FileCheck %s --check-prefixes=CHECK,BE
 
+// RUN: ld.lld --be8 %t.be.o %t256.be.o -o %t.be8
+// RUN: llvm-objdump -s %t.be8 | FileCheck %s --check-prefixes=CHECK,BE
+
 .globl _start
 _start:
 .section .R_ARM_ABS, "ax","progbits"

diff  --git a/lld/test/ELF/arm-exidx-emit-relocs.s b/lld/test/ELF/arm-exidx-emit-relocs.s
index a641200946b93..d3b609fa75073 100644
--- a/lld/test/ELF/arm-exidx-emit-relocs.s
+++ b/lld/test/ELF/arm-exidx-emit-relocs.s
@@ -9,6 +9,10 @@
 // RUN: llvm-objdump -s --triple=armv7aeb-none-linux-gnueabi %t2 | FileCheck -check-prefix=CHECK-EB %s
 // RUN: llvm-readelf --relocs %t2 | FileCheck -check-prefix=CHECK-RELOCS %s
 
+// RUN: ld.lld --be8 --emit-relocs %t -o %t2
+// RUN: llvm-objdump -s --triple=armv7aeb-none-linux-gnueabi %t2 | FileCheck -check-prefix=CHECK-EB %s
+// RUN: llvm-readelf --relocs %t2 | FileCheck -check-prefix=CHECK-RELOCS %s
+
 /// LLD does not support --emit-relocs for .ARM.exidx sections as the relocations
 /// from synthetic table entries won't be represented. Given the known use cases
 /// of --emit-relocs, relocating kernels, and binary analysis, the former doesn't

diff  --git a/lld/test/ELF/arm-exidx-relocatable.s b/lld/test/ELF/arm-exidx-relocatable.s
index e750c0a4e749b..447a276d76110 100644
--- a/lld/test/ELF/arm-exidx-relocatable.s
+++ b/lld/test/ELF/arm-exidx-relocatable.s
@@ -10,6 +10,8 @@
 // Check that relocatable link maintains SHF_LINK_ORDER for big endian
 // RUN: ld.lld -r %t %tcantunwind -o %t4
 // RUN: llvm-readobj -S %t4 | FileCheck %s
+// RUN: ld.lld --be8 -r %t %tcantunwind -o %t4
+// RUN: llvm-readobj -S %t4 | FileCheck %s
 
 // Each assembler created .ARM.exidx section has the SHF_LINK_ORDER flag set
 // with the sh_link containing the section index of the executable section

diff  --git a/lld/test/ELF/arm-exidx-sentinel-norelocatable.s b/lld/test/ELF/arm-exidx-sentinel-norelocatable.s
index 4c44b00708c48..696f0dcd847ca 100644
--- a/lld/test/ELF/arm-exidx-sentinel-norelocatable.s
+++ b/lld/test/ELF/arm-exidx-sentinel-norelocatable.s
@@ -6,6 +6,8 @@
 // RUN: llvm-mc %s -triple=armv7eb-unknown-linux-gnueabi -mcpu=cortex-a8 -filetype=obj -o %t.o
 // RUN: ld.lld -r %t.o -o %t
 // RUN: llvm-readobj -S %t | FileCheck %s
+// RUN: ld.lld --be8 -r %t.o -o %t
+// RUN: llvm-readobj -S %t | FileCheck %s
 
 // Check that when doing a relocatable link we don't add a terminating entry
 // to the .ARM.exidx section

diff  --git a/lld/test/ELF/arm-header.s b/lld/test/ELF/arm-header.s
index 6712410d59f1f..bb20250a46ede 100644
--- a/lld/test/ELF/arm-header.s
+++ b/lld/test/ELF/arm-header.s
@@ -3,6 +3,10 @@
 # RUN: ld.lld %t.o -o %t1
 # RUN: llvm-readobj -h %t1 | FileCheck %s
 
+# RUN: llvm-mc -filetype=obj -triple=armv7aeb-none-linux-gnueabi -mcpu=cortex-a8 %s -o %t.o
+# RUN: ld.lld --be8 %t.o -o %t1
+# RUN: llvm-readobj -h %t1 | FileCheck -check-prefix=CHECK-EB %s
+
 # CHECK: Format: elf32-bigarm
 
 # CHECK: ElfHeader {
@@ -24,3 +28,23 @@
 
 # CHECK-NOT: 0x800000
 
+# CHECK-EB: Format: elf32-bigarm
+
+# CHECK-EB: ElfHeader {
+# CHECK-EB-NEXT:   Ident {
+# CHECK-EB-NEXT:     Magic: (7F 45 4C 46)
+# CHECK-EB-NEXT:     Class: 32-bit (0x1)
+# CHECK-EB-NEXT:     DataEncoding: BigEndian (0x2)
+# CHECK-EB-NEXT:     FileVersion: 1
+# CHECK-EB-NEXT:     OS/ABI: SystemV (0x0)
+# CHECK-EB-NEXT:     ABIVersion: 0
+# CHECK-EB-NEXT:     Unused: (00 00 00 00 00 00 00)
+# CHECK-EB-NEXT:   }
+
+# CHECK-EB:   Flags [ (0x5800200)
+# CHECK-EB-NEXT:     0x200
+# CHECK-EB-NEXT:     0x800000
+# CHECK-EB-NEXT:     0x1000000
+# CHECK-EB-NEXT:     0x4000000
+# CHECK-EB-NEXT:   ]
+

diff  --git a/lld/test/ELF/arm-mov-relocs.s b/lld/test/ELF/arm-mov-relocs.s
index 559f546f7b493..2964a37f4071c 100644
--- a/lld/test/ELF/arm-mov-relocs.s
+++ b/lld/test/ELF/arm-mov-relocs.s
@@ -13,6 +13,11 @@
 // RUN: ld.lld %t3 -o %t4
 // RUN: llvm-objdump --no-print-imm-hex -d %t4 --triple=thumbv7aeb-unknown-linux-gnueabi --no-show-raw-insn | FileCheck %s
 
+// RUN: ld.lld --be8 %t -o %t2
+// RUN: llvm-objdump --no-print-imm-hex -d %t2 --triple=armv7aeb-unknown-linux-gnueabi --no-show-raw-insn | FileCheck %s
+// RUN: ld.lld --be8 %t3 -o %t4
+// RUN: llvm-objdump --no-print-imm-hex -d %t4 --triple=thumbv7aeb-unknown-linux-gnueabi --no-show-raw-insn | FileCheck %s
+
 /// Test the following relocation pairs:
 ///  * R_ARM_MOVW_ABS_NC and R_ARM_MOVT_ABS
 ///  * R_ARM_MOVW_PREL_NC and R_ARM_MOVT_PREL

diff  --git a/lld/test/ELF/arm-plt-reloc.s b/lld/test/ELF/arm-plt-reloc.s
index e2438a64cc573..177eaf4b1f12b 100644
--- a/lld/test/ELF/arm-plt-reloc.s
+++ b/lld/test/ELF/arm-plt-reloc.s
@@ -6,6 +6,20 @@
 // RUN: ld.lld -shared %t1 %t2 -o %t3
 // RUN: llvm-objdump --no-print-imm-hex --triple=armv7a-none-linux-gnueabi -d --no-show-raw-insn %t3 | FileCheck --check-prefix=DSO %s
 // RUN: llvm-readobj -S -r %t3 | FileCheck -check-prefix=DSOREL %s
+
+// RUN: llvm-mc -filetype=obj -triple=armv7aeb-none-linux-gnueabi %p/Inputs/arm-plt-reloc.s -o %t1.be
+// RUN: llvm-mc -filetype=obj -triple=armv7aeb-none-linux-gnueabi %s -o %t2.be
+// RUN: ld.lld %t1.be %t2.be -o %t.be
+// RUN: llvm-objdump --no-print-imm-hex --triple=armv7aeb-none-linux-gnueabi -d --no-show-raw-insn %t.be | FileCheck %s
+// RUN: ld.lld -shared %t1.be %t2.be -o %t3.be
+// RUN: llvm-objdump --no-print-imm-hex --triple=armv7aeb-none-linux-gnueabi -d --no-show-raw-insn %t3.be | FileCheck --check-prefix=DSO %s
+// RUN: llvm-readobj -S -r %t3.be | FileCheck -check-prefix=DSOREL %s
+
+// RUN: ld.lld --be8 %t1.be %t2.be -o %t.be
+// RUN: llvm-objdump --no-print-imm-hex --triple=armv7aeb-none-linux-gnueabi -d --no-show-raw-insn %t.be | FileCheck %s
+// RUN: ld.lld --be8 -shared %t1.be %t2.be -o %t3.be
+// RUN: llvm-objdump --no-print-imm-hex --triple=armv7aeb-none-linux-gnueabi -d --no-show-raw-insn %t3.be | FileCheck --check-prefix=DSO %s
+// RUN: llvm-readobj -S -r %t3.be | FileCheck -check-prefix=DSOREL %s
 //
 // Test PLT entry generation
  .syntax unified
@@ -114,6 +128,13 @@ _start:
 // RUN: llvm-objdump --no-print-imm-hex --triple=armv7a-none-linux-gnueabi -d --no-show-raw-insn %t4 | FileCheck --check-prefix=CHECKHIGH %s
 // RUN: llvm-readobj -S -r %t4 | FileCheck --check-prefix=DSORELHIGH %s
 
+// RUN: ld.lld --hash-style=sysv --script %t.script -shared %t1.be %t2.be -o %t4.be
+// RUN: llvm-objdump --no-print-imm-hex --triple=armv7aeb-none-linux-gnueabi -d --no-show-raw-insn %t4.be | FileCheck --check-prefix=CHECKHIGH %s
+// RUN: llvm-readobj -S -r %t4.be | FileCheck --check-prefix=DSORELHIGH %s
+// RUN: ld.lld --be8 --hash-style=sysv --script %t.script -shared %t1.be %t2.be -o %t4.be
+// RUN: llvm-objdump --no-print-imm-hex --triple=armv7aeb-none-linux-gnueabi -d --no-show-raw-insn %t4.be | FileCheck --check-prefix=CHECKHIGH %s
+// RUN: llvm-readobj -S -r %t4.be | FileCheck --check-prefix=DSORELHIGH %s
+
 // CHECKHIGH: Disassembly of section .text:
 // CHECKHIGH-EMPTY:
 // CHECKHIGH-NEXT: <func1>:
@@ -182,6 +203,13 @@ _start:
 // RUN: llvm-objdump --no-print-imm-hex --triple=armv7a-none-linux-gnueabi -d --no-show-raw-insn %t5 | FileCheck --check-prefix=CHECKLONG %s
 // RUN: llvm-readobj -S -r %t5 | FileCheck --check-prefix=DSORELLONG %s
 
+// RUN: ld.lld --hash-style=sysv --script %t2.script -shared %t1.be %t2.be -o %t5.be
+// RUN: llvm-objdump --no-print-imm-hex --triple=armv7aeb-none-linux-gnueabi -d --no-show-raw-insn %t5.be | FileCheck --check-prefix=CHECKLONG-EB %s
+// RUN: llvm-readobj -S -r %t5.be | FileCheck --check-prefix=DSORELLONG %s
+// RUN: ld.lld --be8 --hash-style=sysv --script %t2.script -shared %t1.be %t2.be -o %t5.be
+// RUN: llvm-objdump --no-print-imm-hex --triple=armv7aeb-none-linux-gnueabi -d --no-show-raw-insn %t5.be | FileCheck --check-prefix=CHECKLONG-EB %s
+// RUN: llvm-readobj -S -r %t5.be | FileCheck --check-prefix=DSORELLONG %s
+
 // CHECKLONG: Disassembly of section .text:
 // CHECKLONG-EMPTY:
 // CHECKLONG-NEXT: <func1>:
@@ -226,6 +254,50 @@ _start:
 // CHECKLONG: <$d>:
 // CHECKLONG-NEXT:     204c:       c8 f0 10 11     .word   0x1110f0c8
 
+// CHECKLONG-EB: Disassembly of section .text:
+// CHECKLONG-EB-EMPTY:
+// CHECKLONG-EB-NEXT: <func1>:
+// CHECKLONG-EB-NEXT:     1000:       bx      lr
+// CHECKLONG-EB: <func2>:
+// CHECKLONG-EB-NEXT:                 bx      lr
+// CHECKLONG-EB: <func3>:
+// CHECKLONG-EB-NEXT:                 bx      lr
+// CHECKLONG-EB: <_start>:
+// CHECKLONG-EB-NEXT:                 b       0x2020
+// CHECKLONG-EB-NEXT:                 bl      0x2030
+// CHECKLONG-EB-NEXT:                 beq     0x2040
+// CHECKLONG-EB-EMPTY:
+// CHECKLONG-EB-NEXT: Disassembly of section .plt:
+// CHECKLONG-EB-EMPTY:
+// CHECKLONG-EB-NEXT: <$a>:
+// CHECKLONG-EB-NEXT:     2000:       str     lr, [sp, #-4]!
+// CHECKLONG-EB-NEXT:                 ldr     lr, [pc, #4]
+// CHECKLONG-EB-NEXT:                 add     lr, pc, lr
+// CHECKLONG-EB-NEXT:                 ldr     pc, [lr, #8]!
+// CHECKLONG-EB: <$d>:
+// CHECKLONG-EB-NEXT:                 11 10 f0 f0     .word   0x1110f0f0
+// CHECKLONG-EB-NEXT:                 d4 d4 d4 d4     .word   0xd4d4d4d4
+// CHECKLONG-EB-NEXT:                 d4 d4 d4 d4     .word   0xd4d4d4d4
+// CHECKLONG-EB-NEXT:                 d4 d4 d4 d4     .word   0xd4d4d4d4
+// CHECKLONG-EB: <$a>:
+// CHECKLONG-EB-NEXT:     2020:       ldr     r12, [pc, #4]
+// CHECKLONG-EB-NEXT:                 add     r12, r12, pc
+// CHECKLONG-EB-NEXT:                 ldr     pc, [r12]
+// CHECKLONG-EB: <$d>:
+// CHECKLONG-EB-NEXT:                 11 10 f0 e0     .word   0x1110f0e0
+// CHECKLONG-EB: <$a>:
+// CHECKLONG-EB-NEXT:     2030:       ldr     r12, [pc, #4]
+// CHECKLONG-EB-NEXT:                 add     r12, r12, pc
+// CHECKLONG-EB-NEXT:                 ldr     pc, [r12]
+// CHECKLONG-EB: <$d>:
+// CHECKLONG-EB-NEXT:                 11 10 f0 d4     .word   0x1110f0d4
+// CHECKLONG-EB: <$a>:
+// CHECKLONG-EB-NEXT:     2040:       ldr     r12, [pc, #4]
+// CHECKLONG-EB-NEXT:                 add     r12, r12, pc
+// CHECKLONG-EB-NEXT:                 ldr     pc, [r12]
+// CHECKLONG-EB: <$d>:
+// CHECKLONG-EB-NEXT:                11 10 f0 c8     .word   0x1110f0c8
+
 // DSORELLONG: Name: .got.plt
 // DSORELLONG-NEXT:     Type: SHT_PROGBITS
 // DSORELLONG-NEXT:     Flags [
@@ -251,6 +323,13 @@ _start:
 // RUN: llvm-objdump --no-print-imm-hex --triple=armv7a-none-linux-gnueabi -d --no-show-raw-insn %t6 | FileCheck --check-prefix=CHECKMIX %s
 // RUN: llvm-readobj -S -r %t6 | FileCheck --check-prefix=DSORELMIX %s
 
+// RUN: ld.lld --hash-style=sysv --script %t3.script -shared %t1.be %t2.be -o %t6.be
+// RUN: llvm-objdump --no-print-imm-hex --triple=armv7aeb-none-linux-gnueabi -d --no-show-raw-insn %t6.be | FileCheck --check-prefix=CHECKMIX-EB %s
+// RUN: llvm-readobj -S -r %t6.be | FileCheck --check-prefix=DSORELMIX %s
+// RUN: ld.lld --be8 --hash-style=sysv --script %t3.script -shared %t1.be %t2.be -o %t6.be
+// RUN: llvm-objdump --no-print-imm-hex --triple=armv7a-none-linux-gnueabi -d --no-show-raw-insn %t6.be | FileCheck --check-prefix=CHECKMIX-EB %s
+// RUN: llvm-readobj -S -r %t6.be | FileCheck --check-prefix=DSORELMIX %s
+
 // CHECKMIX: Disassembly of section .text:
 // CHECKMIX-EMPTY:
 // CHECKMIX-NEXT: <func1>:
@@ -295,6 +374,50 @@ _start:
 // CHECKMIX: <$d>:
 // CHECKMIX-NEXT:     204c:     d4 d4 d4 d4     .word   0xd4d4d4d4
 
+// CHECKMIX-EB: Disassembly of section .text:
+// CHECKMIX-EB-EMPTY:
+// CHECKMIX-EB-NEXT: <func1>:
+// CHECKMIX-EB-NEXT:     1000:       bx      lr
+// CHECKMIX-EB: <func2>:
+// CHECKMIX-EB-NEXT:                 bx      lr
+// CHECKMIX-EB: <func3>:
+// CHECKMIX-EB-NEXT:                 bx      lr
+// CHECKMIX-EB: <_start>:
+// CHECKMIX-EB-NEXT:                 b       0x2020
+// CHECKMIX-EB-NEXT:                 bl      0x2030
+// CHECKMIX-EB-NEXT:                 beq     0x2040
+// CHECKMIX-EB-EMPTY:
+// CHECKMIX-EB-NEXT: Disassembly of section .plt:
+// CHECKMIX-EB-EMPTY:
+// CHECKMIX-EB-NEXT: <$a>:
+// CHECKMIX-EB-NEXT:     2000:       str     lr, [sp, #-4]!
+// CHECKMIX-EB-NEXT:                 ldr     lr, [pc, #4]
+// CHECKMIX-EB-NEXT:                 add     lr, pc, lr
+// CHECKMIX-EB-NEXT:                 ldr     pc, [lr, #8]!
+// CHECKMIX-EB: <$d>:
+// CHECKMIX-EB-NEXT:                 08 00 00 10     .word   0x08000010
+// CHECKMIX-EB-NEXT:                 d4 d4 d4 d4     .word   0xd4d4d4d4
+// CHECKMIX-EB-NEXT:                 d4 d4 d4 d4     .word   0xd4d4d4d4
+// CHECKMIX-EB-NEXT:                 d4 d4 d4 d4     .word   0xd4d4d4d4
+// CHECKMIX-EB: <$a>:
+// CHECKMIX-EB-NEXT:     2020:       ldr     r12, [pc, #4]
+// CHECKMIX-EB-NEXT:                 add     r12, r12, pc
+// CHECKMIX-EB-NEXT:                 ldr     pc, [r12]
+// CHECKMIX-EB: <$d>:
+// CHECKMIX-EB-NEXT:                 08 00 00 00     .word   0x08000000
+// CHECKMIX-EB: <$a>:
+// CHECKMIX-EB-NEXT:     2030:       add     r12, pc, #133169152
+// CHECKMIX-EB-NEXT:                 add     r12, r12, #1044480
+// CHECKMIX-EB-NEXT:                 ldr     pc, [r12, #4088]!
+// CHECKMIX-EB: <$d>:
+// CHECKMIX-EB-NEXT:                 d4 d4 d4 d4     .word   0xd4d4d4d4
+// CHECKMIX-EB: <$a>:
+// CHECKMIX-EB-NEXT:     2040:       add     r12, pc, #133169152
+// CHECKMIX-EB-NEXT:                 add     r12, r12, #1044480
+// CHECKMIX-EB-NEXT:                 ldr     pc, [r12, #4076]!
+// CHECKMIX-EB: <$d>:
+// CHECKMIX-EB-NEXT:                 d4 d4 d4 d4     .word   0xd4d4d4d4
+
 // DSORELMIX:    Name: .got.plt
 // DSORELMIX-NEXT:     Type: SHT_PROGBITS
 // DSORELMIX-NEXT:     Flags [
@@ -307,59 +430,3 @@ _start:
 // DSORELMIX-NEXT:     0x8002030 R_ARM_JUMP_SLOT func2
 // DSORELMIX-NEXT:     0x8002034 R_ARM_JUMP_SLOT func3
 
-// RUN: llvm-mc -filetype=obj -triple=armv7aeb-none-linux-gnueabi -mcpu=cortex-a8 %p/Inputs/arm-plt-reloc.s -o %t1
-// RUN: llvm-mc -filetype=obj -triple=armv7aeb-none-linux-gnueabi -mcpu=cortex-a8 %s -o %t2
-// RUN: ld.lld %t1 %t2 -o %t
-// RUN: llvm-objdump --no-print-imm-hex --triple=armv7aeb-none-linux-gnueabi -d --no-show-raw-insn %t | FileCheck %s
-// RUN: ld.lld -shared %t1 %t2 -o %t3
-// RUN: llvm-objdump --no-print-imm-hex --triple=armv7aeb-none-linux-gnueabi -d --no-show-raw-insn %t3 | FileCheck --check-prefix=DSO %s
-// RUN: llvm-readobj -S -r %t3 | FileCheck -check-prefix=DSOREL %s
-
-// RUN: ld.lld --hash-style=sysv --script %t2.script -shared %t1 %t2 -o %t5
-// RUN: llvm-objdump --no-print-imm-hex --triple=armv7aeb-none-linux-gnueabi -d --no-show-raw-insn %t5 | FileCheck --check-prefix=CHECKLONG-EB %s
-// RUN: llvm-readobj -S -r %t5 | FileCheck --check-prefix=DSORELLONG %s
-
-// CHECKLONG-EB: Disassembly of section .text:
-// CHECKLONG-EB-EMPTY:
-// CHECKLONG-EB-NEXT: <func1>:
-// CHECKLONG-EB-NEXT:     1000:       bx      lr
-// CHECKLONG-EB: <func2>:
-// CHECKLONG-EB-NEXT:     1004:       bx      lr
-// CHECKLONG-EB: <func3>:
-// CHECKLONG-EB-NEXT:     1008:       bx      lr
-// CHECKLONG-EB: <_start>:
-// CHECKLONG-EB-NEXT:     100c:       b       0x2020
-// CHECKLONG-EB-NEXT:     1010:       bl      0x2030
-// CHECKLONG-EB-NEXT:     1014:       beq     0x2040
-// CHECKLONG-EB-EMPTY:
-// CHECKLONG-EB-NEXT: Disassembly of section .plt:
-// CHECKLONG-EB-EMPTY:
-// CHECKLONG-EB-NEXT: <$a>:
-// CHECKLONG-EB-NEXT:     2000:       str     lr, [sp, #-4]!
-// CHECKLONG-EB-NEXT:     2004:       ldr     lr, [pc, #4]
-// CHECKLONG-EB-NEXT:     2008:       add     lr, pc, lr
-// CHECKLONG-EB-NEXT:     200c:       ldr     pc, [lr, #8]!
-// CHECKLONG-EB: <$d>:
-// CHECKLONG-EB-NEXT:     2010:	      11 10 f0 f0     .word   0x1110f0f0
-// CHECKLONG-EB-NEXT:     2014:       d4 d4 d4 d4     .word   0xd4d4d4d4
-// CHECKLONG-EB-NEXT:     2018:       d4 d4 d4 d4     .word   0xd4d4d4d4
-// CHECKLONG-EB-NEXT:     201c:       d4 d4 d4 d4     .word   0xd4d4d4d4
-// CHECKLONG-EB: <$a>:
-// CHECKLONG-EB-NEXT:     2020:       ldr     r12, [pc, #4]
-// CHECKLONG-EB-NEXT:     2024:       add     r12, r12, pc
-// CHECKLONG-EB-NEXT:     2028:       ldr     pc, [r12]
-// CHECKLONG-EB: <$d>:
-// CHECKLONG-EB-NEXT:     202c:       11 10 f0 e0     .word   0x1110f0e0
-// CHECKLONG-EB: <$a>:
-// CHECKLONG-EB-NEXT:     2030:       ldr     r12, [pc, #4]
-// CHECKLONG-EB-NEXT:     2034:       add     r12, r12, pc
-// CHECKLONG-EB-NEXT:     2038:       ldr     pc, [r12]
-// CHECKLONG-EB: <$d>:
-// CHECKLONG-EB-NEXT:     203c:       11 10 f0 d4     .word 0x1110f0d4
-// CHECKLONG-EB: <$a>:
-// CHECKLONG-EB-NEXT:     2040:       ldr     r12, [pc, #4]
-// CHECKLONG-EB-NEXT:     2044:       add     r12, r12, pc
-// CHECKLONG-EB-NEXT:     2048:       ldr     pc, [r12]
-// CHECKLONG-EB: <$d>:
-// CHECKLONG-EB-NEXT:     204c:       11 10 f0 c8     .word   0x1110f0c8
-

diff  --git a/lld/test/ELF/arm-thumb-plt-reloc.s b/lld/test/ELF/arm-thumb-plt-reloc.s
index 580c06d6cfaea..a0a90893318ff 100644
--- a/lld/test/ELF/arm-thumb-plt-reloc.s
+++ b/lld/test/ELF/arm-thumb-plt-reloc.s
@@ -15,6 +15,12 @@
 // RUN: llvm-objdump --no-print-imm-hex --triple=thumbv7aeb-none-linux-gnueabi -d %t.so | FileCheck --check-prefix=DSO %s
 // RUN: llvm-readobj -S -r %t.so | FileCheck -check-prefix=DSOREL %s
 
+// RUN: ld.lld --be8 %t1 %t2 -o %t
+// RUN: llvm-objdump --no-print-imm-hex --triple=thumbv7aeb-none-linux-gnueabi -d %t | FileCheck %s
+// RUN: ld.lld --be8 -shared %t1 %t2 -o %t.so
+// RUN: llvm-objdump --no-print-imm-hex --triple=thumbv7aeb-none-linux-gnueabi -d %t.so | FileCheck --check-prefix=DSO %s
+// RUN: llvm-readobj -S -r %t.so | FileCheck -check-prefix=DSOREL %s
+
 // Test PLT entry generation
  .syntax unified
  .text

diff  --git a/lld/test/ELF/arm-thunk-arm-thumb-reuse.s b/lld/test/ELF/arm-thunk-arm-thumb-reuse.s
index 1618e7eebb931..12538312f0e09 100644
--- a/lld/test/ELF/arm-thunk-arm-thumb-reuse.s
+++ b/lld/test/ELF/arm-thunk-arm-thumb-reuse.s
@@ -7,6 +7,8 @@
 // RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=thumbv7aeb-none-linux-gnueabi -mcpu=cortex-a8 %t/test.s -o %t.o
 // RUN: ld.lld --script %t/script %t.o -o %t2
 // RUN: llvm-objdump --no-print-imm-hex --no-show-raw-insn -d %t2 | FileCheck %s
+// RUN: ld.lld --be8 --script %t/script %t.o -o %t2
+// RUN: llvm-objdump --no-print-imm-hex --no-show-raw-insn -d %t2 | FileCheck %s
 
 /// Test that we can reuse thunks between Arm and Thumb callers
 /// using a BL. Expect two thunks, one for far, one for far2.

diff  --git a/lld/test/ELF/arm-thunk-edgecase.s b/lld/test/ELF/arm-thunk-edgecase.s
index a1c17b859c2f5..46b0335236eea 100644
--- a/lld/test/ELF/arm-thunk-edgecase.s
+++ b/lld/test/ELF/arm-thunk-edgecase.s
@@ -19,6 +19,11 @@
 // RUN: llvm-objdump --no-print-imm-hex --triple=armv7aeb-none-linux-gnueabi -d %tarm_to_thumb.so | FileCheck --check-prefix=ARM-TO-THUMB %s
 // RUN: llvm-objdump --no-print-imm-hex -d %tthumb_to_arm.so | FileCheck --check-prefix=THUMB-TO-ARM %s
 
+// RUN: ld.lld --be8 -shared -Bsymbolic -script %tarm_to_thumb.script %t.o -o %tarm_to_thumb.so
+// RUN: ld.lld --be8 -shared -Bsymbolic -script %tthumb_to_arm.script %t.o -o %tthumb_to_arm.so
+// RUN: llvm-objdump --no-print-imm-hex --triple=armv7aeb-none-linux-gnueabi -d %tarm_to_thumb.so | FileCheck --check-prefix=ARM-TO-THUMB %s
+// RUN: llvm-objdump --no-print-imm-hex -d %tthumb_to_arm.so | FileCheck --check-prefix=THUMB-TO-ARM %s
+
 .syntax unified
 
 .arm

diff  --git a/lld/test/ELF/arm-thunk-largesection.s b/lld/test/ELF/arm-thunk-largesection.s
index 80927adb73bf9..be16393664b6f 100644
--- a/lld/test/ELF/arm-thunk-largesection.s
+++ b/lld/test/ELF/arm-thunk-largesection.s
@@ -13,6 +13,13 @@
 // RUN: llvm-objdump --no-print-imm-hex -d --no-show-raw-insn --start-address=0x22004 --stop-address=0x22008 %t2 | FileCheck --check-prefix=CHECK2 %s
 // RUN: llvm-objdump --no-print-imm-hex -d --no-show-raw-insn --start-address=0x1021ff8 --stop-address=0x1021ffc %t2 | FileCheck --check-prefix=CHECK3 %s
 // RUN: llvm-objdump --no-print-imm-hex -d --no-show-raw-insn --start-address=0x2012ff8 --stop-address=0x2021ffc %t2 | FileCheck --check-prefix=CHECK4 %s
+// RUN: llvm-objdump --no-print-imm-hex -d --no-show-raw-insn --start-address=0x3021fec --stop-address=0x3021ff6 %t2 | FileCheck --check-prefix=CHECK5 %s
+
+// RUN: ld.lld --be8 %t -o %t2
+// RUN: llvm-objdump --no-print-imm-hex -d --no-show-raw-insn --start-address=0x21000 --stop-address=0x21006 %t2 | FileCheck --check-prefix=CHECK1 %s
+// RUN: llvm-objdump --no-print-imm-hex -d --no-show-raw-insn --start-address=0x22004 --stop-address=0x22008 %t2 | FileCheck --check-prefix=CHECK2 %s
+// RUN: llvm-objdump --no-print-imm-hex -d --no-show-raw-insn --start-address=0x1021ff8 --stop-address=0x1021ffc %t2 | FileCheck --check-prefix=CHECK3 %s
+// RUN: llvm-objdump --no-print-imm-hex -d --no-show-raw-insn --start-address=0x2012ff8 --stop-address=0x2021ffc %t2 | FileCheck --check-prefix=CHECK4 %s
 // RUN: llvm-objdump --no-print-imm-hex -d --no-show-raw-insn --start-address=0x3021fec --stop-address=0x3021ff6 %t2 | FileCheck --check-prefix=CHECK5 %s
 
  .syntax unified

diff  --git a/lld/test/ELF/arm-thunk-linkerscript-dotexpr.s b/lld/test/ELF/arm-thunk-linkerscript-dotexpr.s
index 9514560446b06..21849aa3e9e29 100644
--- a/lld/test/ELF/arm-thunk-linkerscript-dotexpr.s
+++ b/lld/test/ELF/arm-thunk-linkerscript-dotexpr.s
@@ -12,6 +12,9 @@
 // RUN: ld.lld --no-rosegment --script %t.script %t -o %t2
 // RUN: llvm-objdump --no-print-imm-hex -d %t2 --start-address=0x94 --stop-address=0xbc | FileCheck --check-prefix=CHECK1 %s
 // RUN: llvm-objdump --no-print-imm-hex -d %t2 --start-address=0x20000bc --stop-address=0x20000de | FileCheck --check-prefix=CHECK2 %s
+// RUN: ld.lld --be8 --no-rosegment --script %t.script %t -o %t2
+// RUN: llvm-objdump --no-print-imm-hex -d %t2 --start-address=0x94 --stop-address=0xbc | FileCheck --check-prefix=CHECK1 %s
+// RUN: llvm-objdump --no-print-imm-hex -d %t2 --start-address=0x20000bc --stop-address=0x20000de | FileCheck --check-prefix=CHECK2 %s
 
 // Test that range extension thunks can handle location expressions within
 // a Section Description

diff  --git a/lld/test/ELF/arm-thunk-linkerscript.s b/lld/test/ELF/arm-thunk-linkerscript.s
index f18861b33ab31..131ab41a40a0c 100644
--- a/lld/test/ELF/arm-thunk-linkerscript.s
+++ b/lld/test/ELF/arm-thunk-linkerscript.s
@@ -11,6 +11,8 @@
 // RUN: llvm-mc -arm-add-build-attributes -filetype=obj -triple=armv7aeb-none-linux-gnueabi -mcpu=cortex-a8 %s -o %t
 // RUN: ld.lld --no-rosegment --script %t.script %t -o %t2
 // RUN: llvm-objdump --no-print-imm-hex -d %t2 | FileCheck %s
+// RUN: ld.lld --be8 --no-rosegment --script %t.script %t -o %t2
+// RUN: llvm-objdump --no-print-imm-hex -d %t2 | FileCheck %s
 
 // Simple test that we can support range extension thunks with linker scripts
  .syntax unified

diff  --git a/lld/test/ELF/arm-thunk-nosuitable.s b/lld/test/ELF/arm-thunk-nosuitable.s
index cf19d0c135d92..dbd8334a2db17 100644
--- a/lld/test/ELF/arm-thunk-nosuitable.s
+++ b/lld/test/ELF/arm-thunk-nosuitable.s
@@ -5,6 +5,8 @@
 
 // RUN: llvm-mc %s --arm-add-build-attributes --triple=armv7aeb-linux-gnueabihf --filetype=obj -mcpu=cortex-a8 -o %t.o
 // RUN: ld.lld %t.o -o %t
+// RUN: llvm-objdump -d --start-address=0x2200b4 --stop-address=0x2200be %t | FileCheck %s
+// RUN: ld.lld --be8 %t.o -o %t
 // RUN: llvm-objdump -d --start-address=0x2200b4 --stop-address=0x2200be %t | FileCheck %s
 
         /// Create a conditional branch too far away from a precreated thunk

diff  --git a/lld/test/ELF/arm-thunk-re-add.s b/lld/test/ELF/arm-thunk-re-add.s
index 996552bfa0b02..3fa876082c398 100644
--- a/lld/test/ELF/arm-thunk-re-add.s
+++ b/lld/test/ELF/arm-thunk-re-add.s
@@ -131,3 +131,10 @@ callers:
 // RUN: llvm-objdump --no-print-imm-hex -d %t.so --start-address=0x1100008 --stop-address=0x1100022 | FileCheck --check-prefix=CHECK2 %s
 // RUN: llvm-objdump --no-print-imm-hex -d %t.so --start-address=0x1100020 --stop-address=0x1100064 --triple=armv7aeb-linux-gnueabihf | FileCheck --check-prefix=CHECK3 %s
 
+// RUN: ld.lld --be8 %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
+// RUN: llvm-objdump --no-print-imm-hex -d %t.so --start-address=0x1000004 --stop-address=0x100001c | FileCheck --check-prefix=CHECK1 %s
+// RUN: llvm-objdump --no-print-imm-hex -d %t.so --start-address=0x1100008 --stop-address=0x1100022 | FileCheck --check-prefix=CHECK2 %s
+// RUN: llvm-objdump --no-print-imm-hex -d %t.so --start-address=0x1100020 --stop-address=0x1100064 --triple=armv7aeb-linux-gnueabihf | FileCheck --check-prefix=CHECK3 %s
+

diff  --git a/lld/test/ELF/arm-thunk-reuse.s b/lld/test/ELF/arm-thunk-reuse.s
index 67993a97e6326..f6815da7af496 100644
--- a/lld/test/ELF/arm-thunk-reuse.s
+++ b/lld/test/ELF/arm-thunk-reuse.s
@@ -3,10 +3,15 @@
 # RUN: llvm-mc -filetype=obj -triple=armv7-a-none-eabi --arm-add-build-attributes %t/a.s -o %t/a.o
 # RUN: ld.lld -pie -T %t/lds %t/a.o -o %t/a
 # RUN: llvm-objdump --no-print-imm-hex -d --no-show-raw-insn %t/a | FileCheck %s
+# RUN: llvm-objdump -s --triple=armv7a-none-linux-gnueabi %t/a | FileCheck --check-prefix=CHECK-LE %s
 
 # RUN: llvm-mc -filetype=obj -triple=armv7eb-a-none-eabi --arm-add-build-attributes -mcpu=cortex-a8 %t/a.s -o %t/a.o
 # RUN: ld.lld -pie -T %t/lds %t/a.o -o %t/a
 # RUN: llvm-objdump --no-print-imm-hex -d --no-show-raw-insn %t/a | FileCheck %s
+# RUN: llvm-objdump -s --triple=armv7eb-a-none-eabi %t/a| FileCheck --check-prefix=CHECK-EB %s
+# RUN: ld.lld --be8 -pie -T %t/lds %t/a.o -o %t/a
+# RUN: llvm-objdump --no-print-imm-hex -d --no-show-raw-insn %t/a | FileCheck %s
+# RUN: llvm-objdump -s --triple=armv7eb-a-none-eabi %t/a| FileCheck --check-prefix=CHECK-LE %s
 
 ## We create a thunk for dest.
 # CHECK-LABEL: <mid>:
@@ -30,6 +35,24 @@
 # CHECK-NEXT:                 add     r12, r12, pc
 # CHECK-NEXT:                 bx      r12
 
+# CHECK-EB: Contents of section .text_low:
+# CHECK-EB-NEXT: 10000 e320f000 e12fff1e
+# CHECK-EB: Contents of section .text_mid:
+# CHECK-EB-NEXT: 2010004 eaffffff e30fcfec e34fcdff e08cc00f
+# CHECK-EB-NEXT: 2010014 e12fff1c
+# CHECK-EB: Contents of section .text_high:
+# CHECK-EB-NEXT: 4010000 eb800000 eaffffff e30fcfec e34fcbff
+# CHECK-EB-NEXT: 4010010 e08cc00f e12fff1c
+
+# CHECK-LE: Contents of section .text_low:
+# CHECK-LE-NEXT: 10000 00f020e3 1eff2fe1
+# CHECK-LE: Contents of section .text_mid:
+# CHECK-LE-NEXT: 2010004 ffffffea eccf0fe3 ffcd4fe3 0fc08ce0
+# CHECK-LE-NEXT: 2010014 1cff2fe1
+# CHECK-LE: Contents of section .text_high:
+# CHECK-LE-NEXT: 4010000 000080eb ffffffea eccf0fe3 ffcb4fe3
+# CHECK-LE-NEXT: 4010010 0fc08ce0 1cff2fe1
+
 #--- a.s
 .section .text_low, "ax", %progbits
 

diff  --git a/lld/test/ELF/arm-thunk-section-too-large.s b/lld/test/ELF/arm-thunk-section-too-large.s
index 227f16485e443..c6c058085968d 100644
--- a/lld/test/ELF/arm-thunk-section-too-large.s
+++ b/lld/test/ELF/arm-thunk-section-too-large.s
@@ -4,6 +4,7 @@
 
 // RUN: llvm-mc %s -triple=armv7aeb-linux-gnueabihf -arm-add-build-attributes -filetype=obj -mcpu=cortex-a8 -o %t.o
 // RUN: not ld.lld %t.o -o /dev/null 2>&1 | FileCheck %s
+// RUN: not ld.lld --be8 %t.o -o /dev/null 2>&1 | FileCheck %s
 
 // CHECK: InputSection too large for range extension thunk
         .syntax unified

diff  --git a/lld/test/ELF/arm-thunk-toolargesection.s b/lld/test/ELF/arm-thunk-toolargesection.s
index e0383572e3ffa..f91c4a4959315 100644
--- a/lld/test/ELF/arm-thunk-toolargesection.s
+++ b/lld/test/ELF/arm-thunk-toolargesection.s
@@ -4,6 +4,7 @@
 
 // RUN: llvm-mc -filetype=obj -triple=thumbv7aeb-none-linux-gnueabi %s -o %t
 // RUN: not ld.lld %t -o /dev/null 2>&1 | FileCheck %s
+// RUN: not ld.lld --be8 %t -o /dev/null 2>&1 | FileCheck %s
 
  .syntax unified
  .balign 0x1000

diff  --git a/lld/test/ELF/arm-v5-reloc-error.s b/lld/test/ELF/arm-v5-reloc-error.s
index 85a675db27e71..bd4b9ad68d10a 100644
--- a/lld/test/ELF/arm-v5-reloc-error.s
+++ b/lld/test/ELF/arm-v5-reloc-error.s
@@ -9,6 +9,7 @@
 
 // RUN: llvm-mc -filetype=obj -triple=armv7aeb-linux-gnueabi -mcpu=cortex-a8 %s -o %t
 // RUN: not ld.lld --script %t.script %t -o /dev/null 2>&1 | FileCheck %s
+// RUN: not ld.lld -be8 --script %t.script %t -o /dev/null 2>&1 | FileCheck %s
 
 // CHECK: error: relocation R_ARM_THM_JUMP24 to far not supported for Armv5 or Armv6 targets
 

diff  --git a/lld/test/ELF/emulation-arm.s b/lld/test/ELF/emulation-arm.s
index 3ab1033279dd7..b061bbb9f3f5b 100644
--- a/lld/test/ELF/emulation-arm.s
+++ b/lld/test/ELF/emulation-arm.s
@@ -30,6 +30,11 @@
 # RUN: llvm-readobj -h %t1 | FileCheck %s --check-prefix=ARMEB
 # RUN: llvm-readobj -h %t1 | FileCheck %s --check-prefix=BE8
 
+# RUN: ld.lld --be8 -marmelfb_linux_eabi %t.o -o %t1
+# echo 'OUTPUT_FORMAT(elf32-bigarm)' > %t6arm.script
+# ld.lld --be8 %tarm -o %t6arm
+# RUN: llvm-readobj -h %t1 | FileCheck %s --check-prefix=ARMEB8
+
 # ARMEB: ElfHeader {
 # ARMEB-NEXT:   Ident {
 # ARMEB-NEXT:     Magic: (7F 45 4C 46)
@@ -54,5 +59,27 @@
 
 # BE8-NOT: 0x800000
 
+# ARMEB8: ElfHeader {
+# ARMEB8-NEXT:   Ident {
+# ARMEB8-NEXT:     Magic: (7F 45 4C 46)
+# ARMEB8-NEXT:     Class: 32-bit (0x1)
+# ARMEB8-NEXT:     DataEncoding: BigEndian (0x2)
+# ARMEB8-NEXT:     FileVersion: 1
+# ARMEB8-NEXT:     OS/ABI: SystemV (0x0)
+# ARMEB8-NEXT:     ABIVersion: 0
+# ARMEB8-NEXT:     Unused: (00 00 00 00 00 00 00)
+# ARMEB8-NEXT:   }
+# ARMEB8-NEXT:   Type: Executable (0x2)
+# ARMEB8-NEXT:   Machine: EM_ARM (0x28)
+# ARMEB8-NEXT:   Version: 1
+
+## Ensure that the EF_ARM_BE8 flag is set for be8
+# ARMEB8:   Flags [ (0x5800200)
+# ARMEB8-NEXT:     0x200
+# ARMEB8-NEXT:     0x800000
+# ARMEB8-NEXT:     0x1000000
+# ARMEB8-NEXT:     0x4000000
+# ARMEB8-NEXT:   ]
+
 .globl _start
 _start:

diff  --git a/lld/test/ELF/target-specific-options.s b/lld/test/ELF/target-specific-options.s
index 76227803f9350..94dccd9e4a0c1 100644
--- a/lld/test/ELF/target-specific-options.s
+++ b/lld/test/ELF/target-specific-options.s
@@ -4,6 +4,9 @@
 # RUN: not ld.lld %t --fix-cortex-a53-843419 -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR-843419
 # ERR-843419: error: --fix-cortex-a53-843419 is only supported on AArch64 targets
 
+# RUN: not ld.lld %t --be8 -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR-BE8
+# ERR-BE8: error: --be8 is only supported on ARM targets
+
 # RUN: not ld.lld %t --pcrel-optimize -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR-PCREL
 # ERR-PCREL: error: --pcrel-optimize is only supported on PowerPC64 targets
 


        


More information about the llvm-commits mailing list