diff options
author | Peter Smith <peter.smith@linaro.org> | 2018-10-16 09:21:17 +0000 |
---|---|---|
committer | Peter Smith <peter.smith@linaro.org> | 2018-10-16 09:21:17 +0000 |
commit | e75b6d78e0f90c1bdcf16d59fdacbbc0ffe6ec4a (patch) | |
tree | 9032adfd39bd7bb9385095220592a1d5a3544721 /clang/lib/Driver | |
parent | 87de55ad01a092164f77f12f8aaccb0c5d7f6a7b (diff) | |
download | bcm5719-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')
-rw-r--r-- | clang/lib/Driver/ToolChains/Arch/ARM.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Driver/ToolChains/Arch/ARM.h | 2 | ||||
-rw-r--r-- | clang/lib/Driver/ToolChains/Gnu.cpp | 38 | ||||
-rw-r--r-- | clang/lib/Driver/ToolChains/NetBSD.cpp | 2 |
4 files changed, 37 insertions, 7 deletions
diff --git a/clang/lib/Driver/ToolChains/Arch/ARM.cpp b/clang/lib/Driver/ToolChains/Arch/ARM.cpp index e454a30b61a..f55efc1a22e 100644 --- a/clang/lib/Driver/ToolChains/Arch/ARM.cpp +++ b/clang/lib/Driver/ToolChains/Arch/ARM.cpp @@ -643,7 +643,7 @@ StringRef arm::getLLVMArchSuffixForARM(StringRef CPU, StringRef Arch, return llvm::ARM::getSubArch(ArchKind); } -void arm::appendEBLinkFlags(const ArgList &Args, ArgStringList &CmdArgs, +void arm::appendBE8LinkFlag(const ArgList &Args, ArgStringList &CmdArgs, const llvm::Triple &Triple) { if (Args.hasArg(options::OPT_r)) return; diff --git a/clang/lib/Driver/ToolChains/Arch/ARM.h b/clang/lib/Driver/ToolChains/Arch/ARM.h index c1dc1688403..9f0dc4ea2e2 100644 --- a/clang/lib/Driver/ToolChains/Arch/ARM.h +++ b/clang/lib/Driver/ToolChains/Arch/ARM.h @@ -29,7 +29,7 @@ StringRef getARMCPUForMArch(llvm::StringRef Arch, const llvm::Triple &Triple); StringRef getLLVMArchSuffixForARM(llvm::StringRef CPU, llvm::StringRef Arch, const llvm::Triple &Triple); -void appendEBLinkFlags(const llvm::opt::ArgList &Args, +void appendBE8LinkFlag(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs, const llvm::Triple &Triple); enum class ReadTPMode { 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); diff --git a/clang/lib/Driver/ToolChains/NetBSD.cpp b/clang/lib/Driver/ToolChains/NetBSD.cpp index 02caafda165..73e230b3ea4 100644 --- a/clang/lib/Driver/ToolChains/NetBSD.cpp +++ b/clang/lib/Driver/ToolChains/NetBSD.cpp @@ -164,7 +164,7 @@ void netbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA, break; case llvm::Triple::armeb: case llvm::Triple::thumbeb: - arm::appendEBLinkFlags(Args, CmdArgs, ToolChain.getEffectiveTriple()); + arm::appendBE8LinkFlag(Args, CmdArgs, ToolChain.getEffectiveTriple()); CmdArgs.push_back("-m"); switch (ToolChain.getTriple().getEnvironment()) { case llvm::Triple::EABI: |