From 644e0b094d211cd0e43feb03dc4252ef4ff205c1 Mon Sep 17 00:00:00 2001
From: Ryan Long <ryan.long@oarcorp.com>
Date: Fri, 10 Sep 2021 17:25:54 -0400
Subject: [PATCH] aarch64: Add ILP32 ABI support in assembly

This adds sanitation of the padding bits of pointers and size_t types as
required by ARM aapcs64 for the AArch64 ILP32 ABI.
---
 newlib/libc/machine/aarch64/memchr.S    |  4 ++
 newlib/libc/machine/aarch64/memcmp.S    |  5 ++
 newlib/libc/machine/aarch64/memcpy.S    |  5 ++
 newlib/libc/machine/aarch64/memset.S    |  4 ++
 newlib/libc/machine/aarch64/setjmp.S    |  4 ++
 newlib/libc/machine/aarch64/strchr.S    |  3 ++
 newlib/libc/machine/aarch64/strchrnul.S |  3 ++
 newlib/libc/machine/aarch64/strcmp.S    |  4 ++
 newlib/libc/machine/aarch64/strcpy.S    |  4 ++
 newlib/libc/machine/aarch64/strlen.S    |  3 ++
 newlib/libc/machine/aarch64/strncmp.S   |  5 ++
 newlib/libc/machine/aarch64/strnlen.S   |  4 ++
 newlib/libc/machine/aarch64/strrchr.S   |  3 ++
 newlib/libc/machine/asmdefs.h           | 96 +++++++++++++++++++++++++++++++++
 14 files changed, 147 insertions(+)
 create mode 100644 newlib/libc/machine/asmdefs.h

diff --git a/newlib/libc/machine/aarch64/memchr.S b/newlib/libc/machine/aarch64/memchr.S
index 53f5d6b..18cee01 100644
--- a/newlib/libc/machine/aarch64/memchr.S
+++ b/newlib/libc/machine/aarch64/memchr.S
@@ -37,6 +37,8 @@
  * Neon Available.
  */
 
+#include "../asmdefs.h"
+
 /* Arguments and results.  */
 #define srcin		x0
 #define chrin		w1
@@ -79,6 +81,8 @@
 	.endm
 
 def_fn memchr
+  PTR_ARG (0)
+  SIZE_ARG (2)
 	/* Do not dereference srcin if no bytes to compare.  */
 	cbz	cntin, .Lzero_length
 	/*
diff --git a/newlib/libc/machine/aarch64/memcmp.S b/newlib/libc/machine/aarch64/memcmp.S
index 605d993..021ba62 100644
--- a/newlib/libc/machine/aarch64/memcmp.S
+++ b/newlib/libc/machine/aarch64/memcmp.S
@@ -63,6 +63,8 @@
  * ARMv8-a, AArch64, unaligned accesses.
  */
 
+#include "../asmdefs.h"
+
 #define L(l) .L ## l
 
 /* Parameters and result.  */
@@ -90,6 +92,9 @@
         .endm
 
 def_fn memcmp p2align=6
+	PTR_ARG (0)
+	PTR_ARG (1)
+	SIZE_ARG (2)
 	subs	limit, limit, 8
 	b.lo	L(less8)
 
diff --git a/newlib/libc/machine/aarch64/memcpy.S b/newlib/libc/machine/aarch64/memcpy.S
index 463bad0..5d87243 100644
--- a/newlib/libc/machine/aarch64/memcpy.S
+++ b/newlib/libc/machine/aarch64/memcpy.S
@@ -62,6 +62,8 @@
 /* See memcpy-stub.c  */
 #else
 
+#include "../asmdefs.h"
+
 #define dstin	x0
 #define src	x1
 #define count	x2
@@ -105,6 +107,9 @@
 */
 
 def_fn memcpy p2align=6
+	PTR_ARG (0)
+	PTR_ARG (1)
+	SIZE_ARG (2)
 	prfm	PLDL1KEEP, [src]
 	add	srcend, src, count
 	add	dstend, dstin, count
