diff options
author | Ed Maste <emaste@FreeBSD.org> | 2018-07-31 15:25:03 +0000 |
---|---|---|
committer | Ed Maste <emaste@FreeBSD.org> | 2018-07-31 15:25:03 +0000 |
commit | fd12f2aaebd2d15445528155c562340ef299b193 (patch) | |
tree | dea7536a7dd56baa0cd1bf7b4cbe8a95bcb27d0c /contrib | |
parent | 100a6d1905b1bb510020e6fe3a535ebf5fc395e8 (diff) | |
download | src-fd12f2aaebd2d15445528155c562340ef299b193.tar.gz src-fd12f2aaebd2d15445528155c562340ef299b193.zip |
Notes
Diffstat (limited to 'contrib')
-rw-r--r-- | contrib/llvm/tools/lld/ELF/Arch/ARM.cpp | 11 | ||||
-rw-r--r-- | contrib/llvm/tools/lld/ELF/Config.h | 4 | ||||
-rw-r--r-- | contrib/llvm/tools/lld/ELF/InputFiles.cpp | 42 |
3 files changed, 56 insertions, 1 deletions
diff --git a/contrib/llvm/tools/lld/ELF/Arch/ARM.cpp b/contrib/llvm/tools/lld/ELF/Arch/ARM.cpp index b9f551e4b3be..fc2ac9beef9c 100644 --- a/contrib/llvm/tools/lld/ELF/Arch/ARM.cpp +++ b/contrib/llvm/tools/lld/ELF/Arch/ARM.cpp @@ -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, diff --git a/contrib/llvm/tools/lld/ELF/Config.h b/contrib/llvm/tools/lld/ELF/Config.h index 1f244df4d652..d705f11bf626 100644 --- a/contrib/llvm/tools/lld/ELF/Config.h +++ b/contrib/llvm/tools/lld/ELF/Config.h @@ -54,6 +54,9 @@ enum class SortSectionPolicy { Default, None, Alignment, Name, Priority }; // 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; diff --git a/contrib/llvm/tools/lld/ELF/InputFiles.cpp b/contrib/llvm/tools/lld/ELF/InputFiles.cpp index 52c65dd8ee70..dfd5bbf1e0fc 100644 --- a/contrib/llvm/tools/lld/ELF/InputFiles.cpp +++ b/contrib/llvm/tools/lld/ELF/InputFiles.cpp @@ -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(const Elf_Shdr &Sec) { 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. |