aboutsummaryrefslogtreecommitdiff
path: root/lld
diff options
context:
space:
mode:
authorSimi Pallipurath <simi.pallipurath@arm.com>2023-06-22 13:55:59 +0100
committerSimi Pallipurath <simi.pallipurath@arm.com>2023-06-22 16:10:18 +0100
commitf146763e0788f84de227623d87adccd5890ecdc6 (patch)
tree7458e2ab5c73bbb28f02149e9f61ff07a18cab99 /lld
parent81ec494c363d4934e692e8b35e0b3fbbc3de1c2b (diff)
downloadllvm-f146763e0788f84de227623d87adccd5890ecdc6.zip
llvm-f146763e0788f84de227623d87adccd5890ecdc6.tar.gz
llvm-f146763e0788f84de227623d87adccd5890ecdc6.tar.bz2
Revert "Revert "[lld][Arm] Big Endian - Byte invariant support.""
This reverts commit d8851384c6ac2a1cea15e05228dbde5f13654e23. Reason: Applied the fix for the Asan buildbot failures.
Diffstat (limited to 'lld')
-rw-r--r--lld/ELF/Arch/ARM.cpp125
-rw-r--r--lld/ELF/Config.h1
-rw-r--r--lld/ELF/Driver.cpp6
-rw-r--r--lld/ELF/Options.td2
-rw-r--r--lld/ELF/OutputSections.cpp6
-rw-r--r--lld/ELF/SyntheticSections.cpp7
-rw-r--r--lld/ELF/Target.h4
-rw-r--r--lld/ELF/Thunks.cpp30
-rw-r--r--lld/ELF/Writer.cpp5
-rw-r--r--lld/docs/ld.lld.12
-rw-r--r--lld/test/ELF/arm-bl-v6.s6
-rw-r--r--lld/test/ELF/arm-data-relocs.s3
-rw-r--r--lld/test/ELF/arm-exidx-emit-relocs.s4
-rw-r--r--lld/test/ELF/arm-exidx-relocatable.s2
-rw-r--r--lld/test/ELF/arm-exidx-sentinel-norelocatable.s2
-rw-r--r--lld/test/ELF/arm-header.s24
-rw-r--r--lld/test/ELF/arm-mov-relocs.s5
-rw-r--r--lld/test/ELF/arm-plt-reloc.s179
-rw-r--r--lld/test/ELF/arm-thumb-plt-reloc.s6
-rw-r--r--lld/test/ELF/arm-thunk-arm-thumb-reuse.s2
-rw-r--r--lld/test/ELF/arm-thunk-edgecase.s5
-rw-r--r--lld/test/ELF/arm-thunk-largesection.s7
-rw-r--r--lld/test/ELF/arm-thunk-linkerscript-dotexpr.s3
-rw-r--r--lld/test/ELF/arm-thunk-linkerscript.s2
-rw-r--r--lld/test/ELF/arm-thunk-nosuitable.s2
-rw-r--r--lld/test/ELF/arm-thunk-re-add.s7
-rw-r--r--lld/test/ELF/arm-thunk-reuse.s23
-rw-r--r--lld/test/ELF/arm-thunk-section-too-large.s1
-rw-r--r--lld/test/ELF/arm-thunk-toolargesection.s1
-rw-r--r--lld/test/ELF/arm-v5-reloc-error.s1
-rw-r--r--lld/test/ELF/emulation-arm.s27
-rw-r--r--lld/test/ELF/target-specific-options.s3
32 files changed, 435 insertions, 68 deletions
diff --git a/lld/ELF/Arch/ARM.cpp b/lld/ELF/Arch/ARM.cpp
index 79635a2..2e1ba26 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 @@ public:
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,117 @@ 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) {
+ if (!sectionMap.contains(sec))
+ return;
+
+ 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 &target;
diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h
index 9565300..813102a 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 4eb10fc..9c813f9 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 0c6884a..d878ae3 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 05f9cdc..0b9b76e 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 48f3012..0a52ad3 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 59534ab..dd0ae39 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 331e28e..8114068 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 3630b19..4396cf3 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 e3db3a2..898ec30 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 7666d6f..65f0620 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 70335aa..91037c8 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 a641200..d3b609f 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 e750c0a..447a276 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 4c44b00..696f0dc 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 6712410..bb20250a 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 559f546..2964a37 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 e2438a6..177eaf4 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 580c06d..a0a9089 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 1618e7e..1253831 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 a1c17b8..46b0335 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 80927ad..be16393 100644
--- a/lld/test/ELF/arm-thunk-largesection.s
+++ b/lld/test/ELF/arm-thunk-largesection.s
@@ -15,6 +15,13 @@
// 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
.balign 0x1000
.thumb
diff --git a/lld/test/ELF/arm-thunk-linkerscript-dotexpr.s b/lld/test/ELF/arm-thunk-linkerscript-dotexpr.s
index 9514560..21849aa 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 f18861b..131ab41 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 cf19d0c..dbd8334 100644
--- a/lld/test/ELF/arm-thunk-nosuitable.s
+++ b/lld/test/ELF/arm-thunk-nosuitable.s
@@ -6,6 +6,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
/// section. This will need a thunk section created within range.
diff --git a/lld/test/ELF/arm-thunk-re-add.s b/lld/test/ELF/arm-thunk-re-add.s
index 996552b..3fa8760 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 67993a9..f6815da 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 227f164..c6c0580 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 e038357..f91c4a4 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 85a675d..bd4b9ad 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 3ab1033..b061bbb 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 7622780..94dccd9 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