[lld] r338377 - [ELF][ARM] Implement support for Tag_ABI_VFP_args
Peter Smith via llvm-commits
llvm-commits at lists.llvm.org
Tue Jul 31 06:41:59 PDT 2018
Author: psmith
Date: Tue Jul 31 06:41:59 2018
New Revision: 338377
URL: http://llvm.org/viewvc/llvm-project?rev=338377&view=rev
Log:
[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 PR36009
Differential Revision: https://reviews.llvm.org/D49993
Added:
lld/trunk/test/ELF/Inputs/arm-vfp-arg-base.s
lld/trunk/test/ELF/Inputs/arm-vfp-arg-compat.s
lld/trunk/test/ELF/Inputs/arm-vfp-arg-toolchain.s
lld/trunk/test/ELF/Inputs/arm-vfp-arg-vfp.s
lld/trunk/test/ELF/arm-tag-vfp-args-errs.s
lld/trunk/test/ELF/arm-tag-vfp-args-illegal.s
lld/trunk/test/ELF/arm-tag-vfp-args.s
Modified:
lld/trunk/ELF/Arch/ARM.cpp
lld/trunk/ELF/Config.h
lld/trunk/ELF/InputFiles.cpp
lld/trunk/test/ELF/arm-eabi-version.s
Modified: lld/trunk/ELF/Arch/ARM.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Arch/ARM.cpp?rev=338377&r1=338376&r2=338377&view=diff
==============================================================================
--- lld/trunk/ELF/Arch/ARM.cpp (original)
+++ lld/trunk/ELF/Arch/ARM.cpp Tue Jul 31 06:41:59 2018
@@ -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: lld/trunk/ELF/Config.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Config.h?rev=338377&r1=338376&r2=338377&view=diff
==============================================================================
--- lld/trunk/ELF/Config.h (original)
+++ lld/trunk/ELF/Config.h Tue Jul 31 06:41:59 2018
@@ -58,6 +58,9 @@ enum class SortSectionPolicy { Default,
// 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;
@@ -196,6 +199,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: lld/trunk/ELF/InputFiles.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.cpp?rev=338377&r1=338376&r2=338377&view=diff
==============================================================================
--- lld/trunk/ELF/InputFiles.cpp (original)
+++ lld/trunk/ELF/InputFiles.cpp Tue Jul 31 06:41:59 2018
@@ -494,6 +494,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.
@@ -573,6 +613,8 @@ InputSectionBase *ObjFile<ELFT>::createI
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.
Added: lld/trunk/test/ELF/Inputs/arm-vfp-arg-base.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/Inputs/arm-vfp-arg-base.s?rev=338377&view=auto
==============================================================================
--- lld/trunk/test/ELF/Inputs/arm-vfp-arg-base.s (added)
+++ lld/trunk/test/ELF/Inputs/arm-vfp-arg-base.s Tue Jul 31 06:41:59 2018
@@ -0,0 +1,16 @@
+ .arch armv7-a
+ .eabi_attribute 20, 1
+ .eabi_attribute 21, 1
+ .eabi_attribute 23, 3
+ .eabi_attribute 24, 1
+ .eabi_attribute 25, 1
+ .eabi_attribute 26, 2
+ .eabi_attribute 30, 6
+ .eabi_attribute 34, 1
+ .eabi_attribute 18, 4
+ .eabi_attribute 28, 0 // Tag_ABI_VFP_args = 0 (AAPCS, Base variant)
+
+ .syntax unified
+ .global f0
+ .type f0, %function
+f0: bx lr
Added: lld/trunk/test/ELF/Inputs/arm-vfp-arg-compat.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/Inputs/arm-vfp-arg-compat.s?rev=338377&view=auto
==============================================================================
--- lld/trunk/test/ELF/Inputs/arm-vfp-arg-compat.s (added)
+++ lld/trunk/test/ELF/Inputs/arm-vfp-arg-compat.s Tue Jul 31 06:41:59 2018
@@ -0,0 +1,16 @@
+ .arch armv7-a
+ .eabi_attribute 20, 1
+ .eabi_attribute 21, 1
+ .eabi_attribute 23, 3
+ .eabi_attribute 24, 1
+ .eabi_attribute 25, 1
+ .eabi_attribute 26, 2
+ .eabi_attribute 30, 6
+ .eabi_attribute 34, 1
+ .eabi_attribute 18, 4
+ .eabi_attribute 28, 3 // Tag_ABI_VFP_args = 3 (Compatible with all)
+
+ .syntax unified
+ .global f3
+ .type f3, %function
+f3: bx lr
Added: lld/trunk/test/ELF/Inputs/arm-vfp-arg-toolchain.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/Inputs/arm-vfp-arg-toolchain.s?rev=338377&view=auto
==============================================================================
--- lld/trunk/test/ELF/Inputs/arm-vfp-arg-toolchain.s (added)
+++ lld/trunk/test/ELF/Inputs/arm-vfp-arg-toolchain.s Tue Jul 31 06:41:59 2018
@@ -0,0 +1,15 @@
+ .arch armv7-a
+ .eabi_attribute 20, 1
+ .eabi_attribute 21, 1
+ .eabi_attribute 23, 3
+ .eabi_attribute 24, 1
+ .eabi_attribute 25, 1
+ .eabi_attribute 26, 2
+ .eabi_attribute 30, 6
+ .eabi_attribute 34, 1
+ .eabi_attribute 18, 4
+ .eabi_attribute 28, 2 // Tag_ABI_VFP_args = 2 (Toolchain specific)
+ .syntax unified
+ .global f2
+ .type f1, %function
+f2: bx lr
Added: lld/trunk/test/ELF/Inputs/arm-vfp-arg-vfp.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/Inputs/arm-vfp-arg-vfp.s?rev=338377&view=auto
==============================================================================
--- lld/trunk/test/ELF/Inputs/arm-vfp-arg-vfp.s (added)
+++ lld/trunk/test/ELF/Inputs/arm-vfp-arg-vfp.s Tue Jul 31 06:41:59 2018
@@ -0,0 +1,15 @@
+ .arch armv7-a
+ .eabi_attribute 20, 1
+ .eabi_attribute 21, 1
+ .eabi_attribute 23, 3
+ .eabi_attribute 24, 1
+ .eabi_attribute 25, 1
+ .eabi_attribute 26, 2
+ .eabi_attribute 30, 6
+ .eabi_attribute 34, 1
+ .eabi_attribute 18, 4
+ .eabi_attribute 28, 1 // Tag_ABI_VFP_args = 1 (AAPCS, VFP variant)
+ .syntax unified
+ .global f1
+ .type f1, %function
+f1: bx lr
Modified: lld/trunk/test/ELF/arm-eabi-version.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/arm-eabi-version.s?rev=338377&r1=338376&r2=338377&view=diff
==============================================================================
--- lld/trunk/test/ELF/arm-eabi-version.s (original)
+++ lld/trunk/test/ELF/arm-eabi-version.s Tue Jul 31 06:41:59 2018
@@ -9,6 +9,7 @@ _start:
bx lr
// CHECK: Flags [
+// CHECK-NEXT: 0x200
// CHECK-NEXT: 0x1000000
// CHECK-NEXT: 0x4000000
// CHECK-NEXT: ]
Added: lld/trunk/test/ELF/arm-tag-vfp-args-errs.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/arm-tag-vfp-args-errs.s?rev=338377&view=auto
==============================================================================
--- lld/trunk/test/ELF/arm-tag-vfp-args-errs.s (added)
+++ lld/trunk/test/ELF/arm-tag-vfp-args-errs.s Tue Jul 31 06:41:59 2018
@@ -0,0 +1,29 @@
+// REQUIRES:arm
+// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/arm-vfp-arg-base.s -o %tbase.o
+// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/arm-vfp-arg-vfp.s -o %tvfp.o
+// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/arm-vfp-arg-toolchain.s -o %ttoolchain.o
+// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o
+// RUN: not ld.lld %t.o %tbase.o %tvfp.o 2>&1 | FileCheck %s
+// RUN: not ld.lld %t.o %tbase.o %ttoolchain.o 2>&1 | FileCheck %s
+// RUN: not ld.lld %t.o %tvfp.o %tbase.o 2>&1 | FileCheck %s
+// RUN: not ld.lld %t.o %tvfp.o %ttoolchain.o 2>&1 | FileCheck %s
+// RUN: not ld.lld %t.o %ttoolchain.o %tbase.o 2>&1 | FileCheck %s
+// RUN: not ld.lld %t.o %ttoolchain.o %tvfp.o 2>&1 | FileCheck %s
+
+// CHECK: incompatible Tag_ABI_VFP_args
+ .arch armv7-a
+ .eabi_attribute 20, 1
+ .eabi_attribute 21, 1
+ .eabi_attribute 23, 3
+ .eabi_attribute 24, 1
+ .eabi_attribute 25, 1
+ .eabi_attribute 26, 2
+ .eabi_attribute 30, 6
+ .eabi_attribute 34, 1
+ .eabi_attribute 18, 4
+ .eabi_attribute 28, 3 // Tag_ABI_VFP_args = 3 (Compatible with all)
+
+ .syntax unified
+ .globl _start
+ .type _start, %function
+_start: bx lr
Added: lld/trunk/test/ELF/arm-tag-vfp-args-illegal.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/arm-tag-vfp-args-illegal.s?rev=338377&view=auto
==============================================================================
--- lld/trunk/test/ELF/arm-tag-vfp-args-illegal.s (added)
+++ lld/trunk/test/ELF/arm-tag-vfp-args-illegal.s Tue Jul 31 06:41:59 2018
@@ -0,0 +1,21 @@
+// REQUIRES:arm
+// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o
+// RUN: not ld.lld %t.o -o %t 2>&1 | FileCheck %s
+
+// CHECK: arm-tag-vfp-args-illegal.s.tmp.o: unknown Tag_ABI_VFP_args value: 5
+ .arch armv7-a
+ .eabi_attribute 20, 1
+ .eabi_attribute 21, 1
+ .eabi_attribute 23, 3
+ .eabi_attribute 24, 1
+ .eabi_attribute 25, 1
+ .eabi_attribute 26, 2
+ .eabi_attribute 30, 6
+ .eabi_attribute 34, 1
+ .eabi_attribute 18, 4
+ .eabi_attribute 28, 5 // Tag_ABI_VFP_args = 5 (Illegal value)
+
+ .syntax unified
+ .globl _start
+ .type _start, %function
+_start: bx lr
Added: lld/trunk/test/ELF/arm-tag-vfp-args.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/arm-tag-vfp-args.s?rev=338377&view=auto
==============================================================================
--- lld/trunk/test/ELF/arm-tag-vfp-args.s (added)
+++ lld/trunk/test/ELF/arm-tag-vfp-args.s Tue Jul 31 06:41:59 2018
@@ -0,0 +1,72 @@
+// REQUIRES:arm
+// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/arm-vfp-arg-base.s -o %tbase.o
+// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/arm-vfp-arg-vfp.s -o %tvfp.o
+// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/arm-vfp-arg-toolchain.s -o %ttoolchain.o
+// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/arm-vfp-arg-compat.s -o %tcompat.o
+// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o
+
+// The default for this file is 0 (Base AAPCS)
+// RUN: ld.lld %t.o -o %tdefault
+// RUN: llvm-readobj -file-headers %tdefault | FileCheck -check-prefix=CHECK-BASE %s
+
+// Expect explicit Base AAPCS.
+// RUN: ld.lld %t.o %tbase.o -o %tbase
+// RUN: llvm-readobj -file-headers %tbase | FileCheck -check-prefix=CHECK-BASE %s
+
+// Expect explicit Base AAPCS when linking Base and Compatible.
+// RUN: ld.lld %t.o %tbase.o %tcompat.o -o %tbasecompat
+// RUN: llvm-readobj -file-headers %tbasecompat | FileCheck -check-prefix=CHECK-BASE %s
+
+// CHECK-BASE: Flags [ (0x5000200)
+// CHECK-BASE-NEXT: 0x200
+// CHECK-BASE-NEXT: 0x1000000
+// CHECK-BASE-NEXT: 0x4000000
+// CHECK-BASE-NEXT: ]
+
+// Expect Hard float VFP AAPCS
+// RUN: ld.lld %t.o %tvfp.o -o %tvfp
+// RUN: llvm-readobj -file-headers %tvfp | FileCheck -check-prefix=CHECK-VFP %s
+
+// Expect Hard float VFP AAPCS when linking VFP and Compatible
+// RUN: ld.lld %t.o %tvfp.o %tcompat.o -o %tvfpcompat
+// RUN: llvm-readobj -file-headers %tvfpcompat | FileCheck -check-prefix=CHECK-VFP %s
+
+// CHECK-VFP: Flags [ (0x5000400)
+// CHECK-VFP-NEXT: 0x400
+// CHECK-VFP-NEXT: 0x1000000
+// CHECK-VFP-NEXT: 0x4000000
+// CHECK-VFP-NEXT: ]
+
+// Expect Toolchain specifc to not use either Base or VFP AAPCS
+// RUN: ld.lld %t.o %ttoolchain.o -o %ttoolchain
+// RUN: llvm-readobj -file-headers %ttoolchain | FileCheck -check-prefix=CHECK-TOOLCHAIN %s
+
+// Expect Toolchain and Compatible to have same affect as Toolchain.
+// RUN: ld.lld %t.o %ttoolchain.o %tcompat.o -o %ttoolchaincompat
+// RUN: llvm-readobj -file-headers %ttoolchaincompat | FileCheck -check-prefix=CHECK-TOOLCHAIN %s
+
+// CHECK-TOOLCHAIN: Flags [ (0x5000000)
+// CHECK-TOOLCHAIN-NEXT: 0x1000000
+// CHECK-TOOLCHAIN-NEXT: 0x4000000
+// CHECK-TOOLCHAIN-NEXT: ]
+
+ .arch armv7-a
+ .eabi_attribute 20, 1
+ .eabi_attribute 21, 1
+ .eabi_attribute 23, 3
+ .eabi_attribute 24, 1
+ .eabi_attribute 25, 1
+ .eabi_attribute 26, 2
+ .eabi_attribute 30, 6
+ .eabi_attribute 34, 1
+ .eabi_attribute 18, 4
+ // We do not specify Tag_ABI_VFP_args (.eabi_attribute 28) in this file.
+ // When omitted the value of the tag defaults to 0, however if there
+ // are other files with explicit Tag_ABI_VFP_args we use that in
+ // preference.
+
+
+ .syntax unified
+ .globl _start
+ .type _start, %function
+_start: bx lr
More information about the llvm-commits
mailing list