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 <k...@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
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to