summaryrefslogtreecommitdiffstats
path: root/clang/lib/Driver/ToolChains/Gnu.cpp
diff options
context:
space:
mode:
authorPeter Smith <peter.smith@linaro.org>2018-10-16 09:21:17 +0000
committerPeter Smith <peter.smith@linaro.org>2018-10-16 09:21:17 +0000
commite75b6d78e0f90c1bdcf16d59fdacbbc0ffe6ec4a (patch)
tree9032adfd39bd7bb9385095220592a1d5a3544721 /clang/lib/Driver/ToolChains/Gnu.cpp
parent87de55ad01a092164f77f12f8aaccb0c5d7f6a7b (diff)
downloadbcm5719-llvm-e75b6d78e0f90c1bdcf16d59fdacbbc0ffe6ec4a.tar.gz
bcm5719-llvm-e75b6d78e0f90c1bdcf16d59fdacbbc0ffe6ec4a.zip
[ARM][AArch64] Pass through endian flags to assembler and linker.
The big-endian arm32 Linux builds are currently failing when the -mbig-endian flag is used but the binutils default on the system is little endian. This also holds when -mlittle-endian is used and the binutils default is big endian. The patch always passes through -EL or -BE to the assembler and linker, taking into account the target and the -mbig-endian and -mlittle-endian flag. Fixes pr38770 Differential Revision: https://reviews.llvm.org/D52784 llvm-svn: 344597
Diffstat (limited to 'clang/lib/Driver/ToolChains/Gnu.cpp')
-rw-r--r--clang/lib/Driver/ToolChains/Gnu.cpp38
1 files changed, 34 insertions, 4 deletions
diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp
index b8b69e71f7d..f850f8e8f52 100644
--- a/clang/lib/Driver/ToolChains/Gnu.cpp
+++ b/clang/lib/Driver/ToolChains/Gnu.cpp
@@ -228,6 +228,29 @@ void tools::gcc::Linker::RenderExtraToolArgs(const JobAction &JA,
// The types are (hopefully) good enough.
}
+// On Arm the endianness of the output file is determined by the target and
+// can be overridden by the pseudo-target flags '-mlittle-endian'/'-EL' and
+// '-mbig-endian'/'-EB'. Unlike other targets the flag does not result in a
+// normalized triple so we must handle the flag here.
+static bool isArmBigEndian(const llvm::Triple &Triple,
+ const ArgList &Args) {
+ bool IsBigEndian = false;
+ switch (Triple.getArch()) {
+ case llvm::Triple::armeb:
+ case llvm::Triple::thumbeb:
+ IsBigEndian = true;
+ case llvm::Triple::arm:
+ case llvm::Triple::thumb:
+ if (Arg *A = Args.getLastArg(options::OPT_mlittle_endian,
+ options::OPT_mbig_endian))
+ IsBigEndian = !A->getOption().matches(options::OPT_mlittle_endian);
+ break;
+ default:
+ break;
+ }
+ return IsBigEndian;
+}
+
static const char *getLDMOption(const llvm::Triple &T, const ArgList &Args) {
switch (T.getArch()) {
case llvm::Triple::x86:
@@ -240,10 +263,9 @@ static const char *getLDMOption(const llvm::Triple &T, const ArgList &Args) {
return "aarch64linuxb";
case llvm::Triple::arm:
case llvm::Triple::thumb:
- return "armelf_linux_eabi";
case llvm::Triple::armeb:
case llvm::Triple::thumbeb:
- return "armelfb_linux_eabi";
+ return isArmBigEndian(T, Args) ? "armelfb_linux_eabi" : "armelf_linux_eabi";
case llvm::Triple::ppc:
return "elf32ppclinux";
case llvm::Triple::ppc64:
@@ -337,8 +359,13 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA,
if (Args.hasArg(options::OPT_s))
CmdArgs.push_back("-s");
- if (Arch == llvm::Triple::armeb || Arch == llvm::Triple::thumbeb)
- arm::appendEBLinkFlags(Args, CmdArgs, Triple);
+ if (Triple.isARM() || Triple.isThumb() || Triple.isAArch64()) {
+ bool IsBigEndian = isArmBigEndian(Triple, Args);
+ if (IsBigEndian)
+ arm::appendBE8LinkFlag(Args, CmdArgs, Triple);
+ IsBigEndian = IsBigEndian || Arch == llvm::Triple::aarch64_be;
+ CmdArgs.push_back(IsBigEndian ? "-EB" : "-EL");
+ }
// Most Android ARM64 targets should enable the linker fix for erratum
// 843419. Only non-Cortex-A53 devices are allowed to skip this flag.
@@ -640,6 +667,7 @@ void tools::gnutools::Assembler::ConstructJob(Compilation &C,
case llvm::Triple::thumb:
case llvm::Triple::thumbeb: {
const llvm::Triple &Triple2 = getToolChain().getTriple();
+ CmdArgs.push_back(isArmBigEndian(Triple2, Args) ? "-EB" : "-EL");
switch (Triple2.getSubArch()) {
case llvm::Triple::ARMSubArch_v7:
CmdArgs.push_back("-mfpu=neon");
@@ -672,6 +700,8 @@ void tools::gnutools::Assembler::ConstructJob(Compilation &C,
}
case llvm::Triple::aarch64:
case llvm::Triple::aarch64_be: {
+ CmdArgs.push_back(
+ getToolChain().getArch() == llvm::Triple::aarch64_be ? "-EB" : "-EL");
Args.AddLastArg(CmdArgs, options::OPT_march_EQ);
normalizeCPUNamesForAssembler(Args, CmdArgs);
OpenPOWER on IntegriCloud