Page MenuHomeFreeBSD

D54560.id169315.diff
No OneTemporary

D54560.id169315.diff

diff --git a/lib/libc/aarch64/aarch64_archfuncs.h b/lib/libc/aarch64/aarch64_archfuncs.h
new file mode 100644
--- /dev/null
+++ b/lib/libc/aarch64/aarch64_archfuncs.h
@@ -0,0 +1,95 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2025 Arm Ltd
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef __AARCH64_ARCHFUNCS_H__
+#define __AARCH64_ARCHFUNCS_H__
+
+#define AARCH64_HAS_MOPS (1 << 0)
+
+#define AARCH64_MAX (AARCH64_HAS_MOPS)
+
+#ifndef __ASSEMBLER__
+
+#include <dlfcn.h>
+
+struct __ifunc_arg_t;
+
+dlfunc_t __archlevel_resolve(uint64_t, struct __ifunc_arg_t *,
+ int32_t[AARCH64_MAX + 1]) __hidden;
+
+#else /* __ASSEMBLER__ */
+
+#include <machine/asm.h>
+#include <sys/cdefs.h>
+
+#define ARCHRESOLVE(func) \
+ .globl CNAME(func); \
+ .type CNAME(func), @gnu_indirect_function; \
+ .set CNAME(func), __CONCAT(func,_resolver); \
+ ARCHENTRY(func, _resolver); \
+ adrp x2, __CONCAT(func,_funcs); \
+ add x2, x2, :lo12:__CONCAT(func,_funcs); \
+ b CNAME(__archlevel_resolve); \
+ ARCHEND(func, _resolver)
+
+/*
+ * The func_funcs array stores the location of the implementations
+ * as the distance from the func_funcs array to the function. Due
+ * to compiling for the medium code model, a 32 bit integer suffices
+ * to hold the distance.
+ *
+ * Doing it this way both saves storage and avoids giving rtld
+ * relocations to process at load time.
+ */
+#define ARCHFUNCS(func) \
+ ARCHRESOLVE(func); \
+ .section .rodata; \
+ .align 4; \
+ __CONCAT(func,_funcs):
+
+#define NOARCHFUNC \
+ .4byte 0
+
+#define ARCHFUNC(func, level) \
+ .4byte __CONCAT(func,level) - __CONCAT(func,_funcs)
+
+#define ENDARCHFUNCS(func) \
+ .zero 4*(AARCH64_MAX+1)-(.-__CONCAT(func,_funcs)); \
+ .size __CONCAT(func,_funcs), .-__CONCAT(func,_funcs)
+
+#define ARCHENTRY(func, level) \
+ .text; \
+ .type __CONCAT(func,level), @function; \
+ __CONCAT(func,level):; \
+ .cfi_startproc
+
+#define ARCHEND(func, level) \
+ END(__CONCAT(func,level))
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* __AARCH64_ARCHFUNCS_H__ */
diff --git a/lib/libc/aarch64/string/Makefile.inc b/lib/libc/aarch64/string/Makefile.inc
--- a/lib/libc/aarch64/string/Makefile.inc
+++ b/lib/libc/aarch64/string/Makefile.inc
@@ -34,7 +34,8 @@
timingsafe_bcmp.S \
timingsafe_memcmp.S \
bcopy.c \
- bzero.c
+ bzero.c \
+ aarch64_string_resolver.c
#
# Add the above functions. Generate an asm file that includes the needed
diff --git a/lib/libc/aarch64/string/aarch64_string_resolver.c b/lib/libc/aarch64/string/aarch64_string_resolver.c
new file mode 100644
--- /dev/null
+++ b/lib/libc/aarch64/string/aarch64_string_resolver.c
@@ -0,0 +1,38 @@
+#include <sys/types.h>
+#include <sys/auxv.h>
+#include "libc_private.h"
+#include <elf.h>
+#include <stddef.h>
+#include "aarch64_archfuncs.h"
+
+struct __ifunc_arg_t
+{
+ unsigned long _size; /* Size of the struct, so it can grow. */
+ unsigned long _hwcap;
+ unsigned long _hwcap2;
+ unsigned long _hwcap3;
+ unsigned long _hwcap4;
+};
+
+#define _IFUNC_ARG_HWCAP (1ULL << 62)
+
+dlfunc_t
+__archlevel_resolve(uint64_t at_hwcap, struct __ifunc_arg_t *ifunc_arg,
+ int32_t funcs[static AARCH64_MAX+1])
+{
+ int level;
+ int mask;
+
+ mask = 0;
+
+ if (at_hwcap & _IFUNC_ARG_HWCAP) {
+ if (ifunc_arg->_hwcap2 & HWCAP2_MOPS)
+ mask |= AARCH64_HAS_MOPS;
+ }
+
+ for (level = AARCH64_MAX; level >= 0; level--)
+ if (funcs[level] != 0 && !(level & ~mask))
+ return (dlfunc_t)((uintptr_t)funcs + (ptrdiff_t)funcs[level]);
+
+ __builtin_trap();
+}
diff --git a/lib/libc/aarch64/string/memcpy.S b/lib/libc/aarch64/string/memcpy.S
--- a/lib/libc/aarch64/string/memcpy.S
+++ b/lib/libc/aarch64/string/memcpy.S
@@ -1,3 +1,26 @@
-#define __memcpy_aarch64_simd memcpy
-#define __memmove_aarch64_simd memmove
+#include "aarch64_archfuncs.h"
+
+ARCHFUNCS(memcpy)
+ ARCHFUNC(memcpy, _base)
+ ARCHFUNC(memcpy, _mops)
+ENDARCHFUNCS(memcpy)
+
+ARCHFUNCS(memmove)
+ ARCHFUNC(memmove, _base)
+ ARCHFUNC(memmove, _mops)
+ENDARCHFUNCS(memmove)
+
+#undef BTI_C
+#undef BTI_J
+#undef ENTRY
+#undef END
+
+
+#define __memcpy_aarch64_simd memcpy_base
+#define __memmove_aarch64_simd memmove_base
#include "aarch64/memcpy-advsimd.S"
+
+#define __memcpy_aarch64_mops memcpy_mops
+#define __memmove_aarch64_mops memmove_mops
+#include "aarch64/memcpy-mops.S"
+#include "aarch64/memmove-mops.S"
diff --git a/lib/libc/aarch64/string/memset.S b/lib/libc/aarch64/string/memset.S
new file mode 100644
--- /dev/null
+++ b/lib/libc/aarch64/string/memset.S
@@ -0,0 +1,19 @@
+#include "aarch64_archfuncs.h"
+
+ARCHFUNCS(memset)
+ ARCHFUNC(memset, _base)
+ ARCHFUNC(memset, _mops)
+ENDARCHFUNCS(memset)
+
+
+#undef BTI_C
+#undef BTI_J
+#undef ENTRY
+#undef END
+
+
+#define __memset_aarch64 memset_base
+#include "aarch64/memset.S"
+
+#define __memset_aarch64_mops memset_mops
+#include "aarch64/memset-mops.S"
diff --git a/sys/arm64/include/asm.h b/sys/arm64/include/asm.h
--- a/sys/arm64/include/asm.h
+++ b/sys/arm64/include/asm.h
@@ -233,6 +233,8 @@
#define GNU_PROPERTY_AARCH64_FEATURE_1_NOTE(x)
#endif
+#define CNAME(csym) csym
+
#endif /* _MACHINE_ASM_H_ */
#endif /* !__arm__ */

File Metadata

Mime Type
text/plain
Expires
Wed, Jan 14, 4:45 AM (5 h, 38 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27627725
Default Alt Text
D54560.id169315.diff (6 KB)

Event Timeline