1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <sys/errno.h> 30 #include <sys/stat.h> 31 #include <sys/modctl.h> 32 #include <sys/conf.h> 33 #include <sys/systm.h> 34 #include <sys/ddi.h> 35 #include <sys/sunddi.h> 36 #include <sys/cpuvar.h> 37 #include <sys/kmem.h> 38 #include <sys/strsubr.h> 39 #include <sys/dtrace.h> 40 #include <sys/kobj.h> 41 #include <sys/modctl.h> 42 #include <sys/atomic.h> 43 #include <vm/seg_kmem.h> 44 #include <sys/stack.h> 45 #include <sys/ctf_api.h> 46 #include <sys/sysmacros.h> 47 48 static dev_info_t *fbt_devi; 49 static dtrace_provider_id_t fbt_id; 50 static uintptr_t fbt_trampoline; 51 static caddr_t fbt_trampoline_window; 52 static size_t fbt_trampoline_size; 53 static int fbt_verbose = 0; 54 55 /* 56 * Various interesting bean counters. 57 */ 58 static int fbt_entry; 59 static int fbt_ret; 60 static int fbt_retl; 61 static int fbt_retl_jmptab; 62 static int fbt_retl_twoinstr; 63 static int fbt_retl_tailcall; 64 static int fbt_retl_tailjmpl; 65 static int fbt_leaf_functions; 66 67 extern char stubs_base[]; 68 extern char stubs_end[]; 69 70 #define FBT_REG_G0 0 71 #define FBT_REG_G1 1 72 #define FBT_REG_O0 8 73 #define FBT_REG_O1 9 74 #define FBT_REG_O2 10 75 #define FBT_REG_O3 11 76 #define FBT_REG_O4 12 77 #define FBT_REG_O5 13 78 #define FBT_REG_O6 14 79 #define FBT_REG_O7 15 80 #define FBT_REG_I0 24 81 #define FBT_REG_I1 25 82 #define FBT_REG_I2 26 83 #define FBT_REG_I3 27 84 #define FBT_REG_I4 28 85 #define FBT_REG_I7 31 86 #define FBT_REG_L0 16 87 #define FBT_REG_L1 17 88 #define FBT_REG_L2 18 89 #define FBT_REG_L3 19 90 #define FBT_REG_PC 5 91 92 #define FBT_REG_ISGLOBAL(r) ((r) < 8) 93 #define FBT_REG_ISOUTPUT(r) ((r) >= 8 && (r) < 16) 94 #define FBT_REG_ISLOCAL(r) ((r) >= 16 && (r) < 24) 95 #define FBT_REG_ISVOLATILE(r) \ 96 ((FBT_REG_ISGLOBAL(r) || FBT_REG_ISOUTPUT(r)) && (r) != FBT_REG_G0) 97 #define FBT_REG_NLOCALS 8 98 99 #define FBT_REG_MARKLOCAL(locals, r) \ 100 if (FBT_REG_ISLOCAL(r)) \ 101 (locals)[(r) - FBT_REG_L0] = 1; 102 103 #define FBT_REG_INITLOCALS(local, locals) \ 104 for ((local) = 0; (local) < FBT_REG_NLOCALS; (local)++) \ 105 (locals)[(local)] = 0; \ 106 (local) = FBT_REG_L0 107 108 #define FBT_REG_ALLOCLOCAL(local, locals) \ 109 while ((locals)[(local) - FBT_REG_L0]) \ 110 (local)++; \ 111 (locals)[(local) - FBT_REG_L0] = 1; 112 113 #define FBT_OP_MASK 0xc0000000 114 #define FBT_OP_SHIFT 30 115 #define FBT_OP(val) ((val) & FBT_FMT1_MASK) 116 117 #define FBT_SIMM13_MASK 0x1fff 118 #define FBT_SIMM13_MAX ((int32_t)0xfff) 119 #define FBT_IMM22_MASK 0x3fffff 120 #define FBT_IMM22_SHIFT 10 121 #define FBT_IMM10_MASK 0x3ff 122 123 #define FBT_DISP30_MASK 0x3fffffff 124 #define FBT_DISP30(from, to) \ 125 (((uintptr_t)(to) - (uintptr_t)(from) >> 2) & FBT_DISP30_MASK) 126 127 #define FBT_DISP22_MASK 0x3fffff 128 #define FBT_DISP22(from, to) \ 129 (((uintptr_t)(to) - (uintptr_t)(from) >> 2) & FBT_DISP22_MASK) 130 131 #define FBT_DISP19_MASK 0x7ffff 132 #define FBT_DISP19(from, to) \ 133 (((uintptr_t)(to) - (uintptr_t)(from) >> 2) & FBT_DISP19_MASK) 134 135 #define FBT_DISP16_HISHIFT 20 136 #define FBT_DISP16_HIMASK (0x3 << FBT_DISP16_HISHIFT) 137 #define FBT_DISP16_LOMASK (0x3fff) 138 #define FBT_DISP16_MASK (FBT_DISP16_HIMASK | FBT_DISP16_LOMASK) 139 #define FBT_DISP16(val) \ 140 ((((val) & FBT_DISP16_HIMASK) >> 6) | ((val) & FBT_DISP16_LOMASK)) 141 142 #define FBT_DISP14_MASK 0x3fff 143 #define FBT_DISP14(from, to) \ 144 (((uintptr_t)(to) - (uintptr_t)(from) >> 2) & FBT_DISP14_MASK) 145 146 #define FBT_OP0 (((uint32_t)0) << FBT_OP_SHIFT) 147 #define FBT_OP1 (((uint32_t)1) << FBT_OP_SHIFT) 148 #define FBT_OP2 (((uint32_t)2) << FBT_OP_SHIFT) 149 #define FBT_ILLTRAP 0 150 151 #define FBT_ANNUL_SHIFT 29 152 #define FBT_ANNUL (1 << FBT_ANNUL_SHIFT) 153 154 #define FBT_FMT3_OP3_SHIFT 19 155 #define FBT_FMT3_OP_MASK 0xc1f80000 156 #define FBT_FMT3_OP(val) ((val) & FBT_FMT3_OP_MASK) 157 158 #define FBT_FMT3_RD_SHIFT 25 159 #define FBT_FMT3_RD_MASK (0x1f << FBT_FMT3_RD_SHIFT) 160 #define FBT_FMT3_RD(val) \ 161 (((val) & FBT_FMT3_RD_MASK) >> FBT_FMT3_RD_SHIFT) 162 163 #define FBT_FMT3_RS1_SHIFT 14 164 #define FBT_FMT3_RS1_MASK (0x1f << FBT_FMT3_RS1_SHIFT) 165 #define FBT_FMT3_RS1(val) \ 166 (((val) & FBT_FMT3_RS1_MASK) >> FBT_FMT3_RS1_SHIFT) 167 #define FBT_FMT3_RS1_SET(val, rs1) \ 168 (val) = ((val) & ~FBT_FMT3_RS1_MASK) | ((rs1) << FBT_FMT3_RS1_SHIFT) 169 170 #define FBT_FMT3_RS2_SHIFT 0 171 #define FBT_FMT3_RS2_MASK (0x1f << FBT_FMT3_RS2_SHIFT) 172 #define FBT_FMT3_RS2(val) \ 173 (((val) & FBT_FMT3_RS2_MASK) >> FBT_FMT3_RS2_SHIFT) 174 #define FBT_FMT3_RS2_SET(val, rs2) \ 175 (val) = ((val) & ~FBT_FMT3_RS2_MASK) | ((rs2) << FBT_FMT3_RS2_SHIFT) 176 177 #define FBT_FMT3_IMM_SHIFT 13 178 #define FBT_FMT3_IMM (1 << FBT_FMT3_IMM_SHIFT) 179 #define FBT_FMT3_SIMM13_MASK FBT_SIMM13_MASK 180 181 #define FBT_FMT3_ISIMM(val) ((val) & FBT_FMT3_IMM) 182 #define FBT_FMT3_SIMM13(val) ((val) & FBT_FMT3_SIMM13_MASK) 183 184 #define FBT_FMT2_OP2_SHIFT 22 185 #define FBT_FMT2_OP2_MASK (0x7 << FBT_FMT2_OP2_SHIFT) 186 #define FBT_FMT2_RD_SHIFT 25 187 188 #define FBT_FMT1_OP(val) ((val) & FBT_OP_MASK) 189 #define FBT_FMT1_DISP30(val) ((val) & FBT_DISP30_MASK) 190 191 #define FBT_FMT2_OP2_BPCC (0x01 << FBT_FMT2_OP2_SHIFT) 192 #define FBT_FMT2_OP2_BCC (0x02 << FBT_FMT2_OP2_SHIFT) 193 #define FBT_FMT2_OP2_BPR (0x03 << FBT_FMT2_OP2_SHIFT) 194 #define FBT_FMT2_OP2_SETHI (0x04 << FBT_FMT2_OP2_SHIFT) 195 196 #define FBT_FMT2_COND_SHIFT 25 197 #define FBT_FMT2_COND_BA (0x8 << FBT_FMT2_COND_SHIFT) 198 #define FBT_FMT2_COND_BL (0x3 << FBT_FMT2_COND_SHIFT) 199 #define FBT_FMT2_COND_BGE (0xb << FBT_FMT2_COND_SHIFT) 200 201 #define FBT_OP_RESTORE (FBT_OP2 | (0x3d << FBT_FMT3_OP3_SHIFT)) 202 #define FBT_OP_SAVE (FBT_OP2 | (0x3c << FBT_FMT3_OP3_SHIFT)) 203 #define FBT_OP_JMPL (FBT_OP2 | (0x38 << FBT_FMT3_OP3_SHIFT)) 204 #define FBT_OP_RETURN (FBT_OP2 | (0x39 << FBT_FMT3_OP3_SHIFT)) 205 #define FBT_OP_CALL FBT_OP1 206 #define FBT_OP_SETHI (FBT_OP0 | FBT_FMT2_OP2_SETHI) 207 #define FBT_OP_ADD (FBT_OP2 | (0x00 << FBT_FMT3_OP3_SHIFT)) 208 #define FBT_OP_OR (FBT_OP2 | (0x02 << FBT_FMT3_OP3_SHIFT)) 209 #define FBT_OP_SUB (FBT_OP2 | (0x04 << FBT_FMT3_OP3_SHIFT)) 210 #define FBT_OP_CC (FBT_OP2 | (0x10 << FBT_FMT3_OP3_SHIFT)) 211 #define FBT_OP_BA (FBT_OP0 | FBT_FMT2_OP2_BCC | FBT_FMT2_COND_BA) 212 #define FBT_OP_BL (FBT_OP0 | FBT_FMT2_OP2_BCC | FBT_FMT2_COND_BL) 213 #define FBT_OP_BGE (FBT_OP0 | FBT_FMT2_OP2_BCC | FBT_FMT2_COND_BGE) 214 #define FBT_OP_BAPCC (FBT_OP0 | FBT_FMT2_OP2_BPCC | FBT_FMT2_COND_BA) 215 #define FBT_OP_RD (FBT_OP2 | (0x28 << FBT_FMT3_OP3_SHIFT)) 216 217 #define FBT_ORLO(rs, val, rd) \ 218 (FBT_OP_OR | ((rs) << FBT_FMT3_RS1_SHIFT) | \ 219 ((rd) << FBT_FMT3_RD_SHIFT) | FBT_FMT3_IMM | ((val) & FBT_IMM10_MASK)) 220 221 #define FBT_ORSIMM13(rs, val, rd) \ 222 (FBT_OP_OR | ((rs) << FBT_FMT3_RS1_SHIFT) | \ 223 ((rd) << FBT_FMT3_RD_SHIFT) | FBT_FMT3_IMM | ((val) & FBT_SIMM13_MASK)) 224 225 #define FBT_ADDSIMM13(rs, val, rd) \ 226 (FBT_OP_ADD | ((rs) << FBT_FMT3_RS1_SHIFT) | \ 227 ((rd) << FBT_FMT3_RD_SHIFT) | FBT_FMT3_IMM | ((val) & FBT_SIMM13_MASK)) 228 229 #define FBT_ADD(rs1, rs2, rd) \ 230 (FBT_OP_ADD | ((rs1) << FBT_FMT3_RS1_SHIFT) | \ 231 ((rs2) << FBT_FMT3_RS2_SHIFT) | ((rd) << FBT_FMT3_RD_SHIFT)) 232 233 #define FBT_CMP(rs1, rs2) \ 234 (FBT_OP_SUB | FBT_OP_CC | ((rs1) << FBT_FMT3_RS1_SHIFT) | \ 235 ((rs2) << FBT_FMT3_RS2_SHIFT) | (FBT_REG_G0 << FBT_FMT3_RD_SHIFT)) 236 237 #define FBT_MOV(rs, rd) \ 238 (FBT_OP_OR | (FBT_REG_G0 << FBT_FMT3_RS1_SHIFT) | \ 239 ((rs) << FBT_FMT3_RS2_SHIFT) | ((rd) << FBT_FMT3_RD_SHIFT)) 240 241 #define FBT_SETHI(val, reg) \ 242 (FBT_OP_SETHI | (reg << FBT_FMT2_RD_SHIFT) | \ 243 ((val >> FBT_IMM22_SHIFT) & FBT_IMM22_MASK)) 244 245 #define FBT_CALL(orig, dest) (FBT_OP_CALL | FBT_DISP30(orig, dest)) 246 247 #define FBT_RET \ 248 (FBT_OP_JMPL | (FBT_REG_I7 << FBT_FMT3_RS1_SHIFT) | \ 249 (FBT_REG_G0 << FBT_FMT3_RD_SHIFT) | FBT_FMT3_IMM | (sizeof (pc_t) << 1)) 250 251 #define FBT_SAVEIMM(rd, val, rs1) \ 252 (FBT_OP_SAVE | ((rs1) << FBT_FMT3_RS1_SHIFT) | \ 253 ((rd) << FBT_FMT3_RD_SHIFT) | FBT_FMT3_IMM | ((val) & FBT_SIMM13_MASK)) 254 255 #define FBT_RESTORE(rd, rs1, rs2) \ 256 (FBT_OP_RESTORE | ((rs1) << FBT_FMT3_RS1_SHIFT) | \ 257 ((rd) << FBT_FMT3_RD_SHIFT) | ((rs2) << FBT_FMT3_RS2_SHIFT)) 258 259 #define FBT_RETURN(rs1, val) \ 260 (FBT_OP_RETURN | ((rs1) << FBT_FMT3_RS1_SHIFT) | \ 261 FBT_FMT3_IMM | ((val) & FBT_SIMM13_MASK)) 262 263 #define FBT_BA(orig, dest) (FBT_OP_BA | FBT_DISP22(orig, dest)) 264 #define FBT_BAA(orig, dest) (FBT_BA(orig, dest) | FBT_ANNUL) 265 #define FBT_BL(orig, dest) (FBT_OP_BL | FBT_DISP22(orig, dest)) 266 #define FBT_BGE(orig, dest) (FBT_OP_BGE | FBT_DISP22(orig, dest)) 267 #define FBT_BDEST(va, instr) ((uintptr_t)(va) + \ 268 (((int32_t)(((instr) & FBT_DISP22_MASK) << 10)) >> 8)) 269 #define FBT_BPCCDEST(va, instr) ((uintptr_t)(va) + \ 270 (((int32_t)(((instr) & FBT_DISP19_MASK) << 13)) >> 11)) 271 #define FBT_BPRDEST(va, instr) ((uintptr_t)(va) + \ 272 (((int32_t)((FBT_DISP16(instr)) << 16)) >> 14)) 273 274 /* 275 * We're only going to treat a save as safe if (a) both rs1 and rd are 276 * %sp and (b) if the instruction has a simm, the value isn't 0. 277 */ 278 #define FBT_IS_SAVE(instr) \ 279 (FBT_FMT3_OP(instr) == FBT_OP_SAVE && \ 280 FBT_FMT3_RD(instr) == FBT_REG_O6 && \ 281 FBT_FMT3_RS1(instr) == FBT_REG_O6 && \ 282 !(FBT_FMT3_ISIMM(instr) && FBT_FMT3_SIMM13(instr) == 0)) 283 284 #define FBT_IS_BA(instr) (((instr) & ~FBT_DISP22_MASK) == FBT_OP_BA) 285 #define FBT_IS_BAPCC(instr) (((instr) & ~FBT_DISP22_MASK) == FBT_OP_BAPCC) 286 287 #define FBT_IS_RDPC(instr) ((FBT_FMT3_OP(instr) == FBT_OP_RD) && \ 288 (FBT_FMT3_RD(instr) == FBT_REG_PC)) 289 290 #define FBT_IS_PCRELATIVE(instr) \ 291 ((((instr) & FBT_OP_MASK) == FBT_OP0 && \ 292 ((instr) & FBT_FMT2_OP2_MASK) != FBT_FMT2_OP2_SETHI) || \ 293 ((instr) & FBT_OP_MASK) == FBT_OP1 || \ 294 FBT_IS_RDPC(instr)) 295 296 #define FBT_IS_CTI(instr) \ 297 ((((instr) & FBT_OP_MASK) == FBT_OP0 && \ 298 ((instr) & FBT_FMT2_OP2_MASK) != FBT_FMT2_OP2_SETHI) || \ 299 ((instr) & FBT_OP_MASK) == FBT_OP1 || \ 300 (FBT_FMT3_OP(instr) == FBT_OP_JMPL) || \ 301 (FBT_FMT3_OP(instr) == FBT_OP_RETURN)) 302 303 #define FBT_PROBENAME_ENTRY "entry" 304 #define FBT_PROBENAME_RETURN "return" 305 #define FBT_ESTIMATE_ID (UINT32_MAX) 306 #define FBT_COUNTER(id, count) if ((id) != FBT_ESTIMATE_ID) (count)++ 307 308 #define FBT_ENTENT_MAXSIZE (16 * sizeof (uint32_t)) 309 #define FBT_RETENT_MAXSIZE (11 * sizeof (uint32_t)) 310 #define FBT_RETLENT_MAXSIZE (23 * sizeof (uint32_t)) 311 #define FBT_ENT_MAXSIZE \ 312 MAX(MAX(FBT_ENTENT_MAXSIZE, FBT_RETENT_MAXSIZE), FBT_RETLENT_MAXSIZE) 313 314 typedef struct fbt_probe { 315 char *fbtp_name; 316 dtrace_id_t fbtp_id; 317 uintptr_t fbtp_addr; 318 struct modctl *fbtp_ctl; 319 int fbtp_loadcnt; 320 int fbtp_symndx; 321 int fbtp_primary; 322 int fbtp_return; 323 uint32_t *fbtp_patchpoint; 324 uint32_t fbtp_patchval; 325 uint32_t fbtp_savedval; 326 struct fbt_probe *fbtp_next; 327 } fbt_probe_t; 328 329 typedef struct fbt_trampoline { 330 uintptr_t fbtt_va; 331 uintptr_t fbtt_limit; 332 uintptr_t fbtt_next; 333 } fbt_trampoline_t; 334 335 static caddr_t 336 fbt_trampoline_map(uintptr_t tramp, size_t size) 337 { 338 uintptr_t offs; 339 page_t **ppl; 340 341 ASSERT(fbt_trampoline_window == NULL); 342 ASSERT(fbt_trampoline_size == 0); 343 ASSERT(fbt_trampoline == NULL); 344 345 size += tramp & PAGEOFFSET; 346 fbt_trampoline = tramp & PAGEMASK; 347 fbt_trampoline_size = (size + PAGESIZE - 1) & PAGEMASK; 348 fbt_trampoline_window = 349 vmem_alloc(heap_arena, fbt_trampoline_size, VM_SLEEP); 350 351 (void) as_pagelock(&kas, &ppl, (caddr_t)fbt_trampoline, 352 fbt_trampoline_size, S_WRITE); 353 354 for (offs = 0; offs < fbt_trampoline_size; offs += PAGESIZE) { 355 hat_devload(kas.a_hat, fbt_trampoline_window + offs, PAGESIZE, 356 hat_getpfnum(kas.a_hat, (caddr_t)fbt_trampoline + offs), 357 PROT_READ | PROT_WRITE, 358 HAT_LOAD_LOCK | HAT_LOAD_NOCONSIST); 359 } 360 361 as_pageunlock(&kas, ppl, (caddr_t)fbt_trampoline, fbt_trampoline_size, 362 S_WRITE); 363 364 return (fbt_trampoline_window + (tramp & PAGEOFFSET)); 365 } 366 367 static void 368 fbt_trampoline_unmap() 369 { 370 ASSERT(fbt_trampoline_window != NULL); 371 ASSERT(fbt_trampoline_size != 0); 372 ASSERT(fbt_trampoline != NULL); 373 374 membar_enter(); 375 sync_icache((caddr_t)fbt_trampoline, fbt_trampoline_size); 376 sync_icache(fbt_trampoline_window, fbt_trampoline_size); 377 378 hat_unload(kas.a_hat, fbt_trampoline_window, fbt_trampoline_size, 379 HAT_UNLOAD_UNLOCK); 380 381 vmem_free(heap_arena, fbt_trampoline_window, fbt_trampoline_size); 382 383 fbt_trampoline_window = NULL; 384 fbt_trampoline = NULL; 385 fbt_trampoline_size = 0; 386 } 387 388 static uintptr_t 389 fbt_patch_entry(uint32_t *instr, uint32_t id, fbt_trampoline_t *tramp, 390 int nargs) 391 { 392 uint32_t *tinstr = (uint32_t *)tramp->fbtt_next; 393 uint32_t first = *instr; 394 uintptr_t va = tramp->fbtt_va; 395 uintptr_t base = tramp->fbtt_next; 396 397 if (tramp->fbtt_next + FBT_ENTENT_MAXSIZE > tramp->fbtt_limit) { 398 /* 399 * There isn't sufficient room for this entry; return failure. 400 */ 401 return (0); 402 } 403 404 FBT_COUNTER(id, fbt_entry); 405 406 if (FBT_IS_SAVE(first)) { 407 *tinstr++ = first; 408 } else { 409 *tinstr++ = FBT_SAVEIMM(FBT_REG_O6, -SA(MINFRAME), FBT_REG_O6); 410 } 411 412 if (id > (uint32_t)FBT_SIMM13_MAX) { 413 *tinstr++ = FBT_SETHI(id, FBT_REG_O0); 414 *tinstr++ = FBT_ORLO(FBT_REG_O0, id, FBT_REG_O0); 415 } else { 416 *tinstr++ = FBT_ORSIMM13(FBT_REG_G0, id, FBT_REG_O0); 417 } 418 419 if (nargs >= 1) 420 *tinstr++ = FBT_MOV(FBT_REG_I0, FBT_REG_O1); 421 422 if (nargs >= 2) 423 *tinstr++ = FBT_MOV(FBT_REG_I1, FBT_REG_O2); 424 425 if (nargs >= 3) 426 *tinstr++ = FBT_MOV(FBT_REG_I2, FBT_REG_O3); 427 428 if (nargs >= 4) 429 *tinstr++ = FBT_MOV(FBT_REG_I3, FBT_REG_O4); 430 431 if (nargs >= 5) 432 *tinstr++ = FBT_MOV(FBT_REG_I4, FBT_REG_O5); 433 434 if (FBT_IS_SAVE(first)) { 435 uintptr_t ret = (uintptr_t)instr - sizeof (uint32_t); 436 437 *tinstr++ = FBT_SETHI(ret, FBT_REG_G1); 438 *tinstr = FBT_CALL((uintptr_t)tinstr - base + va, dtrace_probe); 439 tinstr++; 440 *tinstr++ = FBT_ORLO(FBT_REG_G1, ret, FBT_REG_O7); 441 } else { 442 uintptr_t slot = *--tinstr; 443 uintptr_t ret = (uintptr_t)instr + sizeof (uint32_t); 444 uint32_t delay = first; 445 446 *tinstr = FBT_CALL((uintptr_t)tinstr - base + va, dtrace_probe); 447 tinstr++; 448 *tinstr++ = slot; 449 *tinstr++ = FBT_RESTORE(FBT_REG_G0, FBT_REG_G0, FBT_REG_G0); 450 451 if (FBT_IS_BA(first) || FBT_IS_BAPCC(first)) { 452 /* 453 * This is a special case: we are instrumenting a 454 * a non-annulled branch-always (or variant). We'll 455 * return directly to the destination of the branch, 456 * copying the instruction in the delay slot here, 457 * and then executing it in the slot of a ba. 458 */ 459 if (FBT_IS_BA(first)) { 460 ret = FBT_BDEST(instr, *instr); 461 } else { 462 ret = FBT_BPCCDEST(instr, *instr); 463 } 464 465 delay = *(instr + 1); 466 } 467 468 if ((first & FBT_OP_MASK) != FBT_OP0 || 469 (first & FBT_FMT2_OP2_MASK) != FBT_FMT2_OP2_BPR) { 470 *tinstr = FBT_BA((uintptr_t)tinstr - base + va, ret); 471 tinstr++; 472 *tinstr++ = delay; 473 } else { 474 /* 475 * If this is a branch-on-register, we have a little 476 * more work to do: because the displacement is only 477 * sixteen bits, we're going to thunk the branch into 478 * the trampoline, and then ba,a to the appropriate 479 * destination in the branch targets. That is, we're 480 * constructing this sequence in the trampoline: 481 * 482 * br[cc] %[rs], 1f 483 * <delay-instruction> 484 * ba,a <not-taken-destination> 485 * 1: ba,a <taken-destination> 486 * 487 */ 488 uintptr_t targ = FBT_BPRDEST(instr, first); 489 490 *tinstr = first & ~(FBT_DISP16_MASK); 491 *tinstr |= FBT_DISP14(tinstr, &tinstr[3]); 492 tinstr++; 493 *tinstr++ = *(instr + 1); 494 *tinstr = FBT_BAA((uintptr_t)tinstr - base + va, 495 ret + sizeof (uint32_t)); 496 tinstr++; 497 *tinstr = FBT_BAA((uintptr_t)tinstr - base + va, targ); 498 tinstr++; 499 } 500 } 501 502 tramp->fbtt_va += (uintptr_t)tinstr - tramp->fbtt_next; 503 tramp->fbtt_next = (uintptr_t)tinstr; 504 505 return (1); 506 } 507 508 /* 509 * We are patching control-transfer/restore couplets. There are three 510 * variants of couplet: 511 * 512 * (a) return rs1 + imm 513 * delay 514 * 515 * (b) jmpl rs1 + (rs2 | offset), rd 516 * restore rs1, rs2 | imm, rd 517 * 518 * (c) call displacement 519 * restore rs1, rs2 | imm, rd 520 * 521 * If rs1 in (a) is anything other than %i7, or imm is anything other than 8, 522 * or delay is a DCTI, we fail. If rd from the jmpl in (b) is something other 523 * than %g0 (a ret or a tail-call through a function pointer) or %o7 (a call 524 * through a register), we fail. 525 * 526 * Note that rs1 and rs2 in the restore instructions in (b) and (c) are 527 * potentially outputs and/or globals. Because these registers cannot be 528 * relied upon across the call to dtrace_probe(), we move rs1 into an unused 529 * local, ls0, and rs2 into an unused local, ls1, and restructure the restore 530 * to be: 531 * 532 * restore ls0, ls1, rd 533 * 534 * Likewise, rs1 and rs2 in the jmpl of case (b) may be outputs and/or globals. 535 * If the jmpl uses outputs or globals, we restructure it to be: 536 * 537 * jmpl ls2 + (ls3 | offset), (%g0 | %o7) 538 * 539 */ 540 /*ARGSUSED*/ 541 static int 542 fbt_canpatch_return(uint32_t *instr, int offset, const char *name) 543 { 544 int rd; 545 546 if (FBT_FMT3_OP(*instr) == FBT_OP_RETURN) { 547 uint32_t delay = *(instr + 1); 548 549 if (*instr != FBT_RETURN(FBT_REG_I7, 8)) { 550 /* 551 * It's unclear if we should warn about this or not. 552 * We really wouldn't expect the compiler to generate 553 * return instructions with something other than %i7 554 * as rs1 and 8 as the simm13 -- it would just be 555 * mean-spirited. That said, such a construct isn't 556 * necessarily incorrect. Sill, we err on the side of 557 * caution and warn about it... 558 */ 559 cmn_err(CE_NOTE, "cannot instrument return of %s at " 560 "%p: non-canonical return instruction", name, 561 (void *)instr); 562 return (0); 563 } 564 565 if (FBT_IS_CTI(delay)) { 566 /* 567 * This is even weirder -- a DCTI coupled with a 568 * return instruction. Similar constructs are used to 569 * return from utraps, but these typically have the 570 * return in the slot -- and we wouldn't expect to see 571 * it in the kernel regardless. At any rate, we don't 572 * want to try to instrument this construct, whatever 573 * it may be. 574 */ 575 cmn_err(CE_NOTE, "cannot instrument return of %s at " 576 "%p: CTI in delay slot of return instruction", 577 name, (void *)instr); 578 return (0); 579 } 580 581 if (FBT_IS_PCRELATIVE(delay)) { 582 /* 583 * This is also very weird, but might be correct code 584 * if the function is (for example) returning the 585 * address of the delay instruction of the return as 586 * its return value (e.g. "rd %pc, %o0" in the slot). 587 * Perhaps correct, but still too weird to not warn 588 * about it... 589 */ 590 cmn_err(CE_NOTE, "cannot instrument return of %s at " 591 "%p: PC-relative instruction in delay slot of " 592 "return instruction", name, (void *)instr); 593 return (0); 594 } 595 596 return (1); 597 } 598 599 if (FBT_FMT3_OP(*(instr + 1)) != FBT_OP_RESTORE) 600 return (0); 601 602 if (FBT_FMT1_OP(*instr) == FBT_OP_CALL) 603 return (1); 604 605 if (FBT_FMT3_OP(*instr) != FBT_OP_JMPL) 606 return (0); 607 608 rd = FBT_FMT3_RD(*instr); 609 610 if (rd == FBT_REG_I7 || rd == FBT_REG_O7 || rd == FBT_REG_G0) 611 return (1); 612 613 /* 614 * We have encountered a jmpl that is storing the calling %pc in 615 * some register besides %i7, %o7 or %g0. This is strange; emit 616 * a warning and fail. 617 */ 618 cmn_err(CE_NOTE, "cannot instrument return of %s at %p: unexpected " 619 "jmpl destination register", name, (void *)instr); 620 return (0); 621 } 622 623 static int 624 fbt_canpatch_retl(uint32_t *instr, int offset, const char *name) 625 { 626 if (FBT_FMT1_OP(*instr) == FBT_OP_CALL || 627 (FBT_FMT3_OP(*instr) == FBT_OP_JMPL && 628 FBT_FMT3_RD(*instr) == FBT_REG_O7)) { 629 /* 630 * If this is a call (or a jmpl that links into %o7), we can 631 * patch it iff the next instruction uses %o7 as a destination 632 * register. Because there is an ABI responsibility to 633 * restore %o7 to the value before the call/jmpl, we don't 634 * particularly care how this routine is managing to restore 635 * it (mov, add, ld or divx for all we care). If it doesn't 636 * seem to be restoring it at all, however, we'll refuse 637 * to patch it. 638 */ 639 uint32_t delay = *(instr + 1); 640 uint32_t op, rd; 641 642 op = FBT_FMT1_OP(delay); 643 rd = FBT_FMT3_RD(delay); 644 645 if (op != FBT_OP2 || rd != FBT_REG_O7) { 646 /* 647 * This is odd. Before we assume that we're looking 648 * at something bizarre (and warn accordingly), we'll 649 * check to see if it's obviously a jump table entry. 650 */ 651 if (*instr < (uintptr_t)instr && 652 *instr >= (uintptr_t)instr - offset) 653 return (0); 654 655 cmn_err(CE_NOTE, "cannot instrument return of %s at " 656 "%p: leaf jmpl/call delay isn't restoring %%o7", 657 name, (void *)instr); 658 return (0); 659 } 660 661 return (1); 662 } 663 664 if (offset == sizeof (uint32_t)) { 665 /* 666 * If this is the second instruction in the function, we're 667 * going to allow it to be patched if the first instruction 668 * is a patchable return-from-leaf instruction. 669 */ 670 if (fbt_canpatch_retl(instr - 1, 0, name)) 671 return (1); 672 } 673 674 if (FBT_FMT3_OP(*instr) != FBT_OP_JMPL) 675 return (0); 676 677 if (FBT_FMT3_RD(*instr) != FBT_REG_G0) 678 return (0); 679 680 return (1); 681 } 682 683 /*ARGSUSED*/ 684 static uint32_t 685 fbt_patch_return(uint32_t *instr, uint32_t *funcbase, uint32_t *funclim, 686 int offset, uint32_t id, fbt_trampoline_t *tramp, const char *name) 687 { 688 uint32_t *tinstr = (uint32_t *)tramp->fbtt_next; 689 uint32_t cti = *instr, restore = *(instr + 1), rs1, dest; 690 uintptr_t va = tramp->fbtt_va; 691 uintptr_t base = tramp->fbtt_next; 692 uint32_t locals[FBT_REG_NLOCALS], local; 693 694 if (tramp->fbtt_next + FBT_RETENT_MAXSIZE > tramp->fbtt_limit) { 695 /* 696 * There isn't sufficient room for this entry; return failure. 697 */ 698 return (FBT_ILLTRAP); 699 } 700 701 FBT_COUNTER(id, fbt_ret); 702 703 if (FBT_FMT3_OP(*instr) == FBT_OP_RETURN) { 704 /* 705 * To handle the case of the return instruction, we'll emit a 706 * restore, followed by the instruction in the slot (which 707 * we'll transplant here), and then another save. While it 708 * may seem intellectually unsatisfying to emit the additional 709 * restore/save couplet, one can take solace in the fact that 710 * we don't do this if the instruction in the return delay 711 * slot is a nop -- which it is nearly 90% of the time with 712 * gcc. (And besides, this couplet can't induce unnecessary 713 * spill/fill traps; rewriting the delay instruction to be 714 * in terms of the current window hardly seems worth the 715 * trouble -- let alone the risk.) 716 */ 717 uint32_t delay = *(instr + 1); 718 ASSERT(*instr == FBT_RETURN(FBT_REG_I7, 8)); 719 720 cti = FBT_RET; 721 restore = FBT_RESTORE(FBT_REG_G0, FBT_REG_G0, FBT_REG_G0); 722 723 if (delay != FBT_SETHI(0, FBT_REG_G0)) { 724 *tinstr++ = restore; 725 *tinstr++ = delay; 726 *tinstr++ = FBT_SAVEIMM(FBT_REG_O6, 727 -SA(MINFRAME), FBT_REG_O6); 728 } 729 } 730 731 FBT_REG_INITLOCALS(local, locals); 732 733 /* 734 * Mark the locals used in the jmpl. 735 */ 736 if (FBT_FMT3_OP(cti) == FBT_OP_JMPL) { 737 uint32_t rs1 = FBT_FMT3_RS1(cti); 738 FBT_REG_MARKLOCAL(locals, rs1); 739 740 if (!FBT_FMT3_ISIMM(cti)) { 741 uint32_t rs2 = FBT_FMT3_RS2(cti); 742 FBT_REG_MARKLOCAL(locals, rs2); 743 } 744 } 745 746 /* 747 * And mark the locals used in the restore. 748 */ 749 rs1 = FBT_FMT3_RS1(restore); 750 FBT_REG_MARKLOCAL(locals, rs1); 751 752 if (!FBT_FMT3_ISIMM(restore)) { 753 uint32_t rs2 = FBT_FMT3_RS2(restore); 754 FBT_REG_MARKLOCAL(locals, rs2); 755 } 756 757 if (FBT_FMT3_OP(cti) == FBT_OP_JMPL) { 758 uint32_t rs1 = FBT_FMT3_RS1(cti); 759 760 if (FBT_REG_ISVOLATILE(rs1)) { 761 FBT_REG_ALLOCLOCAL(local, locals); 762 FBT_FMT3_RS1_SET(cti, local); 763 *tinstr++ = FBT_MOV(rs1, local); 764 } 765 766 if (!FBT_FMT3_ISIMM(cti)) { 767 uint32_t rs2 = FBT_FMT3_RS2(cti); 768 769 if (FBT_REG_ISVOLATILE(rs2)) { 770 FBT_REG_ALLOCLOCAL(local, locals); 771 FBT_FMT3_RS2_SET(cti, local); 772 *tinstr++ = FBT_MOV(rs2, local); 773 } 774 } 775 } 776 777 rs1 = FBT_FMT3_RS1(restore); 778 779 if (FBT_REG_ISVOLATILE(rs1)) { 780 FBT_REG_ALLOCLOCAL(local, locals); 781 FBT_FMT3_RS1_SET(restore, local); 782 *tinstr++ = FBT_MOV(rs1, local); 783 } 784 785 if (!FBT_FMT3_ISIMM(restore)) { 786 uint32_t rs2 = FBT_FMT3_RS2(restore); 787 788 if (FBT_REG_ISVOLATILE(rs2)) { 789 FBT_REG_ALLOCLOCAL(local, locals); 790 FBT_FMT3_RS2_SET(restore, local); 791 *tinstr++ = FBT_MOV(rs2, local); 792 } 793 } 794 795 if (id > (uint32_t)FBT_SIMM13_MAX) { 796 *tinstr++ = FBT_SETHI(id, FBT_REG_O0); 797 *tinstr++ = FBT_ORLO(FBT_REG_O0, id, FBT_REG_O0); 798 } else { 799 *tinstr++ = FBT_ORSIMM13(FBT_REG_G0, id, FBT_REG_O0); 800 } 801 802 if (offset > (uint32_t)FBT_SIMM13_MAX) { 803 *tinstr++ = FBT_SETHI(offset, FBT_REG_O1); 804 *tinstr++ = FBT_ORLO(FBT_REG_O1, offset, FBT_REG_O1); 805 } else { 806 *tinstr++ = FBT_ORSIMM13(FBT_REG_G0, offset, FBT_REG_O1); 807 } 808 809 *tinstr = FBT_CALL((uintptr_t)tinstr - base + va, dtrace_probe); 810 tinstr++; 811 812 if (FBT_FMT3_RD(restore) == FBT_REG_O0) { 813 /* 814 * If the destination register of the restore is %o0, we 815 * need to perform the implied calculation to derive the 816 * return value. 817 */ 818 uint32_t add = (restore & ~FBT_FMT3_OP_MASK) | FBT_OP_ADD; 819 add &= ~FBT_FMT3_RD_MASK; 820 *tinstr++ = add | (FBT_REG_O2 << FBT_FMT3_RD_SHIFT); 821 } else { 822 *tinstr++ = FBT_MOV(FBT_REG_I0, FBT_REG_O2); 823 } 824 825 /* 826 * If the control transfer instruction is %pc-relative (i.e. a 827 * call), we need to reset it appropriately. 828 */ 829 if (FBT_FMT1_OP(cti) == FBT_OP_CALL) { 830 dest = (uintptr_t)instr + (FBT_FMT1_DISP30(cti) << 2); 831 *tinstr = FBT_CALL((uintptr_t)tinstr - base + va, dest); 832 tinstr++; 833 } else { 834 *tinstr++ = cti; 835 } 836 837 *tinstr++ = restore; 838 tramp->fbtt_va += (uintptr_t)tinstr - tramp->fbtt_next; 839 tramp->fbtt_next = (uintptr_t)tinstr; 840 841 return (FBT_BAA(instr, va)); 842 } 843 844 static uint32_t 845 fbt_patch_retl(uint32_t *instr, uint32_t *funcbase, uint32_t *funclim, 846 int offset, uint32_t id, fbt_trampoline_t *tramp, const char *name) 847 { 848 uint32_t *tinstr = (uint32_t *)tramp->fbtt_next; 849 uintptr_t va = tramp->fbtt_va; 850 uintptr_t base = tramp->fbtt_next; 851 uint32_t cti = *instr, dest; 852 int annul = 0; 853 854 FBT_COUNTER(id, fbt_retl); 855 856 if (tramp->fbtt_next + FBT_RETLENT_MAXSIZE > tramp->fbtt_limit) { 857 /* 858 * There isn't sufficient room for this entry; return failure. 859 */ 860 return (FBT_ILLTRAP); 861 } 862 863 if (offset == sizeof (uint32_t) && 864 fbt_canpatch_retl(instr - 1, 0, name)) { 865 *tinstr++ = *instr; 866 annul = 1; 867 FBT_COUNTER(id, fbt_retl_twoinstr); 868 } else { 869 if (FBT_FMT3_OP(cti) == FBT_OP_JMPL && 870 FBT_FMT3_RD(cti) != FBT_REG_O7 && 871 FBT_FMT3_RS1(cti) != FBT_REG_O7) { 872 annul = 1; 873 *tinstr++ = *(instr + 1); 874 } 875 } 876 877 *tinstr++ = FBT_SAVEIMM(FBT_REG_O6, -SA(MINFRAME), FBT_REG_O6); 878 879 if (FBT_FMT3_OP(cti) == FBT_OP_JMPL) { 880 uint32_t rs1, rs2, o2i = FBT_REG_I0 - FBT_REG_O0; 881 882 /* 883 * If we have a jmpl and it's in terms of output registers, we 884 * need to rewrite it to be in terms of the corresponding input 885 * registers. If it's in terms of the globals, we'll rewrite 886 * it to be in terms of locals. 887 */ 888 rs1 = FBT_FMT3_RS1(cti); 889 890 if (FBT_REG_ISOUTPUT(rs1)) 891 rs1 += o2i; 892 893 if (FBT_REG_ISGLOBAL(rs1)) { 894 *tinstr++ = FBT_MOV(rs1, FBT_REG_L0); 895 rs1 = FBT_REG_L0; 896 } 897 898 FBT_FMT3_RS1_SET(cti, rs1); 899 900 if (!FBT_FMT3_ISIMM(cti)) { 901 rs2 = FBT_FMT3_RS2(cti); 902 903 if (FBT_REG_ISOUTPUT(rs2)) 904 rs2 += o2i; 905 906 if (FBT_REG_ISGLOBAL(rs2)) { 907 *tinstr++ = FBT_MOV(rs2, FBT_REG_L1); 908 rs2 = FBT_REG_L1; 909 } 910 911 FBT_FMT3_RS2_SET(cti, rs2); 912 } 913 914 /* 915 * Now we need to check the rd and source register for the jmpl; 916 * If neither rd nor the source register is %o7, then we might 917 * have a jmp that is actually part of a jump table. We need 918 * to generate the code to compare it to the base and limit of 919 * the function. 920 */ 921 if (FBT_FMT3_RD(cti) != FBT_REG_O7 && rs1 != FBT_REG_I7) { 922 uintptr_t base = (uintptr_t)funcbase; 923 uintptr_t limit = (uintptr_t)funclim; 924 925 FBT_COUNTER(id, fbt_retl_jmptab); 926 927 if (FBT_FMT3_ISIMM(cti)) { 928 *tinstr++ = FBT_ADDSIMM13(rs1, 929 FBT_FMT3_SIMM13(cti), FBT_REG_L2); 930 } else { 931 *tinstr++ = FBT_ADD(rs1, rs2, FBT_REG_L2); 932 } 933 934 *tinstr++ = FBT_SETHI(base, FBT_REG_L3); 935 *tinstr++ = FBT_ORLO(FBT_REG_L3, base, FBT_REG_L3); 936 *tinstr++ = FBT_CMP(FBT_REG_L2, FBT_REG_L3); 937 *tinstr++ = FBT_BL(0, 8 * sizeof (uint32_t)); 938 *tinstr++ = FBT_SETHI(limit, FBT_REG_L3); 939 *tinstr++ = FBT_ORLO(FBT_REG_L3, limit, FBT_REG_L3); 940 *tinstr++ = FBT_CMP(FBT_REG_L2, FBT_REG_L3); 941 *tinstr++ = FBT_BGE(0, 4 * sizeof (uint32_t)); 942 *tinstr++ = FBT_SETHI(0, FBT_REG_G0); 943 *tinstr++ = cti; 944 *tinstr++ = FBT_RESTORE(FBT_REG_G0, 945 FBT_REG_G0, FBT_REG_G0); 946 } 947 } 948 949 if (id > (uint32_t)FBT_SIMM13_MAX) { 950 *tinstr++ = FBT_SETHI(id, FBT_REG_O0); 951 *tinstr++ = FBT_ORLO(FBT_REG_O0, id, FBT_REG_O0); 952 } else { 953 *tinstr++ = FBT_ORSIMM13(FBT_REG_G0, id, FBT_REG_O0); 954 } 955 956 if (offset > (uint32_t)FBT_SIMM13_MAX) { 957 *tinstr++ = FBT_SETHI(offset, FBT_REG_O1); 958 *tinstr++ = FBT_ORLO(FBT_REG_O1, offset, FBT_REG_O1); 959 } else { 960 *tinstr++ = FBT_ORSIMM13(FBT_REG_G0, offset, FBT_REG_O1); 961 } 962 963 *tinstr = FBT_CALL((uintptr_t)tinstr - base + va, dtrace_probe); 964 tinstr++; 965 *tinstr++ = FBT_MOV(FBT_REG_I0, FBT_REG_O2); 966 967 /* 968 * If the control transfer instruction is %pc-relative (i.e. a 969 * call), we need to reset it appropriately. 970 */ 971 if (FBT_FMT1_OP(cti) == FBT_OP_CALL) { 972 FBT_COUNTER(id, fbt_retl_tailcall); 973 dest = (uintptr_t)instr + (FBT_FMT1_DISP30(cti) << 2); 974 *tinstr = FBT_CALL((uintptr_t)tinstr - base + va, dest); 975 tinstr++; 976 annul = 1; 977 } else { 978 if (FBT_FMT3_OP(cti) == FBT_OP_JMPL) { 979 *tinstr++ = cti; 980 981 if (FBT_FMT3_RD(cti) == FBT_REG_O7) { 982 FBT_COUNTER(id, fbt_retl_tailjmpl); 983 annul = 1; 984 } 985 } else { 986 *tinstr++ = FBT_RET; 987 } 988 } 989 990 *tinstr++ = FBT_RESTORE(FBT_REG_G0, FBT_REG_G0, FBT_REG_G0); 991 992 tramp->fbtt_va += (uintptr_t)tinstr - tramp->fbtt_next; 993 tramp->fbtt_next = (uintptr_t)tinstr; 994 995 return (annul ? FBT_BAA(instr, va) : FBT_BA(instr, va)); 996 } 997 998 /*ARGSUSED*/ 999 static void 1000 fbt_provide_module(void *arg, struct modctl *ctl) 1001 { 1002 struct module *mp = ctl->mod_mp; 1003 char *modname = ctl->mod_modname; 1004 char *str = mp->strings; 1005 int nsyms = mp->nsyms; 1006 Shdr *symhdr = mp->symhdr; 1007 size_t symsize; 1008 char *name; 1009 int i; 1010 fbt_probe_t *fbt, *retfbt; 1011 fbt_trampoline_t tramp; 1012 uintptr_t offset; 1013 int primary = 0; 1014 ctf_file_t *fp = NULL; 1015 int error; 1016 int estimate = 1; 1017 uint32_t faketramp[50]; 1018 size_t fbt_size = 0; 1019 1020 /* 1021 * Employees of dtrace and their families are ineligible. Void 1022 * where prohibited. 1023 */ 1024 if (strcmp(modname, "dtrace") == 0) 1025 return; 1026 1027 if (ctl->mod_requisites != NULL) { 1028 struct modctl_list *list; 1029 1030 list = (struct modctl_list *)ctl->mod_requisites; 1031 1032 for (; list != NULL; list = list->modl_next) { 1033 if (strcmp(list->modl_modp->mod_modname, "dtrace") == 0) 1034 return; 1035 } 1036 } 1037 1038 /* 1039 * KMDB is ineligible for instrumentation -- it may execute in 1040 * any context, including probe context. 1041 */ 1042 if (strcmp(modname, "kmdbmod") == 0) 1043 return; 1044 1045 if (str == NULL || symhdr == NULL || symhdr->sh_addr == NULL) { 1046 /* 1047 * If this module doesn't (yet) have its string or symbol 1048 * table allocated, clear out. 1049 */ 1050 return; 1051 } 1052 1053 symsize = symhdr->sh_entsize; 1054 1055 if (mp->fbt_nentries) { 1056 /* 1057 * This module has some FBT entries allocated; we're afraid 1058 * to screw with it. 1059 */ 1060 return; 1061 } 1062 1063 if (mp->fbt_tab != NULL) 1064 estimate = 0; 1065 1066 /* 1067 * This is a hack for unix/genunix/krtld. 1068 */ 1069 primary = vmem_contains(heap_arena, (void *)ctl, 1070 sizeof (struct modctl)) == 0; 1071 kobj_textwin_alloc(mp); 1072 1073 /* 1074 * Open the CTF data for the module. We'll use this to determine the 1075 * functions that can be instrumented. Note that this call can fail, 1076 * in which case we'll use heuristics to determine the functions that 1077 * can be instrumented. (But in particular, leaf functions will not be 1078 * instrumented.) 1079 */ 1080 fp = ctf_modopen(mp, &error); 1081 1082 forreal: 1083 if (!estimate) { 1084 tramp.fbtt_next = 1085 (uintptr_t)fbt_trampoline_map((uintptr_t)mp->fbt_tab, 1086 mp->fbt_size); 1087 tramp.fbtt_limit = tramp.fbtt_next + mp->fbt_size; 1088 tramp.fbtt_va = (uintptr_t)mp->fbt_tab; 1089 } 1090 1091 for (i = 1; i < nsyms; i++) { 1092 ctf_funcinfo_t f; 1093 uint32_t *instr, *base, *limit; 1094 Sym *sym = (Sym *)(symhdr->sh_addr + i * symsize); 1095 int have_ctf = 0, is_leaf = 0, nargs, cti = 0; 1096 int (*canpatch)(uint32_t *, int, const char *); 1097 uint32_t (*patch)(uint32_t *, uint32_t *, uint32_t *, int, 1098 uint32_t, fbt_trampoline_t *, const char *); 1099 1100 if (ELF_ST_TYPE(sym->st_info) != STT_FUNC) 1101 continue; 1102 1103 /* 1104 * Weak symbols are not candidates. This could be made to 1105 * work (where weak functions and their underlying function 1106 * appear as two disjoint probes), but it's not simple. 1107 */ 1108 if (ELF_ST_BIND(sym->st_info) == STB_WEAK) 1109 continue; 1110 1111 name = str + sym->st_name; 1112 1113 if (strstr(name, "dtrace_") == name && 1114 strstr(name, "dtrace_safe_") != name) { 1115 /* 1116 * Anything beginning with "dtrace_" may be called 1117 * from probe context unless it explitly indicates 1118 * that it won't be called from probe context by 1119 * using the prefix "dtrace_safe_". 1120 */ 1121 continue; 1122 } 1123 1124 if (strstr(name, "kdi_") == name || 1125 strstr(name, "_kdi_") != NULL) { 1126 /* 1127 * Any function name beginning with "kdi_" or 1128 * containing the string "_kdi_" is a part of the 1129 * kernel debugger interface and may be called in 1130 * arbitrary context -- including probe context. 1131 */ 1132 continue; 1133 } 1134 1135 if (strstr(name, "__relocatable") != NULL) { 1136 /* 1137 * Anything with the string "__relocatable" anywhere 1138 * in the function name is considered to be a function 1139 * that may be manually relocated before execution. 1140 * Because FBT uses a PC-relative technique for 1141 * instrumentation, these functions cannot safely 1142 * be instrumented by us. 1143 */ 1144 continue; 1145 } 1146 1147 if (strstr(name, "ip_ocsum") == name) { 1148 /* 1149 * The ip_ocsum_* family of routines are all ABI 1150 * violators. (They expect incoming arguments in the 1151 * globals!) Break the ABI? No soup for you! 1152 */ 1153 continue; 1154 } 1155 1156 /* 1157 * We want to scan the function for one (and only one) save. 1158 * Any more indicates that something fancy is going on. 1159 */ 1160 base = (uint32_t *)sym->st_value; 1161 limit = (uint32_t *)(sym->st_value + sym->st_size); 1162 1163 /* 1164 * We don't want to interpose on the module stubs. 1165 */ 1166 if (base >= (uint32_t *)stubs_base && 1167 base <= (uint32_t *)stubs_end) 1168 continue; 1169 1170 /* 1171 * We can't safely trace a zero-length function... 1172 */ 1173 if (base == limit) 1174 continue; 1175 1176 /* 1177 * Due to 4524008, _init and _fini may have a bloated st_size. 1178 * While this bug was fixed quite some time ago, old drivers 1179 * may be lurking. We need to develop a better solution to 1180 * this problem, such that correct _init and _fini functions 1181 * (the vast majority) may be correctly traced. One solution 1182 * may be to scan through the entire symbol table to see if 1183 * any symbol overlaps with _init. If none does, set a bit in 1184 * the module structure that this module has correct _init and 1185 * _fini sizes. This will cause some pain the first time a 1186 * module is scanned, but at least it would be O(N) instead of 1187 * O(N log N)... 1188 */ 1189 if (strcmp(name, "_init") == 0) 1190 continue; 1191 1192 if (strcmp(name, "_fini") == 0) 1193 continue; 1194 1195 instr = base; 1196 1197 /* 1198 * While we try hard to only trace safe functions (that is, 1199 * functions at TL=0), one unsafe function manages to otherwise 1200 * appear safe: prom_trap(). We could discover prom_trap() 1201 * if we added an additional rule: in order to trace a 1202 * function, we must either (a) discover a restore or (b) 1203 * determine that the function does not have any unlinked 1204 * control transfers to another function (i.e., the function 1205 * never returns). Unfortunately, as of this writing, one 1206 * legitimate function (resume_from_zombie()) transfers 1207 * control to a different function (_resume_from_idle()) 1208 * without executing a restore. Barring a rule to figure out 1209 * that resume_from_zombie() is safe while prom_trap() is not, 1210 * we resort to hard-coding prom_trap() here. 1211 */ 1212 if (strcmp(name, "prom_trap") == 0) 1213 continue; 1214 1215 if (fp != NULL && ctf_func_info(fp, i, &f) != CTF_ERR) { 1216 nargs = f.ctc_argc; 1217 have_ctf = 1; 1218 } else { 1219 nargs = 32; 1220 } 1221 1222 /* 1223 * If the first instruction of the function is a branch and 1224 * it's not a branch-always-not-annulled, we're going to refuse 1225 * to patch it. 1226 */ 1227 if ((*instr & FBT_OP_MASK) == FBT_OP0 && 1228 (*instr & FBT_FMT2_OP2_MASK) != FBT_FMT2_OP2_SETHI && 1229 (*instr & FBT_FMT2_OP2_MASK) != FBT_FMT2_OP2_BPR) { 1230 if (!FBT_IS_BA(*instr) && !FBT_IS_BAPCC(*instr)) { 1231 if (have_ctf) { 1232 cmn_err(CE_NOTE, "cannot instrument %s:" 1233 " begins with non-ba, " 1234 "non-br CTI", name); 1235 } 1236 continue; 1237 } 1238 } 1239 1240 while (!FBT_IS_SAVE(*instr)) { 1241 /* 1242 * Before we assume that this is a leaf routine, check 1243 * forward in the basic block for a save. 1244 */ 1245 int op = *instr & FBT_OP_MASK; 1246 int op2 = *instr & FBT_FMT2_OP2_MASK; 1247 1248 if (op == FBT_OP0 && op2 != FBT_FMT2_OP2_SETHI) { 1249 /* 1250 * This is a CTI. If we see a subsequent 1251 * save, we will refuse to process this 1252 * routine unless both of the following are 1253 * true: 1254 * 1255 * (a) The branch is not annulled 1256 * 1257 * (b) The subsequent save is in the delay 1258 * slot of the branch 1259 */ 1260 if ((*instr & FBT_ANNUL) || 1261 !FBT_IS_SAVE(*(instr + 1))) { 1262 cti = 1; 1263 } else { 1264 instr++; 1265 break; 1266 } 1267 } 1268 1269 if (op == FBT_OP1) 1270 cti = 1; 1271 1272 if (++instr == limit) 1273 break; 1274 } 1275 1276 if (instr < limit && cti) { 1277 /* 1278 * If we found a CTI before the save, we need to not 1279 * do anything. But if we have CTF information, this 1280 * is weird enough that it merits a message. 1281 */ 1282 if (!have_ctf) 1283 continue; 1284 1285 cmn_err(CE_NOTE, "cannot instrument %s: " 1286 "save not in first basic block", name); 1287 continue; 1288 } 1289 1290 if (instr == limit) { 1291 if (!have_ctf) 1292 continue; 1293 is_leaf = 1; 1294 1295 if (!estimate) 1296 fbt_leaf_functions++; 1297 1298 canpatch = fbt_canpatch_retl; 1299 patch = fbt_patch_retl; 1300 } else { 1301 canpatch = fbt_canpatch_return; 1302 patch = fbt_patch_return; 1303 } 1304 1305 if (!have_ctf && !is_leaf) { 1306 /* 1307 * Before we assume that this isn't something tricky, 1308 * look for other saves. If we find them, there are 1309 * multiple entry points here (or something), and we'll 1310 * leave it alone. 1311 */ 1312 while (++instr < limit) { 1313 if (FBT_IS_SAVE(*instr)) 1314 break; 1315 } 1316 1317 if (instr != limit) 1318 continue; 1319 } 1320 1321 instr = base; 1322 1323 if (FBT_IS_CTI(*instr)) { 1324 /* 1325 * If we have a CTI, we want to be sure that we don't 1326 * have a CTI or a PC-relative instruction in the 1327 * delay slot -- we want to be able to thunk the 1328 * instruction into the trampoline without worrying 1329 * about either DCTIs or relocations. It would be 1330 * very odd for the compiler to generate this kind of 1331 * code, so we warn about it if we have CTF 1332 * information. 1333 */ 1334 if (FBT_IS_CTI(*(instr + 1))) { 1335 if (!have_ctf) 1336 continue; 1337 1338 cmn_err(CE_NOTE, "cannot instrument %s: " 1339 "CTI in delay slot of first instruction", 1340 name); 1341 continue; 1342 } 1343 1344 if (FBT_IS_PCRELATIVE(*(instr + 1))) { 1345 if (!have_ctf) 1346 continue; 1347 1348 cmn_err(CE_NOTE, "cannot instrument %s: " 1349 "PC-relative instruction in delay slot of" 1350 " first instruction", name); 1351 continue; 1352 } 1353 } 1354 1355 if (estimate) { 1356 tramp.fbtt_next = (uintptr_t)faketramp; 1357 tramp.fbtt_limit = tramp.fbtt_next + sizeof (faketramp); 1358 (void) fbt_patch_entry(instr, FBT_ESTIMATE_ID, 1359 &tramp, nargs); 1360 fbt_size += tramp.fbtt_next - (uintptr_t)faketramp; 1361 } else { 1362 fbt = kmem_zalloc(sizeof (fbt_probe_t), KM_SLEEP); 1363 fbt->fbtp_name = name; 1364 fbt->fbtp_ctl = ctl; 1365 fbt->fbtp_id = dtrace_probe_create(fbt_id, modname, 1366 name, FBT_PROBENAME_ENTRY, 1, fbt); 1367 fbt->fbtp_patchval = FBT_BAA(instr, tramp.fbtt_va); 1368 1369 if (!fbt_patch_entry(instr, fbt->fbtp_id, 1370 &tramp, nargs)) { 1371 cmn_err(CE_WARN, "unexpectedly short FBT table " 1372 "in module %s (sym %d of %d)", modname, 1373 i, nsyms); 1374 break; 1375 } 1376 1377 fbt->fbtp_patchpoint = 1378 (uint32_t *)((uintptr_t)mp->textwin + 1379 ((uintptr_t)instr - (uintptr_t)mp->text)); 1380 fbt->fbtp_savedval = *instr; 1381 1382 fbt->fbtp_loadcnt = ctl->mod_loadcnt; 1383 fbt->fbtp_primary = primary; 1384 fbt->fbtp_symndx = i; 1385 mp->fbt_nentries++; 1386 } 1387 1388 retfbt = NULL; 1389 again: 1390 if (++instr == limit) 1391 continue; 1392 1393 offset = (uintptr_t)instr - (uintptr_t)base; 1394 1395 if (!(*canpatch)(instr, offset, name)) 1396 goto again; 1397 1398 if (estimate) { 1399 tramp.fbtt_next = (uintptr_t)faketramp; 1400 tramp.fbtt_limit = tramp.fbtt_next + sizeof (faketramp); 1401 (void) (*patch)(instr, base, limit, 1402 offset, FBT_ESTIMATE_ID, &tramp, name); 1403 fbt_size += tramp.fbtt_next - (uintptr_t)faketramp; 1404 1405 goto again; 1406 } 1407 1408 fbt = kmem_zalloc(sizeof (fbt_probe_t), KM_SLEEP); 1409 fbt->fbtp_name = name; 1410 fbt->fbtp_ctl = ctl; 1411 1412 if (retfbt == NULL) { 1413 fbt->fbtp_id = dtrace_probe_create(fbt_id, modname, 1414 name, FBT_PROBENAME_RETURN, 1, fbt); 1415 } else { 1416 retfbt->fbtp_next = fbt; 1417 fbt->fbtp_id = retfbt->fbtp_id; 1418 } 1419 1420 fbt->fbtp_return = 1; 1421 retfbt = fbt; 1422 1423 if ((fbt->fbtp_patchval = (*patch)(instr, base, limit, offset, 1424 fbt->fbtp_id, &tramp, name)) == FBT_ILLTRAP) { 1425 cmn_err(CE_WARN, "unexpectedly short FBT table " 1426 "in module %s (sym %d of %d)", modname, i, nsyms); 1427 break; 1428 } 1429 1430 fbt->fbtp_patchpoint = (uint32_t *)((uintptr_t)mp->textwin + 1431 ((uintptr_t)instr - (uintptr_t)mp->text)); 1432 fbt->fbtp_savedval = *instr; 1433 fbt->fbtp_loadcnt = ctl->mod_loadcnt; 1434 fbt->fbtp_primary = primary; 1435 fbt->fbtp_symndx = i; 1436 mp->fbt_nentries++; 1437 1438 goto again; 1439 } 1440 1441 if (estimate) { 1442 /* 1443 * Slosh on another entry's worth... 1444 */ 1445 fbt_size += FBT_ENT_MAXSIZE; 1446 mp->fbt_size = fbt_size; 1447 mp->fbt_tab = kobj_texthole_alloc(mp->text, fbt_size); 1448 1449 if (mp->fbt_tab == NULL) { 1450 cmn_err(CE_WARN, "couldn't allocate FBT table " 1451 "for module %s", modname); 1452 } else { 1453 estimate = 0; 1454 goto forreal; 1455 } 1456 } else { 1457 fbt_trampoline_unmap(); 1458 } 1459 1460 error: 1461 if (fp != NULL) 1462 ctf_close(fp); 1463 } 1464 1465 /*ARGSUSED*/ 1466 static void 1467 fbt_destroy(void *arg, dtrace_id_t id, void *parg) 1468 { 1469 fbt_probe_t *fbt = parg, *next; 1470 struct modctl *ctl = fbt->fbtp_ctl; 1471 1472 do { 1473 if (ctl != NULL && ctl->mod_loadcnt == fbt->fbtp_loadcnt) { 1474 if ((ctl->mod_loadcnt == fbt->fbtp_loadcnt && 1475 ctl->mod_loaded) || fbt->fbtp_primary) { 1476 ((struct module *) 1477 (ctl->mod_mp))->fbt_nentries--; 1478 } 1479 } 1480 1481 next = fbt->fbtp_next; 1482 kmem_free(fbt, sizeof (fbt_probe_t)); 1483 fbt = next; 1484 } while (fbt != NULL); 1485 } 1486 1487 /*ARGSUSED*/ 1488 static void 1489 fbt_enable(void *arg, dtrace_id_t id, void *parg) 1490 { 1491 fbt_probe_t *fbt = parg, *f; 1492 struct modctl *ctl = fbt->fbtp_ctl; 1493 1494 ctl->mod_nenabled++; 1495 1496 for (f = fbt; f != NULL; f = f->fbtp_next) { 1497 if (f->fbtp_patchpoint == NULL) { 1498 /* 1499 * Due to a shortened FBT table, this entry was never 1500 * completed; refuse to enable it. 1501 */ 1502 if (fbt_verbose) { 1503 cmn_err(CE_NOTE, "fbt is failing for probe %s " 1504 "(short FBT table in %s)", 1505 fbt->fbtp_name, ctl->mod_modname); 1506 } 1507 1508 return; 1509 } 1510 } 1511 1512 /* 1513 * If this module has disappeared since we discovered its probes, 1514 * refuse to enable it. 1515 */ 1516 if (!fbt->fbtp_primary && !ctl->mod_loaded) { 1517 if (fbt_verbose) { 1518 cmn_err(CE_NOTE, "fbt is failing for probe %s " 1519 "(module %s unloaded)", 1520 fbt->fbtp_name, ctl->mod_modname); 1521 } 1522 1523 return; 1524 } 1525 1526 /* 1527 * Now check that our modctl has the expected load count. If it 1528 * doesn't, this module must have been unloaded and reloaded -- and 1529 * we're not going to touch it. 1530 */ 1531 if (ctl->mod_loadcnt != fbt->fbtp_loadcnt) { 1532 if (fbt_verbose) { 1533 cmn_err(CE_NOTE, "fbt is failing for probe %s " 1534 "(module %s reloaded)", 1535 fbt->fbtp_name, ctl->mod_modname); 1536 } 1537 1538 return; 1539 } 1540 1541 for (; fbt != NULL; fbt = fbt->fbtp_next) 1542 *fbt->fbtp_patchpoint = fbt->fbtp_patchval; 1543 } 1544 1545 /*ARGSUSED*/ 1546 static void 1547 fbt_disable(void *arg, dtrace_id_t id, void *parg) 1548 { 1549 fbt_probe_t *fbt = parg, *f; 1550 struct modctl *ctl = fbt->fbtp_ctl; 1551 1552 ASSERT(ctl->mod_nenabled > 0); 1553 ctl->mod_nenabled--; 1554 1555 for (f = fbt; f != NULL; f = f->fbtp_next) { 1556 if (f->fbtp_patchpoint == NULL) 1557 return; 1558 } 1559 1560 if ((!fbt->fbtp_primary && !ctl->mod_loaded) || 1561 (ctl->mod_loadcnt != fbt->fbtp_loadcnt)) 1562 return; 1563 1564 for (; fbt != NULL; fbt = fbt->fbtp_next) 1565 *fbt->fbtp_patchpoint = fbt->fbtp_savedval; 1566 } 1567 1568 /*ARGSUSED*/ 1569 static void 1570 fbt_suspend(void *arg, dtrace_id_t id, void *parg) 1571 { 1572 fbt_probe_t *fbt = parg; 1573 struct modctl *ctl = fbt->fbtp_ctl; 1574 1575 if (!fbt->fbtp_primary && !ctl->mod_loaded) 1576 return; 1577 1578 if (ctl->mod_loadcnt != fbt->fbtp_loadcnt) 1579 return; 1580 1581 ASSERT(ctl->mod_nenabled > 0); 1582 1583 for (; fbt != NULL; fbt = fbt->fbtp_next) 1584 *fbt->fbtp_patchpoint = fbt->fbtp_savedval; 1585 } 1586 1587 /*ARGSUSED*/ 1588 static void 1589 fbt_resume(void *arg, dtrace_id_t id, void *parg) 1590 { 1591 fbt_probe_t *fbt = parg; 1592 struct modctl *ctl = fbt->fbtp_ctl; 1593 1594 if (!fbt->fbtp_primary && !ctl->mod_loaded) 1595 return; 1596 1597 if (ctl->mod_loadcnt != fbt->fbtp_loadcnt) 1598 return; 1599 1600 ASSERT(ctl->mod_nenabled > 0); 1601 1602 for (; fbt != NULL; fbt = fbt->fbtp_next) 1603 *fbt->fbtp_patchpoint = fbt->fbtp_patchval; 1604 } 1605 1606 /*ARGSUSED*/ 1607 static void 1608 fbt_getargdesc(void *arg, dtrace_id_t id, void *parg, dtrace_argdesc_t *desc) 1609 { 1610 fbt_probe_t *fbt = parg; 1611 struct modctl *ctl = fbt->fbtp_ctl; 1612 struct module *mp = ctl->mod_mp; 1613 ctf_file_t *fp = NULL, *pfp; 1614 ctf_funcinfo_t f; 1615 int error; 1616 ctf_id_t argv[32], type; 1617 int argc = sizeof (argv) / sizeof (ctf_id_t); 1618 const char *parent; 1619 1620 if (!ctl->mod_loaded || (ctl->mod_loadcnt != fbt->fbtp_loadcnt)) 1621 goto err; 1622 1623 if (fbt->fbtp_return && desc->dtargd_ndx == 0) { 1624 (void) strcpy(desc->dtargd_native, "int"); 1625 return; 1626 } 1627 1628 if ((fp = ctf_modopen(mp, &error)) == NULL) { 1629 /* 1630 * We have no CTF information for this module -- and therefore 1631 * no args[] information. 1632 */ 1633 goto err; 1634 } 1635 1636 /* 1637 * If we have a parent container, we must manually import it. 1638 */ 1639 if ((parent = ctf_parent_name(fp)) != NULL) { 1640 struct modctl *mod; 1641 1642 /* 1643 * We must iterate over all modules to find the module that 1644 * is our parent. 1645 */ 1646 for (mod = &modules; mod != NULL; mod = mod->mod_next) { 1647 if (strcmp(mod->mod_filename, parent) == 0) 1648 break; 1649 } 1650 1651 if (mod == NULL) 1652 goto err; 1653 1654 if ((pfp = ctf_modopen(mod->mod_mp, &error)) == NULL) 1655 goto err; 1656 1657 if (ctf_import(fp, pfp) != 0) { 1658 ctf_close(pfp); 1659 goto err; 1660 } 1661 1662 ctf_close(pfp); 1663 } 1664 1665 if (ctf_func_info(fp, fbt->fbtp_symndx, &f) == CTF_ERR) 1666 goto err; 1667 1668 if (fbt->fbtp_return) { 1669 if (desc->dtargd_ndx > 1) 1670 goto err; 1671 1672 ASSERT(desc->dtargd_ndx == 1); 1673 type = f.ctc_return; 1674 } else { 1675 if (desc->dtargd_ndx + 1 > f.ctc_argc) 1676 goto err; 1677 1678 if (ctf_func_args(fp, fbt->fbtp_symndx, argc, argv) == CTF_ERR) 1679 goto err; 1680 1681 type = argv[desc->dtargd_ndx]; 1682 } 1683 1684 if (ctf_type_name(fp, type, desc->dtargd_native, 1685 DTRACE_ARGTYPELEN) != NULL) { 1686 ctf_close(fp); 1687 return; 1688 } 1689 err: 1690 if (fp != NULL) 1691 ctf_close(fp); 1692 1693 desc->dtargd_ndx = DTRACE_ARGNONE; 1694 } 1695 1696 static dtrace_pattr_t fbt_attr = { 1697 { DTRACE_STABILITY_EVOLVING, DTRACE_STABILITY_EVOLVING, DTRACE_CLASS_ISA }, 1698 { DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_UNKNOWN }, 1699 { DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_UNKNOWN }, 1700 { DTRACE_STABILITY_EVOLVING, DTRACE_STABILITY_EVOLVING, DTRACE_CLASS_ISA }, 1701 { DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_ISA }, 1702 }; 1703 1704 static dtrace_pops_t fbt_pops = { 1705 NULL, 1706 fbt_provide_module, 1707 fbt_enable, 1708 fbt_disable, 1709 fbt_suspend, 1710 fbt_resume, 1711 fbt_getargdesc, 1712 NULL, 1713 NULL, 1714 fbt_destroy 1715 }; 1716 1717 static int 1718 fbt_attach(dev_info_t *devi, ddi_attach_cmd_t cmd) 1719 { 1720 switch (cmd) { 1721 case DDI_ATTACH: 1722 break; 1723 case DDI_RESUME: 1724 return (DDI_SUCCESS); 1725 default: 1726 return (DDI_FAILURE); 1727 } 1728 1729 if (ddi_create_minor_node(devi, "fbt", S_IFCHR, 0, 1730 DDI_PSEUDO, NULL) == DDI_FAILURE || 1731 dtrace_register("fbt", &fbt_attr, DTRACE_PRIV_KERNEL, 0, 1732 &fbt_pops, NULL, &fbt_id) != 0) { 1733 ddi_remove_minor_node(devi, NULL); 1734 return (DDI_FAILURE); 1735 } 1736 1737 ddi_report_dev(devi); 1738 fbt_devi = devi; 1739 return (DDI_SUCCESS); 1740 } 1741 1742 static int 1743 fbt_detach(dev_info_t *devi, ddi_detach_cmd_t cmd) 1744 { 1745 switch (cmd) { 1746 case DDI_DETACH: 1747 break; 1748 case DDI_SUSPEND: 1749 return (DDI_SUCCESS); 1750 default: 1751 return (DDI_FAILURE); 1752 } 1753 1754 if (dtrace_unregister(fbt_id) != 0) 1755 return (DDI_FAILURE); 1756 1757 ddi_remove_minor_node(devi, NULL); 1758 return (DDI_SUCCESS); 1759 } 1760 1761 /*ARGSUSED*/ 1762 static int 1763 fbt_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result) 1764 { 1765 int error; 1766 1767 switch (infocmd) { 1768 case DDI_INFO_DEVT2DEVINFO: 1769 *result = (void *)fbt_devi; 1770 error = DDI_SUCCESS; 1771 break; 1772 case DDI_INFO_DEVT2INSTANCE: 1773 *result = (void *)0; 1774 error = DDI_SUCCESS; 1775 break; 1776 default: 1777 error = DDI_FAILURE; 1778 } 1779 return (error); 1780 } 1781 1782 /*ARGSUSED*/ 1783 static int 1784 fbt_open(dev_t *devp, int flag, int otyp, cred_t *cred_p) 1785 { 1786 return (0); 1787 } 1788 1789 static struct cb_ops fbt_cb_ops = { 1790 fbt_open, /* open */ 1791 nodev, /* close */ 1792 nulldev, /* strategy */ 1793 nulldev, /* print */ 1794 nodev, /* dump */ 1795 nodev, /* read */ 1796 nodev, /* write */ 1797 nodev, /* ioctl */ 1798 nodev, /* devmap */ 1799 nodev, /* mmap */ 1800 nodev, /* segmap */ 1801 nochpoll, /* poll */ 1802 ddi_prop_op, /* cb_prop_op */ 1803 0, /* streamtab */ 1804 D_NEW | D_MP /* Driver compatibility flag */ 1805 }; 1806 1807 static struct dev_ops fbt_ops = { 1808 DEVO_REV, /* devo_rev */ 1809 0, /* refcnt */ 1810 fbt_info, /* get_dev_info */ 1811 nulldev, /* identify */ 1812 nulldev, /* probe */ 1813 fbt_attach, /* attach */ 1814 fbt_detach, /* detach */ 1815 nodev, /* reset */ 1816 &fbt_cb_ops, /* driver operations */ 1817 NULL, /* bus operations */ 1818 nodev /* dev power */ 1819 }; 1820 1821 /* 1822 * Module linkage information for the kernel. 1823 */ 1824 static struct modldrv modldrv = { 1825 &mod_driverops, /* module type (this is a pseudo driver) */ 1826 "Function Boundary Tracing", /* name of module */ 1827 &fbt_ops, /* driver ops */ 1828 }; 1829 1830 static struct modlinkage modlinkage = { 1831 MODREV_1, 1832 (void *)&modldrv, 1833 NULL 1834 }; 1835 1836 int 1837 _init(void) 1838 { 1839 return (mod_install(&modlinkage)); 1840 } 1841 1842 int 1843 _info(struct modinfo *modinfop) 1844 { 1845 return (mod_info(&modlinkage, modinfop)); 1846 } 1847 1848 int 1849 _fini(void) 1850 { 1851 return (mod_remove(&modlinkage)); 1852 } 1853