diff --git a/newlib/libc/machine/aarch64/memset.S b/newlib/libc/machine/aarch64/memset.S
index 103e3f8..1ba87d8 100644
--- a/newlib/libc/machine/aarch64/memset.S
+++ b/newlib/libc/machine/aarch64/memset.S
@@ -62,6 +62,8 @@
 /* See memset-stub.c  */
 #else
 
+#include "../asmdefs.h"
+
 #define dstin	x0
 #define val	x1
 #define valw	w1
@@ -86,6 +88,8 @@
 	.endm
 
 def_fn memset p2align=6
+	PTR_ARG (0)
+	SIZE_ARG (2)
 
 	dup	v0.16B, valw
 	add	dstend, dstin, count
diff --git a/newlib/libc/machine/aarch64/setjmp.S b/newlib/libc/machine/aarch64/setjmp.S
index 0856145..1337841 100644
--- a/newlib/libc/machine/aarch64/setjmp.S
+++ b/newlib/libc/machine/aarch64/setjmp.S
@@ -26,6 +26,8 @@
    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include "../asmdefs.h"
+
 #define GPR_LAYOUT			\
 	REG_PAIR (x19, x20,  0);	\
 	REG_PAIR (x21, x22, 16);	\
@@ -45,6 +47,7 @@
 	.global	setjmp
 	.type	setjmp, %function
 setjmp:
+  PTR_ARG (0)
 	mov	x16, sp
 #define REG_PAIR(REG1, REG2, OFFS)	stp REG1, REG2, [x0, OFFS]
 #define REG_ONE(REG1, OFFS)		str REG1, [x0, OFFS]
@@ -60,6 +63,7 @@ setjmp:
 	.global	longjmp
 	.type	longjmp, %function
 longjmp:
+  PTR_ARG (0)
 #define REG_PAIR(REG1, REG2, OFFS)	ldp REG1, REG2, [x0, OFFS]
 #define REG_ONE(REG1, OFFS)		ldr REG1, [x0, OFFS]
 	GPR_LAYOUT
diff --git a/newlib/libc/machine/aarch64/strchr.S b/newlib/libc/machine/aarch64/strchr.S
index 2448dbc..502c883 100644
--- a/newlib/libc/machine/aarch64/strchr.S
+++ b/newlib/libc/machine/aarch64/strchr.S
@@ -37,6 +37,8 @@
  * Neon Available.
  */
 
+#include "../asmdefs.h"
+
 /* Arguments and results.  */
 #define srcin		x0
 #define chrin		w1
@@ -83,6 +85,7 @@
 	.endm
 
 def_fn strchr
+	PTR_ARG (0)
 	/* Magic constant 0x40100401 to allow us to identify which lane
 	   matches the requested byte.  Magic constant 0x80200802 used
 	   similarly for NUL termination.  */
diff --git a/newlib/libc/machine/aarch64/strchrnul.S b/newlib/libc/machine/aarch64/strchrnul.S
index a0ac13b..37c273e 100644
--- a/newlib/libc/machine/aarch64/strchrnul.S
+++ b/newlib/libc/machine/aarch64/strchrnul.S
@@ -37,6 +37,8 @@
  * Neon Available.
  */
 
+#include "../asmdefs.h"
+
 /* Arguments and results.  */
 #define srcin		x0
 #define chrin		w1
@@ -79,6 +81,7 @@
 	.endm
 
 def_fn strchrnul
+	PTR_ARG (0)
 	/* Magic constant 0x40100401 to allow us to identify which lane
 	   matches the termination condition.  */
 	mov	wtmp2, #0x0401
diff --git a/newlib/libc/machine/aarch64/strcmp.S b/newlib/libc/machine/aarch64/strcmp.S
index e2bef2d..d6b2ee0 100644
--- a/newlib/libc/machine/aarch64/strcmp.S
+++ b/newlib/libc/machine/aarch64/strcmp.S
@@ -43,6 +43,8 @@
 
 #define L(label) .L ## label
 
+#include "../asmdefs.h"
+
 #define REP8_01 0x0101010101010101
 #define REP8_7f 0x7f7f7f7f7f7f7f7f
 #define REP8_80 0x8080808080808080
