svn commit: r339074 - in head/sys: arm64/arm64 arm64/include conf kern

Andrew Turner andrew at FreeBSD.org
Mon Oct 1 18:51:10 UTC 2018


Author: andrew
Date: Mon Oct  1 18:51:08 2018
New Revision: 339074
URL: https://svnweb.freebsd.org/changeset/base/339074

Log:
  Add kernel ifunc support on arm64.
  
  Tested with ifunc resolvers in the kernel and module with calls from
  kernel to kernel, module to kernel, and module to module.
  
  Reviewed by:	kib (previous version)
  Approved by:	re (gjb)
  Differential Revision:	https://reviews.freebsd.org/D17370

Added:
  head/sys/arm64/include/ifunc.h   (contents, props changed)
Modified:
  head/sys/arm64/arm64/elf_machdep.c
  head/sys/arm64/arm64/machdep.c
  head/sys/conf/kern.pre.mk
  head/sys/kern/link_elf.c

Modified: head/sys/arm64/arm64/elf_machdep.c
==============================================================================
--- head/sys/arm64/arm64/elf_machdep.c	Mon Oct  1 18:48:33 2018	(r339073)
+++ head/sys/arm64/arm64/elf_machdep.c	Mon Oct  1 18:51:08 2018	(r339074)
@@ -133,14 +133,14 @@ bool
 elf_is_ifunc_reloc(Elf_Size r_info __unused)
 {
 
-	return (false);
+	return (ELF_R_TYPE(r_info) == R_AARCH64_IRELATIVE);
 }
 
 static int
 elf_reloc_internal(linker_file_t lf, Elf_Addr relocbase, const void *data,
     int type, int local, elf_lookup_fn lookup)
 {
-	Elf_Addr *where, addr, addend;
+	Elf_Addr *where, addr, addend, val;
 	Elf_Word rtype, symidx;
 	const Elf_Rel *rel;
 	const Elf_Rela *rela;
@@ -182,6 +182,12 @@ elf_reloc_internal(linker_file_t lf, Elf_Addr relocbas
 		if (error != 0)
 			return (-1);
 		*where = addr + addend;
+		break;
+	case R_AARCH64_IRELATIVE:
+		addr = relocbase + addend;
+		val = ((Elf64_Addr (*)(void))addr)();
+		if (*where != val)
+			*where = val;
 		break;
 	default:
 		printf("kldload: unexpected relocation type %d\n", rtype);

Modified: head/sys/arm64/arm64/machdep.c
==============================================================================
--- head/sys/arm64/arm64/machdep.c	Mon Oct  1 18:48:33 2018	(r339073)
+++ head/sys/arm64/arm64/machdep.c	Mon Oct  1 18:51:08 2018	(r339074)
@@ -1004,6 +1004,7 @@ initarm(struct arm64_bootparams *abp)
 
 	boothowto = MD_FETCH(kmdp, MODINFOMD_HOWTO, int);
 	init_static_kenv(MD_FETCH(kmdp, MODINFOMD_ENVP, char *), 0);
+	link_elf_ireloc(kmdp);
 
 #ifdef FDT
 	try_load_dtb(kmdp);

Added: head/sys/arm64/include/ifunc.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/arm64/include/ifunc.h	Mon Oct  1 18:51:08 2018	(r339074)
@@ -0,0 +1,51 @@
+/*-
+ * Copyright (c) 2015-2018 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Konstantin Belousov <kib at FreeBSD.org>
+ * under sponsorship from the FreeBSD Foundation.
+ *
+ * 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.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef __ARM64_IFUNC_H
+#define	__ARM64_IFUNC_H
+
+#define	DEFINE_IFUNC(qual, ret_type, name, args, resolver_qual)		\
+    resolver_qual ret_type (*name##_resolver(void))args __used;		\
+    qual ret_type name args __attribute__((ifunc(#name "_resolver")));	\
+    resolver_qual ret_type (*name##_resolver(void))args
+
+#define	DEFINE_UIFUNC(qual, ret_type, name, args, resolver_qual)	\
+    resolver_qual ret_type (*name##_resolver(uint64_t, uint64_t,	\
+	uint64_t, uint64_t, uint64_t, uint64_t, uint64_t,		\
+	uint64_t))args __used;						\
+    qual ret_type name args __attribute__((ifunc(#name "_resolver")));	\
+    resolver_qual ret_type (*name##_resolver(uint64_t _arg1 __unused,	\
+	uint64_t _arg2 __unused, uint64_t _arg3 __unused,		\
+	uint64_t _arg4 __unused, uint64_t _arg5 __unused,		\
+	uint64_t _arg6 __unused, uint64_t _arg7 __unused,		\
+	uint64_t _arg8 __unused))args
+
+#endif

Modified: head/sys/conf/kern.pre.mk
==============================================================================
--- head/sys/conf/kern.pre.mk	Mon Oct  1 18:48:33 2018	(r339073)
+++ head/sys/conf/kern.pre.mk	Mon Oct  1 18:51:08 2018	(r339074)
@@ -121,9 +121,10 @@ CFLAGS+=	${CONF_CFLAGS}
 LDFLAGS+=	-Wl,--build-id=sha1
 .endif
 
-.if (${MACHINE_CPUARCH} == "amd64" || ${MACHINE_CPUARCH} == "i386") && \
+.if (${MACHINE_CPUARCH} == "aarch64" || ${MACHINE_CPUARCH} == "amd64" || \
+    ${MACHINE_CPUARCH} == "i386") && \
     defined(LINKER_FEATURES) && ${LINKER_FEATURES:Mifunc} == ""
-.error amd64/i386 kernel requires linker ifunc support
+.error amd64/arm64/i386 kernel requires linker ifunc support
 .endif
 .if ${MACHINE_CPUARCH} == "amd64"
 LDFLAGS+=	-Wl,-z max-page-size=2097152 -Wl,-z common-page-size=4096 -Wl,-z -Wl,ifunc-noplt

Modified: head/sys/kern/link_elf.c
==============================================================================
--- head/sys/kern/link_elf.c	Mon Oct  1 18:48:33 2018	(r339073)
+++ head/sys/kern/link_elf.c	Mon Oct  1 18:51:08 2018	(r339074)
@@ -1653,7 +1653,7 @@ link_elf_strtab_get(linker_file_t lf, caddr_t *strtab)
 	return (ef->ddbstrcnt);
 }
 
-#if defined(__i386__) || defined(__amd64__)
+#if defined(__i386__) || defined(__amd64__) || defined(__aarch64__)
 /*
  * Use this lookup routine when performing relocations early during boot.
  * The generic lookup routine depends on kobj, which is not initialized


More information about the svn-src-head mailing list