Module Name:    src
Committed By:   skrll
Date:           Fri Jul 10 12:25:11 UTC 2020

Modified Files:
        src/share/man/man7: kernel_sanitizers.7
        src/sys/arch/arm/altera: cycv_platform.c
        src/sys/arch/arm/amlogic: meson_platform.c
        src/sys/arch/arm/arm: armv6_start.S bootconfig.c cpufunc.c
        src/sys/arch/arm/arm32: arm32_boot.c arm32_kvminit.c arm32_machdep.c
            cpuswitch.S pmap.c
        src/sys/arch/arm/broadcom: bcm283x_platform.c
        src/sys/arch/arm/conf: Makefile.arm
        src/sys/arch/arm/imx/fdt: imx6_platform.c
        src/sys/arch/arm/include/arm32: param.h vmparam.h
        src/sys/arch/arm/nvidia: tegra_platform.c
        src/sys/arch/arm/rockchip: rk_platform.c
        src/sys/arch/arm/samsung: exynos_platform.c
        src/sys/arch/arm/sunxi: sunxi_platform.c
        src/sys/arch/arm/ti: am3_platform.c omap3_platform.c
        src/sys/arch/arm/vexpress: vexpress_platform.c
        src/sys/arch/arm/virt: virt_platform.c
        src/sys/arch/arm/xilinx: zynq_platform.c
        src/sys/arch/evbarm/beagle: beagle_machdep.c
        src/sys/arch/evbarm/conf: GENERIC ldscript.evbarm
        src/sys/arch/evbarm/imx7: imx7_machdep.c
        src/sys/arch/evbarm/include: asan.h
        src/sys/arch/evbarm/zynq: zynq_machdep.c
Added Files:
        src/sys/arch/arm/include: asan.h

Log Message:
Add support for KASAN on ARMv[67]

Thanks to maxv for many pointers and reviews.


To generate a diff of this commit:
cvs rdiff -u -r1.3 -r1.4 src/share/man/man7/kernel_sanitizers.7
cvs rdiff -u -r1.12 -r1.13 src/sys/arch/arm/altera/cycv_platform.c
cvs rdiff -u -r1.14 -r1.15 src/sys/arch/arm/amlogic/meson_platform.c
cvs rdiff -u -r1.19 -r1.20 src/sys/arch/arm/arm/armv6_start.S
cvs rdiff -u -r1.11 -r1.12 src/sys/arch/arm/arm/bootconfig.c
cvs rdiff -u -r1.176 -r1.177 src/sys/arch/arm/arm/cpufunc.c
cvs rdiff -u -r1.38 -r1.39 src/sys/arch/arm/arm32/arm32_boot.c
cvs rdiff -u -r1.63 -r1.64 src/sys/arch/arm/arm32/arm32_kvminit.c
cvs rdiff -u -r1.135 -r1.136 src/sys/arch/arm/arm32/arm32_machdep.c
cvs rdiff -u -r1.100 -r1.101 src/sys/arch/arm/arm32/cpuswitch.S
cvs rdiff -u -r1.416 -r1.417 src/sys/arch/arm/arm32/pmap.c
cvs rdiff -u -r1.39 -r1.40 src/sys/arch/arm/broadcom/bcm283x_platform.c
cvs rdiff -u -r1.54 -r1.55 src/sys/arch/arm/conf/Makefile.arm
cvs rdiff -u -r1.9 -r1.10 src/sys/arch/arm/imx/fdt/imx6_platform.c
cvs rdiff -u -r0 -r1.1 src/sys/arch/arm/include/asan.h
cvs rdiff -u -r1.32 -r1.33 src/sys/arch/arm/include/arm32/param.h
cvs rdiff -u -r1.50 -r1.51 src/sys/arch/arm/include/arm32/vmparam.h
cvs rdiff -u -r1.21 -r1.22 src/sys/arch/arm/nvidia/tegra_platform.c
cvs rdiff -u -r1.8 -r1.9 src/sys/arch/arm/rockchip/rk_platform.c
cvs rdiff -u -r1.28 -r1.29 src/sys/arch/arm/samsung/exynos_platform.c
cvs rdiff -u -r1.38 -r1.39 src/sys/arch/arm/sunxi/sunxi_platform.c
cvs rdiff -u -r1.1 -r1.2 src/sys/arch/arm/ti/am3_platform.c
cvs rdiff -u -r1.2 -r1.3 src/sys/arch/arm/ti/omap3_platform.c
cvs rdiff -u -r1.16 -r1.17 src/sys/arch/arm/vexpress/vexpress_platform.c
cvs rdiff -u -r1.9 -r1.10 src/sys/arch/arm/virt/virt_platform.c
cvs rdiff -u -r1.1 -r1.2 src/sys/arch/arm/xilinx/zynq_platform.c
cvs rdiff -u -r1.82 -r1.83 src/sys/arch/evbarm/beagle/beagle_machdep.c
cvs rdiff -u -r1.80 -r1.81 src/sys/arch/evbarm/conf/GENERIC
cvs rdiff -u -r1.13 -r1.14 src/sys/arch/evbarm/conf/ldscript.evbarm
cvs rdiff -u -r1.13 -r1.14 src/sys/arch/evbarm/imx7/imx7_machdep.c
cvs rdiff -u -r1.1 -r1.2 src/sys/arch/evbarm/include/asan.h
cvs rdiff -u -r1.12 -r1.13 src/sys/arch/evbarm/zynq/zynq_machdep.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/share/man/man7/kernel_sanitizers.7
diff -u src/share/man/man7/kernel_sanitizers.7:1.3 src/share/man/man7/kernel_sanitizers.7:1.4
--- src/share/man/man7/kernel_sanitizers.7:1.3	Tue Jun 30 16:22:55 2020
+++ src/share/man/man7/kernel_sanitizers.7	Fri Jul 10 12:25:11 2020
@@ -1,4 +1,4 @@
-.\"	$NetBSD: kernel_sanitizers.7,v 1.3 2020/06/30 16:22:55 maxv Exp $
+.\"	$NetBSD: kernel_sanitizers.7,v 1.4 2020/07/10 12:25:11 skrll Exp $
 .\"
 .\" Copyright (c) 2020 The NetBSD Foundation, Inc.
 .\" All rights reserved.
@@ -27,7 +27,7 @@
 .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 .\" POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd June 30, 2020
+.Dd July 10, 2020
 .Dt KERNEL_SANITIZERS 7
 .Os
 .Sh NAME
@@ -67,7 +67,7 @@ Heavy runtime checks, and ~12.5% increas
 Shadow memory, compiler instrumentation, special kernel wrappers, and
 light MD infrastructure.
 .Ss Supported architectures
-aarch64 (gcc), amd64 (gcc, llvm).
+aarch64 (gcc), amd64 (gcc, llvm), arm (gcc).
 .Pp
 KASAN is made of six sub-features that perform memory validation:
 .Bd -literal
@@ -80,6 +80,8 @@ KASAN is made of six sub-features that p
 +---------+------+-------+---------+-----------+---------+------+
 | aarch64 | Yes  | Yes   | Yes     | No        | Yes     | Yes  |
 +---------+------+-------+---------+-----------+---------+------+
+| arm     | Yes  | Yes   | Yes     | No        | Yes     | Yes  |
++---------+------+-------+---------+-----------+---------+------+
 .Ed
 .Pp
 An architecture is allowed to have only partial support.
@@ -151,3 +153,5 @@ Support for KUBSAN was developed by
 .An Kamil Rytarowski .
 Support for KASAN, KCSAN and KMSAN was developed by
 .An Maxime Villard .
+Support for KASAN on ARM was developed by
+.An Nick Hudson .

Index: src/sys/arch/arm/altera/cycv_platform.c
diff -u src/sys/arch/arm/altera/cycv_platform.c:1.12 src/sys/arch/arm/altera/cycv_platform.c:1.13
--- src/sys/arch/arm/altera/cycv_platform.c:1.12	Sat Feb 15 08:16:10 2020
+++ src/sys/arch/arm/altera/cycv_platform.c	Fri Jul 10 12:25:08 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: cycv_platform.c,v 1.12 2020/02/15 08:16:10 skrll Exp $ */
+/* $NetBSD: cycv_platform.c,v 1.13 2020/07/10 12:25:08 skrll Exp $ */
 
 /* This file is in the public domain. */
 