@@ -68,6 +70,8 @@
 
 	/* Start of performance-critical section  -- one 64B cache line.  */
 def_fn strcmp p2align=6
+	PTR_ARG (0)
+	PTR_ARG (1)
 	eor	tmp1, src1, src2
 	mov	zeroones, #REP8_01
 	tst	tmp1, #7
diff --git a/newlib/libc/machine/aarch64/strcpy.S b/newlib/libc/machine/aarch64/strcpy.S
index e5405f2..bb49658 100644
--- a/newlib/libc/machine/aarch64/strcpy.S
+++ b/newlib/libc/machine/aarch64/strcpy.S
@@ -36,6 +36,8 @@
  * ARMv8-a, AArch64, unaligned accesses, min page size 4k.
  */
 
+#include "../asmdefs.h"
+
 /* To build as stpcpy, define BUILD_STPCPY before compiling this file.
 
    To test the page crossing code path more thoroughly, compile with
@@ -112,6 +114,8 @@
 #define MIN_PAGE_SIZE (1 << MIN_PAGE_P2)
 
 def_fn STRCPY p2align=6
+	PTR_ARG (0)
+	PTR_ARG (1)
 	/* For moderately short strings, the fastest way to do the copy is to
 	   calculate the length of the string in the same way as strlen, then
 	   essentially do a memcpy of the result.  This avoids the need for
diff --git a/newlib/libc/machine/aarch64/strlen.S b/newlib/libc/machine/aarch64/strlen.S
index 872d136..87e0652 100644
--- a/newlib/libc/machine/aarch64/strlen.S
+++ b/newlib/libc/machine/aarch64/strlen.S
@@ -63,6 +63,8 @@
 \f:
 	.endm
 
+#include "../asmdefs.h"
+
 	/* NUL detection works on the principle that (X - 1) & (~X) & 0x80
 	   (=> (X - 1) & ~(X | 0x7f)) is non-zero iff a byte is zero, and
 	   can be done in parallel across the entire word. A faster check
@@ -105,6 +107,7 @@
 	   boundary.  */
 
 def_fn strlen p2align=6
+	PTR_ARG (0)
 	and	tmp1, srcin, MIN_PAGE_SIZE - 1
 	mov	zeroones, REP8_01
 	cmp	tmp1, MIN_PAGE_SIZE - 16
diff --git a/newlib/libc/machine/aarch64/strncmp.S b/newlib/libc/machine/aarch64/strncmp.S
index ffdabc2..95ab230 100644
--- a/newlib/libc/machine/aarch64/strncmp.S
+++ b/newlib/libc/machine/aarch64/strncmp.S
@@ -41,6 +41,8 @@
 \f:
 	.endm
 
+#include "../asmdefs.h"
+
 #define REP8_01 0x0101010101010101
 #define REP8_7f 0x7f7f7f7f7f7f7f7f
 #define REP8_80 0x8080808080808080
@@ -75,6 +77,9 @@
 	nop	/* Pad so that the loop below fits a cache line.  */
 	.endr
 def_fn strncmp
+	PTR_ARG (0)
+	PTR_ARG (1)
+	SIZE_ARG (2)
 	cbz	limit, .Lret0
 	eor	tmp1, src1, src2
 	mov	zeroones, #REP8_01
diff --git a/newlib/libc/machine/aarch64/strnlen.S b/newlib/libc/machine/aarch64/strnlen.S
index c255c3f..0c3c8fe 100644
--- a/newlib/libc/machine/aarch64/strnlen.S
+++ b/newlib/libc/machine/aarch64/strnlen.S
@@ -35,6 +35,8 @@
  * ARMv8-a, AArch64
  */
 
+#include "../asmdefs.h"
+
 /* Arguments and results.  */
 #define srcin		x0
 #define len		x0
@@ -80,6 +82,8 @@
 	ret
 
 def_fn strnlen
+	PTR_ARG (0)
+	SIZE_ARG (1)
 	cbz	limit, .Lhit_limit
 	mov	zeroones, #REP8_01
 	bic	src, srcin, #15
