From 644e0b094d211cd0e43feb03dc4252ef4ff205c1 Mon Sep 17 00:00:00 2001 From: Ryan Long 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