From owner-svn-src-head@freebsd.org Tue Jul 31 15:25:04 2018 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 7EE81105CAF5; Tue, 31 Jul 2018 15:25:04 +0000 (UTC) (envelope-from emaste@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 31BFE8EA79; Tue, 31 Jul 2018 15:25:04 +0000 (UTC) (envelope-from emaste@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 0E95A15696; Tue, 31 Jul 2018 15:25:04 +0000 (UTC) (envelope-from emaste@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w6VFP36D058212; Tue, 31 Jul 2018 15:25:03 GMT (envelope-from emaste@FreeBSD.org) Received: (from emaste@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w6VFP3vm058210; Tue, 31 Jul 2018 15:25:03 GMT (envelope-from emaste@FreeBSD.org) Message-Id: <201807311525.w6VFP3vm058210@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: emaste set sender to emaste@FreeBSD.org using -f From: Ed Maste Date: Tue, 31 Jul 2018 15:25:03 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r336972 - in head/contrib/llvm/tools/lld/ELF: . Arch X-SVN-Group: head X-SVN-Commit-Author: emaste X-SVN-Commit-Paths: in head/contrib/llvm/tools/lld/ELF: . Arch X-SVN-Commit-Revision: 336972 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.27 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 31 Jul 2018 15:25:04 -0000 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::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::createInputSection(co ArrayRef 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.