svn commit: r336972 - in head/contrib/llvm/tools/lld/ELF: . Arch
Ed Maste
emaste at FreeBSD.org
Tue Jul 31 15:25:04 UTC 2018
Author: emaste
Date: Tue Jul 31 15:25:03 2018
New Revision: 336972
URL: https://svnweb.freebsd.org/changeset/base/336972
Log:
lld: [ELF][ARM] Implement support for Tag_ABI_VFP_args
The Tag_ABI_VFP_args build attribute controls the procedure call
standard used for floating point parameters on ARM. The values are:
0 - Base AAPCS (FP Parameters passed in Core (Integer) registers
1 - VFP AAPCS (FP Parameters passed in FP registers)
2 - Toolchain specific (Neither Base or VFP)
3 - Compatible with all (No use of floating point parameters)
If the Tag_ABI_VFP_args build attribute is missing it has an implicit
value of 0.
We use the attribute in two ways:
* Detect a clash in calling convention between Base, VFP and Toolchain.
we follow ld.bfd's lead and do not error if there is a clash between an
implicit Base AAPCS caused by a missing attribute. Many projects
including the hard-float (VFP AAPCS) version of glibc contain assembler
files that do not use floating point but do not have Tag_ABI_VFP_args.
* Set the EF_ARM_ABI_FLOAT_SOFT or EF_ARM_ABI_FLOAT_HARD ELF header flag
for Base or VFP AAPCS respectively. This flag is used by some ELF
loaders.
References:
* Addenda to, and Errata in, the ABI for the ARM Architecture for
Tag_ABI_VFP_args
* Elf for the ARM Architecture for ELF header flags
Fixes LLVM PR36009
PR: 229050
Obtained from: llvm r338377 by Peter Smith
Modified:
head/contrib/llvm/tools/lld/ELF/Arch/ARM.cpp
head/contrib/llvm/tools/lld/ELF/Config.h
head/contrib/llvm/tools/lld/ELF/InputFiles.cpp
Modified: head/contrib/llvm/tools/lld/ELF/Arch/ARM.cpp
==============================================================================
--- head/contrib/llvm/tools/lld/ELF/Arch/ARM.cpp Tue Jul 31 15:08:02 2018 (r336971)
+++ head/contrib/llvm/tools/lld/ELF/Arch/ARM.cpp Tue Jul 31 15:25:03 2018 (r336972)
@@ -97,10 +97,19 @@ ARM::ARM() {
}
uint32_t ARM::calcEFlags() const {
+ // The ABIFloatType is used by loaders to detect the floating point calling
+ // convention.
+ uint32_t ABIFloatType = 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;
+
// 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;
+ return EF_ARM_EABI_VER5 | ABIFloatType;
}
RelExpr ARM::getRelExpr(RelType Type, const Symbol &S,
Modified: head/contrib/llvm/tools/lld/ELF/Config.h
==============================================================================
--- head/contrib/llvm/tools/lld/ELF/Config.h Tue Jul 31 15:08:02 2018 (r336971)
+++ head/contrib/llvm/tools/lld/ELF/Config.h Tue Jul 31 15:25:03 2018 (r336972)
@@ -54,6 +54,9 @@ enum class SortSectionPolicy { Default, None, Alignmen
// For --target2
enum class Target2Policy { Abs, Rel, GotRel };
+// For tracking ARM Float Argument PCS
+enum class ARMVFPArgKind { Default, Base, VFP, ToolChain };
+
struct SymbolVersion {
llvm::StringRef Name;
bool IsExternCpp;
@@ -169,6 +172,7 @@ struct Configuration {
StripPolicy Strip;
UnresolvedPolicy UnresolvedSymbols;
Target2Policy Target2;
+ ARMVFPArgKind ARMVFPArgs = ARMVFPArgKind::Default;
BuildIdKind BuildId = BuildIdKind::None;
ELFKind EKind = ELFNoneKind;
uint16_t DefaultSymbolVersion = llvm::ELF::VER_NDX_GLOBAL;
Modified: head/contrib/llvm/tools/lld/ELF/InputFiles.cpp
==============================================================================
--- head/contrib/llvm/tools/lld/ELF/InputFiles.cpp Tue Jul 31 15:08:02 2018 (r336971)
+++ head/contrib/llvm/tools/lld/ELF/InputFiles.cpp Tue Jul 31 15:25:03 2018 (r336972)
@@ -441,6 +441,46 @@ void ObjFile<ELFT>::initializeSections(
}
}
+// For ARM only, to set the EF_ARM_ABI_FLOAT_SOFT or EF_ARM_ABI_FLOAT_HARD
+// flag in the ELF Header we need to look at Tag_ABI_VFP_args to find out how
+// the input objects have been compiled.
+static void updateARMVFPArgs(const ARMAttributeParser &Attributes,
+ const InputFile *F) {
+ if (!Attributes.hasAttribute(ARMBuildAttrs::ABI_VFP_args))
+ // If an ABI tag isn't present then it is implicitly given the value of 0
+ // which maps to ARMBuildAttrs::BaseAAPCS. However many assembler files,
+ // including some in glibc that don't use FP args (and should have value 3)
+ // don't have the attribute so we do not consider an implicit value of 0
+ // as a clash.
+ return;
+
+ unsigned VFPArgs = Attributes.getAttributeValue(ARMBuildAttrs::ABI_VFP_args);
+ ARMVFPArgKind Arg;
+ switch (VFPArgs) {
+ case ARMBuildAttrs::BaseAAPCS:
+ Arg = ARMVFPArgKind::Base;
+ break;
+ case ARMBuildAttrs::HardFPAAPCS:
+ Arg = ARMVFPArgKind::VFP;
+ break;
+ case ARMBuildAttrs::ToolChainFPPCS:
+ // Tool chain specific convention that conforms to neither AAPCS variant.
+ Arg = ARMVFPArgKind::ToolChain;
+ break;
+ case ARMBuildAttrs::CompatibleFPAAPCS:
+ // Object compatible with all conventions.
+ return;
+ default:
+ error(toString(F) + ": unknown Tag_ABI_VFP_args value: " + Twine(VFPArgs));
+ return;
+ }
+ // Follow ld.bfd and error if there is a mix of calling conventions.
+ if (Config->ARMVFPArgs != Arg && Config->ARMVFPArgs != ARMVFPArgKind::Default)
+ error(toString(F) + ": incompatible Tag_ABI_VFP_args");
+ else
+ Config->ARMVFPArgs = Arg;
+}
+
// The ARM support in lld makes some use of instructions that are not available
// on all ARM architectures. Namely:
// - Use of BLX instruction for interworking between ARM and Thumb state.
@@ -520,6 +560,8 @@ InputSectionBase *ObjFile<ELFT>::createInputSection(co
ArrayRef<uint8_t> Contents = check(this->getObj().getSectionContents(&Sec));
Attributes.Parse(Contents, /*isLittle*/ Config->EKind == ELF32LEKind);
updateSupportedARMFeatures(Attributes);
+ updateARMVFPArgs(Attributes, this);
+
// FIXME: Retain the first attribute section we see. The eglibc ARM
// dynamic loaders require the presence of an attribute section for dlopen
// to work. In a full implementation we would merge all attribute sections.
More information about the svn-src-all
mailing list