diff --git a/newlib/libc/machine/aarch64/strrchr.S b/newlib/libc/machine/aarch64/strrchr.S
index d64fc09..d0b8046 100644
--- a/newlib/libc/machine/aarch64/strrchr.S
+++ b/newlib/libc/machine/aarch64/strrchr.S
@@ -37,6 +37,8 @@
  * Neon Available.
  */
 
+#include "../asmdefs.h"
+
 /* Arguments and results.  */
 #define srcin		x0
 #define chrin		w1
@@ -89,6 +91,7 @@
 	.endm
 
 def_fn strrchr
+	PTR_ARG (0)
 	/* Magic constant 0x40100401 to allow us to identify which lane
 	   matches the requested byte.  Magic constant 0x80200802 used
 	   similarly for NUL termination.  */
diff --git a/newlib/libc/machine/asmdefs.h b/newlib/libc/machine/asmdefs.h
new file mode 100644
index 0000000..2ff112f
--- /dev/null
+++ b/newlib/libc/machine/asmdefs.h
@@ -0,0 +1,96 @@
+/*
+ * Macros for asm code.
+ *
+ * Copyright (c) 2019, Arm Limited.
+ * SPDX-License-Identifier: MIT
+ */
+
+#ifndef _ASMDEFS_H
+#define _ASMDEFS_H
+
+#if defined(__aarch64__)
+
+/* Branch Target Identitication support.  */
+#define BTI_C		hint	34
+#define BTI_J		hint	36
+/* Return address signing support (pac-ret).  */
+#define PACIASP		hint	25; .cfi_window_save
+#define AUTIASP		hint	29; .cfi_window_save
+
+/* GNU_PROPERTY_AARCH64_* macros from elf.h.  */
+#define FEATURE_1_AND 0xc0000000
+#define FEATURE_1_BTI 1
+#define FEATURE_1_PAC 2
+
+/* Add a NT_GNU_PROPERTY_TYPE_0 note.  */
+#define GNU_PROPERTY(type, value)	\
+  .section .note.gnu.property, "a";	\
+  .p2align 3;				\
+  .word 4;				\
+  .word 16;				\
+  .word 5;				\
+  .asciz "GNU";				\
+  .word type;				\
+  .word 4;				\
+  .word value;				\
+  .word 0;				\
+  .text
+
+/* If set then the GNU Property Note section will be added to
+   mark objects to support BTI and PAC-RET.  */
+#ifndef WANT_GNU_PROPERTY
+#define WANT_GNU_PROPERTY 1
+#endif
+
+#if WANT_GNU_PROPERTY
+/* Add property note with supported features to all asm files.  */
+GNU_PROPERTY (FEATURE_1_AND, FEATURE_1_BTI|FEATURE_1_PAC)
+#endif
+
+#define ENTRY_ALIGN(name, alignment)	\
+  .global name;		\
+  .type name,%function;	\
+  .align alignment;		\
+  name:			\
+  .cfi_startproc;	\
+  BTI_C;
+
+#else
+
+#define END_FILE
+
+#define ENTRY_ALIGN(name, alignment)	\
+  .global name;		\
+  .type name,%function;	\
+  .align alignment;		\
+  name:			\
+  .cfi_startproc;
+
+#endif
+
+#define ENTRY(name)	ENTRY_ALIGN(name, 6)
+
+#define ENTRY_ALIAS(name)	\
+  .global name;		\
+  .type name,%function;	\
+  name:
+
+#define END(name)	\
+  .cfi_endproc;		\
+  .size name, .-name;
+
+#ifdef __ILP32__
+  /* Sanitize padding bits of pointer arguments as per aapcs64 */
+#define PTR_ARG(n)  mov w##n, w##n
+#else
+#define PTR_ARG(n)
+#endif
+
+#ifdef __ILP32__
+  /* Sanitize padding bits of size arguments as per aapcs64 */
+#define SIZE_ARG(n)  mov w##n, w##n
+#else
+#define SIZE_ARG(n)
+#endif
+
+#endif
-- 
1.8.3.1

