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