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