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 /* 1126 * Anything beginning with "kdi_" is a part of the 1127 * kernel debugger interface and may be called in 1128 * arbitrary context -- including probe context. 1129 */ 1130 continue; 1131 } 1132 1133 if (strstr(name, "__relocatable") != NULL) { 1134 /* 1135 * Anything with the string "__relocatable" anywhere 1136 * in the function name is considered to be a function 1137 * that may be manually relocated before execution. 1138 * Because FBT uses a PC-relative technique for 1139 * instrumentation, these functions cannot safely 1140 * be instrumented by us. 1141 */ 1142 continue; 1143 } 1144 1145 if (strstr(name, "ip_ocsum") == name) { 1146 /* 1147 * The ip_ocsum_* family of routines are all ABI 1148 * violators. (They expect incoming arguments in the 1149 * globals!) Break the ABI? No soup for you! 1150 */ 1151 continue; 1152 } 1153 1154 /* 1155 * We want to scan the function for one (and only one) save. 1156 * Any more indicates that something fancy is going on. 1157 */ 1158 base = (uint32_t *)sym->st_value; 1159 limit = (uint32_t *)(sym->st_value + sym->st_size); 1160 1161 /* 1162 * We don't want to interpose on the module stubs. 1163 */ 1164 if (base >= (uint32_t *)stubs_base && 1165 base <= (uint32_t *)stubs_end) 1166 continue; 1167 1168 /* 1169 * We can't safely trace a zero-length function... 1170 */ 1171 if (base == limit) 1172 continue; 1173 1174 /* 1175 * Due to 4524008, _init and _fini may have a bloated st_size. 1176 * While this bug was fixed quite some time ago, old drivers 1177 * may be lurking. We need to develop a better solution to 1178 * this problem, such that correct _init and _fini functions 1179 * (the vast majority) may be correctly traced. One solution 1180 * may be to scan through the entire symbol table to see if 1181 * any symbol overlaps with _init. If none does, set a bit in 1182 * the module structure that this module has correct _init and 1183 * _fini sizes. This will cause some pain the first time a 1184 * module is scanned, but at least it would be O(N) instead of 1185 * O(N log N)... 1186 */ 1187 if (strcmp(name, "_init") == 0) 1188 continue; 1189 1190 if (strcmp(name, "_fini") == 0) 1191 continue; 1192 1193 instr = base; 1194 1195 /* 1196 * While we try hard to only trace safe functions (that is, 1197 * functions at TL=0), one unsafe function manages to otherwise 1198 * appear safe: prom_trap(). We could discover prom_trap() 1199 * if we added an additional rule: in order to trace a 1200 * function, we must either (a) discover a restore or (b) 1201 * determine that the function does not have any unlinked 1202 * control transfers to another function (i.e., the function 1203 * never returns). Unfortunately, as of this writing, one 1204 * legitimate function (resume_from_zombie()) transfers 1205 * control to a different function (_resume_from_idle()) 1206 * without executing a restore. Barring a rule to figure out 1207 * that resume_from_zombie() is safe while prom_trap() is not, 1208 * we resort to hard-coding prom_trap() here. 1209 */ 1210 if (strcmp(name, "prom_trap") == 0) 1211 continue; 1212 1213 if (fp != NULL && ctf_func_info(fp, i, &f) != CTF_ERR) { 1214 nargs = f.ctc_argc; 1215 have_ctf = 1; 1216 } else { 1217 nargs = 32; 1218 } 1219 1220 /* 1221 * If the first instruction of the function is a branch and 1222 * it's not a branch-always-not-annulled, we're going to refuse 1223 * to patch it. 1224 */ 1225 if ((*instr & FBT_OP_MASK) == FBT_OP0 && 1226 (*instr & FBT_FMT2_OP2_MASK) != FBT_FMT2_OP2_SETHI && 1227 (*instr & FBT_FMT2_OP2_MASK) != FBT_FMT2_OP2_BPR) { 1228 if (!FBT_IS_BA(*instr) && !FBT_IS_BAPCC(*instr)) { 1229 if (have_ctf) { 1230 cmn_err(CE_NOTE, "cannot instrument %s:" 1231 " begins with non-ba, " 1232 "non-br CTI", name); 1233 } 1234 continue; 1235 } 1236 } 1237 1238 while (!FBT_IS_SAVE(*instr)) { 1239 /* 1240 * Before we assume that this is a leaf routine, check 1241 * forward in the basic block for a save. 1242 */ 1243 int op = *instr & FBT_OP_MASK; 1244 int op2 = *instr & FBT_FMT2_OP2_MASK; 1245 1246 if (op == FBT_OP0 && op2 != FBT_FMT2_OP2_SETHI) { 1247 /* 1248 * This is a CTI. If we see a subsequent 1249 * save, we will refuse to process this 1250 * routine unless both of the following are 1251 * true: 1252 * 1253 * (a) The branch is not annulled 1254 * 1255 * (b) The subsequent save is in the delay 1256 * slot of the branch 1257 */ 1258 if ((*instr & FBT_ANNUL) || 1259 !FBT_IS_SAVE(*(instr + 1))) { 1260 cti = 1; 1261 } else { 1262 instr++; 1263 break; 1264 } 1265 } 1266 1267 if (op == FBT_OP1) 1268 cti = 1; 1269 1270 if (++instr == limit) 1271 break; 1272 } 1273 1274 if (instr < limit && cti) { 1275 /* 1276 * If we found a CTI before the save, we need to not 1277 * do anything. But if we have CTF information, this 1278 * is weird enough that it merits a message. 1279 */ 1280 if (!have_ctf) 1281 continue; 1282 1283 cmn_err(CE_NOTE, "cannot instrument %s: " 1284 "save not in first basic block", name); 1285 continue; 1286 } 1287 1288 if (instr == limit) { 1289 if (!have_ctf) 1290 continue; 1291 is_leaf = 1; 1292 1293 if (!estimate) 1294 fbt_leaf_functions++; 1295 1296 canpatch = fbt_canpatch_retl; 1297 patch = fbt_patch_retl; 1298 } else { 1299 canpatch = fbt_canpatch_return; 1300 patch = fbt_patch_return; 1301 } 1302 1303 if (!have_ctf && !is_leaf) { 1304 /* 1305 * Before we assume that this isn't something tricky, 1306 * look for other saves. If we find them, there are 1307 * multiple entry points here (or something), and we'll 1308 * leave it alone. 1309 */ 1310 while (++instr < limit) { 1311 if (FBT_IS_SAVE(*instr)) 1312 break; 1313 } 1314 1315 if (instr != limit) 1316 continue; 1317 } 1318 1319 instr = base; 1320 1321 if (FBT_IS_CTI(*instr)) { 1322 /* 1323 * If we have a CTI, we want to be sure that we don't 1324 * have a CTI or a PC-relative instruction in the 1325 * delay slot -- we want to be able to thunk the 1326 * instruction into the trampoline without worrying 1327 * about either DCTIs or relocations. It would be 1328 * very odd for the compiler to generate this kind of 1329 * code, so we warn about it if we have CTF 1330 * information. 1331 */ 1332 if (FBT_IS_CTI(*(instr + 1))) { 1333 if (!have_ctf) 1334 continue; 1335 1336 cmn_err(CE_NOTE, "cannot instrument %s: " 1337 "CTI in delay slot of first instruction", 1338 name); 1339 continue; 1340 } 1341 1342 if (FBT_IS_PCRELATIVE(*(instr + 1))) { 1343 if (!have_ctf) 1344 continue; 1345 1346 cmn_err(CE_NOTE, "cannot instrument %s: " 1347 "PC-relative instruction in delay slot of" 1348 " first instruction", name); 1349 continue; 1350 } 1351 } 1352 1353 if (estimate) { 1354 tramp.fbtt_next = (uintptr_t)faketramp; 1355 tramp.fbtt_limit = tramp.fbtt_next + sizeof (faketramp); 1356 (void) fbt_patch_entry(instr, FBT_ESTIMATE_ID, 1357 &tramp, nargs); 1358 fbt_size += tramp.fbtt_next - (uintptr_t)faketramp; 1359 } else { 1360 fbt = kmem_zalloc(sizeof (fbt_probe_t), KM_SLEEP); 1361 fbt->fbtp_name = name; 1362 fbt->fbtp_ctl = ctl; 1363 fbt->fbtp_id = dtrace_probe_create(fbt_id, modname, 1364 name, FBT_PROBENAME_ENTRY, 1, fbt); 1365 fbt->fbtp_patchval = FBT_BAA(instr, tramp.fbtt_va); 1366 1367 if (!fbt_patch_entry(instr, fbt->fbtp_id, 1368 &tramp, nargs)) { 1369 cmn_err(CE_WARN, "unexpectedly short FBT table " 1370 "in module %s (sym %d of %d)", modname, 1371 i, nsyms); 1372 break; 1373 } 1374 1375 fbt->fbtp_patchpoint = 1376 (uint32_t *)((uintptr_t)mp->textwin + 1377 ((uintptr_t)instr - (uintptr_t)mp->text)); 1378 fbt->fbtp_savedval = *instr; 1379 1380 fbt->fbtp_loadcnt = ctl->mod_loadcnt; 1381 fbt->fbtp_primary = primary; 1382 fbt->fbtp_symndx = i; 1383 mp->fbt_nentries++; 1384 } 1385 1386 retfbt = NULL; 1387 again: 1388 if (++instr == limit) 1389 continue; 1390 1391 offset = (uintptr_t)instr - (uintptr_t)base; 1392 1393 if (!(*canpatch)(instr, offset, name)) 1394 goto again; 1395 1396 if (estimate) { 1397 tramp.fbtt_next = (uintptr_t)faketramp; 1398 tramp.fbtt_limit = tramp.fbtt_next + sizeof (faketramp); 1399 (void) (*patch)(instr, base, limit, 1400 offset, FBT_ESTIMATE_ID, &tramp, name); 1401 fbt_size += tramp.fbtt_next - (uintptr_t)faketramp; 1402 1403 goto again; 1404 } 1405 1406 fbt = kmem_zalloc(sizeof (fbt_probe_t), KM_SLEEP); 1407 fbt->fbtp_name = name; 1408 fbt->fbtp_ctl = ctl; 1409 1410 if (retfbt == NULL) { 1411 fbt->fbtp_id = dtrace_probe_create(fbt_id, modname, 1412 name, FBT_PROBENAME_RETURN, 1, fbt); 1413 } else { 1414 retfbt->fbtp_next = fbt; 1415 fbt->fbtp_id = retfbt->fbtp_id; 1416 } 1417 1418 fbt->fbtp_return = 1; 1419 retfbt = fbt; 1420 1421 if ((fbt->fbtp_patchval = (*patch)(instr, base, limit, offset, 1422 fbt->fbtp_id, &tramp, name)) == FBT_ILLTRAP) { 1423 cmn_err(CE_WARN, "unexpectedly short FBT table " 1424 "in module %s (sym %d of %d)", modname, i, nsyms); 1425 break; 1426 } 1427 1428 fbt->fbtp_patchpoint = (uint32_t *)((uintptr_t)mp->textwin + 1429 ((uintptr_t)instr - (uintptr_t)mp->text)); 1430 fbt->fbtp_savedval = *instr; 1431 fbt->fbtp_loadcnt = ctl->mod_loadcnt; 1432 fbt->fbtp_primary = primary; 1433 fbt->fbtp_symndx = i; 1434 mp->fbt_nentries++; 1435 1436 goto again; 1437 } 1438 1439 if (estimate) { 1440 /* 1441 * Slosh on another entry's worth... 1442 */ 1443 fbt_size += FBT_ENT_MAXSIZE; 1444 mp->fbt_size = fbt_size; 1445 mp->fbt_tab = kobj_texthole_alloc(mp->text, fbt_size); 1446 1447 if (mp->fbt_tab == NULL) { 1448 cmn_err(CE_WARN, "couldn't allocate FBT table " 1449 "for module %s", modname); 1450 } else { 1451 estimate = 0; 1452 goto forreal; 1453 } 1454 } else { 1455 fbt_trampoline_unmap(); 1456 } 1457 1458 error: 1459 if (fp != NULL) 1460 ctf_close(fp); 1461 } 1462 1463 /*ARGSUSED*/ 1464 static void 1465 fbt_destroy(void *arg, dtrace_id_t id, void *parg) 1466 { 1467 fbt_probe_t *fbt = parg, *next; 1468 struct modctl *ctl = fbt->fbtp_ctl; 1469 1470 do { 1471 if (ctl != NULL && ctl->mod_loadcnt == fbt->fbtp_loadcnt) { 1472 if ((ctl->mod_loadcnt == fbt->fbtp_loadcnt && 1473 ctl->mod_loaded) || fbt->fbtp_primary) { 1474 ((struct module *) 1475 (ctl->mod_mp))->fbt_nentries--; 1476 } 1477 } 1478 1479 next = fbt->fbtp_next; 1480 kmem_free(fbt, sizeof (fbt_probe_t)); 1481 fbt = next; 1482 } while (fbt != NULL); 1483 } 1484 1485 /*ARGSUSED*/ 1486 static void 1487 fbt_enable(void *arg, dtrace_id_t id, void *parg) 1488 { 1489 fbt_probe_t *fbt = parg, *f; 1490 struct modctl *ctl = fbt->fbtp_ctl; 1491 1492 ctl->mod_nenabled++; 1493 1494 for (f = fbt; f != NULL; f = f->fbtp_next) { 1495 if (f->fbtp_patchpoint == NULL) { 1496 /* 1497 * Due to a shortened FBT table, this entry was never 1498 * completed; refuse to enable it. 1499 */ 1500 if (fbt_verbose) { 1501 cmn_err(CE_NOTE, "fbt is failing for probe %s " 1502 "(short FBT table in %s)", 1503 fbt->fbtp_name, ctl->mod_modname); 1504 } 1505 1506 return; 1507 } 1508 } 1509 1510 /* 1511 * If this module has disappeared since we discovered its probes, 1512 * refuse to enable it. 1513 */ 1514 if (!fbt->fbtp_primary && !ctl->mod_loaded) { 1515 if (fbt_verbose) { 1516 cmn_err(CE_NOTE, "fbt is failing for probe %s " 1517 "(module %s unloaded)", 1518 fbt->fbtp_name, ctl->mod_modname); 1519 } 1520 1521 return; 1522 } 1523 1524 /* 1525 * Now check that our modctl has the expected load count. If it 1526 * doesn't, this module must have been unloaded and reloaded -- and 1527 * we're not going to touch it. 1528 */ 1529 if (ctl->mod_loadcnt != fbt->fbtp_loadcnt) { 1530 if (fbt_verbose) { 1531 cmn_err(CE_NOTE, "fbt is failing for probe %s " 1532 "(module %s reloaded)", 1533 fbt->fbtp_name, ctl->mod_modname); 1534 } 1535 1536 return; 1537 } 1538 1539 for (; fbt != NULL; fbt = fbt->fbtp_next) 1540 *fbt->fbtp_patchpoint = fbt->fbtp_patchval; 1541 } 1542 1543 /*ARGSUSED*/ 1544 static void 1545 fbt_disable(void *arg, dtrace_id_t id, void *parg) 1546 { 1547 fbt_probe_t *fbt = parg, *f; 1548 struct modctl *ctl = fbt->fbtp_ctl; 1549 1550 ASSERT(ctl->mod_nenabled > 0); 1551 ctl->mod_nenabled--; 1552 1553 for (f = fbt; f != NULL; f = f->fbtp_next) { 1554 if (f->fbtp_patchpoint == NULL) 1555 return; 1556 } 1557 1558 if ((!fbt->fbtp_primary && !ctl->mod_loaded) || 1559 (ctl->mod_loadcnt != fbt->fbtp_loadcnt)) 1560 return; 1561 1562 for (; fbt != NULL; fbt = fbt->fbtp_next) 1563 *fbt->fbtp_patchpoint = fbt->fbtp_savedval; 1564 } 1565 1566 /*ARGSUSED*/ 1567 static void 1568 fbt_suspend(void *arg, dtrace_id_t id, void *parg) 1569 { 1570 fbt_probe_t *fbt = parg; 1571 struct modctl *ctl = fbt->fbtp_ctl; 1572 1573 if (!fbt->fbtp_primary && !ctl->mod_loaded) 1574 return; 1575 1576 if (ctl->mod_loadcnt != fbt->fbtp_loadcnt) 1577 return; 1578 1579 ASSERT(ctl->mod_nenabled > 0); 1580 1581 for (; fbt != NULL; fbt = fbt->fbtp_next) 1582 *fbt->fbtp_patchpoint = fbt->fbtp_savedval; 1583 } 1584 1585 /*ARGSUSED*/ 1586 static void 1587 fbt_resume(void *arg, dtrace_id_t id, void *parg) 1588 { 1589 fbt_probe_t *fbt = parg; 1590 struct modctl *ctl = fbt->fbtp_ctl; 1591 1592 if (!fbt->fbtp_primary && !ctl->mod_loaded) 1593 return; 1594 1595 if (ctl->mod_loadcnt != fbt->fbtp_loadcnt) 1596 return; 1597 1598 ASSERT(ctl->mod_nenabled > 0); 1599 1600 for (; fbt != NULL; fbt = fbt->fbtp_next) 1601 *fbt->fbtp_patchpoint = fbt->fbtp_patchval; 1602 } 1603 1604 /*ARGSUSED*/ 1605 static void 1606 fbt_getargdesc(void *arg, dtrace_id_t id, void *parg, dtrace_argdesc_t *desc) 1607 { 1608 fbt_probe_t *fbt = parg; 1609 struct modctl *ctl = fbt->fbtp_ctl; 1610 struct module *mp = ctl->mod_mp; 1611 ctf_file_t *fp = NULL, *pfp; 1612 ctf_funcinfo_t f; 1613 int error; 1614 ctf_id_t argv[32], type; 1615 int argc = sizeof (argv) / sizeof (ctf_id_t); 1616 const char *parent; 1617 1618 if (!ctl->mod_loaded || (ctl->mod_loadcnt != fbt->fbtp_loadcnt)) 1619 goto err; 1620 1621 if (fbt->fbtp_return && desc->dtargd_ndx == 0) { 1622 (void) strcpy(desc->dtargd_native, "int"); 1623 return; 1624 } 1625 1626 if ((fp = ctf_modopen(mp, &error)) == NULL) { 1627 /* 1628 * We have no CTF information for this module -- and therefore 1629 * no args[] information. 1630 */ 1631 goto err; 1632 } 1633 1634 /* 1635 * If we have a parent container, we must manually import it. 1636 */ 1637 if ((parent = ctf_parent_name(fp)) != NULL) { 1638 struct modctl *mod; 1639 1640 /* 1641 * We must iterate over all modules to find the module that 1642 * is our parent. 1643 */ 1644 for (mod = &modules; mod != NULL; mod = mod->mod_next) { 1645 if (strcmp(mod->mod_filename, parent) == 0) 1646 break; 1647 } 1648 1649 if (mod == NULL) 1650 goto err; 1651 1652 if ((pfp = ctf_modopen(mod->mod_mp, &error)) == NULL) 1653 goto err; 1654 1655 if (ctf_import(fp, pfp) != 0) { 1656 ctf_close(pfp); 1657 goto err; 1658 } 1659 1660 ctf_close(pfp); 1661 } 1662 1663 if (ctf_func_info(fp, fbt->fbtp_symndx, &f) == CTF_ERR) 1664 goto err; 1665 1666 if (fbt->fbtp_return) { 1667 if (desc->dtargd_ndx > 1) 1668 goto err; 1669 1670 ASSERT(desc->dtargd_ndx == 1); 1671 type = f.ctc_return; 1672 } else { 1673 if (desc->dtargd_ndx + 1 > f.ctc_argc) 1674 goto err; 1675 1676 if (ctf_func_args(fp, fbt->fbtp_symndx, argc, argv) == CTF_ERR) 1677 goto err; 1678 1679 type = argv[desc->dtargd_ndx]; 1680 } 1681 1682 if (ctf_type_name(fp, type, desc->dtargd_native, 1683 DTRACE_ARGTYPELEN) != NULL) { 1684 ctf_close(fp); 1685 return; 1686 } 1687 err: 1688 if (fp != NULL) 1689 ctf_close(fp); 1690 1691 desc->dtargd_ndx = DTRACE_ARGNONE; 1692 } 1693 1694 static dtrace_pattr_t fbt_attr = { 1695 { DTRACE_STABILITY_EVOLVING, DTRACE_STABILITY_EVOLVING, DTRACE_CLASS_ISA }, 1696 { DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_UNKNOWN }, 1697 { DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_UNKNOWN }, 1698 { DTRACE_STABILITY_EVOLVING, DTRACE_STABILITY_EVOLVING, DTRACE_CLASS_ISA }, 1699 { DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_ISA }, 1700 }; 1701 1702 static dtrace_pops_t fbt_pops = { 1703 NULL, 1704 fbt_provide_module, 1705 fbt_enable, 1706 fbt_disable, 1707 fbt_suspend, 1708 fbt_resume, 1709 fbt_getargdesc, 1710 NULL, 1711 NULL, 1712 fbt_destroy 1713 }; 1714 1715 static int 1716 fbt_attach(dev_info_t *devi, ddi_attach_cmd_t cmd) 1717 { 1718 switch (cmd) { 1719 case DDI_ATTACH: 1720 break; 1721 case DDI_RESUME: 1722 return (DDI_SUCCESS); 1723 default: 1724 return (DDI_FAILURE); 1725 } 1726 1727 if (ddi_create_minor_node(devi, "fbt", S_IFCHR, 0, 1728 DDI_PSEUDO, NULL) == DDI_FAILURE || 1729 dtrace_register("fbt", &fbt_attr, DTRACE_PRIV_KERNEL, 0, 1730 &fbt_pops, NULL, &fbt_id) != 0) { 1731 ddi_remove_minor_node(devi, NULL); 1732 return (DDI_FAILURE); 1733 } 1734 1735 ddi_report_dev(devi); 1736 fbt_devi = devi; 1737 return (DDI_SUCCESS); 1738 } 1739 1740 static int 1741 fbt_detach(dev_info_t *devi, ddi_detach_cmd_t cmd) 1742 { 1743 switch (cmd) { 1744 case DDI_DETACH: 1745 break; 1746 case DDI_SUSPEND: 1747 return (DDI_SUCCESS); 1748 default: 1749 return (DDI_FAILURE); 1750 } 1751 1752 if (dtrace_unregister(fbt_id) != 0) 1753 return (DDI_FAILURE); 1754 1755 ddi_remove_minor_node(devi, NULL); 1756 return (DDI_SUCCESS); 1757 } 1758 1759 /*ARGSUSED*/ 1760 static int 1761 fbt_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result) 1762 { 1763 int error; 1764 1765 switch (infocmd) { 1766 case DDI_INFO_DEVT2DEVINFO: 1767 *result = (void *)fbt_devi; 1768 error = DDI_SUCCESS; 1769 break; 1770 case DDI_INFO_DEVT2INSTANCE: 1771 *result = (void *)0; 1772 error = DDI_SUCCESS; 1773 break; 1774 default: 1775 error = DDI_FAILURE; 1776 } 1777 return (error); 1778 } 1779 1780 /*ARGSUSED*/ 1781 static int 1782 fbt_open(dev_t *devp, int flag, int otyp, cred_t *cred_p) 1783 { 1784 return (0); 1785 } 1786 1787 static struct cb_ops fbt_cb_ops = { 1788 fbt_open, /* open */ 1789 nodev, /* close */ 1790 nulldev, /* strategy */ 1791 nulldev, /* print */ 1792 nodev, /* dump */ 1793 nodev, /* read */ 1794 nodev, /* write */ 1795 nodev, /* ioctl */ 1796 nodev, /* devmap */ 1797 nodev, /* mmap */ 1798 nodev, /* segmap */ 1799 nochpoll, /* poll */ 1800 ddi_prop_op, /* cb_prop_op */ 1801 0, /* streamtab */ 1802 D_NEW | D_MP /* Driver compatibility flag */ 1803 }; 1804 1805 static struct dev_ops fbt_ops = { 1806 DEVO_REV, /* devo_rev */ 1807 0, /* refcnt */ 1808 fbt_info, /* get_dev_info */ 1809 nulldev, /* identify */ 1810 nulldev, /* probe */ 1811 fbt_attach, /* attach */ 1812 fbt_detach, /* detach */ 1813 nodev, /* reset */ 1814 &fbt_cb_ops, /* driver operations */ 1815 NULL, /* bus operations */ 1816 nodev /* dev power */ 1817 }; 1818 1819 /* 1820 * Module linkage information for the kernel. 1821 */ 1822 static struct modldrv modldrv = { 1823 &mod_driverops, /* module type (this is a pseudo driver) */ 1824 "Function Boundary Tracing", /* name of module */ 1825 &fbt_ops, /* driver ops */ 1826 }; 1827 1828 static struct modlinkage modlinkage = { 1829 MODREV_1, 1830 (void *)&modldrv, 1831 NULL 1832 }; 1833 1834 int 1835 _init(void) 1836 { 1837 return (mod_install(&modlinkage)); 1838 } 1839 1840 int 1841 _info(struct modinfo *modinfop) 1842 { 1843 return (mod_info(&modlinkage, modinfop)); 1844 } 1845 1846 int 1847 _fini(void) 1848 { 1849 return (mod_remove(&modlinkage)); 1850 } 1851