Home | History | Annotate | Line # | Download | only in fbt
fbt.c revision 1.19
      1  1.19  pgoyette /*	$NetBSD: fbt.c,v 1.19 2016/07/17 02:09:10 pgoyette Exp $	*/
      2   1.2    darran 
      3   1.1    darran /*
      4   1.1    darran  * CDDL HEADER START
      5   1.1    darran  *
      6   1.1    darran  * The contents of this file are subject to the terms of the
      7   1.1    darran  * Common Development and Distribution License (the "License").
      8   1.1    darran  * You may not use this file except in compliance with the License.
      9   1.1    darran  *
     10   1.1    darran  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
     11   1.1    darran  * or http://www.opensolaris.org/os/licensing.
     12   1.1    darran  * See the License for the specific language governing permissions
     13   1.1    darran  * and limitations under the License.
     14   1.1    darran  *
     15   1.1    darran  * When distributing Covered Code, include this CDDL HEADER in each
     16   1.1    darran  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     17   1.1    darran  * If applicable, add the following below this CDDL HEADER, with the
     18   1.1    darran  * fields enclosed by brackets "[]" replaced with your own identifying
     19   1.1    darran  * information: Portions Copyright [yyyy] [name of copyright owner]
     20   1.1    darran  *
     21   1.1    darran  * CDDL HEADER END
     22   1.1    darran  *
     23   1.1    darran  * Portions Copyright 2006-2008 John Birrell jb (at) freebsd.org
     24   1.3    darran  * Portions Copyright 2010 Darran Hunt darran (at) NetBSD.org
     25   1.1    darran  *
     26   1.1    darran  * $FreeBSD: src/sys/cddl/dev/fbt/fbt.c,v 1.1.4.1 2009/08/03 08:13:06 kensmith Exp $
     27   1.1    darran  *
     28   1.1    darran  */
     29   1.1    darran 
     30   1.1    darran /*
     31   1.1    darran  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
     32   1.1    darran  * Use is subject to license terms.
     33   1.1    darran  */
     34   1.1    darran 
     35   1.1    darran #include <sys/cdefs.h>
     36   1.1    darran #include <sys/param.h>
     37   1.1    darran #include <sys/systm.h>
     38   1.1    darran #include <sys/conf.h>
     39   1.1    darran #include <sys/cpuvar.h>
     40   1.1    darran #include <sys/fcntl.h>
     41   1.1    darran #include <sys/filio.h>
     42   1.1    darran #include <sys/kernel.h>
     43   1.1    darran #include <sys/kmem.h>
     44   1.5  christos #include <sys/ksyms.h>
     45   1.3    darran #include <sys/cpu.h>
     46   1.1    darran #include <sys/kthread.h>
     47   1.1    darran #include <sys/limits.h>
     48   1.1    darran #include <sys/linker.h>
     49   1.1    darran #include <sys/lock.h>
     50   1.1    darran #include <sys/malloc.h>
     51   1.1    darran #include <sys/module.h>
     52   1.1    darran #include <sys/mutex.h>
     53   1.1    darran #include <sys/poll.h>
     54   1.1    darran #include <sys/proc.h>
     55   1.1    darran #include <sys/selinfo.h>
     56   1.1    darran #include <sys/syscall.h>
     57   1.1    darran #include <sys/uio.h>
     58   1.1    darran #include <sys/unistd.h>
     59   1.1    darran 
     60   1.3    darran #include <machine/cpu.h>
     61  1.14     ozaki #if defined(__i386__) || defined(__amd64__)
     62   1.3    darran #include <machine/cpufunc.h>
     63   1.3    darran #include <machine/specialreg.h>
     64   1.3    darran #if 0
     65   1.3    darran #include <x86/cpuvar.h>
     66   1.3    darran #endif
     67   1.3    darran #include <x86/cputypes.h>
     68  1.14     ozaki #elif __arm__
     69  1.14     ozaki #include <machine/trap.h>
     70  1.14     ozaki #include <arm/cpufunc.h>
     71  1.14     ozaki #include <arm/armreg.h>
     72  1.14     ozaki #include <arm/frame.h>
     73  1.14     ozaki #endif
     74   1.3    darran 
     75   1.3    darran #define ELFSIZE ARCH_ELFSIZE
     76   1.3    darran #include <sys/exec_elf.h>
     77   1.3    darran 
     78   1.1    darran #include <sys/dtrace.h>
     79   1.1    darran #include <sys/dtrace_bsd.h>
     80   1.3    darran #include <sys/kern_ctf.h>
     81   1.7      tron #include <sys/dtrace_impl.h>
     82   1.3    darran 
     83   1.3    darran mod_ctf_t *modptr;
     84   1.1    darran 
     85   1.1    darran MALLOC_DEFINE(M_FBT, "fbt", "Function Boundary Tracing");
     86   1.1    darran 
     87  1.14     ozaki #if defined(__i386__) || defined(__amd64__)
     88   1.1    darran #define	FBT_PUSHL_EBP		0x55
     89   1.1    darran #define	FBT_MOVL_ESP_EBP0_V0	0x8b
     90   1.1    darran #define	FBT_MOVL_ESP_EBP1_V0	0xec
     91   1.1    darran #define	FBT_MOVL_ESP_EBP0_V1	0x89
     92   1.1    darran #define	FBT_MOVL_ESP_EBP1_V1	0xe5
     93   1.1    darran #define	FBT_REX_RSP_RBP		0x48
     94   1.1    darran 
     95   1.1    darran #define	FBT_POPL_EBP		0x5d
     96   1.1    darran #define	FBT_RET			0xc3
     97   1.1    darran #define	FBT_RET_IMM16		0xc2
     98   1.1    darran #define	FBT_LEAVE		0xc9
     99  1.14     ozaki #endif
    100   1.1    darran 
    101   1.1    darran #ifdef __amd64__
    102   1.1    darran #define	FBT_PATCHVAL		0xcc
    103  1.14     ozaki #elif defined(__i386__)
    104  1.14     ozaki #define	FBT_PATCHVAL		0xf0
    105  1.14     ozaki 
    106  1.14     ozaki #elif defined(__arm__)
    107  1.14     ozaki #define	FBT_PATCHVAL		DTRACE_BREAKPOINT
    108  1.14     ozaki 
    109  1.14     ozaki /* entry and return */
    110  1.14     ozaki #define	FBT_BX_LR_P(insn)	(((insn) & ~INSN_COND_MASK) == 0x012fff1e)
    111  1.14     ozaki #define	FBT_B_LABEL_P(insn)	(((insn) & 0xff000000) == 0xea000000)
    112  1.14     ozaki /* entry */
    113  1.14     ozaki #define	FBT_MOV_IP_SP_P(insn)	((insn) == 0xe1a0c00d)
    114  1.14     ozaki /* index=1, add=1, wback=0 */
    115  1.14     ozaki #define	FBT_LDR_IMM_P(insn)	(((insn) & 0xfff00000) == 0xe5900000)
    116  1.14     ozaki #define	FBT_MOVW_P(insn)	(((insn) & 0xfff00000) == 0xe3000000)
    117  1.14     ozaki #define	FBT_MOV_IMM_P(insn)	(((insn) & 0xffff0000) == 0xe3a00000)
    118  1.14     ozaki #define	FBT_CMP_IMM_P(insn)	(((insn) & 0xfff00000) == 0xe3500000)
    119  1.14     ozaki #define	FBT_PUSH_P(insn)	(((insn) & 0xffff0000) == 0xe92d0000)
    120  1.14     ozaki /* return */
    121  1.14     ozaki /* cond=always, writeback=no, rn=sp and register_list includes pc */
    122  1.14     ozaki #define	FBT_LDM_P(insn)	(((insn) & 0x0fff8000) == 0x089d8000)
    123  1.14     ozaki #define	FBT_LDMIB_P(insn)	(((insn) & 0x0fff8000) == 0x099d8000)
    124  1.14     ozaki #define	FBT_MOV_PC_LR_P(insn)	(((insn) & ~INSN_COND_MASK) == 0x01a0f00e)
    125  1.14     ozaki /* cond=always, writeback=no, rn=sp and register_list includes lr, but not pc */
    126  1.14     ozaki #define	FBT_LDM_LR_P(insn)	(((insn) & 0xffffc000) == 0xe89d4000)
    127  1.14     ozaki #define	FBT_LDMIB_LR_P(insn)	(((insn) & 0xffffc000) == 0xe99d4000)
    128  1.14     ozaki 
    129  1.14     ozaki /* rval = insn | invop_id (overwriting cond with invop ID) */
    130  1.14     ozaki #define	BUILD_RVAL(insn, id)	(((insn) & ~INSN_COND_MASK) | __SHIFTIN((id), INSN_COND_MASK))
    131  1.14     ozaki /* encode cond in the first byte */
    132  1.14     ozaki #define	PATCHVAL_ENCODE_COND(insn)	(FBT_PATCHVAL | __SHIFTOUT((insn), INSN_COND_MASK))
    133  1.14     ozaki 
    134   1.1    darran #else
    135  1.14     ozaki #error "architecture not supported"
    136   1.1    darran #endif
    137   1.1    darran 
    138   1.3    darran static dev_type_open(fbt_open);
    139   1.1    darran static int	fbt_unload(void);
    140   1.1    darran static void	fbt_getargdesc(void *, dtrace_id_t, void *, dtrace_argdesc_t *);
    141   1.3    darran static void	fbt_provide_module(void *, dtrace_modctl_t *);
    142   1.1    darran static void	fbt_destroy(void *, dtrace_id_t, void *);
    143   1.3    darran static int	fbt_enable(void *, dtrace_id_t, void *);
    144   1.1    darran static void	fbt_disable(void *, dtrace_id_t, void *);
    145   1.3    darran static void	fbt_load(void);
    146   1.1    darran static void	fbt_suspend(void *, dtrace_id_t, void *);
    147   1.1    darran static void	fbt_resume(void *, dtrace_id_t, void *);
    148   1.1    darran 
    149   1.1    darran #define	FBT_ENTRY	"entry"
    150   1.1    darran #define	FBT_RETURN	"return"
    151   1.1    darran #define	FBT_ADDR2NDX(addr)	((((uintptr_t)(addr)) >> 4) & fbt_probetab_mask)
    152   1.1    darran #define	FBT_PROBETAB_SIZE	0x8000		/* 32k entries -- 128K total */
    153   1.1    darran 
    154   1.3    darran static const struct cdevsw fbt_cdevsw = {
    155  1.19  pgoyette 	.d_open		= fbt_open,
    156  1.19  pgoyette 	.d_close	= noclose,
    157  1.19  pgoyette 	.d_read		= noread,
    158  1.19  pgoyette 	.d_write	= nowrite,
    159  1.19  pgoyette 	.d_ioctl	= noioctl,
    160  1.19  pgoyette 	.d_stop		= nostop,
    161  1.19  pgoyette 	.d_tty		= notty,
    162  1.19  pgoyette 	.d_poll		= nopoll,
    163  1.19  pgoyette 	.d_mmap		= nommap,
    164  1.19  pgoyette 	.d_kqfilter	= nokqfilter,
    165  1.19  pgoyette 	.d_discard	= nodiscard,
    166  1.19  pgoyette 	.d_flag		= D_OTHER
    167   1.1    darran };
    168   1.1    darran 
    169   1.1    darran static dtrace_pattr_t fbt_attr = {
    170   1.1    darran { DTRACE_STABILITY_EVOLVING, DTRACE_STABILITY_EVOLVING, DTRACE_CLASS_COMMON },
    171   1.1    darran { DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_UNKNOWN },
    172   1.1    darran { DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_ISA },
    173   1.1    darran { DTRACE_STABILITY_EVOLVING, DTRACE_STABILITY_EVOLVING, DTRACE_CLASS_COMMON },
    174   1.1    darran { DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_ISA },
    175   1.1    darran };
    176   1.1    darran 
    177   1.1    darran static dtrace_pops_t fbt_pops = {
    178   1.1    darran 	NULL,
    179   1.1    darran 	fbt_provide_module,
    180   1.1    darran 	fbt_enable,
    181   1.1    darran 	fbt_disable,
    182   1.1    darran 	fbt_suspend,
    183   1.1    darran 	fbt_resume,
    184   1.1    darran 	fbt_getargdesc,
    185   1.1    darran 	NULL,
    186   1.1    darran 	NULL,
    187   1.1    darran 	fbt_destroy
    188   1.1    darran };
    189   1.1    darran 
    190   1.1    darran typedef struct fbt_probe {
    191   1.1    darran 	struct fbt_probe *fbtp_hashnext;
    192  1.14     ozaki #if defined(__i386__) || defined(__amd64__)
    193   1.1    darran 	uint8_t		*fbtp_patchpoint;
    194   1.1    darran 	int8_t		fbtp_rval;
    195   1.1    darran 	uint8_t		fbtp_patchval;
    196   1.1    darran 	uint8_t		fbtp_savedval;
    197  1.14     ozaki #elif __arm__
    198  1.14     ozaki 	uint32_t	*fbtp_patchpoint;
    199  1.14     ozaki 	int32_t		fbtp_rval;
    200  1.14     ozaki 	uint32_t	fbtp_patchval;
    201  1.14     ozaki 	uint32_t	fbtp_savedval;
    202  1.14     ozaki #endif
    203   1.1    darran 	uintptr_t	fbtp_roffset;
    204   1.1    darran 	dtrace_id_t	fbtp_id;
    205   1.1    darran 	const char	*fbtp_name;
    206   1.3    darran 	dtrace_modctl_t	*fbtp_ctl;
    207   1.1    darran 	int		fbtp_loadcnt;
    208   1.1    darran 	int		fbtp_primary;
    209   1.1    darran 	int		fbtp_invop_cnt;
    210   1.1    darran 	int		fbtp_symindx;
    211   1.1    darran 	struct fbt_probe *fbtp_next;
    212   1.1    darran } fbt_probe_t;
    213   1.1    darran 
    214   1.5  christos #ifdef notyet
    215   1.1    darran static struct cdev		*fbt_cdev;
    216   1.5  christos static int			fbt_verbose = 0;
    217   1.5  christos #endif
    218   1.1    darran static dtrace_provider_id_t	fbt_id;
    219   1.1    darran static fbt_probe_t		**fbt_probetab;
    220   1.1    darran static int			fbt_probetab_size;
    221   1.1    darran static int			fbt_probetab_mask;
    222   1.1    darran 
    223  1.14     ozaki #ifdef __arm__
    224  1.14     ozaki extern void (* dtrace_emulation_jump_addr)(int, struct trapframe *);
    225  1.14     ozaki 
    226  1.14     ozaki static uint32_t
    227  1.14     ozaki expand_imm(uint32_t imm12)
    228  1.14     ozaki {
    229  1.14     ozaki 	uint32_t unrot = imm12 & 0xff;
    230  1.14     ozaki 	int amount = 2 * (imm12 >> 8);
    231  1.14     ozaki 
    232  1.14     ozaki 	if (amount)
    233  1.14     ozaki 		return (unrot >> amount) | (unrot << (32 - amount));
    234  1.14     ozaki 	else
    235  1.14     ozaki 		return unrot;
    236  1.14     ozaki }
    237  1.14     ozaki 
    238  1.14     ozaki static uint32_t
    239  1.14     ozaki add_with_carry(uint32_t x, uint32_t y, int carry_in,
    240  1.14     ozaki 	int *carry_out, int *overflow)
    241  1.14     ozaki {
    242  1.14     ozaki 	uint32_t result;
    243  1.14     ozaki 	uint64_t unsigned_sum = x + y + (uint32_t)carry_in;
    244  1.14     ozaki 	int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in;
    245  1.14     ozaki 	KASSERT(carry_in == 1);
    246  1.14     ozaki 
    247  1.14     ozaki 	result = (uint32_t)(unsigned_sum & 0xffffffff);
    248  1.14     ozaki 	*carry_out = ((uint64_t)result == unsigned_sum) ? 1 : 0;
    249  1.14     ozaki 	*overflow = ((int64_t)result == signed_sum) ? 0 : 1;
    250  1.14     ozaki 
    251  1.14     ozaki 	return result;
    252  1.14     ozaki }
    253  1.14     ozaki 
    254  1.14     ozaki static void
    255  1.14     ozaki fbt_emulate(int _op, struct trapframe *frame)
    256  1.14     ozaki {
    257  1.14     ozaki 	uint32_t op = _op;
    258  1.14     ozaki 
    259  1.14     ozaki 	switch (op >> 28) {
    260  1.14     ozaki 	case DTRACE_INVOP_MOV_IP_SP:
    261  1.14     ozaki 		/* mov ip, sp */
    262  1.14     ozaki 		frame->tf_ip = frame->tf_svc_sp;
    263  1.14     ozaki 		frame->tf_pc += 4;
    264  1.14     ozaki 		break;
    265  1.14     ozaki 	case DTRACE_INVOP_BX_LR:
    266  1.14     ozaki 		/* bx lr */
    267  1.14     ozaki 		frame->tf_pc = frame->tf_svc_lr;
    268  1.14     ozaki 		break;
    269  1.14     ozaki 	case DTRACE_INVOP_MOV_PC_LR:
    270  1.14     ozaki 		/* mov pc, lr */
    271  1.14     ozaki 		frame->tf_pc = frame->tf_svc_lr;
    272  1.14     ozaki 		break;
    273  1.14     ozaki 	case DTRACE_INVOP_LDM:
    274  1.14     ozaki 		/* ldm sp, {..., pc} */
    275  1.14     ozaki 		/* FALLTHRU */
    276  1.14     ozaki 	case DTRACE_INVOP_LDMIB: {
    277  1.14     ozaki 		/* ldmib sp, {..., pc} */
    278  1.14     ozaki 		uint32_t register_list = (op & 0xffff);
    279  1.14     ozaki 		uint32_t *sp = (uint32_t *)(intptr_t)frame->tf_svc_sp;
    280  1.14     ozaki 		uint32_t *regs = &frame->tf_r0;
    281  1.14     ozaki 		int i;
    282  1.14     ozaki 
    283  1.14     ozaki 		/* IDMIB */
    284  1.14     ozaki 		if ((op >> 28) == 5)
    285  1.14     ozaki 			sp++;
    286  1.14     ozaki 
    287  1.14     ozaki 		for (i=0; i <= 12; i++) {
    288  1.14     ozaki 			if (register_list & (1 << i))
    289  1.14     ozaki 				regs[i] = *sp++;
    290  1.14     ozaki 		}
    291  1.14     ozaki 		if (register_list & (1 << 13))
    292  1.14     ozaki 			frame->tf_svc_sp = *sp++;
    293  1.14     ozaki 		if (register_list & (1 << 14))
    294  1.14     ozaki 			frame->tf_svc_lr = *sp++;
    295  1.14     ozaki 		frame->tf_pc = *sp;
    296  1.14     ozaki 		break;
    297  1.14     ozaki 	}
    298  1.14     ozaki 	case DTRACE_INVOP_LDR_IMM: {
    299  1.14     ozaki 		/* ldr r?, [{pc,r?}, #?] */
    300  1.14     ozaki 		uint32_t rt = (op >> 12) & 0xf;
    301  1.14     ozaki 		uint32_t rn = (op >> 16) & 0xf;
    302  1.14     ozaki 		uint32_t imm = op & 0xfff;
    303  1.14     ozaki 		uint32_t *regs = &frame->tf_r0;
    304  1.14     ozaki 		KDASSERT(rt <= 12);
    305  1.14     ozaki 		KDASSERT(rn == 15 || rn =< 12);
    306  1.14     ozaki 		if (rn == 15)
    307  1.14     ozaki 			regs[rt] = *((uint32_t *)(intptr_t)(frame->tf_pc + 8 + imm));
    308  1.14     ozaki 		else
    309  1.14     ozaki 			regs[rt] = *((uint32_t *)(intptr_t)(regs[rn] + imm));
    310  1.14     ozaki 		frame->tf_pc += 4;
    311  1.14     ozaki 		break;
    312  1.14     ozaki 	}
    313  1.14     ozaki 	case DTRACE_INVOP_MOVW: {
    314  1.14     ozaki 		/* movw r?, #? */
    315  1.14     ozaki 		uint32_t rd = (op >> 12) & 0xf;
    316  1.14     ozaki 		uint32_t imm = (op & 0xfff) | ((op & 0xf0000) >> 4);
    317  1.14     ozaki 		uint32_t *regs = &frame->tf_r0;
    318  1.14     ozaki 		KDASSERT(rd <= 12);
    319  1.14     ozaki 		regs[rd] = imm;
    320  1.14     ozaki 		frame->tf_pc += 4;
    321  1.14     ozaki 		break;
    322  1.14     ozaki 	}
    323  1.14     ozaki 	case DTRACE_INVOP_MOV_IMM: {
    324  1.14     ozaki 		/* mov r?, #? */
    325  1.14     ozaki 		uint32_t rd = (op >> 12) & 0xf;
    326  1.14     ozaki 		uint32_t imm = expand_imm(op & 0xfff);
    327  1.14     ozaki 		uint32_t *regs = &frame->tf_r0;
    328  1.14     ozaki 		KDASSERT(rd <= 12);
    329  1.14     ozaki 		regs[rd] = imm;
    330  1.14     ozaki 		frame->tf_pc += 4;
    331  1.14     ozaki 		break;
    332  1.14     ozaki 	}
    333  1.14     ozaki 	case DTRACE_INVOP_CMP_IMM: {
    334  1.14     ozaki 		/* cmp r?, #? */
    335  1.14     ozaki 		uint32_t rn = (op >> 16) & 0xf;
    336  1.14     ozaki 		uint32_t *regs = &frame->tf_r0;
    337  1.14     ozaki 		uint32_t imm = expand_imm(op & 0xfff);
    338  1.14     ozaki 		uint32_t spsr = frame->tf_spsr;
    339  1.14     ozaki 		uint32_t result;
    340  1.14     ozaki 		int carry;
    341  1.14     ozaki 		int overflow;
    342  1.14     ozaki 		/*
    343  1.14     ozaki 		 * (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), 1);
    344  1.14     ozaki 		 * APSR.N = result<31>;
    345  1.14     ozaki 		 * APSR.Z = IsZeroBit(result);
    346  1.14     ozaki 		 * APSR.C = carry;
    347  1.14     ozaki 		 * APSR.V = overflow;
    348  1.14     ozaki 		 */
    349  1.14     ozaki 		KDASSERT(rn <= 12);
    350  1.14     ozaki 		result = add_with_carry(regs[rn], ~imm, 1, &carry, &overflow);
    351  1.14     ozaki 		if (result & 0x80000000)
    352  1.14     ozaki 			spsr |= PSR_N_bit;
    353  1.14     ozaki 		else
    354  1.14     ozaki 			spsr &= ~PSR_N_bit;
    355  1.14     ozaki 		if (result == 0)
    356  1.14     ozaki 			spsr |= PSR_Z_bit;
    357  1.14     ozaki 		else
    358  1.14     ozaki 			spsr &= ~PSR_Z_bit;
    359  1.14     ozaki 		if (carry)
    360  1.14     ozaki 			spsr |= PSR_C_bit;
    361  1.14     ozaki 		else
    362  1.14     ozaki 			spsr &= ~PSR_C_bit;
    363  1.14     ozaki 		if (overflow)
    364  1.14     ozaki 			spsr |= PSR_V_bit;
    365  1.14     ozaki 		else
    366  1.14     ozaki 			spsr &= ~PSR_V_bit;
    367  1.14     ozaki 
    368  1.14     ozaki #if 0
    369  1.14     ozaki 		aprint_normal("pc=%x Rn=%x imm=%x %c%c%c%c\n", frame->tf_pc, regs[rn], imm,
    370  1.14     ozaki 		    (spsr & PSR_N_bit) ? 'N' : 'n',
    371  1.14     ozaki 		    (spsr & PSR_Z_bit) ? 'Z' : 'z',
    372  1.14     ozaki 		    (spsr & PSR_C_bit) ? 'C' : 'c',
    373  1.14     ozaki 		    (spsr & PSR_V_bit) ? 'V' : 'v');
    374  1.14     ozaki #endif
    375  1.14     ozaki 		frame->tf_spsr = spsr;
    376  1.14     ozaki 		frame->tf_pc += 4;
    377  1.14     ozaki 		break;
    378  1.14     ozaki 	}
    379  1.14     ozaki 	case DTRACE_INVOP_B_LABEL: {
    380  1.14     ozaki 		/* b ??? */
    381  1.14     ozaki 		uint32_t imm = (op & 0x00ffffff) << 2;
    382  1.14     ozaki 		int32_t diff;
    383  1.14     ozaki 		/* SignExtend(imm26, 32) */
    384  1.14     ozaki 		if (imm & 0x02000000)
    385  1.14     ozaki 			imm |= 0xfc000000;
    386  1.14     ozaki 		diff = (int32_t)imm;
    387  1.14     ozaki 		frame->tf_pc += 8 + diff;
    388  1.14     ozaki 		break;
    389  1.14     ozaki 	}
    390  1.14     ozaki 	/* FIXME: push will overwrite trapframe... */
    391  1.14     ozaki 	case DTRACE_INVOP_PUSH: {
    392  1.14     ozaki 		/* push {...} */
    393  1.14     ozaki 		uint32_t register_list = (op & 0xffff);
    394  1.14     ozaki 		uint32_t *sp = (uint32_t *)(intptr_t)frame->tf_svc_sp;
    395  1.14     ozaki 		uint32_t *regs = &frame->tf_r0;
    396  1.14     ozaki 		int i;
    397  1.14     ozaki 		int count = 0;
    398  1.14     ozaki 
    399  1.14     ozaki #if 0
    400  1.14     ozaki 		if ((op & 0x0fff0fff) == 0x052d0004) {
    401  1.14     ozaki 			/* A2: str r4, [sp, #-4]! */
    402  1.14     ozaki 			*(sp - 1) = regs[4];
    403  1.14     ozaki 			frame->tf_pc += 4;
    404  1.14     ozaki 			break;
    405  1.14     ozaki 		}
    406  1.14     ozaki #endif
    407  1.14     ozaki 
    408  1.14     ozaki 		for (i=0; i < 16; i++) {
    409  1.14     ozaki 			if (register_list & (1 << i))
    410  1.14     ozaki 				count++;
    411  1.14     ozaki 		}
    412  1.14     ozaki 		sp -= count;
    413  1.14     ozaki 
    414  1.14     ozaki 		for (i=0; i <= 12; i++) {
    415  1.14     ozaki 			if (register_list & (1 << i))
    416  1.14     ozaki 				*sp++ = regs[i];
    417  1.14     ozaki 		}
    418  1.14     ozaki 		if (register_list & (1 << 13))
    419  1.14     ozaki 			*sp++ = frame->tf_svc_sp;
    420  1.14     ozaki 		if (register_list & (1 << 14))
    421  1.14     ozaki 			*sp++ = frame->tf_svc_lr;
    422  1.14     ozaki 		if (register_list & (1 << 15))
    423  1.14     ozaki 			*sp = frame->tf_pc + 8;
    424  1.14     ozaki 
    425  1.14     ozaki 		/* make sure the caches and memory are in sync */
    426  1.14     ozaki 		cpu_dcache_wbinv_range(frame->tf_svc_sp, count * 4);
    427  1.14     ozaki 
    428  1.14     ozaki 		/* In case the current page tables have been modified ... */
    429  1.14     ozaki 		cpu_tlb_flushID();
    430  1.14     ozaki 		cpu_cpwait();
    431  1.14     ozaki 
    432  1.14     ozaki 		frame->tf_svc_sp -= count * 4;
    433  1.14     ozaki 		frame->tf_pc += 4;
    434  1.14     ozaki 
    435  1.14     ozaki 		break;
    436  1.14     ozaki 	}
    437  1.14     ozaki 	default:
    438  1.14     ozaki 		KDASSERTMSG(0, "op=%u\n", op >> 28);
    439  1.14     ozaki 	}
    440  1.14     ozaki }
    441  1.14     ozaki #endif
    442  1.14     ozaki 
    443   1.1    darran static void
    444   1.1    darran fbt_doubletrap(void)
    445   1.1    darran {
    446   1.1    darran 	fbt_probe_t *fbt;
    447   1.1    darran 	int i;
    448   1.1    darran 
    449   1.1    darran 	for (i = 0; i < fbt_probetab_size; i++) {
    450   1.1    darran 		fbt = fbt_probetab[i];
    451   1.1    darran 
    452   1.1    darran 		for (; fbt != NULL; fbt = fbt->fbtp_next)
    453   1.1    darran 			*fbt->fbtp_patchpoint = fbt->fbtp_savedval;
    454   1.1    darran 	}
    455   1.1    darran }
    456   1.1    darran 
    457   1.3    darran 
    458   1.1    darran static int
    459   1.1    darran fbt_invop(uintptr_t addr, uintptr_t *stack, uintptr_t rval)
    460   1.1    darran {
    461  1.11       chs 	solaris_cpu_t *cpu = &solaris_cpu[cpu_number()];
    462   1.1    darran 	uintptr_t stack0, stack1, stack2, stack3, stack4;
    463   1.1    darran 	fbt_probe_t *fbt = fbt_probetab[FBT_ADDR2NDX(addr)];
    464   1.1    darran 
    465   1.1    darran 	for (; fbt != NULL; fbt = fbt->fbtp_hashnext) {
    466   1.1    darran 		if ((uintptr_t)fbt->fbtp_patchpoint == addr) {
    467   1.1    darran 			fbt->fbtp_invop_cnt++;
    468   1.1    darran 			if (fbt->fbtp_roffset == 0) {
    469   1.1    darran 				int i = 0;
    470   1.1    darran 				/*
    471   1.1    darran 				 * When accessing the arguments on the stack,
    472   1.1    darran 				 * we must protect against accessing beyond
    473   1.1    darran 				 * the stack.  We can safely set NOFAULT here
    474   1.1    darran 				 * -- we know that interrupts are already
    475   1.1    darran 				 * disabled.
    476   1.1    darran 				 */
    477   1.1    darran 				DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);
    478  1.11       chs 				cpu->cpu_dtrace_caller = stack[i++];
    479   1.1    darran 				stack0 = stack[i++];
    480   1.1    darran 				stack1 = stack[i++];
    481   1.1    darran 				stack2 = stack[i++];
    482   1.1    darran 				stack3 = stack[i++];
    483   1.1    darran 				stack4 = stack[i++];
    484   1.1    darran 				DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT |
    485   1.1    darran 				    CPU_DTRACE_BADADDR);
    486   1.1    darran 
    487   1.1    darran 				dtrace_probe(fbt->fbtp_id, stack0, stack1,
    488   1.1    darran 				    stack2, stack3, stack4);
    489   1.1    darran 
    490  1.11       chs 				cpu->cpu_dtrace_caller = 0;
    491   1.1    darran 			} else {
    492   1.1    darran #ifdef __amd64__
    493   1.1    darran 				/*
    494   1.1    darran 				 * On amd64, we instrument the ret, not the
    495   1.1    darran 				 * leave.  We therefore need to set the caller
    496   1.1    darran 				 * to assure that the top frame of a stack()
    497   1.1    darran 				 * action is correct.
    498   1.1    darran 				 */
    499   1.1    darran 				DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);
    500  1.11       chs 				cpu->cpu_dtrace_caller = stack[0];
    501   1.1    darran 				DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT |
    502   1.1    darran 				    CPU_DTRACE_BADADDR);
    503   1.1    darran #endif
    504   1.1    darran 
    505   1.1    darran 				dtrace_probe(fbt->fbtp_id, fbt->fbtp_roffset,
    506   1.1    darran 				    rval, 0, 0, 0);
    507  1.11       chs 				cpu->cpu_dtrace_caller = 0;
    508   1.1    darran 			}
    509   1.1    darran 
    510   1.1    darran 			return (fbt->fbtp_rval);
    511   1.1    darran 		}
    512   1.1    darran 	}
    513   1.1    darran 
    514   1.1    darran 	return (0);
    515   1.1    darran }
    516   1.1    darran 
    517  1.14     ozaki #if defined(__i386__) || defined(__amd64__)
    518   1.1    darran static int
    519   1.3    darran fbt_provide_module_cb(const char *name, int symindx, void *value,
    520   1.4    darran 	uint32_t symsize, int type, void *opaque)
    521   1.1    darran {
    522   1.1    darran 	fbt_probe_t *fbt, *retfbt;
    523   1.3    darran 	u_int8_t *instr, *limit;
    524   1.3    darran 	dtrace_modctl_t *mod = opaque;
    525   1.3    darran 	const char *modname = mod->mod_info->mi_name;
    526   1.1    darran 	int j;
    527   1.4    darran 	int size;
    528   1.3    darran 
    529   1.3    darran 	/* got a function? */
    530   1.3    darran 	if (ELF_ST_TYPE(type) != STT_FUNC) {
    531   1.3    darran 	    return 0;
    532   1.3    darran 	}
    533   1.1    darran 
    534   1.1    darran 	if (strncmp(name, "dtrace_", 7) == 0 &&
    535   1.1    darran 	    strncmp(name, "dtrace_safe_", 12) != 0) {
    536   1.1    darran 		/*
    537   1.1    darran 		 * Anything beginning with "dtrace_" may be called
    538   1.1    darran 		 * from probe context unless it explicitly indicates
    539   1.1    darran 		 * that it won't be called from probe context by
    540   1.1    darran 		 * using the prefix "dtrace_safe_".
    541   1.1    darran 		 */
    542   1.1    darran 		return (0);
    543   1.1    darran 	}
    544   1.1    darran 
    545   1.1    darran 	if (name[0] == '_' && name[1] == '_')
    546   1.1    darran 		return (0);
    547   1.1    darran 
    548  1.10      yamt 	/*
    549  1.10      yamt 	 * Exclude some more symbols which can be called from probe context.
    550  1.10      yamt 	 */
    551  1.10      yamt 	if (strcmp(name, "x86_curcpu") == 0 /* CPU */
    552  1.10      yamt 	    || strcmp(name, "x86_curlwp") == 0 /* curproc, curlwp, curthread */
    553  1.10      yamt 	    || strcmp(name, "cpu_index") == 0 /* cpu_number, curcpu_id */
    554  1.10      yamt 	    || strncmp(name, "db_", 3) == 0 /* debugger */
    555  1.10      yamt 	    || strncmp(name, "ddb_", 4) == 0 /* debugger */
    556  1.10      yamt 	    || strncmp(name, "kdb_", 4) == 0 /* debugger */
    557  1.10      yamt 	    || strncmp(name, "lockdebug_", 10) == 0 /* lockdebug XXX for now */
    558  1.10      yamt 	    || strncmp(name, "kauth_", 5) == 0 /* CRED XXX for now */
    559  1.10      yamt 	    ) {
    560  1.10      yamt 		return 0;
    561  1.10      yamt 	}
    562  1.10      yamt 
    563   1.3    darran 	instr = (u_int8_t *) value;
    564   1.4    darran 	limit = (u_int8_t *) value + symsize;
    565   1.1    darran 
    566   1.1    darran #ifdef __amd64__
    567   1.1    darran 	while (instr < limit) {
    568   1.1    darran 		if (*instr == FBT_PUSHL_EBP)
    569   1.1    darran 			break;
    570   1.1    darran 
    571   1.1    darran 		if ((size = dtrace_instr_size(instr)) <= 0)
    572   1.1    darran 			break;
    573   1.1    darran 
    574   1.1    darran 		instr += size;
    575   1.1    darran 	}
    576   1.1    darran 
    577   1.1    darran 	if (instr >= limit || *instr != FBT_PUSHL_EBP) {
    578   1.1    darran 		/*
    579   1.1    darran 		 * We either don't save the frame pointer in this
    580   1.1    darran 		 * function, or we ran into some disassembly
    581   1.1    darran 		 * screw-up.  Either way, we bail.
    582   1.1    darran 		 */
    583   1.1    darran 		return (0);
    584   1.1    darran 	}
    585   1.1    darran #else
    586   1.3    darran 	if (instr[0] != FBT_PUSHL_EBP) {
    587   1.1    darran 		return (0);
    588   1.3    darran 	}
    589   1.1    darran 
    590   1.1    darran 	if (!(instr[1] == FBT_MOVL_ESP_EBP0_V0 &&
    591   1.1    darran 	    instr[2] == FBT_MOVL_ESP_EBP1_V0) &&
    592   1.1    darran 	    !(instr[1] == FBT_MOVL_ESP_EBP0_V1 &&
    593   1.3    darran 	    instr[2] == FBT_MOVL_ESP_EBP1_V1)) {
    594   1.1    darran 		return (0);
    595   1.3    darran 	}
    596   1.1    darran #endif
    597   1.1    darran 	fbt = malloc(sizeof (fbt_probe_t), M_FBT, M_WAITOK | M_ZERO);
    598   1.1    darran 	fbt->fbtp_name = name;
    599   1.1    darran 	fbt->fbtp_id = dtrace_probe_create(fbt_id, modname,
    600   1.1    darran 	    name, FBT_ENTRY, 3, fbt);
    601   1.1    darran 	fbt->fbtp_patchpoint = instr;
    602   1.3    darran 	fbt->fbtp_ctl = mod;
    603   1.3    darran 	/* fbt->fbtp_loadcnt = lf->loadcnt; */
    604   1.1    darran 	fbt->fbtp_rval = DTRACE_INVOP_PUSHL_EBP;
    605   1.1    darran 	fbt->fbtp_savedval = *instr;
    606   1.1    darran 	fbt->fbtp_patchval = FBT_PATCHVAL;
    607   1.1    darran 	fbt->fbtp_symindx = symindx;
    608   1.1    darran 
    609   1.1    darran 	fbt->fbtp_hashnext = fbt_probetab[FBT_ADDR2NDX(instr)];
    610   1.1    darran 	fbt_probetab[FBT_ADDR2NDX(instr)] = fbt;
    611   1.3    darran 	mod->mod_fbtentries++;
    612   1.1    darran 
    613   1.3    darran 	retfbt = NULL;
    614   1.1    darran 
    615   1.3    darran 	while (instr < limit) {
    616   1.3    darran 		if (instr >= limit)
    617   1.3    darran 			return (0);
    618   1.1    darran 
    619   1.3    darran 		/*
    620   1.3    darran 		 * If this disassembly fails, then we've likely walked off into
    621   1.3    darran 		 * a jump table or some other unsuitable area.  Bail out of the
    622   1.3    darran 		 * disassembly now.
    623   1.3    darran 		 */
    624   1.3    darran 		if ((size = dtrace_instr_size(instr)) <= 0)
    625   1.3    darran 			return (0);
    626   1.1    darran 
    627   1.1    darran #ifdef __amd64__
    628   1.3    darran 		/*
    629   1.3    darran 		 * We only instrument "ret" on amd64 -- we don't yet instrument
    630   1.3    darran 		 * ret imm16, largely because the compiler doesn't seem to
    631   1.3    darran 		 * (yet) emit them in the kernel...
    632   1.3    darran 		 */
    633   1.3    darran 		if (*instr != FBT_RET) {
    634   1.3    darran 			instr += size;
    635   1.3    darran 			continue;
    636   1.3    darran 		}
    637   1.1    darran #else
    638   1.3    darran 		if (!(size == 1 &&
    639   1.3    darran 		    (*instr == FBT_POPL_EBP || *instr == FBT_LEAVE) &&
    640   1.3    darran 		    (*(instr + 1) == FBT_RET ||
    641   1.3    darran 		    *(instr + 1) == FBT_RET_IMM16))) {
    642   1.3    darran 			instr += size;
    643   1.3    darran 			continue;
    644   1.3    darran 		}
    645   1.1    darran #endif
    646   1.1    darran 
    647   1.3    darran 		/*
    648   1.3    darran 		 * We (desperately) want to avoid erroneously instrumenting a
    649   1.3    darran 		 * jump table, especially given that our markers are pretty
    650   1.3    darran 		 * short:  two bytes on x86, and just one byte on amd64.  To
    651   1.3    darran 		 * determine if we're looking at a true instruction sequence
    652   1.3    darran 		 * or an inline jump table that happens to contain the same
    653   1.3    darran 		 * byte sequences, we resort to some heuristic sleeze:  we
    654   1.3    darran 		 * treat this instruction as being contained within a pointer,
    655   1.3    darran 		 * and see if that pointer points to within the body of the
    656   1.3    darran 		 * function.  If it does, we refuse to instrument it.
    657   1.3    darran 		 */
    658   1.3    darran 		for (j = 0; j < sizeof (uintptr_t); j++) {
    659   1.3    darran 			caddr_t check = (caddr_t) instr - j;
    660   1.3    darran 			uint8_t *ptr;
    661   1.1    darran 
    662   1.3    darran 			if (check < (caddr_t)value)
    663   1.3    darran 				break;
    664   1.1    darran 
    665   1.3    darran 			if (check + sizeof (caddr_t) > (caddr_t)limit)
    666   1.3    darran 				continue;
    667   1.1    darran 
    668   1.3    darran 			ptr = *(uint8_t **)check;
    669   1.1    darran 
    670   1.3    darran 			if (ptr >= (uint8_t *) value && ptr < limit) {
    671   1.3    darran 				instr += size;
    672   1.3    darran 				continue;
    673   1.3    darran 			}
    674   1.1    darran 		}
    675   1.1    darran 
    676   1.3    darran 		/*
    677   1.3    darran 		 * We have a winner!
    678   1.3    darran 		 */
    679   1.3    darran 		fbt = malloc(sizeof (fbt_probe_t), M_FBT, M_WAITOK | M_ZERO);
    680   1.3    darran 		fbt->fbtp_name = name;
    681   1.1    darran 
    682   1.3    darran 		if (retfbt == NULL) {
    683   1.3    darran 			fbt->fbtp_id = dtrace_probe_create(fbt_id, modname,
    684   1.3    darran 			    name, FBT_RETURN, 3, fbt);
    685   1.3    darran 		} else {
    686   1.3    darran 			retfbt->fbtp_next = fbt;
    687   1.3    darran 			fbt->fbtp_id = retfbt->fbtp_id;
    688   1.3    darran 		}
    689   1.1    darran 
    690   1.3    darran 		retfbt = fbt;
    691   1.3    darran 		fbt->fbtp_patchpoint = instr;
    692   1.3    darran 		fbt->fbtp_ctl = mod;
    693   1.3    darran 		/* fbt->fbtp_loadcnt = lf->loadcnt; */
    694   1.3    darran 		fbt->fbtp_symindx = symindx;
    695   1.1    darran 
    696   1.1    darran #ifndef __amd64__
    697   1.3    darran 		if (*instr == FBT_POPL_EBP) {
    698   1.3    darran 			fbt->fbtp_rval = DTRACE_INVOP_POPL_EBP;
    699   1.3    darran 		} else {
    700   1.3    darran 			ASSERT(*instr == FBT_LEAVE);
    701   1.3    darran 			fbt->fbtp_rval = DTRACE_INVOP_LEAVE;
    702   1.3    darran 		}
    703   1.3    darran 		fbt->fbtp_roffset =
    704   1.3    darran 		    (uintptr_t)(instr - (uint8_t *) value) + 1;
    705   1.1    darran 
    706   1.1    darran #else
    707   1.3    darran 		ASSERT(*instr == FBT_RET);
    708   1.3    darran 		fbt->fbtp_rval = DTRACE_INVOP_RET;
    709   1.3    darran 		fbt->fbtp_roffset =
    710   1.3    darran 		    (uintptr_t)(instr - (uint8_t *) value);
    711   1.1    darran #endif
    712   1.1    darran 
    713   1.3    darran 		fbt->fbtp_savedval = *instr;
    714   1.3    darran 		fbt->fbtp_patchval = FBT_PATCHVAL;
    715   1.3    darran 		fbt->fbtp_hashnext = fbt_probetab[FBT_ADDR2NDX(instr)];
    716   1.3    darran 		fbt_probetab[FBT_ADDR2NDX(instr)] = fbt;
    717   1.3    darran 
    718   1.3    darran 		mod->mod_fbtentries++;
    719   1.1    darran 
    720   1.3    darran 		instr += size;
    721   1.3    darran 	}
    722   1.1    darran 
    723   1.3    darran 	return 0;
    724   1.1    darran }
    725   1.1    darran 
    726  1.14     ozaki #elif defined(__arm__)
    727  1.14     ozaki 
    728  1.14     ozaki static int
    729  1.14     ozaki fbt_provide_module_cb(const char *name, int symindx, void *value,
    730  1.14     ozaki 	uint32_t symsize, int type, void *opaque)
    731  1.14     ozaki {
    732  1.14     ozaki 	fbt_probe_t *fbt, *retfbt;
    733  1.14     ozaki 	uint32_t *instr, *limit;
    734  1.14     ozaki 	bool was_ldm_lr = false;
    735  1.14     ozaki 	dtrace_modctl_t *mod = opaque;
    736  1.14     ozaki 	const char *modname = mod->mod_info->mi_name;
    737  1.14     ozaki 	int size;
    738  1.14     ozaki 
    739  1.14     ozaki 	/* got a function? */
    740  1.14     ozaki 	if (ELF_ST_TYPE(type) != STT_FUNC) {
    741  1.14     ozaki 	    return 0;
    742  1.14     ozaki 	}
    743  1.14     ozaki 
    744  1.14     ozaki 	if (strncmp(name, "dtrace_", 7) == 0 &&
    745  1.14     ozaki 	    strncmp(name, "dtrace_safe_", 12) != 0) {
    746  1.14     ozaki 		/*
    747  1.14     ozaki 		 * Anything beginning with "dtrace_" may be called
    748  1.14     ozaki 		 * from probe context unless it explicitly indicates
    749  1.14     ozaki 		 * that it won't be called from probe context by
    750  1.14     ozaki 		 * using the prefix "dtrace_safe_".
    751  1.14     ozaki 		 */
    752  1.14     ozaki 		return (0);
    753  1.14     ozaki 	}
    754  1.14     ozaki 
    755  1.14     ozaki 	if (name[0] == '_' && name[1] == '_')
    756  1.14     ozaki 		return (0);
    757  1.14     ozaki 
    758  1.14     ozaki 	/*
    759  1.14     ozaki 	 * Exclude some more symbols which can be called from probe context.
    760  1.14     ozaki 	 */
    761  1.14     ozaki 	if (strncmp(name, "db_", 3) == 0 /* debugger */
    762  1.14     ozaki 	    || strncmp(name, "ddb_", 4) == 0 /* debugger */
    763  1.14     ozaki 	    || strncmp(name, "kdb_", 4) == 0 /* debugger */
    764  1.14     ozaki 	    || strncmp(name, "lockdebug_", 10) == 0 /* lockdebug XXX for now */
    765  1.14     ozaki 	    || strncmp(name, "kauth_", 5) == 0 /* CRED XXX for now */
    766  1.14     ozaki 	    /* Sensitive functions on ARM */
    767  1.14     ozaki 	    || strncmp(name, "_spl", 4) == 0
    768  1.14     ozaki 	    || strcmp(name, "binuptime") == 0
    769  1.14     ozaki 	    || strcmp(name, "dosoftints") == 0
    770  1.14     ozaki 	    || strcmp(name, "fbt_emulate") == 0
    771  1.14     ozaki 	    || strcmp(name, "nanouptime") == 0
    772  1.14     ozaki 	    || strcmp(name, "undefinedinstruction") == 0
    773  1.15     ozaki 	    || strncmp(name, "dmt_", 4) == 0 /* omap */
    774  1.15     ozaki 	    || strncmp(name, "mvsoctmr_", 9) == 0 /* marvell */
    775  1.14     ozaki 	    ) {
    776  1.14     ozaki 		return 0;
    777  1.14     ozaki 	}
    778  1.14     ozaki 
    779  1.14     ozaki 	instr = (uint32_t *) value;
    780  1.14     ozaki 	limit = (uint32_t *)((uintptr_t)value + symsize);
    781  1.14     ozaki 
    782  1.14     ozaki 	if (!FBT_MOV_IP_SP_P(*instr)
    783  1.14     ozaki 	    && !FBT_BX_LR_P(*instr)
    784  1.14     ozaki 	    && !FBT_MOVW_P(*instr)
    785  1.14     ozaki 	    && !FBT_MOV_IMM_P(*instr)
    786  1.14     ozaki 	    && !FBT_B_LABEL_P(*instr)
    787  1.14     ozaki 	    && !FBT_LDR_IMM_P(*instr)
    788  1.14     ozaki 	    && !FBT_CMP_IMM_P(*instr)
    789  1.14     ozaki 	    /* && !FBT_PUSH_P(*instr) */
    790  1.14     ozaki 	    ) {
    791  1.14     ozaki 		return 0;
    792  1.14     ozaki 	}
    793  1.14     ozaki 
    794  1.14     ozaki 	fbt = malloc(sizeof (fbt_probe_t), M_FBT, M_WAITOK | M_ZERO);
    795  1.14     ozaki 	fbt->fbtp_name = name;
    796  1.14     ozaki 	fbt->fbtp_id = dtrace_probe_create(fbt_id, modname,
    797  1.14     ozaki 	    name, FBT_ENTRY, 3, fbt);
    798  1.14     ozaki 	fbt->fbtp_patchpoint = instr;
    799  1.14     ozaki 	fbt->fbtp_ctl = mod;
    800  1.14     ozaki 	/* fbt->fbtp_loadcnt = lf->loadcnt; */
    801  1.14     ozaki 	if (FBT_MOV_IP_SP_P(*instr))
    802  1.14     ozaki 		fbt->fbtp_rval = BUILD_RVAL(*instr, DTRACE_INVOP_MOV_IP_SP);
    803  1.14     ozaki 	else if (FBT_LDR_IMM_P(*instr))
    804  1.14     ozaki 		fbt->fbtp_rval = BUILD_RVAL(*instr, DTRACE_INVOP_LDR_IMM);
    805  1.14     ozaki 	else if (FBT_MOVW_P(*instr))
    806  1.14     ozaki 		fbt->fbtp_rval = BUILD_RVAL(*instr, DTRACE_INVOP_MOVW);
    807  1.14     ozaki 	else if (FBT_MOV_IMM_P(*instr))
    808  1.14     ozaki 		fbt->fbtp_rval = BUILD_RVAL(*instr, DTRACE_INVOP_MOV_IMM);
    809  1.14     ozaki 	else if (FBT_CMP_IMM_P(*instr))
    810  1.14     ozaki 		fbt->fbtp_rval = BUILD_RVAL(*instr, DTRACE_INVOP_CMP_IMM);
    811  1.14     ozaki 	else if (FBT_BX_LR_P(*instr))
    812  1.14     ozaki 		fbt->fbtp_rval = BUILD_RVAL(*instr, DTRACE_INVOP_BX_LR);
    813  1.14     ozaki 	else if (FBT_PUSH_P(*instr))
    814  1.14     ozaki 		fbt->fbtp_rval = BUILD_RVAL(*instr, DTRACE_INVOP_PUSH);
    815  1.14     ozaki 	else if (FBT_B_LABEL_P(*instr))
    816  1.14     ozaki 		fbt->fbtp_rval = BUILD_RVAL(*instr, DTRACE_INVOP_B_LABEL);
    817  1.14     ozaki 
    818  1.14     ozaki 	fbt->fbtp_patchval = PATCHVAL_ENCODE_COND(*instr);
    819  1.14     ozaki 	fbt->fbtp_savedval = *instr;
    820  1.14     ozaki 	fbt->fbtp_symindx = symindx;
    821  1.14     ozaki 
    822  1.14     ozaki 	fbt->fbtp_hashnext = fbt_probetab[FBT_ADDR2NDX(instr)];
    823  1.14     ozaki 	fbt_probetab[FBT_ADDR2NDX(instr)] = fbt;
    824  1.14     ozaki 	mod->mod_fbtentries++;
    825  1.14     ozaki 
    826  1.14     ozaki 	retfbt = NULL;
    827  1.14     ozaki 
    828  1.14     ozaki 	while (instr < limit) {
    829  1.14     ozaki 		if (instr >= limit)
    830  1.14     ozaki 			return (0);
    831  1.14     ozaki 
    832  1.14     ozaki 		size = 1;
    833  1.14     ozaki 
    834  1.14     ozaki 		if (!FBT_BX_LR_P(*instr)
    835  1.14     ozaki 		    && !FBT_MOV_PC_LR_P(*instr)
    836  1.14     ozaki 		    && !FBT_LDM_P(*instr)
    837  1.14     ozaki 		    && !FBT_LDMIB_P(*instr)
    838  1.14     ozaki 		    && !(was_ldm_lr && FBT_B_LABEL_P(*instr))
    839  1.14     ozaki 		    ) {
    840  1.14     ozaki 			if (FBT_LDM_LR_P(*instr) || FBT_LDMIB_LR_P(*instr))
    841  1.14     ozaki 				was_ldm_lr = true;
    842  1.14     ozaki 			else
    843  1.14     ozaki 				was_ldm_lr = false;
    844  1.14     ozaki 			instr += size;
    845  1.14     ozaki 			continue;
    846  1.14     ozaki 		}
    847  1.14     ozaki 
    848  1.14     ozaki 		/*
    849  1.14     ozaki 		 * We have a winner!
    850  1.14     ozaki 		 */
    851  1.14     ozaki 		fbt = malloc(sizeof (fbt_probe_t), M_FBT, M_WAITOK | M_ZERO);
    852  1.14     ozaki 		fbt->fbtp_name = name;
    853  1.14     ozaki 
    854  1.14     ozaki 		if (retfbt == NULL) {
    855  1.14     ozaki 			fbt->fbtp_id = dtrace_probe_create(fbt_id, modname,
    856  1.14     ozaki 			    name, FBT_RETURN, 3, fbt);
    857  1.14     ozaki 		} else {
    858  1.14     ozaki 			retfbt->fbtp_next = fbt;
    859  1.14     ozaki 			fbt->fbtp_id = retfbt->fbtp_id;
    860  1.14     ozaki 		}
    861  1.14     ozaki 
    862  1.14     ozaki 		retfbt = fbt;
    863  1.14     ozaki 		fbt->fbtp_patchpoint = instr;
    864  1.14     ozaki 		fbt->fbtp_ctl = mod;
    865  1.14     ozaki 		/* fbt->fbtp_loadcnt = lf->loadcnt; */
    866  1.14     ozaki 		fbt->fbtp_symindx = symindx;
    867  1.14     ozaki 
    868  1.14     ozaki 		if (FBT_BX_LR_P(*instr))
    869  1.14     ozaki 			fbt->fbtp_rval = BUILD_RVAL(*instr, DTRACE_INVOP_BX_LR);
    870  1.14     ozaki 		else if (FBT_MOV_PC_LR_P(*instr))
    871  1.14     ozaki 			fbt->fbtp_rval = BUILD_RVAL(*instr, DTRACE_INVOP_MOV_PC_LR);
    872  1.14     ozaki 		else if (FBT_LDM_P(*instr))
    873  1.14     ozaki 			fbt->fbtp_rval = BUILD_RVAL(*instr, DTRACE_INVOP_LDM);
    874  1.14     ozaki 		else if (FBT_LDMIB_P(*instr))
    875  1.14     ozaki 			fbt->fbtp_rval = BUILD_RVAL(*instr, DTRACE_INVOP_LDMIB);
    876  1.14     ozaki 		else if (FBT_B_LABEL_P(*instr))
    877  1.14     ozaki 			fbt->fbtp_rval = BUILD_RVAL(*instr, DTRACE_INVOP_B_LABEL);
    878  1.14     ozaki 
    879  1.14     ozaki 		fbt->fbtp_roffset = (uintptr_t)(instr - (uint32_t *) value);
    880  1.14     ozaki 		fbt->fbtp_patchval = PATCHVAL_ENCODE_COND(*instr);
    881  1.14     ozaki 
    882  1.14     ozaki 		fbt->fbtp_savedval = *instr;
    883  1.14     ozaki 		fbt->fbtp_hashnext = fbt_probetab[FBT_ADDR2NDX(instr)];
    884  1.14     ozaki 		fbt_probetab[FBT_ADDR2NDX(instr)] = fbt;
    885  1.14     ozaki 
    886  1.14     ozaki 		mod->mod_fbtentries++;
    887  1.14     ozaki 
    888  1.14     ozaki 		instr += size;
    889  1.14     ozaki 		was_ldm_lr = false;
    890  1.14     ozaki 	}
    891  1.14     ozaki 
    892  1.14     ozaki 	return 0;
    893  1.14     ozaki }
    894  1.14     ozaki #else
    895  1.14     ozaki #error "architecture not supported"
    896  1.14     ozaki #endif
    897  1.14     ozaki 
    898  1.14     ozaki 
    899   1.1    darran static void
    900   1.3    darran fbt_provide_module(void *arg, dtrace_modctl_t *mod)
    901   1.1    darran {
    902   1.1    darran 	char modname[MAXPATHLEN];
    903   1.1    darran 	int i;
    904   1.1    darran 	size_t len;
    905   1.1    darran 
    906   1.3    darran 	strlcpy(modname, mod->mod_info->mi_name, sizeof(modname));
    907   1.1    darran 	len = strlen(modname);
    908   1.3    darran 	if (len > 5 && strcmp(modname + len - 3, ".kmod") == 0)
    909   1.3    darran 		modname[len - 4] = '\0';
    910   1.1    darran 
    911   1.1    darran 	/*
    912   1.1    darran 	 * Employees of dtrace and their families are ineligible.  Void
    913   1.1    darran 	 * where prohibited.
    914   1.1    darran 	 */
    915   1.1    darran 	if (strcmp(modname, "dtrace") == 0)
    916   1.1    darran 		return;
    917   1.1    darran 
    918   1.1    darran 	/*
    919   1.1    darran 	 * The cyclic timer subsystem can be built as a module and DTrace
    920   1.1    darran 	 * depends on that, so it is ineligible too.
    921   1.1    darran 	 */
    922   1.1    darran 	if (strcmp(modname, "cyclic") == 0)
    923   1.1    darran 		return;
    924   1.1    darran 
    925   1.1    darran 	/*
    926   1.1    darran 	 * To register with DTrace, a module must list 'dtrace' as a
    927   1.1    darran 	 * dependency in order for the kernel linker to resolve
    928   1.1    darran 	 * symbols like dtrace_register(). All modules with such a
    929   1.1    darran 	 * dependency are ineligible for FBT tracing.
    930   1.1    darran 	 */
    931   1.3    darran 	for (i = 0; i < mod->mod_nrequired; i++) {
    932   1.3    darran 		if (strncmp(mod->mod_required[i]->mod_info->mi_name,
    933   1.3    darran 			    "dtrace", 6) == 0)
    934   1.1    darran 			return;
    935   1.3    darran 	}
    936   1.1    darran 
    937   1.3    darran 	if (mod->mod_fbtentries) {
    938   1.1    darran 		/*
    939   1.1    darran 		 * This module has some FBT entries allocated; we're afraid
    940   1.1    darran 		 * to screw with it.
    941   1.1    darran 		 */
    942   1.1    darran 		return;
    943   1.1    darran 	}
    944   1.1    darran 
    945   1.1    darran 	/*
    946   1.1    darran 	 * List the functions in the module and the symbol values.
    947   1.1    darran 	 */
    948   1.3    darran 	ksyms_mod_foreach(modname, fbt_provide_module_cb, mod);
    949   1.1    darran }
    950   1.1    darran 
    951   1.1    darran static void
    952   1.1    darran fbt_destroy(void *arg, dtrace_id_t id, void *parg)
    953   1.1    darran {
    954   1.1    darran 	fbt_probe_t *fbt = parg, *next, *hash, *last;
    955   1.3    darran 	dtrace_modctl_t *ctl;
    956   1.1    darran 	int ndx;
    957   1.1    darran 
    958   1.1    darran 	do {
    959   1.1    darran 		ctl = fbt->fbtp_ctl;
    960   1.1    darran 
    961   1.3    darran 		ctl->mod_fbtentries--;
    962   1.1    darran 
    963   1.1    darran 		/*
    964   1.1    darran 		 * Now we need to remove this probe from the fbt_probetab.
    965   1.1    darran 		 */
    966   1.1    darran 		ndx = FBT_ADDR2NDX(fbt->fbtp_patchpoint);
    967   1.1    darran 		last = NULL;
    968   1.1    darran 		hash = fbt_probetab[ndx];
    969   1.1    darran 
    970   1.1    darran 		while (hash != fbt) {
    971   1.1    darran 			ASSERT(hash != NULL);
    972   1.1    darran 			last = hash;
    973   1.1    darran 			hash = hash->fbtp_hashnext;
    974   1.1    darran 		}
    975   1.1    darran 
    976   1.1    darran 		if (last != NULL) {
    977   1.1    darran 			last->fbtp_hashnext = fbt->fbtp_hashnext;
    978   1.1    darran 		} else {
    979   1.1    darran 			fbt_probetab[ndx] = fbt->fbtp_hashnext;
    980   1.1    darran 		}
    981   1.1    darran 
    982   1.1    darran 		next = fbt->fbtp_next;
    983   1.1    darran 		free(fbt, M_FBT);
    984   1.1    darran 
    985   1.1    darran 		fbt = next;
    986   1.1    darran 	} while (fbt != NULL);
    987   1.1    darran }
    988   1.1    darran 
    989  1.14     ozaki #if defined(__i386__) || defined(__amd64__)
    990  1.14     ozaki 
    991   1.3    darran static int
    992   1.1    darran fbt_enable(void *arg, dtrace_id_t id, void *parg)
    993   1.1    darran {
    994   1.1    darran 	fbt_probe_t *fbt = parg;
    995   1.5  christos #if 0
    996   1.3    darran 	dtrace_modctl_t *ctl = fbt->fbtp_ctl;
    997   1.5  christos #endif
    998   1.3    darran 	u_long psl;
    999   1.3    darran 	u_long cr0;
   1000   1.3    darran 
   1001   1.1    darran 
   1002   1.3    darran #if 0	/* XXX TBD */
   1003   1.1    darran 	ctl->nenabled++;
   1004   1.1    darran 
   1005   1.1    darran 	/*
   1006   1.1    darran 	 * Now check that our modctl has the expected load count.  If it
   1007   1.1    darran 	 * doesn't, this module must have been unloaded and reloaded -- and
   1008   1.1    darran 	 * we're not going to touch it.
   1009   1.1    darran 	 */
   1010   1.1    darran 	if (ctl->loadcnt != fbt->fbtp_loadcnt) {
   1011   1.1    darran 		if (fbt_verbose) {
   1012   1.1    darran 			printf("fbt is failing for probe %s "
   1013   1.1    darran 			    "(module %s reloaded)",
   1014   1.1    darran 			    fbt->fbtp_name, ctl->filename);
   1015   1.1    darran 		}
   1016   1.1    darran 
   1017   1.1    darran 		return;
   1018   1.1    darran 	}
   1019   1.3    darran #endif
   1020   1.3    darran 
   1021   1.3    darran 	/* Disable interrupts. */
   1022   1.3    darran 	psl = x86_read_psl();
   1023   1.3    darran 	x86_disable_intr();
   1024   1.3    darran 
   1025   1.3    darran 	/* Disable write protection in supervisor mode. */
   1026   1.3    darran 	cr0 = rcr0();
   1027   1.3    darran 	lcr0(cr0 & ~CR0_WP);
   1028   1.1    darran 
   1029   1.1    darran 	for (; fbt != NULL; fbt = fbt->fbtp_next) {
   1030   1.1    darran 		*fbt->fbtp_patchpoint = fbt->fbtp_patchval;
   1031   1.1    darran 	}
   1032   1.3    darran 
   1033   1.3    darran 	/* Write back and invalidate cache, flush pipelines. */
   1034   1.3    darran 	wbinvd();
   1035   1.3    darran 	x86_flush();
   1036   1.3    darran 	x86_write_psl(psl);
   1037   1.3    darran 
   1038   1.3    darran 	/* Re-enable write protection. */
   1039   1.3    darran 	lcr0(cr0);
   1040   1.3    darran 
   1041   1.3    darran 	return 0;
   1042   1.1    darran }
   1043   1.1    darran 
   1044   1.1    darran static void
   1045   1.1    darran fbt_disable(void *arg, dtrace_id_t id, void *parg)
   1046   1.1    darran {
   1047   1.1    darran 	fbt_probe_t *fbt = parg;
   1048   1.5  christos #if 0
   1049   1.3    darran 	dtrace_modctl_t *ctl = fbt->fbtp_ctl;
   1050   1.5  christos #endif
   1051   1.3    darran 	u_long psl;
   1052   1.3    darran 	u_long cr0;
   1053   1.1    darran 
   1054   1.3    darran #if 0	/* XXX TBD */
   1055   1.1    darran 	ASSERT(ctl->nenabled > 0);
   1056   1.1    darran 	ctl->nenabled--;
   1057   1.1    darran 
   1058   1.1    darran 	if ((ctl->loadcnt != fbt->fbtp_loadcnt))
   1059   1.1    darran 		return;
   1060   1.3    darran #endif
   1061   1.3    darran 	/* Disable interrupts. */
   1062   1.3    darran 	psl = x86_read_psl();
   1063   1.3    darran 	x86_disable_intr();
   1064   1.3    darran 
   1065   1.3    darran 	/* Disable write protection in supervisor mode. */
   1066   1.3    darran 	cr0 = rcr0();
   1067   1.3    darran 	lcr0(cr0 & ~CR0_WP);
   1068   1.1    darran 
   1069   1.1    darran 	for (; fbt != NULL; fbt = fbt->fbtp_next)
   1070   1.1    darran 		*fbt->fbtp_patchpoint = fbt->fbtp_savedval;
   1071   1.3    darran 
   1072   1.3    darran 	/* Write back and invalidate cache, flush pipelines. */
   1073   1.3    darran 	wbinvd();
   1074   1.3    darran 	x86_flush();
   1075   1.3    darran 	x86_write_psl(psl);
   1076   1.3    darran 
   1077   1.3    darran 	/* Re-enable write protection. */
   1078   1.3    darran 	lcr0(cr0);
   1079   1.1    darran }
   1080   1.1    darran 
   1081   1.1    darran static void
   1082   1.1    darran fbt_suspend(void *arg, dtrace_id_t id, void *parg)
   1083   1.1    darran {
   1084   1.1    darran 	fbt_probe_t *fbt = parg;
   1085   1.5  christos #if 0
   1086   1.3    darran 	dtrace_modctl_t *ctl = fbt->fbtp_ctl;
   1087   1.5  christos #endif
   1088   1.3    darran 	u_long psl;
   1089   1.3    darran 	u_long cr0;
   1090   1.1    darran 
   1091   1.3    darran #if 0	/* XXX TBD */
   1092   1.1    darran 	ASSERT(ctl->nenabled > 0);
   1093   1.1    darran 
   1094   1.1    darran 	if ((ctl->loadcnt != fbt->fbtp_loadcnt))
   1095   1.1    darran 		return;
   1096   1.3    darran #endif
   1097   1.3    darran 
   1098   1.3    darran 	/* Disable interrupts. */
   1099   1.3    darran 	psl = x86_read_psl();
   1100   1.3    darran 	x86_disable_intr();
   1101   1.3    darran 
   1102   1.3    darran 	/* Disable write protection in supervisor mode. */
   1103   1.3    darran 	cr0 = rcr0();
   1104   1.3    darran 	lcr0(cr0 & ~CR0_WP);
   1105   1.1    darran 
   1106   1.1    darran 	for (; fbt != NULL; fbt = fbt->fbtp_next)
   1107   1.1    darran 		*fbt->fbtp_patchpoint = fbt->fbtp_savedval;
   1108   1.3    darran 
   1109   1.3    darran 	/* Write back and invalidate cache, flush pipelines. */
   1110   1.3    darran 	wbinvd();
   1111   1.3    darran 	x86_flush();
   1112   1.3    darran 	x86_write_psl(psl);
   1113   1.3    darran 
   1114   1.3    darran 	/* Re-enable write protection. */
   1115   1.3    darran 	lcr0(cr0);
   1116   1.1    darran }
   1117   1.1    darran 
   1118   1.1    darran static void
   1119   1.1    darran fbt_resume(void *arg, dtrace_id_t id, void *parg)
   1120   1.1    darran {
   1121   1.1    darran 	fbt_probe_t *fbt = parg;
   1122   1.5  christos #if 0
   1123   1.3    darran 	dtrace_modctl_t *ctl = fbt->fbtp_ctl;
   1124   1.5  christos #endif
   1125   1.3    darran 	u_long psl;
   1126   1.3    darran 	u_long cr0;
   1127   1.1    darran 
   1128   1.3    darran #if 0	/* XXX TBD */
   1129   1.1    darran 	ASSERT(ctl->nenabled > 0);
   1130   1.1    darran 
   1131   1.1    darran 	if ((ctl->loadcnt != fbt->fbtp_loadcnt))
   1132   1.1    darran 		return;
   1133   1.3    darran #endif
   1134   1.3    darran 	/* Disable interrupts. */
   1135   1.3    darran 	psl = x86_read_psl();
   1136   1.3    darran 	x86_disable_intr();
   1137   1.3    darran 
   1138   1.3    darran 	/* Disable write protection in supervisor mode. */
   1139   1.3    darran 	cr0 = rcr0();
   1140   1.3    darran 	lcr0(cr0 & ~CR0_WP);
   1141   1.1    darran 
   1142   1.1    darran 	for (; fbt != NULL; fbt = fbt->fbtp_next)
   1143   1.1    darran 		*fbt->fbtp_patchpoint = fbt->fbtp_patchval;
   1144   1.3    darran 
   1145   1.3    darran 	/* Write back and invalidate cache, flush pipelines. */
   1146   1.3    darran 	wbinvd();
   1147   1.3    darran 	x86_flush();
   1148   1.3    darran 	x86_write_psl(psl);
   1149   1.3    darran 
   1150   1.3    darran 	/* Re-enable write protection. */
   1151   1.3    darran 	lcr0(cr0);
   1152   1.1    darran }
   1153   1.1    darran 
   1154  1.14     ozaki #elif defined(__arm__)
   1155  1.14     ozaki 
   1156  1.14     ozaki static int
   1157  1.14     ozaki fbt_enable(void *arg, dtrace_id_t id, void *parg)
   1158  1.14     ozaki {
   1159  1.14     ozaki 	fbt_probe_t *fbt = parg;
   1160  1.14     ozaki #if 0
   1161  1.14     ozaki 	dtrace_modctl_t *ctl = fbt->fbtp_ctl;
   1162  1.14     ozaki #endif
   1163  1.14     ozaki 	dtrace_icookie_t c;
   1164  1.14     ozaki 
   1165  1.14     ozaki 
   1166  1.14     ozaki #if 0	/* XXX TBD */
   1167  1.14     ozaki 	ctl->nenabled++;
   1168  1.14     ozaki 
   1169  1.14     ozaki 	/*
   1170  1.14     ozaki 	 * Now check that our modctl has the expected load count.  If it
   1171  1.14     ozaki 	 * doesn't, this module must have been unloaded and reloaded -- and
   1172  1.14     ozaki 	 * we're not going to touch it.
   1173  1.14     ozaki 	 */
   1174  1.14     ozaki 	if (ctl->loadcnt != fbt->fbtp_loadcnt) {
   1175  1.14     ozaki 		if (fbt_verbose) {
   1176  1.14     ozaki 			printf("fbt is failing for probe %s "
   1177  1.14     ozaki 			    "(module %s reloaded)",
   1178  1.14     ozaki 			    fbt->fbtp_name, ctl->filename);
   1179  1.14     ozaki 		}
   1180  1.14     ozaki 
   1181  1.14     ozaki 		return;
   1182  1.14     ozaki 	}
   1183  1.14     ozaki #endif
   1184  1.14     ozaki 
   1185  1.14     ozaki 	c = dtrace_interrupt_disable();
   1186  1.14     ozaki 
   1187  1.14     ozaki 	for (fbt = parg; fbt != NULL; fbt = fbt->fbtp_next) {
   1188  1.14     ozaki 		*fbt->fbtp_patchpoint = fbt->fbtp_patchval;
   1189  1.14     ozaki 		cpu_idcache_wbinv_range((vaddr_t)fbt->fbtp_patchpoint, 4);
   1190  1.14     ozaki 	}
   1191  1.14     ozaki 
   1192  1.14     ozaki 	dtrace_interrupt_enable(c);
   1193  1.14     ozaki 
   1194  1.14     ozaki 	return 0;
   1195  1.14     ozaki }
   1196  1.14     ozaki 
   1197  1.14     ozaki static void
   1198  1.14     ozaki fbt_disable(void *arg, dtrace_id_t id, void *parg)
   1199  1.14     ozaki {
   1200  1.14     ozaki 	fbt_probe_t *fbt = parg;
   1201  1.14     ozaki #if 0
   1202  1.14     ozaki 	dtrace_modctl_t *ctl = fbt->fbtp_ctl;
   1203  1.14     ozaki #endif
   1204  1.14     ozaki 	dtrace_icookie_t c;
   1205  1.14     ozaki 
   1206  1.14     ozaki #if 0	/* XXX TBD */
   1207  1.14     ozaki 	ASSERT(ctl->nenabled > 0);
   1208  1.14     ozaki 	ctl->nenabled--;
   1209  1.14     ozaki 
   1210  1.14     ozaki 	if ((ctl->loadcnt != fbt->fbtp_loadcnt))
   1211  1.14     ozaki 		return;
   1212  1.14     ozaki #endif
   1213  1.14     ozaki 
   1214  1.14     ozaki 	c = dtrace_interrupt_disable();
   1215  1.14     ozaki 
   1216  1.14     ozaki 	for (; fbt != NULL; fbt = fbt->fbtp_next) {
   1217  1.14     ozaki 		*fbt->fbtp_patchpoint = fbt->fbtp_savedval;
   1218  1.14     ozaki 		cpu_idcache_wbinv_range((vaddr_t)fbt->fbtp_patchpoint, 4);
   1219  1.14     ozaki 	}
   1220  1.14     ozaki 
   1221  1.14     ozaki 	dtrace_interrupt_enable(c);
   1222  1.14     ozaki }
   1223  1.14     ozaki 
   1224  1.14     ozaki static void
   1225  1.14     ozaki fbt_suspend(void *arg, dtrace_id_t id, void *parg)
   1226  1.14     ozaki {
   1227  1.14     ozaki 	fbt_probe_t *fbt = parg;
   1228  1.14     ozaki #if 0
   1229  1.14     ozaki 	dtrace_modctl_t *ctl = fbt->fbtp_ctl;
   1230  1.14     ozaki #endif
   1231  1.14     ozaki 	dtrace_icookie_t c;
   1232  1.14     ozaki 
   1233  1.14     ozaki #if 0	/* XXX TBD */
   1234  1.14     ozaki 	ASSERT(ctl->nenabled > 0);
   1235  1.14     ozaki 
   1236  1.14     ozaki 	if ((ctl->loadcnt != fbt->fbtp_loadcnt))
   1237  1.14     ozaki 		return;
   1238  1.14     ozaki #endif
   1239  1.14     ozaki 
   1240  1.14     ozaki 	c = dtrace_interrupt_disable();
   1241  1.14     ozaki 
   1242  1.14     ozaki 	for (; fbt != NULL; fbt = fbt->fbtp_next) {
   1243  1.14     ozaki 		*fbt->fbtp_patchpoint = fbt->fbtp_savedval;
   1244  1.14     ozaki 		cpu_idcache_wbinv_range((vaddr_t)fbt->fbtp_patchpoint, 4);
   1245  1.14     ozaki 	}
   1246  1.14     ozaki 
   1247  1.14     ozaki 	dtrace_interrupt_enable(c);
   1248  1.14     ozaki }
   1249  1.14     ozaki 
   1250  1.14     ozaki static void
   1251  1.14     ozaki fbt_resume(void *arg, dtrace_id_t id, void *parg)
   1252  1.14     ozaki {
   1253  1.14     ozaki 	fbt_probe_t *fbt = parg;
   1254  1.14     ozaki #if 0
   1255  1.14     ozaki 	dtrace_modctl_t *ctl = fbt->fbtp_ctl;
   1256  1.14     ozaki #endif
   1257  1.14     ozaki 	dtrace_icookie_t c;
   1258  1.14     ozaki 
   1259  1.14     ozaki #if 0	/* XXX TBD */
   1260  1.14     ozaki 	ASSERT(ctl->nenabled > 0);
   1261  1.14     ozaki 
   1262  1.14     ozaki 	if ((ctl->loadcnt != fbt->fbtp_loadcnt))
   1263  1.14     ozaki 		return;
   1264  1.14     ozaki #endif
   1265  1.14     ozaki 
   1266  1.14     ozaki 	c = dtrace_interrupt_disable();
   1267  1.14     ozaki 
   1268  1.14     ozaki 	for (; fbt != NULL; fbt = fbt->fbtp_next) {
   1269  1.14     ozaki 		*fbt->fbtp_patchpoint = fbt->fbtp_patchval;
   1270  1.14     ozaki 		cpu_idcache_wbinv_range((vaddr_t)fbt->fbtp_patchpoint, 4);
   1271  1.14     ozaki 	}
   1272  1.14     ozaki 
   1273  1.14     ozaki 	dtrace_interrupt_enable(c);
   1274  1.14     ozaki }
   1275  1.14     ozaki 
   1276  1.14     ozaki #else
   1277  1.14     ozaki #error "architecture not supported"
   1278  1.14     ozaki #endif
   1279  1.14     ozaki 
   1280   1.1    darran static int
   1281   1.3    darran fbt_ctfoff_init(dtrace_modctl_t *mod, mod_ctf_t *mc)
   1282   1.1    darran {
   1283   1.3    darran 	const Elf_Sym *symp = mc->symtab;
   1284   1.3    darran 	const ctf_header_t *hp = (const ctf_header_t *) mc->ctftab;
   1285   1.3    darran 	const uint8_t *ctfdata = mc->ctftab + sizeof(ctf_header_t);
   1286   1.1    darran 	int i;
   1287   1.1    darran 	uint32_t *ctfoff;
   1288   1.1    darran 	uint32_t objtoff = hp->cth_objtoff;
   1289   1.1    darran 	uint32_t funcoff = hp->cth_funcoff;
   1290   1.1    darran 	ushort_t info;
   1291   1.1    darran 	ushort_t vlen;
   1292   1.3    darran 	int nsyms = (mc->nmap != NULL) ? mc->nmapsize : mc->nsym;
   1293   1.1    darran 
   1294   1.1    darran 	/* Sanity check. */
   1295   1.1    darran 	if (hp->cth_magic != CTF_MAGIC) {
   1296   1.3    darran 		printf("Bad magic value in CTF data of '%s'\n",
   1297   1.3    darran 			mod->mod_info->mi_name);
   1298   1.1    darran 		return (EINVAL);
   1299   1.1    darran 	}
   1300   1.1    darran 
   1301   1.3    darran 	if (mc->symtab == NULL) {
   1302   1.3    darran 		printf("No symbol table in '%s'\n",
   1303   1.3    darran 			mod->mod_info->mi_name);
   1304   1.1    darran 		return (EINVAL);
   1305   1.1    darran 	}
   1306   1.1    darran 
   1307   1.3    darran 	if ((ctfoff = malloc(sizeof(uint32_t) * nsyms, M_FBT, M_WAITOK)) == NULL)
   1308   1.1    darran 		return (ENOMEM);
   1309   1.1    darran 
   1310   1.3    darran 	mc->ctfoffp = ctfoff;
   1311   1.3    darran 
   1312   1.3    darran 	for (i = 0; i < nsyms; i++, ctfoff++, symp++) {
   1313   1.3    darran 	   	if (mc->nmap != NULL) {
   1314   1.3    darran 			if (mc->nmap[i] == 0) {
   1315   1.3    darran 				printf("%s.%d: Error! Got zero nmap!\n",
   1316   1.3    darran 					__func__, __LINE__);
   1317   1.3    darran 				continue;
   1318   1.3    darran 			}
   1319   1.3    darran 
   1320   1.3    darran 			/* CTF expects the pre-sorted symbol ordering,
   1321   1.3    darran 			 * so map it from that to the current sorted
   1322   1.3    darran 			 * and trimmed symbol table.
   1323   1.3    darran 			 * ctfoff[new-ind] = oldind symbol info.
   1324   1.3    darran 			 */
   1325   1.3    darran 
   1326   1.3    darran 			/* map old index to new symbol table */
   1327   1.3    darran 			symp = &mc->symtab[mc->nmap[i] - 1];
   1328   1.3    darran 
   1329   1.3    darran 			/* map old index to new ctfoff index */
   1330   1.3    darran 			ctfoff = &mc->ctfoffp[mc->nmap[i]-1];
   1331   1.3    darran 		}
   1332   1.1    darran 
   1333   1.1    darran 		if (symp->st_name == 0 || symp->st_shndx == SHN_UNDEF) {
   1334   1.1    darran 			*ctfoff = 0xffffffff;
   1335   1.1    darran 			continue;
   1336   1.1    darran 		}
   1337   1.1    darran 
   1338   1.1    darran 		switch (ELF_ST_TYPE(symp->st_info)) {
   1339   1.1    darran 		case STT_OBJECT:
   1340   1.1    darran 			if (objtoff >= hp->cth_funcoff ||
   1341   1.1    darran                             (symp->st_shndx == SHN_ABS && symp->st_value == 0)) {
   1342   1.1    darran 				*ctfoff = 0xffffffff;
   1343   1.1    darran                                 break;
   1344   1.1    darran                         }
   1345   1.1    darran 
   1346   1.1    darran                         *ctfoff = objtoff;
   1347   1.1    darran                         objtoff += sizeof (ushort_t);
   1348   1.1    darran 			break;
   1349   1.1    darran 
   1350   1.1    darran 		case STT_FUNC:
   1351   1.1    darran 			if (funcoff >= hp->cth_typeoff) {
   1352   1.1    darran 				*ctfoff = 0xffffffff;
   1353   1.1    darran 				break;
   1354   1.1    darran 			}
   1355   1.1    darran 
   1356   1.1    darran 			*ctfoff = funcoff;
   1357   1.1    darran 
   1358   1.1    darran 			info = *((const ushort_t *)(ctfdata + funcoff));
   1359   1.1    darran 			vlen = CTF_INFO_VLEN(info);
   1360   1.1    darran 
   1361   1.1    darran 			/*
   1362   1.1    darran 			 * If we encounter a zero pad at the end, just skip it.
   1363   1.1    darran 			 * Otherwise skip over the function and its return type
   1364   1.1    darran 			 * (+2) and the argument list (vlen).
   1365   1.1    darran 			 */
   1366   1.1    darran 			if (CTF_INFO_KIND(info) == CTF_K_UNKNOWN && vlen == 0)
   1367   1.1    darran 				funcoff += sizeof (ushort_t); /* skip pad */
   1368   1.1    darran 			else
   1369   1.1    darran 				funcoff += sizeof (ushort_t) * (vlen + 2);
   1370   1.1    darran 			break;
   1371   1.1    darran 
   1372   1.1    darran 		default:
   1373   1.1    darran 			*ctfoff = 0xffffffff;
   1374   1.1    darran 			break;
   1375   1.1    darran 		}
   1376   1.1    darran 	}
   1377   1.1    darran 
   1378   1.1    darran 	return (0);
   1379   1.1    darran }
   1380   1.1    darran 
   1381   1.1    darran static ssize_t
   1382   1.9  christos fbt_get_ctt_size(uint8_t xversion, const ctf_type_t *tp, ssize_t *sizep,
   1383   1.1    darran     ssize_t *incrementp)
   1384   1.1    darran {
   1385   1.1    darran 	ssize_t size, increment;
   1386   1.1    darran 
   1387   1.9  christos 	if (xversion > CTF_VERSION_1 &&
   1388   1.1    darran 	    tp->ctt_size == CTF_LSIZE_SENT) {
   1389   1.1    darran 		size = CTF_TYPE_LSIZE(tp);
   1390   1.1    darran 		increment = sizeof (ctf_type_t);
   1391   1.1    darran 	} else {
   1392   1.1    darran 		size = tp->ctt_size;
   1393   1.1    darran 		increment = sizeof (ctf_stype_t);
   1394   1.1    darran 	}
   1395   1.1    darran 
   1396   1.1    darran 	if (sizep)
   1397   1.1    darran 		*sizep = size;
   1398   1.1    darran 	if (incrementp)
   1399   1.1    darran 		*incrementp = increment;
   1400   1.1    darran 
   1401   1.1    darran 	return (size);
   1402   1.1    darran }
   1403   1.1    darran 
   1404   1.1    darran static int
   1405   1.3    darran fbt_typoff_init(mod_ctf_t *mc)
   1406   1.1    darran {
   1407   1.3    darran 	const ctf_header_t *hp = (const ctf_header_t *) mc->ctftab;
   1408   1.1    darran 	const ctf_type_t *tbuf;
   1409   1.1    darran 	const ctf_type_t *tend;
   1410   1.1    darran 	const ctf_type_t *tp;
   1411   1.3    darran 	const uint8_t *ctfdata = mc->ctftab + sizeof(ctf_header_t);
   1412   1.1    darran 	int ctf_typemax = 0;
   1413   1.1    darran 	uint32_t *xp;
   1414   1.1    darran 	ulong_t pop[CTF_K_MAX + 1] = { 0 };
   1415   1.1    darran 
   1416   1.1    darran 	/* Sanity check. */
   1417   1.1    darran 	if (hp->cth_magic != CTF_MAGIC)
   1418   1.1    darran 		return (EINVAL);
   1419   1.1    darran 
   1420   1.1    darran 	tbuf = (const ctf_type_t *) (ctfdata + hp->cth_typeoff);
   1421   1.1    darran 	tend = (const ctf_type_t *) (ctfdata + hp->cth_stroff);
   1422   1.1    darran 
   1423   1.1    darran 	int child = hp->cth_parname != 0;
   1424   1.1    darran 
   1425   1.1    darran 	/*
   1426   1.1    darran 	 * We make two passes through the entire type section.  In this first
   1427   1.1    darran 	 * pass, we count the number of each type and the total number of types.
   1428   1.1    darran 	 */
   1429   1.1    darran 	for (tp = tbuf; tp < tend; ctf_typemax++) {
   1430   1.1    darran 		ushort_t kind = CTF_INFO_KIND(tp->ctt_info);
   1431   1.1    darran 		ulong_t vlen = CTF_INFO_VLEN(tp->ctt_info);
   1432   1.1    darran 		ssize_t size, increment;
   1433   1.1    darran 
   1434   1.1    darran 		size_t vbytes;
   1435   1.1    darran 		uint_t n;
   1436   1.1    darran 
   1437   1.1    darran 		(void) fbt_get_ctt_size(hp->cth_version, tp, &size, &increment);
   1438   1.1    darran 
   1439   1.1    darran 		switch (kind) {
   1440   1.1    darran 		case CTF_K_INTEGER:
   1441   1.1    darran 		case CTF_K_FLOAT:
   1442   1.1    darran 			vbytes = sizeof (uint_t);
   1443   1.1    darran 			break;
   1444   1.1    darran 		case CTF_K_ARRAY:
   1445   1.1    darran 			vbytes = sizeof (ctf_array_t);
   1446   1.1    darran 			break;
   1447   1.1    darran 		case CTF_K_FUNCTION:
   1448   1.1    darran 			vbytes = sizeof (ushort_t) * (vlen + (vlen & 1));
   1449   1.1    darran 			break;
   1450   1.1    darran 		case CTF_K_STRUCT:
   1451   1.1    darran 		case CTF_K_UNION:
   1452   1.1    darran 			if (size < CTF_LSTRUCT_THRESH) {
   1453   1.1    darran 				ctf_member_t *mp = (ctf_member_t *)
   1454   1.1    darran 				    ((uintptr_t)tp + increment);
   1455   1.1    darran 
   1456   1.1    darran 				vbytes = sizeof (ctf_member_t) * vlen;
   1457   1.1    darran 				for (n = vlen; n != 0; n--, mp++)
   1458   1.1    darran 					child |= CTF_TYPE_ISCHILD(mp->ctm_type);
   1459   1.1    darran 			} else {
   1460   1.1    darran 				ctf_lmember_t *lmp = (ctf_lmember_t *)
   1461   1.1    darran 				    ((uintptr_t)tp + increment);
   1462   1.1    darran 
   1463   1.1    darran 				vbytes = sizeof (ctf_lmember_t) * vlen;
   1464   1.1    darran 				for (n = vlen; n != 0; n--, lmp++)
   1465   1.1    darran 					child |=
   1466   1.1    darran 					    CTF_TYPE_ISCHILD(lmp->ctlm_type);
   1467   1.1    darran 			}
   1468   1.1    darran 			break;
   1469   1.1    darran 		case CTF_K_ENUM:
   1470   1.1    darran 			vbytes = sizeof (ctf_enum_t) * vlen;
   1471   1.1    darran 			break;
   1472   1.1    darran 		case CTF_K_FORWARD:
   1473   1.1    darran 			/*
   1474   1.1    darran 			 * For forward declarations, ctt_type is the CTF_K_*
   1475   1.1    darran 			 * kind for the tag, so bump that population count too.
   1476   1.1    darran 			 * If ctt_type is unknown, treat the tag as a struct.
   1477   1.1    darran 			 */
   1478   1.1    darran 			if (tp->ctt_type == CTF_K_UNKNOWN ||
   1479   1.1    darran 			    tp->ctt_type >= CTF_K_MAX)
   1480   1.1    darran 				pop[CTF_K_STRUCT]++;
   1481   1.1    darran 			else
   1482   1.1    darran 				pop[tp->ctt_type]++;
   1483   1.1    darran 			/*FALLTHRU*/
   1484   1.1    darran 		case CTF_K_UNKNOWN:
   1485   1.1    darran 			vbytes = 0;
   1486   1.1    darran 			break;
   1487   1.1    darran 		case CTF_K_POINTER:
   1488   1.1    darran 		case CTF_K_TYPEDEF:
   1489   1.1    darran 		case CTF_K_VOLATILE:
   1490   1.1    darran 		case CTF_K_CONST:
   1491   1.1    darran 		case CTF_K_RESTRICT:
   1492   1.1    darran 			child |= CTF_TYPE_ISCHILD(tp->ctt_type);
   1493   1.1    darran 			vbytes = 0;
   1494   1.1    darran 			break;
   1495   1.1    darran 		default:
   1496   1.1    darran 			printf("%s(%d): detected invalid CTF kind -- %u\n", __func__, __LINE__, kind);
   1497   1.1    darran 			return (EIO);
   1498   1.1    darran 		}
   1499   1.1    darran 		tp = (ctf_type_t *)((uintptr_t)tp + increment + vbytes);
   1500   1.1    darran 		pop[kind]++;
   1501   1.1    darran 	}
   1502   1.1    darran 
   1503   1.3    darran 	mc->typlen = ctf_typemax;
   1504   1.1    darran 
   1505   1.3    darran 	if ((xp = malloc(sizeof(uint32_t) * ctf_typemax, M_FBT, M_ZERO | M_WAITOK)) == NULL)
   1506   1.1    darran 		return (ENOMEM);
   1507   1.1    darran 
   1508   1.3    darran 	mc->typoffp = xp;
   1509   1.1    darran 
   1510   1.1    darran 	/* type id 0 is used as a sentinel value */
   1511   1.1    darran 	*xp++ = 0;
   1512   1.1    darran 
   1513   1.1    darran 	/*
   1514   1.1    darran 	 * In the second pass, fill in the type offset.
   1515   1.1    darran 	 */
   1516   1.1    darran 	for (tp = tbuf; tp < tend; xp++) {
   1517   1.1    darran 		ushort_t kind = CTF_INFO_KIND(tp->ctt_info);
   1518   1.1    darran 		ulong_t vlen = CTF_INFO_VLEN(tp->ctt_info);
   1519   1.1    darran 		ssize_t size, increment;
   1520   1.1    darran 
   1521   1.1    darran 		size_t vbytes;
   1522   1.1    darran 		uint_t n;
   1523   1.1    darran 
   1524   1.1    darran 		(void) fbt_get_ctt_size(hp->cth_version, tp, &size, &increment);
   1525   1.1    darran 
   1526   1.1    darran 		switch (kind) {
   1527   1.1    darran 		case CTF_K_INTEGER:
   1528   1.1    darran 		case CTF_K_FLOAT:
   1529   1.1    darran 			vbytes = sizeof (uint_t);
   1530   1.1    darran 			break;
   1531   1.1    darran 		case CTF_K_ARRAY:
   1532   1.1    darran 			vbytes = sizeof (ctf_array_t);
   1533   1.1    darran 			break;
   1534   1.1    darran 		case CTF_K_FUNCTION:
   1535   1.1    darran 			vbytes = sizeof (ushort_t) * (vlen + (vlen & 1));
   1536   1.1    darran 			break;
   1537   1.1    darran 		case CTF_K_STRUCT:
   1538   1.1    darran 		case CTF_K_UNION:
   1539   1.1    darran 			if (size < CTF_LSTRUCT_THRESH) {
   1540   1.1    darran 				ctf_member_t *mp = (ctf_member_t *)
   1541   1.1    darran 				    ((uintptr_t)tp + increment);
   1542   1.1    darran 
   1543   1.1    darran 				vbytes = sizeof (ctf_member_t) * vlen;
   1544   1.1    darran 				for (n = vlen; n != 0; n--, mp++)
   1545   1.1    darran 					child |= CTF_TYPE_ISCHILD(mp->ctm_type);
   1546   1.1    darran 			} else {
   1547   1.1    darran 				ctf_lmember_t *lmp = (ctf_lmember_t *)
   1548   1.1    darran 				    ((uintptr_t)tp + increment);
   1549   1.1    darran 
   1550   1.1    darran 				vbytes = sizeof (ctf_lmember_t) * vlen;
   1551   1.1    darran 				for (n = vlen; n != 0; n--, lmp++)
   1552   1.1    darran 					child |=
   1553   1.1    darran 					    CTF_TYPE_ISCHILD(lmp->ctlm_type);
   1554   1.1    darran 			}
   1555   1.1    darran 			break;
   1556   1.1    darran 		case CTF_K_ENUM:
   1557   1.1    darran 			vbytes = sizeof (ctf_enum_t) * vlen;
   1558   1.1    darran 			break;
   1559   1.1    darran 		case CTF_K_FORWARD:
   1560   1.1    darran 		case CTF_K_UNKNOWN:
   1561   1.1    darran 			vbytes = 0;
   1562   1.1    darran 			break;
   1563   1.1    darran 		case CTF_K_POINTER:
   1564   1.1    darran 		case CTF_K_TYPEDEF:
   1565   1.1    darran 		case CTF_K_VOLATILE:
   1566   1.1    darran 		case CTF_K_CONST:
   1567   1.1    darran 		case CTF_K_RESTRICT:
   1568   1.1    darran 			vbytes = 0;
   1569   1.1    darran 			break;
   1570   1.1    darran 		default:
   1571   1.1    darran 			printf("%s(%d): detected invalid CTF kind -- %u\n", __func__, __LINE__, kind);
   1572   1.1    darran 			return (EIO);
   1573   1.1    darran 		}
   1574   1.1    darran 		*xp = (uint32_t)((uintptr_t) tp - (uintptr_t) ctfdata);
   1575   1.1    darran 		tp = (ctf_type_t *)((uintptr_t)tp + increment + vbytes);
   1576   1.1    darran 	}
   1577   1.1    darran 
   1578   1.1    darran 	return (0);
   1579   1.1    darran }
   1580   1.1    darran 
   1581   1.1    darran /*
   1582   1.1    darran  * CTF Declaration Stack
   1583   1.1    darran  *
   1584   1.1    darran  * In order to implement ctf_type_name(), we must convert a type graph back
   1585   1.1    darran  * into a C type declaration.  Unfortunately, a type graph represents a storage
   1586   1.1    darran  * class ordering of the type whereas a type declaration must obey the C rules
   1587   1.1    darran  * for operator precedence, and the two orderings are frequently in conflict.
   1588   1.1    darran  * For example, consider these CTF type graphs and their C declarations:
   1589   1.1    darran  *
   1590   1.1    darran  * CTF_K_POINTER -> CTF_K_FUNCTION -> CTF_K_INTEGER  : int (*)()
   1591   1.1    darran  * CTF_K_POINTER -> CTF_K_ARRAY -> CTF_K_INTEGER     : int (*)[]
   1592   1.1    darran  *
   1593   1.1    darran  * In each case, parentheses are used to raise operator * to higher lexical
   1594   1.1    darran  * precedence, so the string form of the C declaration cannot be constructed by
   1595   1.1    darran  * walking the type graph links and forming the string from left to right.
   1596   1.1    darran  *
   1597   1.1    darran  * The functions in this file build a set of stacks from the type graph nodes
   1598   1.1    darran  * corresponding to the C operator precedence levels in the appropriate order.
   1599   1.1    darran  * The code in ctf_type_name() can then iterate over the levels and nodes in
   1600   1.1    darran  * lexical precedence order and construct the final C declaration string.
   1601   1.1    darran  */
   1602   1.1    darran typedef struct ctf_list {
   1603   1.1    darran 	struct ctf_list *l_prev; /* previous pointer or tail pointer */
   1604   1.1    darran 	struct ctf_list *l_next; /* next pointer or head pointer */
   1605   1.1    darran } ctf_list_t;
   1606   1.1    darran 
   1607   1.1    darran #define	ctf_list_prev(elem)	((void *)(((ctf_list_t *)(elem))->l_prev))
   1608   1.1    darran #define	ctf_list_next(elem)	((void *)(((ctf_list_t *)(elem))->l_next))
   1609   1.1    darran 
   1610   1.1    darran typedef enum {
   1611   1.1    darran 	CTF_PREC_BASE,
   1612   1.1    darran 	CTF_PREC_POINTER,
   1613   1.1    darran 	CTF_PREC_ARRAY,
   1614   1.1    darran 	CTF_PREC_FUNCTION,
   1615   1.1    darran 	CTF_PREC_MAX
   1616   1.1    darran } ctf_decl_prec_t;
   1617   1.1    darran 
   1618   1.1    darran typedef struct ctf_decl_node {
   1619   1.1    darran 	ctf_list_t cd_list;			/* linked list pointers */
   1620   1.1    darran 	ctf_id_t cd_type;			/* type identifier */
   1621   1.1    darran 	uint_t cd_kind;				/* type kind */
   1622   1.1    darran 	uint_t cd_n;				/* type dimension if array */
   1623   1.1    darran } ctf_decl_node_t;
   1624   1.1    darran 
   1625   1.1    darran typedef struct ctf_decl {
   1626   1.1    darran 	ctf_list_t cd_nodes[CTF_PREC_MAX];	/* declaration node stacks */
   1627   1.1    darran 	int cd_order[CTF_PREC_MAX];		/* storage order of decls */
   1628   1.1    darran 	ctf_decl_prec_t cd_qualp;		/* qualifier precision */
   1629   1.1    darran 	ctf_decl_prec_t cd_ordp;		/* ordered precision */
   1630   1.1    darran 	char *cd_buf;				/* buffer for output */
   1631   1.1    darran 	char *cd_ptr;				/* buffer location */
   1632   1.1    darran 	char *cd_end;				/* buffer limit */
   1633   1.1    darran 	size_t cd_len;				/* buffer space required */
   1634   1.1    darran 	int cd_err;				/* saved error value */
   1635   1.1    darran } ctf_decl_t;
   1636   1.1    darran 
   1637   1.1    darran /*
   1638   1.1    darran  * Simple doubly-linked list append routine.  This implementation assumes that
   1639   1.1    darran  * each list element contains an embedded ctf_list_t as the first member.
   1640   1.1    darran  * An additional ctf_list_t is used to store the head (l_next) and tail
   1641   1.1    darran  * (l_prev) pointers.  The current head and tail list elements have their
   1642   1.1    darran  * previous and next pointers set to NULL, respectively.
   1643   1.1    darran  */
   1644   1.1    darran static void
   1645   1.1    darran ctf_list_append(ctf_list_t *lp, void *new)
   1646   1.1    darran {
   1647   1.1    darran 	ctf_list_t *p = lp->l_prev;	/* p = tail list element */
   1648   1.1    darran 	ctf_list_t *q = new;		/* q = new list element */
   1649   1.1    darran 
   1650   1.1    darran 	lp->l_prev = q;
   1651   1.1    darran 	q->l_prev = p;
   1652   1.1    darran 	q->l_next = NULL;
   1653   1.1    darran 
   1654   1.1    darran 	if (p != NULL)
   1655   1.1    darran 		p->l_next = q;
   1656   1.1    darran 	else
   1657   1.1    darran 		lp->l_next = q;
   1658   1.1    darran }
   1659   1.1    darran 
   1660   1.1    darran /*
   1661   1.1    darran  * Prepend the specified existing element to the given ctf_list_t.  The
   1662   1.1    darran  * existing pointer should be pointing at a struct with embedded ctf_list_t.
   1663   1.1    darran  */
   1664   1.1    darran static void
   1665   1.1    darran ctf_list_prepend(ctf_list_t *lp, void *new)
   1666   1.1    darran {
   1667   1.1    darran 	ctf_list_t *p = new;		/* p = new list element */
   1668   1.1    darran 	ctf_list_t *q = lp->l_next;	/* q = head list element */
   1669   1.1    darran 
   1670   1.1    darran 	lp->l_next = p;
   1671   1.1    darran 	p->l_prev = NULL;
   1672   1.1    darran 	p->l_next = q;
   1673   1.1    darran 
   1674   1.1    darran 	if (q != NULL)
   1675   1.1    darran 		q->l_prev = p;
   1676   1.1    darran 	else
   1677   1.1    darran 		lp->l_prev = p;
   1678   1.1    darran }
   1679   1.1    darran 
   1680   1.1    darran static void
   1681   1.1    darran ctf_decl_init(ctf_decl_t *cd, char *buf, size_t len)
   1682   1.1    darran {
   1683   1.1    darran 	int i;
   1684   1.1    darran 
   1685   1.1    darran 	bzero(cd, sizeof (ctf_decl_t));
   1686   1.1    darran 
   1687   1.1    darran 	for (i = CTF_PREC_BASE; i < CTF_PREC_MAX; i++)
   1688   1.1    darran 		cd->cd_order[i] = CTF_PREC_BASE - 1;
   1689   1.1    darran 
   1690   1.1    darran 	cd->cd_qualp = CTF_PREC_BASE;
   1691   1.1    darran 	cd->cd_ordp = CTF_PREC_BASE;
   1692   1.1    darran 
   1693   1.1    darran 	cd->cd_buf = buf;
   1694   1.1    darran 	cd->cd_ptr = buf;
   1695   1.1    darran 	cd->cd_end = buf + len;
   1696   1.1    darran }
   1697   1.1    darran 
   1698   1.1    darran static void
   1699   1.1    darran ctf_decl_fini(ctf_decl_t *cd)
   1700   1.1    darran {
   1701   1.1    darran 	ctf_decl_node_t *cdp, *ndp;
   1702   1.1    darran 	int i;
   1703   1.1    darran 
   1704   1.1    darran 	for (i = CTF_PREC_BASE; i < CTF_PREC_MAX; i++) {
   1705   1.1    darran 		for (cdp = ctf_list_next(&cd->cd_nodes[i]);
   1706   1.1    darran 		    cdp != NULL; cdp = ndp) {
   1707   1.1    darran 			ndp = ctf_list_next(cdp);
   1708   1.1    darran 			free(cdp, M_FBT);
   1709   1.1    darran 		}
   1710   1.1    darran 	}
   1711   1.1    darran }
   1712   1.1    darran 
   1713   1.1    darran static const ctf_type_t *
   1714   1.3    darran ctf_lookup_by_id(mod_ctf_t *mc, ctf_id_t type)
   1715   1.1    darran {
   1716   1.1    darran 	const ctf_type_t *tp;
   1717   1.1    darran 	uint32_t offset;
   1718   1.3    darran 	uint32_t *typoff = mc->typoffp;
   1719   1.1    darran 
   1720   1.3    darran 	if (type >= mc->typlen) {
   1721   1.3    darran 		printf("%s(%d): type %d exceeds max %ld\n",__func__,__LINE__,(int) type,mc->typlen);
   1722   1.1    darran 		return(NULL);
   1723   1.1    darran 	}
   1724   1.1    darran 
   1725   1.1    darran 	/* Check if the type isn't cross-referenced. */
   1726   1.1    darran 	if ((offset = typoff[type]) == 0) {
   1727   1.1    darran 		printf("%s(%d): type %d isn't cross referenced\n",__func__,__LINE__, (int) type);
   1728   1.1    darran 		return(NULL);
   1729   1.1    darran 	}
   1730   1.1    darran 
   1731   1.3    darran 	tp = (const ctf_type_t *)(mc->ctftab + offset + sizeof(ctf_header_t));
   1732   1.1    darran 
   1733   1.1    darran 	return (tp);
   1734   1.1    darran }
   1735   1.1    darran 
   1736   1.1    darran static void
   1737   1.3    darran fbt_array_info(mod_ctf_t *mc, ctf_id_t type, ctf_arinfo_t *arp)
   1738   1.1    darran {
   1739   1.3    darran 	const ctf_header_t *hp = (const ctf_header_t *) mc->ctftab;
   1740   1.1    darran 	const ctf_type_t *tp;
   1741   1.1    darran 	const ctf_array_t *ap;
   1742   1.1    darran 	ssize_t increment;
   1743   1.1    darran 
   1744   1.1    darran 	bzero(arp, sizeof(*arp));
   1745   1.1    darran 
   1746   1.3    darran 	if ((tp = ctf_lookup_by_id(mc, type)) == NULL)
   1747   1.1    darran 		return;
   1748   1.1    darran 
   1749   1.1    darran 	if (CTF_INFO_KIND(tp->ctt_info) != CTF_K_ARRAY)
   1750   1.1    darran 		return;
   1751   1.1    darran 
   1752   1.1    darran 	(void) fbt_get_ctt_size(hp->cth_version, tp, NULL, &increment);
   1753   1.1    darran 
   1754   1.1    darran 	ap = (const ctf_array_t *)((uintptr_t)tp + increment);
   1755   1.1    darran 	arp->ctr_contents = ap->cta_contents;
   1756   1.1    darran 	arp->ctr_index = ap->cta_index;
   1757   1.1    darran 	arp->ctr_nelems = ap->cta_nelems;
   1758   1.1    darran }
   1759   1.1    darran 
   1760   1.1    darran static const char *
   1761   1.3    darran ctf_strptr(mod_ctf_t *mc, int name)
   1762   1.1    darran {
   1763   1.3    darran 	const ctf_header_t *hp = (const ctf_header_t *) mc->ctftab;;
   1764   1.1    darran 	const char *strp = "";
   1765   1.1    darran 
   1766   1.1    darran 	if (name < 0 || name >= hp->cth_strlen)
   1767   1.1    darran 		return(strp);
   1768   1.1    darran 
   1769   1.3    darran 	strp = (const char *)(mc->ctftab + hp->cth_stroff + name + sizeof(ctf_header_t));
   1770   1.1    darran 
   1771   1.1    darran 	return (strp);
   1772   1.1    darran }
   1773   1.1    darran 
   1774   1.1    darran static void
   1775   1.3    darran ctf_decl_push(ctf_decl_t *cd, mod_ctf_t *mc, ctf_id_t type)
   1776   1.1    darran {
   1777   1.1    darran 	ctf_decl_node_t *cdp;
   1778   1.1    darran 	ctf_decl_prec_t prec;
   1779   1.1    darran 	uint_t kind, n = 1;
   1780   1.1    darran 	int is_qual = 0;
   1781   1.1    darran 
   1782   1.1    darran 	const ctf_type_t *tp;
   1783   1.1    darran 	ctf_arinfo_t ar;
   1784   1.1    darran 
   1785   1.3    darran 	if ((tp = ctf_lookup_by_id(mc, type)) == NULL) {
   1786   1.1    darran 		cd->cd_err = ENOENT;
   1787   1.1    darran 		return;
   1788   1.1    darran 	}
   1789   1.1    darran 
   1790   1.1    darran 	switch (kind = CTF_INFO_KIND(tp->ctt_info)) {
   1791   1.1    darran 	case CTF_K_ARRAY:
   1792   1.3    darran 		fbt_array_info(mc, type, &ar);
   1793   1.3    darran 		ctf_decl_push(cd, mc, ar.ctr_contents);
   1794   1.1    darran 		n = ar.ctr_nelems;
   1795   1.1    darran 		prec = CTF_PREC_ARRAY;
   1796   1.1    darran 		break;
   1797   1.1    darran 
   1798   1.1    darran 	case CTF_K_TYPEDEF:
   1799   1.3    darran 		if (ctf_strptr(mc, tp->ctt_name)[0] == '\0') {
   1800   1.3    darran 			ctf_decl_push(cd, mc, tp->ctt_type);
   1801   1.1    darran 			return;
   1802   1.1    darran 		}
   1803   1.1    darran 		prec = CTF_PREC_BASE;
   1804   1.1    darran 		break;
   1805   1.1    darran 
   1806   1.1    darran 	case CTF_K_FUNCTION:
   1807   1.3    darran 		ctf_decl_push(cd, mc, tp->ctt_type);
   1808   1.1    darran 		prec = CTF_PREC_FUNCTION;
   1809   1.1    darran 		break;
   1810   1.1    darran 
   1811   1.1    darran 	case CTF_K_POINTER:
   1812   1.3    darran 		ctf_decl_push(cd, mc, tp->ctt_type);
   1813   1.1    darran 		prec = CTF_PREC_POINTER;
   1814   1.1    darran 		break;
   1815   1.1    darran 
   1816   1.1    darran 	case CTF_K_VOLATILE:
   1817   1.1    darran 	case CTF_K_CONST:
   1818   1.1    darran 	case CTF_K_RESTRICT:
   1819   1.3    darran 		ctf_decl_push(cd, mc, tp->ctt_type);
   1820   1.1    darran 		prec = cd->cd_qualp;
   1821   1.1    darran 		is_qual++;
   1822   1.1    darran 		break;
   1823   1.1    darran 
   1824   1.1    darran 	default:
   1825   1.1    darran 		prec = CTF_PREC_BASE;
   1826   1.1    darran 	}
   1827   1.1    darran 
   1828   1.1    darran 	if ((cdp = malloc(sizeof (ctf_decl_node_t), M_FBT, M_WAITOK)) == NULL) {
   1829   1.1    darran 		cd->cd_err = EAGAIN;
   1830   1.1    darran 		return;
   1831   1.1    darran 	}
   1832   1.1    darran 
   1833   1.1    darran 	cdp->cd_type = type;
   1834   1.1    darran 	cdp->cd_kind = kind;
   1835   1.1    darran 	cdp->cd_n = n;
   1836   1.1    darran 
   1837   1.1    darran 	if (ctf_list_next(&cd->cd_nodes[prec]) == NULL)
   1838   1.1    darran 		cd->cd_order[prec] = cd->cd_ordp++;
   1839   1.1    darran 
   1840   1.1    darran 	/*
   1841   1.1    darran 	 * Reset cd_qualp to the highest precedence level that we've seen so
   1842   1.1    darran 	 * far that can be qualified (CTF_PREC_BASE or CTF_PREC_POINTER).
   1843   1.1    darran 	 */
   1844   1.1    darran 	if (prec > cd->cd_qualp && prec < CTF_PREC_ARRAY)
   1845   1.1    darran 		cd->cd_qualp = prec;
   1846   1.1    darran 
   1847   1.1    darran 	/*
   1848   1.1    darran 	 * C array declarators are ordered inside out so prepend them.  Also by
   1849   1.1    darran 	 * convention qualifiers of base types precede the type specifier (e.g.
   1850   1.1    darran 	 * const int vs. int const) even though the two forms are equivalent.
   1851   1.1    darran 	 */
   1852   1.1    darran 	if (kind == CTF_K_ARRAY || (is_qual && prec == CTF_PREC_BASE))
   1853   1.1    darran 		ctf_list_prepend(&cd->cd_nodes[prec], cdp);
   1854   1.1    darran 	else
   1855   1.1    darran 		ctf_list_append(&cd->cd_nodes[prec], cdp);
   1856   1.1    darran }
   1857   1.1    darran 
   1858   1.1    darran static void
   1859   1.1    darran ctf_decl_sprintf(ctf_decl_t *cd, const char *format, ...)
   1860   1.1    darran {
   1861   1.1    darran 	size_t len = (size_t)(cd->cd_end - cd->cd_ptr);
   1862   1.1    darran 	va_list ap;
   1863   1.1    darran 	size_t n;
   1864   1.1    darran 
   1865   1.1    darran 	va_start(ap, format);
   1866   1.1    darran 	n = vsnprintf(cd->cd_ptr, len, format, ap);
   1867   1.1    darran 	va_end(ap);
   1868   1.1    darran 
   1869   1.1    darran 	cd->cd_ptr += MIN(n, len);
   1870   1.1    darran 	cd->cd_len += n;
   1871   1.1    darran }
   1872   1.1    darran 
   1873   1.1    darran static ssize_t
   1874   1.3    darran fbt_type_name(mod_ctf_t *mc, ctf_id_t type, char *buf, size_t len)
   1875   1.1    darran {
   1876   1.1    darran 	ctf_decl_t cd;
   1877   1.1    darran 	ctf_decl_node_t *cdp;
   1878   1.1    darran 	ctf_decl_prec_t prec, lp, rp;
   1879   1.1    darran 	int ptr, arr;
   1880   1.1    darran 	uint_t k;
   1881   1.1    darran 
   1882   1.3    darran 	if (mc == NULL && type == CTF_ERR)
   1883   1.1    darran 		return (-1); /* simplify caller code by permitting CTF_ERR */
   1884   1.1    darran 
   1885   1.1    darran 	ctf_decl_init(&cd, buf, len);
   1886   1.3    darran 	ctf_decl_push(&cd, mc, type);
   1887   1.1    darran 
   1888   1.1    darran 	if (cd.cd_err != 0) {
   1889   1.1    darran 		ctf_decl_fini(&cd);
   1890   1.1    darran 		return (-1);
   1891   1.1    darran 	}
   1892   1.1    darran 
   1893   1.1    darran 	/*
   1894   1.1    darran 	 * If the type graph's order conflicts with lexical precedence order
   1895   1.1    darran 	 * for pointers or arrays, then we need to surround the declarations at
   1896   1.1    darran 	 * the corresponding lexical precedence with parentheses.  This can
   1897   1.1    darran 	 * result in either a parenthesized pointer (*) as in int (*)() or
   1898   1.1    darran 	 * int (*)[], or in a parenthesized pointer and array as in int (*[])().
   1899   1.1    darran 	 */
   1900   1.1    darran 	ptr = cd.cd_order[CTF_PREC_POINTER] > CTF_PREC_POINTER;
   1901   1.1    darran 	arr = cd.cd_order[CTF_PREC_ARRAY] > CTF_PREC_ARRAY;
   1902   1.1    darran 
   1903   1.1    darran 	rp = arr ? CTF_PREC_ARRAY : ptr ? CTF_PREC_POINTER : -1;
   1904   1.1    darran 	lp = ptr ? CTF_PREC_POINTER : arr ? CTF_PREC_ARRAY : -1;
   1905   1.1    darran 
   1906   1.1    darran 	k = CTF_K_POINTER; /* avoid leading whitespace (see below) */
   1907   1.1    darran 
   1908   1.1    darran 	for (prec = CTF_PREC_BASE; prec < CTF_PREC_MAX; prec++) {
   1909   1.1    darran 		for (cdp = ctf_list_next(&cd.cd_nodes[prec]);
   1910   1.1    darran 		    cdp != NULL; cdp = ctf_list_next(cdp)) {
   1911   1.1    darran 
   1912   1.1    darran 			const ctf_type_t *tp =
   1913   1.3    darran 			    ctf_lookup_by_id(mc, cdp->cd_type);
   1914   1.3    darran 			const char *name = ctf_strptr(mc, tp->ctt_name);
   1915   1.1    darran 
   1916   1.1    darran 			if (k != CTF_K_POINTER && k != CTF_K_ARRAY)
   1917   1.1    darran 				ctf_decl_sprintf(&cd, " ");
   1918   1.1    darran 
   1919   1.1    darran 			if (lp == prec) {
   1920   1.1    darran 				ctf_decl_sprintf(&cd, "(");
   1921   1.1    darran 				lp = -1;
   1922   1.1    darran 			}
   1923   1.1    darran 
   1924   1.1    darran 			switch (cdp->cd_kind) {
   1925   1.1    darran 			case CTF_K_INTEGER:
   1926   1.1    darran 			case CTF_K_FLOAT:
   1927   1.1    darran 			case CTF_K_TYPEDEF:
   1928   1.1    darran 				ctf_decl_sprintf(&cd, "%s", name);
   1929   1.1    darran 				break;
   1930   1.1    darran 			case CTF_K_POINTER:
   1931   1.1    darran 				ctf_decl_sprintf(&cd, "*");
   1932   1.1    darran 				break;
   1933   1.1    darran 			case CTF_K_ARRAY:
   1934   1.1    darran 				ctf_decl_sprintf(&cd, "[%u]", cdp->cd_n);
   1935   1.1    darran 				break;
   1936   1.1    darran 			case CTF_K_FUNCTION:
   1937   1.1    darran 				ctf_decl_sprintf(&cd, "()");
   1938   1.1    darran 				break;
   1939   1.1    darran 			case CTF_K_STRUCT:
   1940   1.1    darran 			case CTF_K_FORWARD:
   1941   1.1    darran 				ctf_decl_sprintf(&cd, "struct %s", name);
   1942   1.1    darran 				break;
   1943   1.1    darran 			case CTF_K_UNION:
   1944   1.1    darran 				ctf_decl_sprintf(&cd, "union %s", name);
   1945   1.1    darran 				break;
   1946   1.1    darran 			case CTF_K_ENUM:
   1947   1.1    darran 				ctf_decl_sprintf(&cd, "enum %s", name);
   1948   1.1    darran 				break;
   1949   1.1    darran 			case CTF_K_VOLATILE:
   1950   1.1    darran 				ctf_decl_sprintf(&cd, "volatile");
   1951   1.1    darran 				break;
   1952   1.1    darran 			case CTF_K_CONST:
   1953   1.1    darran 				ctf_decl_sprintf(&cd, "const");
   1954   1.1    darran 				break;
   1955   1.1    darran 			case CTF_K_RESTRICT:
   1956   1.1    darran 				ctf_decl_sprintf(&cd, "restrict");
   1957   1.1    darran 				break;
   1958   1.1    darran 			}
   1959   1.1    darran 
   1960   1.1    darran 			k = cdp->cd_kind;
   1961   1.1    darran 		}
   1962   1.1    darran 
   1963   1.1    darran 		if (rp == prec)
   1964   1.1    darran 			ctf_decl_sprintf(&cd, ")");
   1965   1.1    darran 	}
   1966   1.1    darran 
   1967   1.1    darran 	ctf_decl_fini(&cd);
   1968   1.1    darran 	return (cd.cd_len);
   1969   1.1    darran }
   1970   1.1    darran 
   1971   1.1    darran static void
   1972   1.1    darran fbt_getargdesc(void *arg __unused, dtrace_id_t id __unused, void *parg, dtrace_argdesc_t *desc)
   1973   1.1    darran {
   1974   1.1    darran 	const ushort_t *dp;
   1975   1.1    darran 	fbt_probe_t *fbt = parg;
   1976   1.3    darran 	mod_ctf_t mc;
   1977   1.3    darran 	dtrace_modctl_t *ctl = fbt->fbtp_ctl;
   1978   1.1    darran 	int ndx = desc->dtargd_ndx;
   1979   1.1    darran 	int symindx = fbt->fbtp_symindx;
   1980   1.1    darran 	uint32_t *ctfoff;
   1981   1.1    darran 	uint32_t offset;
   1982   1.1    darran 	ushort_t info, kind, n;
   1983   1.3    darran 	int nsyms;
   1984   1.1    darran 
   1985   1.1    darran 	desc->dtargd_ndx = DTRACE_ARGNONE;
   1986   1.1    darran 
   1987   1.1    darran 	/* Get a pointer to the CTF data and it's length. */
   1988   1.3    darran 	if (mod_ctf_get(ctl, &mc) != 0) {
   1989   1.6    darran 		static int report=0;
   1990   1.6    darran 		if (report < 1) {
   1991   1.6    darran 		    report++;
   1992   1.6    darran 		    printf("FBT: Error no CTF section found in module \"%s\"\n",
   1993   1.6    darran 			    ctl->mod_info->mi_name);
   1994   1.6    darran 		}
   1995   1.1    darran 		/* No CTF data? Something wrong? *shrug* */
   1996   1.1    darran 		return;
   1997   1.3    darran 	}
   1998   1.3    darran 
   1999   1.3    darran 	nsyms = (mc.nmap != NULL) ? mc.nmapsize : mc.nsym;
   2000   1.1    darran 
   2001   1.1    darran 	/* Check if this module hasn't been initialised yet. */
   2002   1.3    darran 	if (mc.ctfoffp == NULL) {
   2003   1.1    darran 		/*
   2004   1.1    darran 		 * Initialise the CTF object and function symindx to
   2005   1.1    darran 		 * byte offset array.
   2006   1.1    darran 		 */
   2007   1.3    darran 		if (fbt_ctfoff_init(ctl, &mc) != 0) {
   2008   1.1    darran 			return;
   2009   1.3    darran 		}
   2010   1.1    darran 
   2011   1.1    darran 		/* Initialise the CTF type to byte offset array. */
   2012   1.3    darran 		if (fbt_typoff_init(&mc) != 0) {
   2013   1.1    darran 			return;
   2014   1.3    darran 		}
   2015   1.1    darran 	}
   2016   1.1    darran 
   2017   1.3    darran 	ctfoff = mc.ctfoffp;
   2018   1.1    darran 
   2019   1.3    darran 	if (ctfoff == NULL || mc.typoffp == NULL) {
   2020   1.1    darran 		return;
   2021   1.3    darran 	}
   2022   1.1    darran 
   2023   1.1    darran 	/* Check if the symbol index is out of range. */
   2024   1.3    darran 	if (symindx >= nsyms)
   2025   1.1    darran 		return;
   2026   1.1    darran 
   2027   1.1    darran 	/* Check if the symbol isn't cross-referenced. */
   2028   1.1    darran 	if ((offset = ctfoff[symindx]) == 0xffffffff)
   2029   1.1    darran 		return;
   2030   1.1    darran 
   2031   1.3    darran 	dp = (const ushort_t *)(mc.ctftab + offset + sizeof(ctf_header_t));
   2032   1.1    darran 
   2033   1.1    darran 	info = *dp++;
   2034   1.1    darran 	kind = CTF_INFO_KIND(info);
   2035   1.1    darran 	n = CTF_INFO_VLEN(info);
   2036   1.1    darran 
   2037   1.1    darran 	if (kind == CTF_K_UNKNOWN && n == 0) {
   2038  1.12  christos 		printf("%s(%d): Unknown function %s!\n",__func__,__LINE__,
   2039  1.12  christos 		    fbt->fbtp_name);
   2040   1.1    darran 		return;
   2041   1.1    darran 	}
   2042   1.1    darran 
   2043   1.1    darran 	if (kind != CTF_K_FUNCTION) {
   2044  1.12  christos 		printf("%s(%d): Expected a function %s!\n",__func__,__LINE__,
   2045  1.12  christos 		    fbt->fbtp_name);
   2046   1.1    darran 		return;
   2047   1.1    darran 	}
   2048   1.1    darran 
   2049   1.1    darran 	/* Check if the requested argument doesn't exist. */
   2050   1.1    darran 	if (ndx >= n)
   2051   1.1    darran 		return;
   2052   1.1    darran 
   2053   1.1    darran 	/* Skip the return type and arguments up to the one requested. */
   2054   1.1    darran 	dp += ndx + 1;
   2055   1.1    darran 
   2056   1.3    darran 	if (fbt_type_name(&mc, *dp, desc->dtargd_native, sizeof(desc->dtargd_native)) > 0) {
   2057   1.1    darran 		desc->dtargd_ndx = ndx;
   2058   1.3    darran 	}
   2059   1.1    darran 
   2060   1.1    darran 	return;
   2061   1.1    darran }
   2062   1.1    darran 
   2063   1.1    darran static void
   2064   1.3    darran fbt_load(void)
   2065   1.1    darran {
   2066   1.1    darran 	/* Default the probe table size if not specified. */
   2067   1.1    darran 	if (fbt_probetab_size == 0)
   2068   1.1    darran 		fbt_probetab_size = FBT_PROBETAB_SIZE;
   2069   1.1    darran 
   2070   1.1    darran 	/* Choose the hash mask for the probe table. */
   2071   1.1    darran 	fbt_probetab_mask = fbt_probetab_size - 1;
   2072   1.1    darran 
   2073   1.1    darran 	/* Allocate memory for the probe table. */
   2074   1.1    darran 	fbt_probetab =
   2075   1.1    darran 	    malloc(fbt_probetab_size * sizeof (fbt_probe_t *), M_FBT, M_WAITOK | M_ZERO);
   2076   1.1    darran 
   2077   1.1    darran 	dtrace_doubletrap_func = fbt_doubletrap;
   2078   1.1    darran 	dtrace_invop_add(fbt_invop);
   2079  1.14     ozaki #ifdef __arm__
   2080  1.14     ozaki 	dtrace_emulation_jump_addr = fbt_emulate;
   2081  1.14     ozaki #endif
   2082   1.1    darran 
   2083   1.1    darran 	if (dtrace_register("fbt", &fbt_attr, DTRACE_PRIV_USER,
   2084   1.1    darran 	    NULL, &fbt_pops, NULL, &fbt_id) != 0)
   2085   1.1    darran 		return;
   2086   1.1    darran }
   2087   1.1    darran 
   2088   1.1    darran 
   2089   1.1    darran static int
   2090   1.3    darran fbt_unload(void)
   2091   1.1    darran {
   2092   1.1    darran 	int error = 0;
   2093   1.1    darran 
   2094  1.14     ozaki #ifdef __arm__
   2095  1.14     ozaki 	dtrace_emulation_jump_addr = NULL;
   2096  1.14     ozaki #endif
   2097   1.1    darran 	/* De-register the invalid opcode handler. */
   2098   1.1    darran 	dtrace_invop_remove(fbt_invop);
   2099   1.1    darran 
   2100   1.1    darran 	dtrace_doubletrap_func = NULL;
   2101   1.1    darran 
   2102   1.1    darran 	/* De-register this DTrace provider. */
   2103   1.1    darran 	if ((error = dtrace_unregister(fbt_id)) != 0)
   2104   1.1    darran 		return (error);
   2105   1.1    darran 
   2106   1.1    darran 	/* Free the probe table. */
   2107   1.1    darran 	free(fbt_probetab, M_FBT);
   2108   1.1    darran 	fbt_probetab = NULL;
   2109   1.1    darran 	fbt_probetab_mask = 0;
   2110   1.1    darran 
   2111   1.1    darran 	return (error);
   2112   1.1    darran }
   2113   1.1    darran 
   2114   1.3    darran 
   2115   1.1    darran static int
   2116  1.18     ozaki dtrace_fbt_modcmd(modcmd_t cmd, void *data)
   2117   1.1    darran {
   2118   1.3    darran 	int bmajor = -1, cmajor = -1;
   2119  1.17     ozaki 	int error;
   2120   1.1    darran 
   2121   1.3    darran 	switch (cmd) {
   2122   1.3    darran 	case MODULE_CMD_INIT:
   2123   1.3    darran 		fbt_load();
   2124   1.3    darran 		return devsw_attach("fbt", NULL, &bmajor,
   2125   1.3    darran 		    &fbt_cdevsw, &cmajor);
   2126   1.3    darran 	case MODULE_CMD_FINI:
   2127  1.17     ozaki 		error = fbt_unload();
   2128  1.17     ozaki 		if (error != 0)
   2129  1.17     ozaki 			return error;
   2130   1.3    darran 		return devsw_detach(NULL, &fbt_cdevsw);
   2131  1.17     ozaki 	case MODULE_CMD_AUTOUNLOAD:
   2132  1.17     ozaki 		return EBUSY;
   2133   1.1    darran 	default:
   2134   1.3    darran 		return ENOTTY;
   2135   1.1    darran 	}
   2136   1.1    darran }
   2137   1.1    darran 
   2138   1.1    darran static int
   2139   1.3    darran fbt_open(dev_t dev, int flags, int mode, struct lwp *l)
   2140   1.1    darran {
   2141   1.1    darran 	return (0);
   2142   1.1    darran }
   2143   1.1    darran 
   2144  1.18     ozaki MODULE(MODULE_CLASS_MISC, dtrace_fbt, "dtrace");
   2145