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