diff options
Diffstat (limited to 'devel/llvm60/files/lld/patch-head-r336972.diff')
-rw-r--r-- | devel/llvm60/files/lld/patch-head-r336972.diff | 146 |
1 files changed, 146 insertions, 0 deletions
diff --git a/devel/llvm60/files/lld/patch-head-r336972.diff b/devel/llvm60/files/lld/patch-head-r336972.diff new file mode 100644 index 000000000000..d7497ce5390a --- /dev/null +++ b/devel/llvm60/files/lld/patch-head-r336972.diff @@ -0,0 +1,146 @@ +r336972 | emaste | 2018-07-31 17:25:03 +0200 (Tue, 31 Jul 2018) | 37 lines + +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 + +Index: tools/lld/ELF/Arch/ARM.cpp +=================================================================== +--- tools/lld/ELF/Arch/ARM.cpp (revision 336971) ++++ tools/lld/ELF/Arch/ARM.cpp (revision 336972) +@@ -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, +Index: tools/lld/ELF/Config.h +=================================================================== +--- tools/lld/ELF/Config.h (revision 336971) ++++ tools/lld/ELF/Config.h (revision 336972) +@@ -54,6 +54,9 @@ enum class SortSectionPolicy { Default, None, Alig + // 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; +Index: tools/lld/ELF/InputFiles.cpp +=================================================================== +--- tools/lld/ELF/InputFiles.cpp (revision 336971) ++++ tools/lld/ELF/InputFiles.cpp (revision 336972) +@@ -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>::createInputSectio + 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. |