@@ -7,7 +7,7 @@
 #include "opt_multiprocessor.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cycv_platform.c,v 1.12 2020/02/15 08:16:10 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cycv_platform.c,v 1.13 2020/07/10 12:25:08 skrll Exp $");
 
 #define	_ARM32_BUS_DMA_PRIVATE
 #include <sys/param.h>
@@ -34,7 +34,7 @@ __KERNEL_RCSID(0, "$NetBSD: cycv_platfor
 
 void cycv_platform_early_putchar(char);
 
-void
+void __noasan
 cycv_platform_early_putchar(char c) {
 #ifdef CONSADDR
 #define CONSADDR_VA (CONSADDR - CYCV_PERIPHERAL_BASE + CYCV_PERIPHERAL_VBASE)

Index: src/sys/arch/arm/amlogic/meson_platform.c
diff -u src/sys/arch/arm/amlogic/meson_platform.c:1.14 src/sys/arch/arm/amlogic/meson_platform.c:1.15
--- src/sys/arch/arm/amlogic/meson_platform.c:1.14	Sat Jun 20 15:48:19 2020
+++ src/sys/arch/arm/amlogic/meson_platform.c	Fri Jul 10 12:25:08 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: meson_platform.c,v 1.14 2020/06/20 15:48:19 skrll Exp $ */
+/* $NetBSD: meson_platform.c,v 1.15 2020/07/10 12:25:08 skrll Exp $ */
 
 /*-
  * Copyright (c) 2019 Jared McNeill <jmcne...@invisible.ca>
@@ -33,7 +33,7 @@
 #include "arml2cc.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: meson_platform.c,v 1.14 2020/06/20 15:48:19 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: meson_platform.c,v 1.15 2020/07/10 12:25:08 skrll Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -156,7 +156,7 @@ meson_platform_init_attach_args(struct f
 
 void meson_platform_early_putchar(char);
 
-void
+void __noasan
 meson_platform_early_putchar(char c)
 {
 #ifdef CONSADDR

Index: src/sys/arch/arm/arm/armv6_start.S
diff -u src/sys/arch/arm/arm/armv6_start.S:1.19 src/sys/arch/arm/arm/armv6_start.S:1.20
--- src/sys/arch/arm/arm/armv6_start.S:1.19	Thu Jul  9 11:40:54 2020
+++ src/sys/arch/arm/arm/armv6_start.S	Fri Jul 10 12:25:08 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: armv6_start.S,v 1.19 2020/07/09 11:40:54 skrll Exp $	*/
+/*	$NetBSD: armv6_start.S,v 1.20 2020/07/10 12:25:08 skrll Exp $	*/
 
 /*-
  * Copyright (c) 2012, 2017, 2018 The NetBSD Foundation, Inc.
@@ -34,6 +34,7 @@
 #include "opt_cpuoptions.h"
 #include "opt_cputypes.h"
 #include "opt_fdt.h"
+#include "opt_kasan.h"
 #include "opt_multiprocessor.h"
 
 #include <sys/cdefs.h>
@@ -466,6 +467,10 @@ generic_startv7:
 	b	armv7_mmuinit
 
 generic_vstartv7:
+#ifdef KASAN
+	ldr	r0, =start_stacks_bottom
+	bl	_C_LABEL(kasan_early_init)
+#endif
 
 	/* r0 = &cpu_info_store[0] */
 	movw	r0, #:lower16:cpu_info_store
@@ -513,6 +518,11 @@ generic_startv6:
 	b	armv6_mmuinit
 
 generic_vstartv6:
+#ifdef KASAN
+	ldr	r0, =start_stacks_bottom
+	bl	_C_LABEL(kasan_early_init)
+#endif
+
 	VPRINTF("go\n\r")
 
 	/*

Index: src/sys/arch/arm/arm/bootconfig.c
diff -u src/sys/arch/arm/arm/bootconfig.c:1.11 src/sys/arch/arm/arm/bootconfig.c:1.12
--- src/sys/arch/arm/arm/bootconfig.c:1.11	Thu Jun  1 02:45:05 2017
+++ src/sys/arch/arm/arm/bootconfig.c	Fri Jul 10 12:25:08 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: bootconfig.c,v 1.11 2017/06/01 02:45:05 chs Exp $	*/
+/*	$NetBSD: bootconfig.c,v 1.12 2020/07/10 12:25:08 skrll Exp $	*/
 
 /*
  * Copyright (c) 1994-1998 Mark Brinicombe.
@@ -40,7 +40,7 @@
 
 #include <sys/param.h>
 
-__KERNEL_RCSID(0, "$NetBSD: bootconfig.c,v 1.11 2017/06/01 02:45:05 chs Exp $");
+__KERNEL_RCSID(0, "$NetBSD: bootconfig.c,v 1.12 2020/07/10 12:25:08 skrll Exp $");
 
 #include <sys/systm.h>
 #include <sys/kmem.h>
@@ -58,7 +58,7 @@ __KERNEL_RCSID(0, "$NetBSD: bootconfig.c
  * will return ptr of "moo milk=1", *not* "moo"
  */
 
-int
+int __noasan
 get_bootconf_option(char *opts, const char *opt, int type, void *result)
 {
 	char *ptr;

Index: src/sys/arch/arm/arm/cpufunc.c
diff -u src/sys/arch/arm/arm/cpufunc.c:1.176 src/sys/arch/arm/arm/cpufunc.c:1.177
--- src/sys/arch/arm/arm/cpufunc.c:1.176	Wed Feb  5 07:37:35 2020
+++ src/sys/arch/arm/arm/cpufunc.c	Fri Jul 10 12:25:08 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: cpufunc.c,v 1.176 2020/02/05 07:37:35 skrll Exp $	*/
+/*	$NetBSD: cpufunc.c,v 1.177 2020/07/10 12:25:08 skrll Exp $	*/
 
 /*
  * arm7tdmi support code Copyright (c) 2001 John Fremlin
@@ -49,7 +49,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cpufunc.c,v 1.176 2020/02/05 07:37:35 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpufunc.c,v 1.177 2020/07/10 12:25:08 skrll Exp $");
 
 #include "opt_arm_start.h"
 #include "opt_compat_netbsd.h"
@@ -2372,7 +2372,7 @@ struct cpu_option {
 
 static u_int parse_cpu_options(char *, struct cpu_option *, u_int);
 
-static u_int
+static u_int __noasan
 parse_cpu_options(char *args, struct cpu_option *optlist, u_int cpuctrl)
 {
 	int integer;

Index: src/sys/arch/arm/arm32/arm32_boot.c
diff -u src/sys/arch/arm/arm32/arm32_boot.c:1.38 src/sys/arch/arm/arm32/arm32_boot.c:1.39
--- src/sys/arch/arm/arm32/arm32_boot.c:1.38	Sat Jun  6 09:03:59 2020
+++ src/sys/arch/arm/arm32/arm32_boot.c	Fri Jul 10 12:25:09 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: arm32_boot.c,v 1.38 2020/06/06 09:03:59 skrll Exp $	*/
+/*	$NetBSD: arm32_boot.c,v 1.39 2020/07/10 12:25:09 skrll Exp $	*/
 
 /*
  * Copyright (c) 2002, 2003, 2005  Genetec Corporation.  All rights reserved.
@@ -122,7 +122,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(1, "$NetBSD: arm32_boot.c,v 1.38 2020/06/06 09:03:59 skrll Exp $");
+__KERNEL_RCSID(1, "$NetBSD: arm32_boot.c,v 1.39 2020/07/10 12:25:09 skrll Exp $");
 
 #include "opt_arm_debug.h"
 #include "opt_cputypes.h"
@@ -132,6 +132,7 @@ __KERNEL_RCSID(1, "$NetBSD: arm32_boot.c
 
 #include <sys/param.h>
 
+#include <sys/asan.h>
 #include <sys/atomic.h>
 #include <sys/cpu.h>
 #include <sys/device.h>
@@ -296,6 +297,8 @@ initarm_common(vaddr_t kvm_base, vsize_t
 	VPRINTF("pmap ");
 	pmap_bootstrap(kvm_base, kvm_base + kvm_size);
 
+	kasan_init();
+
 #ifdef __HAVE_MEMORY_DISK__
 	md_root_setconf(memory_disk, sizeof memory_disk);
 #endif

Index: src/sys/arch/arm/arm32/arm32_kvminit.c
diff -u src/sys/arch/arm/arm32/arm32_kvminit.c:1.63 src/sys/arch/arm/arm32/arm32_kvminit.c:1.64
--- src/sys/arch/arm/arm32/arm32_kvminit.c:1.63	Fri Jul  3 06:33:39 2020
+++ src/sys/arch/arm/arm32/arm32_kvminit.c	Fri Jul 10 12:25:09 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: arm32_kvminit.c,v 1.63 2020/07/03 06:33:39 skrll Exp $	*/
+/*	$NetBSD: arm32_kvminit.c,v 1.64 2020/07/10 12:25:09 skrll Exp $	*/
 
 /*
  * Copyright (c) 2002, 2003, 2005  Genetec Corporation.  All rights reserved.
@@ -127,10 +127,11 @@
 #include "opt_multiprocessor.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: arm32_kvminit.c,v 1.63 2020/07/03 06:33:39 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: arm32_kvminit.c,v 1.64 2020/07/10 12:25:09 skrll Exp $");
 
 #include <sys/param.h>
 
+#include <sys/asan.h>
 #include <sys/bus.h>
 #include <sys/device.h>
 #include <sys/kernel.h>
@@ -178,6 +179,16 @@ extern char _end[];
 /* Page tables for mapping kernel VM */
 #define KERNEL_L2PT_VMDATA_NUM	8	/* start with 32MB of KVM */
 
+#ifdef KASAN
+vaddr_t kasan_kernelstart;
+vaddr_t kasan_kernelsize;
+
+#define	KERNEL_L2PT_KASAN_NUM	howmany(VM_KERNEL_KASAN_SIZE, L2_S_SEGSIZE)
+pv_addr_t kasan_l2pt[KERNEL_L2PT_KASAN_NUM];
+#else
+#define KERNEL_L2PT_KASAN_NUM	0
+#endif
+
 u_long kern_vtopdiff __attribute__((__section__(".data")));
 
 void
@@ -463,6 +474,7 @@ arm32_kernel_vm_init(vaddr_t kernel_vm_b
 	kernel_size -= (bmi->bmi_kernelstart & -L2_S_SEGSIZE);
 	kernel_size += L1_TABLE_SIZE;
 	kernel_size += PAGE_SIZE * KERNEL_L2PT_VMDATA_NUM;
+	kernel_size += PAGE_SIZE * KERNEL_L2PT_KASAN_NUM;
 	if (map_vectors_p) {
 		kernel_size += PAGE_SIZE;	/* L2PT for VECTORS */
 	}
@@ -560,6 +572,18 @@ arm32_kernel_vm_init(vaddr_t kernel_vm_b
 		add_pages(bmi, &vmdata_l2pt[idx]);
 	}
 
+#ifdef KASAN
+	/*
+	 * Now allocate L2 pages for the KASAN shadow map l2pt VA space.
+	 */
+	VPRINTF(" kasan");
+	for (size_t idx = 0; idx < KERNEL_L2PT_KASAN_NUM; ++idx) {
+		valloc_pages(bmi, &kasan_l2pt[idx], 1,
+		    VM_PROT_READ | VM_PROT_WRITE, PTE_PAGETABLE, true);
+		add_pages(bmi, &kasan_l2pt[idx]);
+	}
+
+#endif
 	/*
 	 * If someone wanted a L2 page for I/O, allocate it now.
 	 */
@@ -600,6 +624,11 @@ arm32_kernel_vm_init(vaddr_t kernel_vm_b
 	msgbufphys = msgbuf.pv_pa;
 	msgbufaddr = (void *)msgbuf.pv_va;
 
+#ifdef KASAN
+	kasan_kernelstart = KERNEL_BASE;
+	kasan_kernelsize = (msgbuf.pv_va + round_page(MSGBUFSIZE)) - KERNEL_BASE;
+#endif
+
 	if (map_vectors_p) {
 		/*
 		 * Allocate a page for the system vector page.
@@ -699,6 +728,21 @@ arm32_kernel_vm_init(vaddr_t kernel_vm_b
 		    va, "(io)");
 	}
 
+#ifdef KASAN
+	VPRINTF("%s: kasan_shadow_base %x KERNEL_L2PT_KASAN_NUM %d\n", __func__,
+	    VM_KERNEL_KASAN_BASE, KERNEL_L2PT_KASAN_NUM);
+
+	for (size_t idx = 0; idx < KERNEL_L2PT_KASAN_NUM; idx++) {
+		const vaddr_t va = VM_KERNEL_KASAN_BASE  + idx * L2_S_SEGSIZE;
+
+		pmap_link_l2pt(l1pt_va, va, &kasan_l2pt[idx]);
+
+		VPRINTF("%s: adding L2 pt (VA %#lx, PA %#lx) for VA %#lx %s\n",
+		    __func__, kasan_l2pt[idx].pv_va, kasan_l2pt[idx].pv_pa,
+		    va, "(kasan)");
+	}
+#endif
+
 	/* update the top of the kernel VM */
 	pmap_curmaxkvaddr =
 	    kernel_vm_base + (KERNEL_L2PT_VMDATA_NUM * L2_S_SEGSIZE);
@@ -1011,6 +1055,11 @@ arm32_kernel_vm_init(vaddr_t kernel_vm_b
 
 	cpu_tlb_flushID();
 
+#ifdef KASAN
+	extern uint8_t start_stacks_bottom[];
+	kasan_early_init((void *)start_stacks_bottom);
+#endif
+
 #ifdef ARM_MMU_EXTENDED
 	VPRINTF("\nsctlr=%#x actlr=%#x\n",
 	    armreg_sctlr_read(), armreg_auxctl_read());

Index: src/sys/arch/arm/arm32/arm32_machdep.c
diff -u src/sys/arch/arm/arm32/arm32_machdep.c:1.135 src/sys/arch/arm/arm32/arm32_machdep.c:1.136
--- src/sys/arch/arm/arm32/arm32_machdep.c:1.135	Sun Jun 21 17:25:03 2020
+++ src/sys/arch/arm/arm32/arm32_machdep.c	Fri Jul 10 12:25:09 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: arm32_machdep.c,v 1.135 2020/06/21 17:25:03 jmcneill Exp $	*/
+/*	$NetBSD: arm32_machdep.c,v 1.136 2020/07/10 12:25:09 skrll Exp $	*/
 
 /*
  * Copyright (c) 1994-1998 Mark Brinicombe.
@@ -42,7 +42,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: arm32_machdep.c,v 1.135 2020/06/21 17:25:03 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: arm32_machdep.c,v 1.136 2020/07/10 12:25:09 skrll Exp $");
 
 #include "opt_arm_debug.h"
 #include "opt_arm_start.h"
@@ -726,7 +726,7 @@ cpu_uarea_alloc_idlelwp(struct cpu_info 
  * -  kmutex(9) relies on curcpu which isn't setup yet.
  *
  */
-void
+void __noasan
 cpu_init_secondary_processor(int cpuindex)
 {
 	// pmap_kernel has been successfully built and we can switch to it

Index: src/sys/arch/arm/arm32/cpuswitch.S
diff -u src/sys/arch/arm/arm32/cpuswitch.S:1.100 src/sys/arch/arm/arm32/cpuswitch.S:1.101
--- src/sys/arch/arm/arm32/cpuswitch.S:1.100	Mon Jul  6 07:36:14 2020
+++ src/sys/arch/arm/arm32/cpuswitch.S	Fri Jul 10 12:25:09 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: cpuswitch.S,v 1.100 2020/07/06 07:36:14 skrll Exp $	*/
+/*	$NetBSD: cpuswitch.S,v 1.101 2020/07/10 12:25:09 skrll Exp $	*/
 
 /*
  * Copyright 2003 Wasabi Systems, Inc.
@@ -79,6 +79,7 @@
 
 #include "opt_armfpe.h"
 #include "opt_cpuoptions.h"
+#include "opt_kasan.h"
 #include "opt_lockdebug.h"
 #include "opt_multiprocessor.h"
 
@@ -86,7 +87,7 @@
 #include <arm/asm.h>
 #include <arm/locore.h>
 
-	RCSID("$NetBSD: cpuswitch.S,v 1.100 2020/07/06 07:36:14 skrll Exp $")
+	RCSID("$NetBSD: cpuswitch.S,v 1.101 2020/07/10 12:25:09 skrll Exp $")
 
 /* LINTSTUB: include <sys/param.h> */
 
@@ -388,6 +389,11 @@ ENTRY_NP(softint_switch)
 #endif
 	str	r5, [r7, #(CI_CURLWP)]	/* save new lwp */
 
+#ifdef KASAN
+	mov	r0, r5
+	bl	_C_LABEL(kasan_softint)
+#endif
+
 	/*
 	 * Normally, we'd get {r8-r13} but since this is a softint lwp
 	 * its existing state doesn't matter.  We start the stack just

Index: src/sys/arch/arm/arm32/pmap.c
diff -u src/sys/arch/arm/arm32/pmap.c:1.416 src/sys/arch/arm/arm32/pmap.c:1.417
--- src/sys/arch/arm/arm32/pmap.c:1.416	Fri Jul  3 17:14:23 2020
+++ src/sys/arch/arm/arm32/pmap.c	Fri Jul 10 12:25:09 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: pmap.c,v 1.416 2020/07/03 17:14:23 skrll Exp $	*/
+/*	$NetBSD: pmap.c,v 1.417 2020/07/10 12:25:09 skrll Exp $	*/
 
 /*
  * Copyright 2003 Wasabi Systems, Inc.
@@ -192,11 +192,12 @@
 #endif
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.416 2020/07/03 17:14:23 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.417 2020/07/10 12:25:09 skrll Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
 
+#include <sys/asan.h>
 #include <sys/atomic.h>
 #include <sys/bus.h>
 #include <sys/cpu.h>
@@ -5945,11 +5946,13 @@ pmap_growkernel(vaddr_t maxkvaddr)
 	 * whoops!   we need to add kernel PTPs
 	 */
 
+	vaddr_t pmap_maxkvaddr = pmap_curmaxkvaddr;
+
 	s = splvm();	/* to be safe */
 	mutex_enter(&kpm_lock);
 
 	/* Map 1MB at a time */
-	size_t l1slot = l1pte_index(pmap_curmaxkvaddr);
+	size_t l1slot = l1pte_index(pmap_maxkvaddr);
 #ifdef ARM_MMU_EXTENDED
 	pd_entry_t * const spdep = &kpm->pm_l1[l1slot];
 	pd_entry_t *pdep = spdep;
@@ -5994,6 +5997,9 @@ pmap_growkernel(vaddr_t maxkvaddr)
 	mutex_exit(&kpm_lock);
 	splx(s);
 
+	kasan_shadow_map((void *)pmap_maxkvaddr,
+	    (size_t)(pmap_curmaxkvaddr - pmap_maxkvaddr));
+
 out:
 	return pmap_curmaxkvaddr;
 }

Index: src/sys/arch/arm/broadcom/bcm283x_platform.c
diff -u src/sys/arch/arm/broadcom/bcm283x_platform.c:1.39 src/sys/arch/arm/broadcom/bcm283x_platform.c:1.40
--- src/sys/arch/arm/broadcom/bcm283x_platform.c:1.39	Fri Jun 26 08:42:01 2020
+++ src/sys/arch/arm/broadcom/bcm283x_platform.c	Fri Jul 10 12:25:09 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: bcm283x_platform.c,v 1.39 2020/06/26 08:42:01 skrll Exp $	*/
+/*	$NetBSD: bcm283x_platform.c,v 1.40 2020/07/10 12:25:09 skrll Exp $	*/
 
 /*-
  * Copyright (c) 2017 Jared D. McNeill <jmcne...@invisible.ca>
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: bcm283x_platform.c,v 1.39 2020/06/26 08:42:01 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: bcm283x_platform.c,v 1.40 2020/07/10 12:25:09 skrll Exp $");
 
 #include "opt_arm_debug.h"
 #include "opt_bcm283x.h"
@@ -1330,7 +1330,7 @@ bcm2711_platform_init_attach_args(struct
 #endif
 
 
-static void
+static void __noasan
 bcm283x_platform_early_putchar(vaddr_t va, paddr_t pa, char c)
 {
 	volatile uint32_t *uartaddr =
@@ -1347,7 +1347,7 @@ bcm283x_platform_early_putchar(vaddr_t v
 		continue;
 }
 
-void
+void __noasan
 bcm2835_platform_early_putchar(char c)
 {
 	paddr_t pa = BCM2835_PERIPHERALS_BUS_TO_PHYS(BCM2835_UART0_BASE);
@@ -1356,7 +1356,7 @@ bcm2835_platform_early_putchar(char c)
 	bcm283x_platform_early_putchar(va, pa, c);
 }
 
-void
+void __noasan
 bcm2836_platform_early_putchar(char c)
 {
 	paddr_t pa = BCM2836_PERIPHERALS_BUS_TO_PHYS(BCM2835_UART0_BASE);
@@ -1365,7 +1365,7 @@ bcm2836_platform_early_putchar(char c)
 	bcm283x_platform_early_putchar(va, pa, c);
 }
 
-void
+void __noasan
 bcm2837_platform_early_putchar(char c)
 {
 #define AUCONSADDR_PA	BCM2836_PERIPHERALS_BUS_TO_PHYS(BCM2835_AUX_UART_BASE)
@@ -1383,7 +1383,7 @@ bcm2837_platform_early_putchar(char c)
 #undef AUCONSADDR_PA
 }
 
-void
+void __noasan
 bcm2711_platform_early_putchar(char c)
 {
 #define AUCONSADDR_PA	BCM2711_PERIPHERALS_BUS_TO_PHYS(BCM2835_AUX_UART_BASE)

Index: src/sys/arch/arm/conf/Makefile.arm
diff -u src/sys/arch/arm/conf/Makefile.arm:1.54 src/sys/arch/arm/conf/Makefile.arm:1.55
--- src/sys/arch/arm/conf/Makefile.arm:1.54	Wed Feb  5 07:37:36 2020
+++ src/sys/arch/arm/conf/Makefile.arm	Fri Jul 10 12:25:09 2020
@@ -1,4 +1,4 @@
-#	$NetBSD: Makefile.arm,v 1.54 2020/02/05 07:37:36 skrll Exp $
+#	$NetBSD: Makefile.arm,v 1.55 2020/07/10 12:25:09 skrll Exp $
 
 # Makefile for NetBSD
 #
@@ -61,6 +61,25 @@ OPT_DDB=	%DDB%
 CFLAGS+=	-mapcs-frame
 .endif
 
+# Note: -fasan-shadow-offset=
+#	KASAN_SHADOW_START - (__MD_KERNMEM_BASE >> KASAN_SHADOW_SCALE_SHIFT) =
+#       0xc000_0000 - (0x8000_0000 >> 3) = 0xb000_0000
+#
+
+.if ${KASAN:U0} > 0 && ${HAVE_GCC:U0} > 0
+KASANFLAGS=	\
+	-fsanitize=kernel-address \
+	--param asan-globals=1 \
+	--param asan-stack=1 \
+	--param asan-instrument-allocas=1 \
+	-fsanitize-address-use-after-scope \
+	-fasan-shadow-offset=0xb0000000
+.for f in subr_asan.c
+KASANFLAGS.${f}=	# empty
+.endfor
+CFLAGS+=	${KASANFLAGS.${.IMPSRC:T}:U${KASANFLAGS}}
+.endif
+
 ##
 ## (3) libkern and compat
 ##

Index: src/sys/arch/arm/imx/fdt/imx6_platform.c
diff -u src/sys/arch/arm/imx/fdt/imx6_platform.c:1.9 src/sys/arch/arm/imx/fdt/imx6_platform.c:1.10
--- src/sys/arch/arm/imx/fdt/imx6_platform.c:1.9	Sun May 24 08:47:19 2020
+++ src/sys/arch/arm/imx/fdt/imx6_platform.c	Fri Jul 10 12:25:09 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: imx6_platform.c,v 1.9 2020/05/24 08:47:19 skrll Exp $	*/
+/*	$NetBSD: imx6_platform.c,v 1.10 2020/07/10 12:25:09 skrll Exp $	*/
 /*-
  * Copyright (c) 2019 Genetec Corporation.  All rights reserved.
  * Written by Hashimoto Kenichi for Genetec Corporation.
@@ -25,7 +25,7 @@
  * SUCH DAMAGE.
  */
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: imx6_platform.c,v 1.9 2020/05/24 08:47:19 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: imx6_platform.c,v 1.10 2020/07/10 12:25:09 skrll Exp $");
 
 #include "arml2cc.h"
 #include "opt_console.h"
@@ -97,7 +97,7 @@ imx_platform_init_attach_args(struct fdt
 
 void imx_platform_early_putchar(char);
 
-void
+void __noasan
 imx_platform_early_putchar(char c)
 {
 #ifdef CONSADDR

Index: src/sys/arch/arm/include/arm32/param.h
diff -u src/sys/arch/arm/include/arm32/param.h:1.32 src/sys/arch/arm/include/arm32/param.h:1.33
--- src/sys/arch/arm/include/arm32/param.h:1.32	Wed Jul  8 06:58:33 2020
+++ src/sys/arch/arm/include/arm32/param.h	Fri Jul 10 12:25:09 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: param.h,v 1.32 2020/07/08 06:58:33 skrll Exp $	*/
+/*	$NetBSD: param.h,v 1.33 2020/07/10 12:25:09 skrll Exp $	*/
 
 /*
  * Copyright (c) 1994,1995 Mark Brinicombe.
@@ -37,6 +37,7 @@
 
 #ifdef _KERNEL_OPT
 #include "opt_arm32_pmap.h"
+#include "opt_kasan.h"
 #endif
 
 /*
@@ -54,7 +55,11 @@
 
 #define SSIZE		1		/* initial stack size/NBPG */
 #define SINCR		1		/* increment of stack/NBPG */
+#ifdef KASAN
+#define UPAGES		4
+#else
 #define UPAGES		2
+#endif
 #define USPACE		(UPAGES * NBPG)	/* total size of u-area */
 
 #ifndef MSGBUFSIZE
@@ -67,7 +72,7 @@
  */
 #define	NKMEMPAGES_MIN_DEFAULT	((8 * 1024 * 1024) >> PAGE_SHIFT)
 
-#if defined(_ARM_ARCH_6)
+#if defined(_ARM_ARCH_6) && !defined(KASAN)
 #define	NKMEMPAGES_MAX_DEFAULT	((768 * 1024 * 1024) >> PAGE_SHIFT)
 #else
 #define	NKMEMPAGES_MAX_DEFAULT	((256 * 1024 * 1024) >> PAGE_SHIFT)

Index: src/sys/arch/arm/include/arm32/vmparam.h
diff -u src/sys/arch/arm/include/arm32/vmparam.h:1.50 src/sys/arch/arm/include/arm32/vmparam.h:1.51
--- src/sys/arch/arm/include/arm32/vmparam.h:1.50	Fri Jul 10 07:31:33 2020
+++ src/sys/arch/arm/include/arm32/vmparam.h	Fri Jul 10 12:25:09 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: vmparam.h,v 1.50 2020/07/10 07:31:33 skrll Exp $	*/
+/*	$NetBSD: vmparam.h,v 1.51 2020/07/10 12:25:09 skrll Exp $	*/
 
 /*
  * Copyright (c) 2001, 2002 Wasabi Systems, Inc.
@@ -38,6 +38,7 @@
 #ifndef _ARM_ARM32_VMPARAM_H_
 #define	_ARM_ARM32_VMPARAM_H_
 
+#include "opt_kasan.h"
 
 /*
  * Virtual Memory parameters common to all arm32 platforms.
@@ -88,12 +89,17 @@
  * Mach derived constants
  */
 #define	VM_MIN_ADDRESS		((vaddr_t) PAGE_SIZE)
+
 #define	VM_MAXUSER_ADDRESS	((vaddr_t) KERNEL_BASE - PAGE_SIZE)
 #define	VM_MAX_ADDRESS		VM_MAXUSER_ADDRESS
 
 #define	VM_MIN_KERNEL_ADDRESS	((vaddr_t) KERNEL_BASE)
 #define	VM_MAX_KERNEL_ADDRESS	((vaddr_t) -(PAGE_SIZE+1))
 
+// AddressSanitizer dedicates 1/8 of kernel memory to its shadow memory (e.g.
+// 128MB to cover 1GB for ARM) and uses a special KVA range for the shadow
+// address corresponding to a kernel memory address.
+
 /*
  * kernel virtual space layout without direct map (common case)
  *
@@ -101,6 +107,14 @@
  *   0x9000_0000 - 1536MB Kernel VM Space
  *   0xf000_0000 -  256MB IO
  *
+ * kernel virtual space layout with KASAN
+ *
+ *   0x8000_0000 -  256MB kernel text/data/bss
+ *   0x9000_0000 -  768MB Kernel VM Space
+ *   0xc000_0000 -  128MB (KASAN SHADOW MAP)
+ *   0xc800_0000 -  640MB (spare)
+ *   0xf000_0000 -  256MB IO
+ *
  * kernel virtual space layout with direct map (1GB limited)
  *   0x8000_0000 - 1024MB kernel text/data/bss and direct map start
  *   0xc000_0000 -  768MB Kernel VM Space
@@ -108,13 +122,29 @@
  *
  */
 
+#ifdef KASAN
+#define VM_KERNEL_KASAN_BASE	0xc0000000
+#define VM_KERNEL_KASAN_SIZE	(KERNEL_VM_SIZE >> KASAN_SHADOW_SCALE_SHIFT)
+#define VM_KERNEL_KASAN_END	(VM_KERNEL_KASAN_BASE + VM_KERNEL_KASAN_SIZE)
+#define VM_KERNEL_VM_END	VM_KERNEL_KASAN_BASE
+#else
+#define VM_KERNEL_VM_END	VM_KERNEL_IO_ADDRESS
+#endif
+
 #ifdef __HAVE_MM_MD_DIRECT_MAPPED_PHYS
+#ifdef KASAN
+#error KASAN and __HAVE_MM_MD_DIRECT_MAPPED_PHYS is unsupported
+#endif
 #define VM_KERNEL_VM_BASE	0xc0000000
 #else
 #define VM_KERNEL_VM_BASE	0x90000000
 #endif
+#else
+#ifdef KASAN
+#error KASAN is unsupported on pre-ARMv6
+#endif
 
-#define VM_KERNEL_VM_SIZE	(VM_KERNEL_IO_ADDRESS - VM_KERNEL_VM_BASE)
+#define VM_KERNEL_VM_SIZE	(VM_KERNEL_VM_END - VM_KERNEL_VM_BASE)
 
 #define VM_KERNEL_IO_ADDRESS	0xf0000000
 #define VM_KERNEL_IO_SIZE	(VM_MAX_KERNEL_ADDRESS - VM_KERNEL_IO_ADDRESS)

Index: src/sys/arch/arm/nvidia/tegra_platform.c
diff -u src/sys/arch/arm/nvidia/tegra_platform.c:1.21 src/sys/arch/arm/nvidia/tegra_platform.c:1.22
--- src/sys/arch/arm/nvidia/tegra_platform.c:1.21	Sat Jun 20 15:48:19 2020
+++ src/sys/arch/arm/nvidia/tegra_platform.c	Fri Jul 10 12:25:09 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: tegra_platform.c,v 1.21 2020/06/20 15:48:19 skrll Exp $ */
+/* $NetBSD: tegra_platform.c,v 1.22 2020/07/10 12:25:09 skrll Exp $ */
 
 /*-
  * Copyright (c) 2017 Jared D. McNeill <jmcne...@invisible.ca>
@@ -34,7 +34,7 @@
 #include "ukbd.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tegra_platform.c,v 1.21 2020/06/20 15:48:19 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tegra_platform.c,v 1.22 2020/07/10 12:25:09 skrll Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -69,7 +69,7 @@ __KERNEL_RCSID(0, "$NetBSD: tegra_platfo
 
 void tegra_platform_early_putchar(char);
 
-void
+void __noasan
 tegra_platform_early_putchar(char c)
 {
 #ifdef CONSADDR

Index: src/sys/arch/arm/rockchip/rk_platform.c
diff -u src/sys/arch/arm/rockchip/rk_platform.c:1.8 src/sys/arch/arm/rockchip/rk_platform.c:1.9
--- src/sys/arch/arm/rockchip/rk_platform.c:1.8	Tue Oct 30 16:41:52 2018
+++ src/sys/arch/arm/rockchip/rk_platform.c	Fri Jul 10 12:25:09 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: rk_platform.c,v 1.8 2018/10/30 16:41:52 skrll Exp $ */
+/* $NetBSD: rk_platform.c,v 1.9 2020/07/10 12:25:09 skrll Exp $ */
 
 /*-
  * Copyright (c) 2018 Jared McNeill <jmcne...@invisible.ca>
@@ -31,7 +31,7 @@
 #include "opt_console.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rk_platform.c,v 1.8 2018/10/30 16:41:52 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rk_platform.c,v 1.9 2020/07/10 12:25:09 skrll Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -121,7 +121,7 @@ rk3328_platform_devmap(void)
 
 void rk3328_platform_early_putchar(char);
 
-void
+void __noasan
 rk3328_platform_early_putchar(char c)
 {
 #ifdef CONSADDR

Index: src/sys/arch/arm/samsung/exynos_platform.c
diff -u src/sys/arch/arm/samsung/exynos_platform.c:1.28 src/sys/arch/arm/samsung/exynos_platform.c:1.29
--- src/sys/arch/arm/samsung/exynos_platform.c:1.28	Thu Mar 19 08:33:04 2020
+++ src/sys/arch/arm/samsung/exynos_platform.c	Fri Jul 10 12:25:09 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: exynos_platform.c,v 1.28 2020/03/19 08:33:04 skrll Exp $ */
+/* $NetBSD: exynos_platform.c,v 1.29 2020/07/10 12:25:09 skrll Exp $ */
 
 /*-
  * Copyright (c) 2017 Jared D. McNeill <jmcne...@invisible.ca>
@@ -35,7 +35,7 @@
 #include "ukbd.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: exynos_platform.c,v 1.28 2020/03/19 08:33:04 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: exynos_platform.c,v 1.29 2020/07/10 12:25:09 skrll Exp $");
 
 
 /*
@@ -230,7 +230,7 @@ exynos_platform_init_attach_args(struct 
 	faa->faa_dmat = &arm_generic_dma_tag;
 }
 
-void
+void __noasan
 exynos_platform_early_putchar(char c)
 {
 #ifdef CONSADDR

Index: src/sys/arch/arm/sunxi/sunxi_platform.c
diff -u src/sys/arch/arm/sunxi/sunxi_platform.c:1.38 src/sys/arch/arm/sunxi/sunxi_platform.c:1.39
--- src/sys/arch/arm/sunxi/sunxi_platform.c:1.38	Sun Nov 24 10:27:37 2019
+++ src/sys/arch/arm/sunxi/sunxi_platform.c	Fri Jul 10 12:25:10 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: sunxi_platform.c,v 1.38 2019/11/24 10:27:37 jmcneill Exp $ */
+/* $NetBSD: sunxi_platform.c,v 1.39 2020/07/10 12:25:10 skrll Exp $ */
 
 /*-
  * Copyright (c) 2017 Jared McNeill <jmcne...@invisible.ca>
@@ -31,7 +31,7 @@
 #include "opt_console.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sunxi_platform.c,v 1.38 2019/11/24 10:27:37 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sunxi_platform.c,v 1.39 2020/07/10 12:25:10 skrll Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -183,7 +183,7 @@ sunxi_platform_init_attach_args(struct f
 
 void sunxi_platform_early_putchar(char);
 
-void
+void __noasan
 sunxi_platform_early_putchar(char c)
 {
 #ifdef CONSADDR

Index: src/sys/arch/arm/ti/am3_platform.c
diff -u src/sys/arch/arm/ti/am3_platform.c:1.1 src/sys/arch/arm/ti/am3_platform.c:1.2
--- src/sys/arch/arm/ti/am3_platform.c:1.1	Tue Oct 29 10:54:10 2019
+++ src/sys/arch/arm/ti/am3_platform.c	Fri Jul 10 12:25:10 2020
@@ -1,9 +1,9 @@
-/* $NetBSD: am3_platform.c,v 1.1 2019/10/29 10:54:10 jmcneill Exp $ */
+/* $NetBSD: am3_platform.c,v 1.2 2020/07/10 12:25:10 skrll Exp $ */
 
 #include "opt_console.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: am3_platform.c,v 1.1 2019/10/29 10:54:10 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: am3_platform.c,v 1.2 2020/07/10 12:25:10 skrll Exp $");
 
 #include <sys/param.h>
 
@@ -14,6 +14,7 @@ __KERNEL_RCSID(0, "$NetBSD: am3_platform
 
 #include <dev/ic/comreg.h>
 
+#include <machine/vmparam.h>
 #include <arch/evbarm/fdt/platform.h>
 
 extern struct bus_space armv7_generic_bs_tag;
@@ -22,7 +23,7 @@ extern struct arm32_bus_dma_tag arm_gene
 
 void am33xx_platform_early_putchar(char);
 
-void
+void __noasan
 am33xx_platform_early_putchar(char c)
 {
 #ifdef CONSADDR

Index: src/sys/arch/arm/ti/omap3_platform.c
diff -u src/sys/arch/arm/ti/omap3_platform.c:1.2 src/sys/arch/arm/ti/omap3_platform.c:1.3
--- src/sys/arch/arm/ti/omap3_platform.c:1.2	Wed Oct 30 22:21:06 2019
+++ src/sys/arch/arm/ti/omap3_platform.c	Fri Jul 10 12:25:10 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: omap3_platform.c,v 1.2 2019/10/30 22:21:06 jmcneill Exp $ */
+/* $NetBSD: omap3_platform.c,v 1.3 2020/07/10 12:25:10 skrll Exp $ */
 
 /*-
  * Copyright (c) 2019 Jared McNeill <jmcne...@invisible.ca>
@@ -30,7 +30,7 @@
 #include "opt_console.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: omap3_platform.c,v 1.2 2019/10/30 22:21:06 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: omap3_platform.c,v 1.3 2020/07/10 12:25:10 skrll Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -130,7 +130,7 @@ omap3_platform_init_attach_args(struct f
 
 void omap3_platform_early_putchar(char);
 
-void
+void __noasan
 omap3_platform_early_putchar(char c)
 {
 #ifdef CONSADDR

Index: src/sys/arch/arm/vexpress/vexpress_platform.c
diff -u src/sys/arch/arm/vexpress/vexpress_platform.c:1.16 src/sys/arch/arm/vexpress/vexpress_platform.c:1.17
--- src/sys/arch/arm/vexpress/vexpress_platform.c:1.16	Sat Feb 15 08:16:12 2020
+++ src/sys/arch/arm/vexpress/vexpress_platform.c	Fri Jul 10 12:25:10 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: vexpress_platform.c,v 1.16 2020/02/15 08:16:12 skrll Exp $ */
+/* $NetBSD: vexpress_platform.c,v 1.17 2020/07/10 12:25:10 skrll Exp $ */
 
 /*-
  * Copyright (c) 2017 Jared McNeill <jmcne...@invisible.ca>
@@ -30,7 +30,7 @@
 #include "opt_console.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vexpress_platform.c,v 1.16 2020/02/15 08:16:12 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vexpress_platform.c,v 1.17 2020/07/10 12:25:10 skrll Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -92,7 +92,7 @@ static bus_space_handle_t sysreg_bsh;
 
 void vexpress_platform_early_putchar(char);
 
-void
+void __noasan
 vexpress_platform_early_putchar(char c)
 {
 #ifdef CONSADDR

Index: src/sys/arch/arm/virt/virt_platform.c
diff -u src/sys/arch/arm/virt/virt_platform.c:1.9 src/sys/arch/arm/virt/virt_platform.c:1.10
--- src/sys/arch/arm/virt/virt_platform.c:1.9	Tue Oct 30 16:41:52 2018
+++ src/sys/arch/arm/virt/virt_platform.c	Fri Jul 10 12:25:10 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: virt_platform.c,v 1.9 2018/10/30 16:41:52 skrll Exp $ */
+/* $NetBSD: virt_platform.c,v 1.10 2020/07/10 12:25:10 skrll Exp $ */
 
 /*-
  * Copyright (c) 2018 Jared McNeill <jmcne...@invisible.ca>
@@ -30,7 +30,7 @@
 #include "opt_multiprocessor.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: virt_platform.c,v 1.9 2018/10/30 16:41:52 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: virt_platform.c,v 1.10 2020/07/10 12:25:10 skrll Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -64,7 +64,7 @@ __KERNEL_RCSID(0, "$NetBSD: virt_platfor
 
 void virt_platform_early_putchar(char);
 
-void
+void __noasan
 virt_platform_early_putchar(char c)
 {
 	volatile uint32_t *uartaddr = cpu_earlydevice_va_p() ?

Index: src/sys/arch/arm/xilinx/zynq_platform.c
diff -u src/sys/arch/arm/xilinx/zynq_platform.c:1.1 src/sys/arch/arm/xilinx/zynq_platform.c:1.2
--- src/sys/arch/arm/xilinx/zynq_platform.c:1.1	Tue Jun 11 13:01:48 2019
+++ src/sys/arch/arm/xilinx/zynq_platform.c	Fri Jul 10 12:25:10 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: zynq_platform.c,v 1.1 2019/06/11 13:01:48 skrll Exp $	*/
+/*	$NetBSD: zynq_platform.c,v 1.2 2020/07/10 12:25:10 skrll Exp $	*/
 
 /*-
  * Copyright (c) 2019 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
 #include "arml2cc.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: zynq_platform.c,v 1.1 2019/06/11 13:01:48 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: zynq_platform.c,v 1.2 2020/07/10 12:25:10 skrll Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -108,7 +108,7 @@ zynq_platform_init_attach_args(struct fd
 	faa->faa_dmat = &arm_generic_dma_tag;
 }
 
-void
+void __noasan
 zynq_platform_early_putchar(char c)
 {
 #ifdef CONSADDR

Index: src/sys/arch/evbarm/beagle/beagle_machdep.c
diff -u src/sys/arch/evbarm/beagle/beagle_machdep.c:1.82 src/sys/arch/evbarm/beagle/beagle_machdep.c:1.83
--- src/sys/arch/evbarm/beagle/beagle_machdep.c:1.82	Sat Feb 15 08:16:12 2020
+++ src/sys/arch/evbarm/beagle/beagle_machdep.c	Fri Jul 10 12:25:10 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: beagle_machdep.c,v 1.82 2020/02/15 08:16:12 skrll Exp $ */
+/*	$NetBSD: beagle_machdep.c,v 1.83 2020/07/10 12:25:10 skrll Exp $ */
 
 /*
  * Machine dependent functions for kernel setup for TI OSK5912 board.
@@ -125,7 +125,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: beagle_machdep.c,v 1.82 2020/02/15 08:16:12 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: beagle_machdep.c,v 1.83 2020/07/10 12:25:10 skrll Exp $");
 
 #include "opt_arm_debug.h"
 #include "opt_console.h"
@@ -532,7 +532,7 @@ beagle_db_trap(int where)
 
 void beagle_platform_early_putchar(char);
 
-void
+void __noasan
 beagle_platform_early_putchar(char c)
 {
 	volatile uint32_t *com0addr = cpu_earlydevice_va_p() ?

Index: src/sys/arch/evbarm/conf/GENERIC
diff -u src/sys/arch/evbarm/conf/GENERIC:1.80 src/sys/arch/evbarm/conf/GENERIC:1.81
--- src/sys/arch/evbarm/conf/GENERIC:1.80	Wed Jun 10 17:57:50 2020
+++ src/sys/arch/evbarm/conf/GENERIC	Fri Jul 10 12:25:10 2020
@@ -1,5 +1,5 @@
 #
-#	$NetBSD: GENERIC,v 1.80 2020/06/10 17:57:50 jmcneill Exp $
+#	$NetBSD: GENERIC,v 1.81 2020/07/10 12:25:10 skrll Exp $
 #
 #	GENERIC ARM (aarch32) kernel
 #
@@ -81,6 +81,14 @@ options 	MSGBUFSIZE=32768
 
 #options 	EARLYCONS=zynq, CONSADDR=0xe0001000
 
+# Kernel Address Sanitizer (kASan). The quarantine is optional and can
+# help KASAN find more use-after-frees. Use KASAN_PANIC if you want panics
+# instead of warnings.
+#makeoptions 	KASAN=1		# mandatory
+#options 	KASAN		# mandatory
+#options 	POOL_QUARANTINE	# optional
+#options 	KASAN_PANIC	# optional
+
 makeoptions 	DEBUG="-g"	# compile full symbol table
 makeoptions 	COPY_SYMTAB=1
 

Index: src/sys/arch/evbarm/conf/ldscript.evbarm
diff -u src/sys/arch/evbarm/conf/ldscript.evbarm:1.13 src/sys/arch/evbarm/conf/ldscript.evbarm:1.14
--- src/sys/arch/evbarm/conf/ldscript.evbarm:1.13	Mon Feb  8 21:08:03 2016
+++ src/sys/arch/evbarm/conf/ldscript.evbarm	Fri Jul 10 12:25:10 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: ldscript.evbarm,v 1.13 2016/02/08 21:08:03 skrll Exp $	*/
+/*	$NetBSD: ldscript.evbarm,v 1.14 2020/07/10 12:25:10 skrll Exp $	*/
 
 ENTRY(KERNEL_BASE_phys)
 SECTIONS
@@ -16,11 +16,24 @@ SECTIONS
     *(.text.*)
     *(.stub)
     *(.glue_7t) *(.glue_7)
-    *(.rodata) *(.rodata.*)
   }
+
+  PROVIDE(__rodata_start = .);
+  .rodata :
+  {
+    *(.rodata)
+    *(.rodata.*)
+    . = ALIGN(64);
+    __CTOR_LIST__ = .;
+    *(.ctors)
+    *(.init_array)
+    __CTOR_END__ = .;
+  }
+
   PROVIDE (__etext = .);
   PROVIDE (_etext = .);
   PROVIDE (etext = .);
+
   /* Adjust the address for the data segment to start on the next large page
      boundary.  */
   . = ALIGN(0x10000);

Index: src/sys/arch/evbarm/imx7/imx7_machdep.c
diff -u src/sys/arch/evbarm/imx7/imx7_machdep.c:1.13 src/sys/arch/evbarm/imx7/imx7_machdep.c:1.14
--- src/sys/arch/evbarm/imx7/imx7_machdep.c:1.13	Sat Feb 15 08:16:12 2020
+++ src/sys/arch/evbarm/imx7/imx7_machdep.c	Fri Jul 10 12:25:10 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: imx7_machdep.c,v 1.13 2020/02/15 08:16:12 skrll Exp $	*/
+/*	$NetBSD: imx7_machdep.c,v 1.14 2020/07/10 12:25:10 skrll Exp $	*/
 
 /*-
  * Copyright (c) 2012 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: imx7_machdep.c,v 1.13 2020/02/15 08:16:12 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: imx7_machdep.c,v 1.14 2020/07/10 12:25:10 skrll Exp $");
 
 #include "opt_evbarm_boardtype.h"
 #include "opt_arm_debug.h"
@@ -164,7 +164,7 @@ static struct boot_physmem bp_highgig = 
 };
 #endif
 
-void
+void __noasan
 imx7_platform_early_putchar(char c)
 {
 #define CONADDR_VA (CONADDR - IMX7_IOREG_PBASE + KERNEL_IO_IOREG_VBASE)

Index: src/sys/arch/evbarm/include/asan.h
diff -u src/sys/arch/evbarm/include/asan.h:1.1 src/sys/arch/evbarm/include/asan.h:1.2
--- src/sys/arch/evbarm/include/asan.h:1.1	Thu Nov  1 20:34:50 2018
+++ src/sys/arch/evbarm/include/asan.h	Fri Jul 10 12:25:10 2020
@@ -1,5 +1,9 @@
-/*	$NetBSD: asan.h,v 1.1 2018/11/01 20:34:50 maxv Exp $	*/
+/*	$NetBSD: asan.h,v 1.2 2020/07/10 12:25:10 skrll Exp $	*/
 
 #ifdef __aarch64__
 #include <aarch64/asan.h>
 #endif
+
+#ifdef __arm__
+#include <arm/asan.h>
+#endif

Index: src/sys/arch/evbarm/zynq/zynq_machdep.c
diff -u src/sys/arch/evbarm/zynq/zynq_machdep.c:1.12 src/sys/arch/evbarm/zynq/zynq_machdep.c:1.13
--- src/sys/arch/evbarm/zynq/zynq_machdep.c:1.12	Sat Feb 15 08:16:12 2020
+++ src/sys/arch/evbarm/zynq/zynq_machdep.c	Fri Jul 10 12:25:11 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: zynq_machdep.c,v 1.12 2020/02/15 08:16:12 skrll Exp $	*/
+/*	$NetBSD: zynq_machdep.c,v 1.13 2020/07/10 12:25:11 skrll Exp $	*/
 /*-
  * Copyright (c) 2012 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -29,7 +29,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: zynq_machdep.c,v 1.12 2020/02/15 08:16:12 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: zynq_machdep.c,v 1.13 2020/07/10 12:25:11 skrll Exp $");
 
 #include "opt_evbarm_boardtype.h"
 #include "opt_arm_debug.h"
@@ -165,7 +165,7 @@ static const struct pmap_devmap devmap[]
 	{ 0, 0, 0, 0, 0 }
 };
 
-void
+void __noasan
 zynq_platform_early_putchar(char c)
 {
 #define CONADDR_VA (CONADDR - ZYNQ7000_IOREG_PBASE + KERNEL_IO_IOREG_VBASE)

Added files:

Index: src/sys/arch/arm/include/asan.h
diff -u /dev/null src/sys/arch/arm/include/asan.h:1.1
--- /dev/null	Fri Jul 10 12:25:11 2020
+++ src/sys/arch/arm/include/asan.h	Fri Jul 10 12:25:09 2020
@@ -0,0 +1,262 @@
+/*	$NetBSD: asan.h,v 1.1 2020/07/10 12:25:09 skrll Exp $	*/
+
+/*
+ * Copyright (c) 2020 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Nick Hudson.
+ *
+ * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
+ */
+
+#include <sys/atomic.h>
+#include <sys/ksyms.h>
+
+#include <arm/vmparam.h>
+#include <arm/arm32/machdep.h>
+#include <arm/arm32/pmap.h>
+
+#define KASAN_MD_SHADOW_START	VM_KERNEL_KASAN_BASE
+#define KASAN_MD_SHADOW_END	VM_KERNEL_KASAN_END
+#define __MD_KERNMEM_BASE	KERNEL_BASE
+
+static inline int8_t *
+kasan_md_addr_to_shad(const void *addr)
+{
+	vaddr_t va = (vaddr_t)addr;
+	return (int8_t *)(KASAN_MD_SHADOW_START +
+	    ((va - __MD_KERNMEM_BASE) >> KASAN_SHADOW_SCALE_SHIFT));
+}
+
+static inline bool
+kasan_md_unsupported(vaddr_t addr)
+{
+	return addr < VM_MIN_KERNEL_ADDRESS ||
+	    addr >= KASAN_MD_SHADOW_START;
+}
+
+/* -------------------------------------------------------------------------- */
+
+/*
+ * Early mapping, used to map just the stack at boot time. We rely on the fact
+ * that VA = PA + KERNEL_BASE.
+ */
+
+#define KASAN_NEARLYPAGES	2
+
+static bool __md_early __read_mostly;
+static size_t __md_nearlypages __attribute__((__section__(".data")));
+static uint8_t __md_earlypages[KASAN_NEARLYPAGES * PAGE_SIZE]
+    __aligned(PAGE_SIZE)  __attribute__((__section__(".data")));
+
+static vaddr_t
+__md_palloc(void)
+{
+	paddr_t pa;
+
+	if (__predict_false(__md_early)) {
+		KASSERTMSG(__md_nearlypages < KASAN_NEARLYPAGES,
+		    "__md_nearlypages %zu", __md_nearlypages);
+
+		vaddr_t va = (vaddr_t)(&__md_earlypages[0] + __md_nearlypages * PAGE_SIZE);
+		__md_nearlypages++;
+		__builtin_memset((void *)va, 0, PAGE_SIZE);
+
+		return KERN_VTOPHYS(va);
+	}
+
+	if (!uvm.page_init_done) {
+		if (uvm_page_physget(&pa) == false)
+			panic("KASAN can't get a page");
+
+		return pa;
+	}
+
+	struct vm_page *pg;
+retry:
+	pg = uvm_pagealloc(NULL, 0, NULL, 0);
+	if (pg == NULL) {
+		uvm_wait(__func__);
+		goto retry;
+	}
+	pa = VM_PAGE_TO_PHYS(pg);
+
+	return pa;
+}
+
+static void
+kasan_md_shadow_map_page(vaddr_t va)
+{
+	const uint32_t mask = L1_TABLE_SIZE - 1;
+	const paddr_t ttb = (paddr_t)(armreg_ttbr1_read() & ~mask);
+	pd_entry_t * const pdep = (pd_entry_t *)KERN_PHYSTOV(ttb);
+
+	const size_t l1slot = l1pte_index(va);
+	vaddr_t l2ptva;
+
+	KASSERT((va & PAGE_MASK) == 0);
+	KASSERT(__md_early || l1pte_page_p(pdep[l1slot]));
+
+	if (!l1pte_page_p(pdep[l1slot])) {
+		KASSERT(__md_early);
+		const paddr_t l2ptpa = __md_palloc();
+		const vaddr_t segl2va = va & -L2_S_SEGSIZE;
+		const size_t segl1slot = l1pte_index(segl2va);
+
+		const pd_entry_t npde =
+		    L1_C_PROTO | l2ptpa | L1_C_DOM(PMAP_DOMAIN_KERNEL);
+
+		l1pte_set(pdep + segl1slot, npde);
+		PDE_SYNC_RANGE(pdep, PAGE_SIZE / L2_T_SIZE);
+
+		l2ptva = KERN_PHYSTOV(l1pte_pa(pdep[l1slot]));
+	} else {
+		/*
+		 * The shadow map area L2PTs were allocated and mapped
+		 * by arm32_kernel_vm_init.  Use the array of pv_addr_t
+		 * to get the l2ptva.
+		 */
+		extern pv_addr_t kasan_l2pt[];
+		const size_t off = va - KASAN_MD_SHADOW_START;
+		const size_t segoff = off & (L2_S_SEGSIZE - 1);
+		const size_t idx = off / L2_S_SEGSIZE;
+		const vaddr_t segl2ptva = kasan_l2pt[idx].pv_va;
+		l2ptva = segl2ptva + l1pte_index(segoff) * L2_TABLE_SIZE_REAL;
+	}
+
+	pt_entry_t * l2pt = (pt_entry_t *)l2ptva;
+	pt_entry_t * const ptep = &l2pt[l2pte_index(va)];
+
+	if (!l2pte_valid_p(*ptep)) {
+		const int prot = VM_PROT_READ | VM_PROT_WRITE;
+		const paddr_t pa = __md_palloc();
+		pt_entry_t npte =
+		    L2_S_PROTO |
+		    pa |
+		    pte_l2_s_cache_mode_pt |
+		    L2_S_PROT(PTE_KERNEL, prot);
+
+		l2pte_set(ptep, npte, 0);
+		PTE_SYNC(ptep);
+		__builtin_memset((void *)va, 0, PAGE_SIZE);
+	}
+}
+
+/*
+ * Map the init stacks of the BP and APs. We will map the rest in kasan_init.
+ */
+#define INIT_ARM_STACK_SHIFT	9
+#define INIT_ARM_STACK_SIZE	(1 << INIT_ARM_STACK_SHIFT)
+
+static void
+kasan_md_early_init(void *stack)
+{
+
+	__md_early = true;
+	__md_nearlypages = 0;
+	kasan_shadow_map(stack, INIT_ARM_STACK_SIZE * MAXCPUS);
+	__md_early = false;
+}
+
+static void
+kasan_md_init(void)
+{
+	extern vaddr_t kasan_kernelstart;
+	extern vaddr_t kasan_kernelsize;
+
+	kasan_shadow_map((void *)kasan_kernelstart, kasan_kernelsize);
+
+	/* The VAs we've created until now. */
+	vaddr_t eva;
+
+	eva = pmap_growkernel(KERNEL_VM_BASE);
+	kasan_shadow_map((void *)KERNEL_VM_BASE, eva - KERNEL_VM_BASE);
+}
+
+
+static inline bool
+__md_unwind_end(const char *name)
+{
+	static const char * const vectors[] = {
+		"undefined_entry",
+		"swi_entry",
+		"prefetch_abort_entry",
+		"data_abort_entry",
+		"address_exception_entry",
+		"irq_entry",
+		"fiqvector"
+	};
+
+	for (size_t i = 0; i < __arraycount(vectors); i++) {
+		if (!strncmp(name, vectors[i], strlen(vectors[i])))
+			return true;
+	}
+
+	return false;
+}
+
+static void
+kasan_md_unwind(void)
+{
+	uint32_t lr, *fp;
+	const char *mod;
+	const char *sym;
+	size_t nsym;
+	int error;
+
+	fp = (uint32_t *)__builtin_frame_address(0);
+	nsym = 0;
+
+	while (1) {
+		/*
+		 * normal frame
+		 *  fp[ 0] saved code pointer
+		 *  fp[-1] saved lr value
+		 *  fp[-2] saved sp value
+		 *  fp[-3] saved fp value
+		 */
+		lr = fp[-1];
+
+		if (lr < VM_MIN_KERNEL_ADDRESS) {
+			break;
+		}
+		error = ksyms_getname(&mod, &sym, (vaddr_t)lr, KSYMS_PROC);
+		if (error) {
+			break;
+		}
+		printf("#%zu %p in %s <%s>\n", nsym, (void *)lr, sym, mod);
+		if (__md_unwind_end(sym)) {
+			break;
+		}
+
+		fp = (uint32_t *)fp[-3];
+		if (fp == NULL) {
+			break;
+		}
+		nsym++;
+
+		if (nsym >= 15) {
+			break;
+		}
+	}
+}

Reply via email to