diff --git a/cddl/lib/libdtrace/Makefile b/cddl/lib/libdtrace/Makefile index 5232293e0be5..23cc8d2db574 100644 --- a/cddl/lib/libdtrace/Makefile +++ b/cddl/lib/libdtrace/Makefile @@ -1,150 +1,151 @@ # $FreeBSD$ .PATH: ${SRCTOP}/cddl/contrib/opensolaris/lib/libdtrace/common .PATH: ${SRCTOP}/cddl/contrib/opensolaris/lib/libgen/common PACKAGE= dtrace LIB= dtrace SRCS= dt_aggregate.c \ dt_as.c \ dt_buf.c \ dt_cc.c \ dt_cg.c \ dt_consume.c \ dt_decl.c \ dt_dis.c \ dt_dof.c \ dt_error.c \ dt_errtags.c \ dt_grammar.y \ dt_handle.c \ dt_ident.c \ dt_isadep.c \ dt_inttab.c \ dt_lex.l \ dt_link.c \ dt_list.c \ dt_map.c \ dt_module.c \ dt_names.c \ dt_open.c \ dt_options.c \ dt_parser.c \ dt_pcb.c \ dt_pid.c \ dt_pq.c \ dt_pragma.c \ dt_print.c \ dt_printf.c \ dt_proc.c \ dt_program.c \ dt_provider.c \ dt_regset.c \ dt_string.c \ dt_strtab.c \ dt_subr.c \ dt_sugar.c \ dt_work.c \ dt_xlator.c \ gmatch.c DSRCS= errno.d \ io.d \ ip.d \ psinfo.d \ sctp.d \ siftr.d \ signal.d \ tcp.d \ socket.d \ udp.d \ udplite.d \ unistd.d FILES= ${DSRCS} FILESDIR= /usr/lib/dtrace FILESMODE= ${NOBINMODE} INCSGROUPS= INCS SYSINCS SYSINCSDIR= ${INCLUDEDIR}/sys INCS+= ${SRCTOP}/cddl/contrib/opensolaris/lib/libdtrace/common/dtrace.h SYSINCS+= ${SRCTOP}/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h SYSINCS+= ${SRCTOP}/sys/cddl/contrib/opensolaris/uts/common/sys/ctf_api.h WARNS?= 1 CFLAGS+= -DIN_BASE CFLAGS+= -I${SRCTOP}/sys/contrib/openzfs/include CFLAGS+= -I${SRCTOP}/sys/contrib/openzfs/lib/libspl/include/ CFLAGS+= -I${SRCTOP}/sys/contrib/openzfs/lib/libspl/include/os/freebsd CFLAGS+= -I${SRCTOP}/sys CFLAGS+= -include ${SRCTOP}/sys/contrib/openzfs/include/os/freebsd/spl/sys/ccompile.h CFLAGS+= -DHAVE_ISSETUGID CFLAGS+= -I${.OBJDIR} -I${.CURDIR} \ -I${SRCTOP}/sys/cddl/dev/dtrace/${MACHINE_ARCH} \ -I${SRCTOP}/sys/cddl/dev/kinst \ -I${SRCTOP}/sys/cddl/compat/opensolaris \ -I${SRCTOP}/cddl/compat/opensolaris/include \ -I${OPENSOLARIS_USR_DISTDIR}/head \ -I${OPENSOLARIS_USR_DISTDIR}/lib/libctf/common \ -I${OPENSOLARIS_USR_DISTDIR}/lib/libdtrace/common \ -I${OPENSOLARIS_SYS_DISTDIR}/uts/common #CFLAGS+= -DYYDEBUG .if ${MACHINE_CPUARCH} == "aarch64" CFLAGS+= -I${OPENSOLARIS_SYS_DISTDIR}/uts/aarch64 .PATH: ${SRCTOP}/cddl/contrib/opensolaris/lib/libdtrace/aarch64 .PATH: ${SRCTOP}/sys/cddl/dev/dtrace/aarch64 .elif ${MACHINE_CPUARCH} == "amd64" || ${MACHINE_CPUARCH} == "i386" CFLAGS+= -I${SRCTOP}/sys/cddl/dev/dtrace/x86 CFLAGS+= -I${OPENSOLARIS_SYS_DISTDIR}/uts/intel -DDIS_MEM .PATH: ${SRCTOP}/cddl/contrib/opensolaris/lib/libdtrace/i386 .PATH: ${SRCTOP}/sys/cddl/dev/dtrace/${MACHINE_ARCH} .PATH: ${SRCTOP}/sys/cddl/dev/dtrace/x86 .elif ${MACHINE_CPUARCH} == "arm" CFLAGS+= -I${OPENSOLARIS_SYS_DISTDIR}/uts/arm .PATH: ${SRCTOP}/cddl/contrib/opensolaris/lib/libdtrace/arm .PATH: ${SRCTOP}/sys/cddl/dev/dtrace/arm .elif ${MACHINE_CPUARCH} == "powerpc" CFLAGS+= -I${OPENSOLARIS_SYS_DISTDIR}/uts/powerpc .PATH: ${SRCTOP}/cddl/contrib/opensolaris/lib/libdtrace/powerpc .PATH: ${SRCTOP}/sys/cddl/dev/dtrace/powerpc .elif ${MACHINE_CPUARCH} == "riscv" CFLAGS+= -I${OPENSOLARIS_SYS_DISTDIR}/uts/riscv .PATH: ${SRCTOP}/cddl/contrib/opensolaris/lib/libdtrace/riscv .PATH: ${SRCTOP}/sys/cddl/dev/dtrace/riscv .else # temporary hack CFLAGS+= -I${OPENSOLARIS_SYS_DISTDIR}/uts/intel .endif .if ${MACHINE_ARCH} == "i386" || ${MACHINE_ARCH} == "amd64" SRCS+= dis_tables.c instr_size.c DSRCS+= regs_x86.d .endif .if ${MACHINE_CPUARCH} == "riscv" SRCS+= instr_size.c DSRCS+= regs_riscv.d .endif .if ${MACHINE_CPUARCH} == "aarch64" SRCS+= instr_size.c +DSRCS+= regs_aarch64.d .endif YFLAGS+=-d LIBADD= ctf elf proc pthread rtld_db CLEANFILES= dt_errtags.c dt_names.c .include dt_errtags.c: ${OPENSOLARIS_USR_DISTDIR}/lib/libdtrace/common/dt_errtags.h sh ${OPENSOLARIS_USR_DISTDIR}/lib/libdtrace/common/mkerrtags.sh < ${.ALLSRC} > ${.TARGET} dt_names.c: ${OPENSOLARIS_SYS_DISTDIR}/uts/common/sys/dtrace.h sh ${OPENSOLARIS_USR_DISTDIR}/lib/libdtrace/common/mknames.sh < ${.ALLSRC} > ${.TARGET} diff --git a/cddl/lib/libdtrace/regs_aarch64.d b/cddl/lib/libdtrace/regs_aarch64.d new file mode 100644 index 000000000000..7d20b5c546c5 --- /dev/null +++ b/cddl/lib/libdtrace/regs_aarch64.d @@ -0,0 +1,74 @@ +/* + * SPDX-License-Identifier: CDDL 1.0 + * + * Copyright 2023 Christos Margiolis + */ + +inline int R_X0 = 0; +#pragma D binding "1.13" R_X0 +inline int R_X1 = 1; +#pragma D binding "1.13" R_X1 +inline int R_X2 = 2; +#pragma D binding "1.13" R_X2 +inline int R_X3 = 3; +#pragma D binding "1.13" R_X3 +inline int R_X4 = 4; +#pragma D binding "1.13" R_X4 +inline int R_X5 = 5; +#pragma D binding "1.13" R_X5 +inline int R_X6 = 6; +#pragma D binding "1.13" R_X6 +inline int R_X7 = 7; +#pragma D binding "1.13" R_X7 +inline int R_X8 = 8; +#pragma D binding "1.13" R_X8 +inline int R_X9 = 9; +#pragma D binding "1.13" R_X9 +inline int R_X10 = 10; +#pragma D binding "1.13" R_X10 +inline int R_X11 = 11; +#pragma D binding "1.13" R_X11 +inline int R_X12 = 12; +#pragma D binding "1.13" R_X12 +inline int R_X13 = 13; +#pragma D binding "1.13" R_X13 +inline int R_X14 = 14; +#pragma D binding "1.13" R_X14 +inline int R_X15 = 15; +#pragma D binding "1.13" R_X15 +inline int R_X16 = 16; +#pragma D binding "1.13" R_X16 +inline int R_X17 = 17; +#pragma D binding "1.13" R_X17 +inline int R_X18 = 18; +#pragma D binding "1.13" R_X18 +inline int R_X19 = 19; +#pragma D binding "1.13" R_X19 +inline int R_X20 = 20; +#pragma D binding "1.13" R_X20 +inline int R_X21 = 21; +#pragma D binding "1.13" R_X21 +inline int R_X22 = 22; +#pragma D binding "1.13" R_X22 +inline int R_X23 = 23; +#pragma D binding "1.13" R_X23 +inline int R_X24 = 24; +#pragma D binding "1.13" R_X24 +inline int R_X25 = 25; +#pragma D binding "1.13" R_X25 +inline int R_X26 = 26; +#pragma D binding "1.13" R_X26 +inline int R_X27 = 27; +#pragma D binding "1.13" R_X27 +inline int R_X28 = 28; +#pragma D binding "1.13" R_X28 +inline int R_X29 = 29; +#pragma D binding "1.13" R_X29 +inline int R_FP= 29; +#pragma D binding "1.13" R_FP +inline int R_LR = 30; +#pragma D binding "1.13" R_LR +inline int R_SP = 31; +#pragma D binding "1.13" R_SP +inline int R_PC = 32; +#pragma D binding "1.13" R_PC diff --git a/sys/cddl/dev/dtrace/aarch64/dtrace_isa.c b/sys/cddl/dev/dtrace/aarch64/dtrace_isa.c index 98a0e6e498ed..09dc0b729928 100644 --- a/sys/cddl/dev/dtrace/aarch64/dtrace_isa.c +++ b/sys/cddl/dev/dtrace/aarch64/dtrace_isa.c @@ -1,388 +1,398 @@ /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END * * $FreeBSD$ */ /* * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "regset.h" #define MAX_USTACK_DEPTH 2048 uint8_t dtrace_fuword8_nocheck(void *); uint16_t dtrace_fuword16_nocheck(void *); uint32_t dtrace_fuword32_nocheck(void *); uint64_t dtrace_fuword64_nocheck(void *); void dtrace_getpcstack(pc_t *pcstack, int pcstack_limit, int aframes, uint32_t *intrpc) { struct unwind_state state; int scp_offset; int depth; depth = 0; if (intrpc != 0) { pcstack[depth++] = (pc_t) intrpc; } aframes++; state.fp = (uintptr_t)__builtin_frame_address(0); state.pc = (uintptr_t)dtrace_getpcstack; while (depth < pcstack_limit) { if (!unwind_frame(curthread, &state)) break; if (!INKERNEL(state.pc)) break; /* * NB: Unlike some other architectures, we don't need to * explicitly insert cpu_dtrace_caller as it appears in the * normal kernel stack trace rather than a special trap frame. */ if (aframes > 0) { aframes--; } else { pcstack[depth++] = state.pc; } } for (; depth < pcstack_limit; depth++) { pcstack[depth] = 0; } } static int dtrace_getustack_common(uint64_t *pcstack, int pcstack_limit, uintptr_t pc, uintptr_t fp) { volatile uint16_t *flags = (volatile uint16_t *)&cpu_core[curcpu].cpuc_dtrace_flags; int ret = 0; uintptr_t oldfp = fp; ASSERT(pcstack == NULL || pcstack_limit > 0); while (pc != 0) { /* * We limit the number of times we can go around this * loop to account for a circular stack. */ if (ret++ >= MAX_USTACK_DEPTH) { *flags |= CPU_DTRACE_BADSTACK; cpu_core[curcpu].cpuc_dtrace_illval = fp; break; } if (pcstack != NULL) { *pcstack++ = (uint64_t)pc; pcstack_limit--; if (pcstack_limit <= 0) break; } if (fp == 0) break; pc = dtrace_fuword64((void *)(fp + offsetof(struct arm64_frame, f_retaddr))); fp = dtrace_fuword64((void *)fp); if (fp == oldfp) { *flags |= CPU_DTRACE_BADSTACK; cpu_core[curcpu].cpuc_dtrace_illval = fp; break; } /* * ARM64TODO: * This workaround might not be necessary. It needs to be * revised and removed from all architectures if found * unwanted. Leaving the original x86 comment for reference. * * This is totally bogus: if we faulted, we're going to clear * the fault and break. This is to deal with the apparently * broken Java stacks on x86. */ if (*flags & CPU_DTRACE_FAULT) { *flags &= ~CPU_DTRACE_FAULT; break; } oldfp = fp; } return (ret); } void dtrace_getupcstack(uint64_t *pcstack, int pcstack_limit) { proc_t *p = curproc; struct trapframe *tf; uintptr_t pc, fp; volatile uint16_t *flags = (volatile uint16_t *)&cpu_core[curcpu].cpuc_dtrace_flags; int n; if (*flags & CPU_DTRACE_FAULT) return; if (pcstack_limit <= 0) return; /* * If there's no user context we still need to zero the stack. */ if (p == NULL || (tf = curthread->td_frame) == NULL) goto zero; *pcstack++ = (uint64_t)p->p_pid; pcstack_limit--; if (pcstack_limit <= 0) return; pc = tf->tf_elr; fp = tf->tf_x[29]; if (DTRACE_CPUFLAG_ISSET(CPU_DTRACE_ENTRY)) { /* * In an entry probe. The frame pointer has not yet been * pushed (that happens in the function prologue). The * best approach is to add the current pc as a missing top * of stack and back the pc up to the caller, which is stored * at the current stack pointer address since the call * instruction puts it there right before the branch. */ *pcstack++ = (uint64_t)pc; pcstack_limit--; if (pcstack_limit <= 0) return; pc = tf->tf_lr; } n = dtrace_getustack_common(pcstack, pcstack_limit, pc, fp); ASSERT(n >= 0); ASSERT(n <= pcstack_limit); pcstack += n; pcstack_limit -= n; zero: while (pcstack_limit-- > 0) *pcstack++ = 0; } int dtrace_getustackdepth(void) { printf("IMPLEMENT ME: %s\n", __func__); return (0); } void dtrace_getufpstack(uint64_t *pcstack, uint64_t *fpstack, int pcstack_limit) { printf("IMPLEMENT ME: %s\n", __func__); } /*ARGSUSED*/ uint64_t dtrace_getarg(int arg, int aframes) { printf("IMPLEMENT ME: %s\n", __func__); return (0); } int dtrace_getstackdepth(int aframes) { struct unwind_state state; int scp_offset; int depth; bool done; depth = 1; done = false; state.fp = (uintptr_t)__builtin_frame_address(0); state.pc = (uintptr_t)dtrace_getstackdepth; do { done = !unwind_frame(curthread, &state); if (!INKERNEL(state.pc) || !INKERNEL(state.fp)) break; depth++; } while (!done); if (depth < aframes) return (0); else return (depth - aframes); } ulong_t dtrace_getreg(struct trapframe *rp, uint_t reg) { - - printf("IMPLEMENT ME: %s\n", __func__); - - return (0); + switch (reg) { + case REG_X0 ... REG_X29: + return (rp->tf_x[reg]); + case REG_LR: + return (rp->tf_lr); + case REG_SP: + return (rp->tf_sp); + case REG_PC: + return (rp->tf_elr); + default: + DTRACE_CPUFLAG_SET(CPU_DTRACE_ILLOP); + return (0); + } + /* NOTREACHED */ } static int dtrace_copycheck(uintptr_t uaddr, uintptr_t kaddr, size_t size) { if (uaddr + size > VM_MAXUSER_ADDRESS || uaddr + size < uaddr) { DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR); cpu_core[curcpu].cpuc_dtrace_illval = uaddr; return (0); } return (1); } void dtrace_copyin(uintptr_t uaddr, uintptr_t kaddr, size_t size, volatile uint16_t *flags) { if (dtrace_copycheck(uaddr, kaddr, size)) dtrace_copy(uaddr, kaddr, size); } void dtrace_copyout(uintptr_t kaddr, uintptr_t uaddr, size_t size, volatile uint16_t *flags) { if (dtrace_copycheck(uaddr, kaddr, size)) dtrace_copy(kaddr, uaddr, size); } void dtrace_copyinstr(uintptr_t uaddr, uintptr_t kaddr, size_t size, volatile uint16_t *flags) { if (dtrace_copycheck(uaddr, kaddr, size)) dtrace_copystr(uaddr, kaddr, size, flags); } void dtrace_copyoutstr(uintptr_t kaddr, uintptr_t uaddr, size_t size, volatile uint16_t *flags) { if (dtrace_copycheck(uaddr, kaddr, size)) dtrace_copystr(kaddr, uaddr, size, flags); } uint8_t dtrace_fuword8(void *uaddr) { if ((uintptr_t)uaddr > VM_MAXUSER_ADDRESS) { DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR); cpu_core[curcpu].cpuc_dtrace_illval = (uintptr_t)uaddr; return (0); } return (dtrace_fuword8_nocheck(uaddr)); } uint16_t dtrace_fuword16(void *uaddr) { if ((uintptr_t)uaddr > VM_MAXUSER_ADDRESS) { DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR); cpu_core[curcpu].cpuc_dtrace_illval = (uintptr_t)uaddr; return (0); } return (dtrace_fuword16_nocheck(uaddr)); } uint32_t dtrace_fuword32(void *uaddr) { if ((uintptr_t)uaddr > VM_MAXUSER_ADDRESS) { DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR); cpu_core[curcpu].cpuc_dtrace_illval = (uintptr_t)uaddr; return (0); } return (dtrace_fuword32_nocheck(uaddr)); } uint64_t dtrace_fuword64(void *uaddr) { if ((uintptr_t)uaddr > VM_MAXUSER_ADDRESS) { DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR); cpu_core[curcpu].cpuc_dtrace_illval = (uintptr_t)uaddr; return (0); } return (dtrace_fuword64_nocheck(uaddr)); } diff --git a/sys/cddl/dev/dtrace/aarch64/regset.h b/sys/cddl/dev/dtrace/aarch64/regset.h index f99b48f8354f..492405d4a258 100644 --- a/sys/cddl/dev/dtrace/aarch64/regset.h +++ b/sys/cddl/dev/dtrace/aarch64/regset.h @@ -1,51 +1,84 @@ /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END * * $FreeBSD$ */ /* * Copyright 2004 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* Copyright (c) 1990, 1991 UNIX System Laboratories, Inc. */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */ #ifndef _REGSET_H #define _REGSET_H /* * #pragma ident "@(#)regset.h 1.11 05/06/08 SMI" */ #ifdef __cplusplus extern "C" { #endif -/* Place here */ +#define REG_X0 0 +#define REG_X1 1 +#define REG_X2 2 +#define REG_X3 3 +#define REG_X4 4 +#define REG_X5 5 +#define REG_X6 6 +#define REG_X7 7 +#define REG_X8 8 +#define REG_X9 9 +#define REG_X10 10 +#define REG_X11 11 +#define REG_X12 12 +#define REG_X13 13 +#define REG_X14 14 +#define REG_X15 15 +#define REG_X16 16 +#define REG_X17 17 +#define REG_X18 18 +#define REG_X19 19 +#define REG_X20 20 +#define REG_X21 21 +#define REG_X22 22 +#define REG_X23 23 +#define REG_X24 24 +#define REG_X25 25 +#define REG_X26 26 +#define REG_X27 27 +#define REG_X28 28 +#define REG_X29 29 +#define REG_FP REG_X29 +#define REG_LR 30 +#define REG_SP 31 +#define REG_PC 32 #ifdef __cplusplus } #endif #endif /* _REGSET_H */