arm64: asm: Provide a mechanism for generating ELF note for BTI
authorMark Brown <broonie@kernel.org>
Wed, 6 May 2020 19:51:35 +0000 (20:51 +0100)
committerWill Deacon <will@kernel.org>
Thu, 7 May 2020 16:53:20 +0000 (17:53 +0100)
ELF files built for BTI should have a program property note section which
identifies them as such. The linker expects to find this note in all
object files it is linking into a BTI annotated output, the compiler will
ensure that this happens for C files but for assembler files we need to do
this in the source so provide a macro which can be used for this purpose.
To support likely future requirements for additional notes we split the
defininition of the flags to set for BTI code from the macro that creates
the note itself.

This is mainly for use in the vDSO which should be a normal ELF shared
library and should therefore include BTI annotations when built for BTI.

Signed-off-by: Mark Brown <broonie@kernel.org>
Link: https://lore.kernel.org/r/20200506195138.22086-9-broonie@kernel.org
Signed-off-by: Will Deacon <will@kernel.org>
arch/arm64/include/asm/assembler.h

index 0bff325..54d1811 100644 (file)
@@ -736,4 +736,54 @@ USER(\label, ic    ivau, \tmp2)                    // invalidate I line PoU
 .Lyield_out_\@ :
        .endm
 
+/*
+ * This macro emits a program property note section identifying
+ * architecture features which require special handling, mainly for
+ * use in assembly files included in the VDSO.
+ */
+
+#define NT_GNU_PROPERTY_TYPE_0  5
+#define GNU_PROPERTY_AARCH64_FEATURE_1_AND      0xc0000000
+
+#define GNU_PROPERTY_AARCH64_FEATURE_1_BTI      (1U << 0)
+#define GNU_PROPERTY_AARCH64_FEATURE_1_PAC      (1U << 1)
+
+#ifdef CONFIG_ARM64_BTI_KERNEL
+#define GNU_PROPERTY_AARCH64_FEATURE_1_DEFAULT         \
+               ((GNU_PROPERTY_AARCH64_FEATURE_1_BTI |  \
+                 GNU_PROPERTY_AARCH64_FEATURE_1_PAC))
+#endif
+
+#ifdef GNU_PROPERTY_AARCH64_FEATURE_1_DEFAULT
+.macro emit_aarch64_feature_1_and, feat=GNU_PROPERTY_AARCH64_FEATURE_1_DEFAULT
+       .pushsection .note.gnu.property, "a"
+       .align  3
+       .long   2f - 1f
+       .long   6f - 3f
+       .long   NT_GNU_PROPERTY_TYPE_0
+1:      .string "GNU"
+2:
+       .align  3
+3:      .long   GNU_PROPERTY_AARCH64_FEATURE_1_AND
+       .long   5f - 4f
+4:
+       /*
+        * This is described with an array of char in the Linux API
+        * spec but the text and all other usage (including binutils,
+        * clang and GCC) treat this as a 32 bit value so no swizzling
+        * is required for big endian.
+        */
+       .long   \feat
+5:
+       .align  3
+6:
+       .popsection
+.endm
+
+#else
+.macro emit_aarch64_feature_1_and, feat=0
+.endm
+
+#endif /* GNU_PROPERTY_AARCH64_FEATURE_1_DEFAULT */
+
 #endif /* __ASM_ASSEMBLER_H */