xref: /xnu-8020.121.3/bsd/dev/dtrace/sdt.c (revision fdd8201d7b966f0c3ea610489d29bd841d358941)
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 2009 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #include <sys/param.h>
27 #include <sys/systm.h>
28 #include <sys/errno.h>
29 #include <sys/stat.h>
30 #include <sys/ioctl.h>
31 #include <sys/conf.h>
32 #include <sys/fcntl.h>
33 #include <miscfs/devfs/devfs.h>
34 
35 #if defined(__arm__) || defined(__arm64__)
36 #include <arm/caches_internal.h>
37 #endif /* defined(__arm__) || defined(__arm64__) */
38 
39 #include <sys/dtrace.h>
40 #include <sys/dtrace_impl.h>
41 
42 #include <sys/dtrace_glue.h>
43 
44 #include <sys/sdt_impl.h>
45 extern int dtrace_kernel_symbol_mode;
46 
47 #include <ptrauth.h>
48 
49 /* #include <machine/trap.h */
50 struct savearea_t; /* Used anonymously */
51 
52 #if defined(__arm__)
53 typedef kern_return_t (*perfCallback)(int, struct savearea_t *, __unused int, __unused int);
54 extern perfCallback tempDTraceTrapHook;
55 extern kern_return_t fbt_perfCallback(int, struct savearea_t *, __unused int, __unused int);
56 #define SDT_PATCHVAL    0xdefc
57 #define SDT_AFRAMES             7
58 #elif defined(__arm64__)
59 typedef kern_return_t (*perfCallback)(int, struct savearea_t *, __unused int, __unused int);
60 extern perfCallback tempDTraceTrapHook;
61 extern kern_return_t fbt_perfCallback(int, struct savearea_t *, __unused int, __unused int);
62 #define SDT_PATCHVAL    0xe7eeee7e
63 #define SDT_AFRAMES             7
64 #elif defined(__x86_64__)
65 typedef kern_return_t (*perfCallback)(int, struct savearea_t *, uintptr_t *, int);
66 extern perfCallback tempDTraceTrapHook;
67 extern kern_return_t fbt_perfCallback(int, struct savearea_t *, uintptr_t *, int);
68 #define SDT_PATCHVAL    0xf0
69 #define SDT_AFRAMES             6
70 #else
71 #error Unknown architecture
72 #endif
73 
74 #define SDT_PROBETAB_SIZE       0x1000          /* 4k entries -- 16K total */
75 
76 #define SDT_UNKNOWN_FUNCNAME    "."             /* function symbol name when not found in symbol table */
77 
78 
79 static int              sdt_verbose = 0;
80 sdt_probe_t             **sdt_probetab;
81 int                     sdt_probetab_size;
82 int                     sdt_probetab_mask;
83 
84 /*ARGSUSED*/
85 static void
__sdt_provide_module(void * arg,struct modctl * ctl)86 __sdt_provide_module(void *arg, struct modctl *ctl)
87 {
88 #pragma unused(arg)
89 	char *modname = ctl->mod_modname;
90 	sdt_probedesc_t *sdpd;
91 	sdt_probe_t *sdp, *old;
92 	sdt_provider_t *prov;
93 
94 	/*
95 	 * One for all, and all for one:  if we haven't yet registered all of
96 	 * our providers, we'll refuse to provide anything.
97 	 */
98 	for (prov = sdt_providers; prov->sdtp_name != NULL; prov++) {
99 		if (prov->sdtp_id == DTRACE_PROVNONE) {
100 			return;
101 		}
102 	}
103 
104 	/* Nothing to do. Module is either invalid or we haven't found any SDT probe descriptions. */
105 	if (!ctl || ctl->mod_sdtprobecnt != 0 || (sdpd = ctl->mod_sdtdesc) == NULL) {
106 		return;
107 	}
108 
109 	for (sdpd = ctl->mod_sdtdesc; sdpd != NULL; sdpd = sdpd->sdpd_next) {
110 		dtrace_id_t id;
111 
112 		/* Validate probe's provider name.  Do not provide probes for unknown providers. */
113 		for (prov = sdt_providers; prov->sdtp_name != NULL; prov++) {
114 			if (strcmp(prov->sdtp_prefix, sdpd->sdpd_prov) == 0) {
115 				break;
116 			}
117 		}
118 
119 		if (prov->sdtp_name == NULL) {
120 			printf("Ignoring probes from unsupported provider %s\n", sdpd->sdpd_prov);
121 			continue;
122 		}
123 
124 		if (sdpd->sdpd_func == NULL) {
125 			/*
126 			 * Ignore probes for which we don't have any symbol.  That's likely some problem with
127 			 * __sdt section processing.
128 			 */
129 			printf("Ignoring probe %s (no symbol name)\n", sdpd->sdpd_name);
130 			continue;
131 		}
132 
133 		sdp = kmem_zalloc(sizeof(sdt_probe_t), KM_SLEEP);
134 		sdp->sdp_loadcnt = ctl->mod_loadcnt;
135 		sdp->sdp_ctl = ctl;
136 		sdp->sdp_name = kmem_alloc(strlen(sdpd->sdpd_name) + 1, KM_SLEEP);
137 		(void) strlcpy(sdp->sdp_name, sdpd->sdpd_name, strlen(sdpd->sdpd_name) + 1);
138 		sdp->sdp_namelen = strlen(sdpd->sdpd_name) + 1;
139 		sdp->sdp_provider = prov;
140 
141 		/*
142 		 * We have our provider.  Now create the probe.
143 		 */
144 		if ((id = dtrace_probe_lookup(prov->sdtp_id, modname,
145 		    sdpd->sdpd_func, sdp->sdp_name)) != DTRACE_IDNONE) {
146 			old = dtrace_probe_arg(prov->sdtp_id, id);
147 			ASSERT(old != NULL);
148 
149 			sdp->sdp_next = old->sdp_next;
150 			sdp->sdp_id = id;
151 			old->sdp_next = sdp;
152 		} else {
153 			sdp->sdp_id = dtrace_probe_create(prov->sdtp_id,
154 			    modname, sdpd->sdpd_func, sdp->sdp_name, SDT_AFRAMES, sdp);
155 
156 			ctl->mod_sdtprobecnt++;
157 		}
158 
159 #if 0
160 		printf("__sdt_provide_module:  sdpd=0x%p  sdp=0x%p  name=%s, id=%d\n", sdpd, sdp,
161 		    sdp->sdp_name, sdp->sdp_id);
162 #endif
163 
164 		sdp->sdp_hashnext =
165 		    sdt_probetab[SDT_ADDR2NDX(sdpd->sdpd_offset)];
166 		sdt_probetab[SDT_ADDR2NDX(sdpd->sdpd_offset)] = sdp;
167 
168 		sdp->sdp_patchval = SDT_PATCHVAL;
169 		sdp->sdp_patchpoint = (sdt_instr_t *)sdpd->sdpd_offset;
170 		sdp->sdp_savedval = *sdp->sdp_patchpoint;
171 	}
172 }
173 
174 /*ARGSUSED*/
175 static void
sdt_destroy(void * arg,dtrace_id_t id,void * parg)176 sdt_destroy(void *arg, dtrace_id_t id, void *parg)
177 {
178 #pragma unused(arg,id)
179 	sdt_probe_t *sdp = parg, *old, *last, *hash;
180 	int ndx;
181 
182 	struct modctl *ctl = sdp->sdp_ctl;
183 
184 	/*
185 	 * Decrement SDT probe counts only when a probe being destroyed belongs to the
186 	 * currently loaded version of a module and not the stale one.
187 	 */
188 	if (ctl != NULL && ctl->mod_loadcnt == sdp->sdp_loadcnt && ctl->mod_loaded) {
189 		ctl->mod_sdtprobecnt--;
190 	}
191 
192 	while (sdp != NULL) {
193 		old = sdp;
194 
195 		/*
196 		 * Now we need to remove this probe from the sdt_probetab.
197 		 */
198 		ndx = SDT_ADDR2NDX(sdp->sdp_patchpoint);
199 		last = NULL;
200 		hash = sdt_probetab[ndx];
201 
202 		while (hash != sdp) {
203 			ASSERT(hash != NULL);
204 			last = hash;
205 			hash = hash->sdp_hashnext;
206 		}
207 
208 		if (last != NULL) {
209 			last->sdp_hashnext = sdp->sdp_hashnext;
210 		} else {
211 			sdt_probetab[ndx] = sdp->sdp_hashnext;
212 		}
213 
214 		kmem_free(sdp->sdp_name, sdp->sdp_namelen);
215 		sdp = sdp->sdp_next;
216 		kmem_free(old, sizeof(sdt_probe_t));
217 	}
218 }
219 
220 /*ARGSUSED*/
221 static int
sdt_enable(void * arg,dtrace_id_t id,void * parg)222 sdt_enable(void *arg, dtrace_id_t id, void *parg)
223 {
224 #pragma unused(arg,id)
225 	sdt_probe_t *sdp = parg;
226 	struct modctl *ctl = sdp->sdp_ctl;
227 
228 	ctl->mod_nenabled++;
229 
230 	/*
231 	 * If this module has disappeared since we discovered its probes,
232 	 * refuse to enable it.
233 	 */
234 	if (!ctl->mod_loaded) {
235 		if (sdt_verbose) {
236 			cmn_err(CE_NOTE, "sdt is failing for probe %s "
237 			    "(module %s unloaded)",
238 			    sdp->sdp_name, ctl->mod_modname);
239 		}
240 		goto err;
241 	}
242 
243 	/*
244 	 * Now check that our modctl has the expected load count.  If it
245 	 * doesn't, this module must have been unloaded and reloaded -- and
246 	 * we're not going to touch it.
247 	 */
248 	if (ctl->mod_loadcnt != sdp->sdp_loadcnt) {
249 		if (sdt_verbose) {
250 			cmn_err(CE_NOTE, "sdt is failing for probe %s "
251 			    "(module %s reloaded)",
252 			    sdp->sdp_name, ctl->mod_modname);
253 		}
254 		goto err;
255 	}
256 
257 	dtrace_casptr(&tempDTraceTrapHook, NULL, ptrauth_nop_cast(void *, &fbt_perfCallback));
258 	if (tempDTraceTrapHook != (perfCallback)fbt_perfCallback) {
259 		if (sdt_verbose) {
260 			cmn_err(CE_NOTE, "sdt_enable is failing for probe %s "
261 			    "in module %s: tempDTraceTrapHook already occupied.",
262 			    sdp->sdp_name, ctl->mod_modname);
263 		}
264 		return 0;
265 	}
266 
267 	while (sdp != NULL) {
268 		(void)ml_nofault_copy((vm_offset_t)&sdp->sdp_patchval, (vm_offset_t)sdp->sdp_patchpoint,
269 		    (vm_size_t)sizeof(sdp->sdp_patchval));
270 
271 		/*
272 		 * Make the patched instruction visible via a data + instruction
273 		 * cache fush on platforms that need it
274 		 */
275 		flush_dcache((vm_offset_t)sdp->sdp_patchpoint, (vm_size_t)sizeof(sdp->sdp_patchval), 0);
276 		invalidate_icache((vm_offset_t)sdp->sdp_patchpoint, (vm_size_t)sizeof(sdp->sdp_patchval), 0);
277 
278 		sdp = sdp->sdp_next;
279 	}
280 
281 err:
282 	return 0;
283 }
284 
285 /*ARGSUSED*/
286 static void
sdt_disable(void * arg,dtrace_id_t id,void * parg)287 sdt_disable(void *arg, dtrace_id_t id, void *parg)
288 {
289 #pragma unused(arg,id)
290 	sdt_probe_t *sdp = parg;
291 	struct modctl *ctl = sdp->sdp_ctl;
292 
293 	ctl->mod_nenabled--;
294 
295 	if (!ctl->mod_loaded || ctl->mod_loadcnt != sdp->sdp_loadcnt) {
296 		goto err;
297 	}
298 
299 	while (sdp != NULL) {
300 		(void)ml_nofault_copy((vm_offset_t)&sdp->sdp_savedval, (vm_offset_t)sdp->sdp_patchpoint,
301 		    (vm_size_t)sizeof(sdp->sdp_savedval));
302 		/*
303 		 * Make the patched instruction visible via a data + instruction
304 		 * cache flush on platforms that need it
305 		 */
306 		flush_dcache((vm_offset_t)sdp->sdp_patchpoint, (vm_size_t)sizeof(sdp->sdp_savedval), 0);
307 		invalidate_icache((vm_offset_t)sdp->sdp_patchpoint, (vm_size_t)sizeof(sdp->sdp_savedval), 0);
308 		sdp = sdp->sdp_next;
309 	}
310 
311 err:
312 	;
313 }
314 
315 static dtrace_pops_t sdt_pops = {
316 	.dtps_provide =         NULL,
317 	.dtps_provide_module =  sdt_provide_module,
318 	.dtps_enable =          sdt_enable,
319 	.dtps_disable =         sdt_disable,
320 	.dtps_suspend =         NULL,
321 	.dtps_resume =          NULL,
322 	.dtps_getargdesc =      sdt_getargdesc,
323 	.dtps_getargval =       sdt_getarg,
324 	.dtps_usermode =        NULL,
325 	.dtps_destroy =         sdt_destroy,
326 };
327 
328 /*ARGSUSED*/
329 static int
sdt_attach(dev_info_t * devi)330 sdt_attach(dev_info_t *devi)
331 {
332 	sdt_provider_t *prov;
333 
334 	if (ddi_create_minor_node(devi, "sdt", S_IFCHR,
335 	    0, DDI_PSEUDO, 0) == DDI_FAILURE) {
336 		cmn_err(CE_NOTE, "/dev/sdt couldn't create minor node");
337 		ddi_remove_minor_node(devi, NULL);
338 		return DDI_FAILURE;
339 	}
340 
341 	if (sdt_probetab_size == 0) {
342 		sdt_probetab_size = SDT_PROBETAB_SIZE;
343 	}
344 
345 	sdt_probetab_mask = sdt_probetab_size - 1;
346 	sdt_probetab =
347 	    kmem_zalloc(sdt_probetab_size * sizeof(sdt_probe_t *), KM_SLEEP);
348 	dtrace_invop_add(sdt_invop);
349 
350 	for (prov = sdt_providers; prov->sdtp_name != NULL; prov++) {
351 		if (dtrace_register(prov->sdtp_name, prov->sdtp_attr,
352 		    DTRACE_PRIV_KERNEL, NULL,
353 		    &sdt_pops, prov, &prov->sdtp_id) != 0) {
354 			cmn_err(CE_WARN, "failed to register sdt provider %s",
355 			    prov->sdtp_name);
356 		}
357 	}
358 
359 	return DDI_SUCCESS;
360 }
361 
362 /*
363  * APPLE NOTE:  sdt_detach not implemented
364  */
365 #if !defined(__APPLE__)
366 /*ARGSUSED*/
367 static int
sdt_detach(dev_info_t * dip,ddi_detach_cmd_t cmd)368 sdt_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
369 {
370 	sdt_provider_t *prov;
371 
372 	switch (cmd) {
373 	case DDI_DETACH:
374 		break;
375 
376 	case DDI_SUSPEND:
377 		return DDI_SUCCESS;
378 
379 	default:
380 		return DDI_FAILURE;
381 	}
382 
383 	for (prov = sdt_providers; prov->sdtp_name != NULL; prov++) {
384 		if (prov->sdtp_id != DTRACE_PROVNONE) {
385 			if (dtrace_unregister(prov->sdtp_id) != 0) {
386 				return DDI_FAILURE;
387 			}
388 
389 			prov->sdtp_id = DTRACE_PROVNONE;
390 		}
391 	}
392 
393 	dtrace_invop_remove(sdt_invop);
394 	kmem_free(sdt_probetab, sdt_probetab_size * sizeof(sdt_probe_t *));
395 
396 	return DDI_SUCCESS;
397 }
398 #endif /* __APPLE__ */
399 
400 d_open_t _sdt_open;
401 
402 int
_sdt_open(dev_t dev,int flags,int devtype,struct proc * p)403 _sdt_open(dev_t dev, int flags, int devtype, struct proc *p)
404 {
405 #pragma unused(dev,flags,devtype,p)
406 	return 0;
407 }
408 
409 #define SDT_MAJOR  -24 /* let the kernel pick the device number */
410 
411 static const struct cdevsw sdt_cdevsw =
412 {
413 	.d_open = _sdt_open,
414 	.d_close = eno_opcl,
415 	.d_read = eno_rdwrt,
416 	.d_write = eno_rdwrt,
417 	.d_ioctl = eno_ioctl,
418 	.d_stop = (stop_fcn_t *)nulldev,
419 	.d_reset = (reset_fcn_t *)nulldev,
420 	.d_select = eno_select,
421 	.d_mmap = eno_mmap,
422 	.d_strategy = eno_strat,
423 	.d_reserved_1 = eno_getc,
424 	.d_reserved_2 = eno_putc,
425 };
426 
427 
428 #include <mach-o/nlist.h>
429 #include <libkern/kernel_mach_header.h>
430 
431 /*
432  * Represents single record in __DATA,__sdt section.
433  */
434 typedef struct dtrace_sdt_def {
435 	uintptr_t      dsd_addr;    /* probe site location */
436 	const char     *dsd_prov;   /* provider's name */
437 	const char     *dsd_name;   /* probe's name */
438 } __attribute__((__packed__))  dtrace_sdt_def_t;
439 
440 /*
441  * Creates a copy of name and unescapes '-' characters.
442  */
443 static char *
sdt_strdup_name(const char * name)444 sdt_strdup_name(const char *name)
445 {
446 	size_t len = strlen(name) + 1;
447 	size_t i, j;
448 	char *nname = kmem_alloc(len, KM_SLEEP);
449 
450 	for (i = 0, j = 0; name[j] != '\0'; i++) {
451 		if (name[j] == '_' && name[j + 1] == '_') {
452 			nname[i] = '-';
453 			j += 2;
454 		} else {
455 			nname[i] = name[j++];
456 		}
457 	}
458 
459 	nname[i] = '\0';
460 	return nname;
461 }
462 
463 /*
464  * Returns Mach-O header that should be used for given modctl.
465  */
466 static kernel_mach_header_t *
sdt_get_module_mh(struct modctl * ctl)467 sdt_get_module_mh(struct modctl *ctl)
468 {
469 	kernel_mach_header_t *mh = (kernel_mach_header_t *)ctl->mod_address;
470 
471 	/* Static KEXTs have their __sdt section merged into kernel's __sdt. */
472 	if (MOD_IS_STATIC_KEXT(ctl)) {
473 		mh = &_mh_execute_header;
474 	}
475 
476 	if (mh->magic != MH_MAGIC_KERNEL) {
477 		return NULL;
478 	}
479 
480 	return mh;
481 }
482 
483 /*
484  * Finds symbol table for given kernel module.
485  */
486 static uint32_t
sdt_find_symbol_table(struct modctl * ctl,kernel_nlist_t ** sym,char ** strings)487 sdt_find_symbol_table(struct modctl *ctl, kernel_nlist_t **sym, char **strings)
488 {
489 	kernel_mach_header_t        *mh = sdt_get_module_mh(ctl);
490 	struct load_command         *cmd = (struct load_command *)&mh[1];
491 	kernel_segment_command_t    *orig_le = NULL;
492 	struct symtab_command       *orig_st = NULL;
493 
494 	for (int i = 0; i < mh->ncmds; i++) {
495 		if (cmd->cmd == LC_SEGMENT_KERNEL) {
496 			kernel_segment_command_t *orig_sg = (kernel_segment_command_t *) cmd;
497 
498 			if (LIT_STRNEQL(orig_sg->segname, SEG_LINKEDIT)) {
499 				orig_le = orig_sg;
500 			}
501 		} else if (cmd->cmd == LC_SYMTAB) {
502 			orig_st = (struct symtab_command *) cmd;
503 		}
504 
505 		cmd = (struct load_command *) ((uintptr_t) cmd + cmd->cmdsize);
506 	}
507 
508 	if ((orig_st == NULL) || (orig_le == NULL)) {
509 		return 0;
510 	}
511 
512 	*sym = (kernel_nlist_t *)(orig_le->vmaddr + orig_st->symoff - orig_le->fileoff);
513 	*strings = (char *)(orig_le->vmaddr + orig_st->stroff - orig_le->fileoff);
514 
515 	return orig_st->nsyms;
516 }
517 
518 /* Last kernel address. */
519 static SECURITY_READ_ONLY_LATE(vm_address_t) kern_end = (vm_address_t)-1;
520 
521 void
sdt_early_init(void)522 sdt_early_init(void)
523 {
524 	kernel_mach_header_t        *mh = &_mh_execute_header;
525 	kernel_section_t            *sec_ks = NULL;
526 	kc_format_t                 kc_format;
527 
528 	if (!PE_get_primary_kc_format(&kc_format)) {
529 		kc_format = KCFormatUnknown;
530 	}
531 
532 	/*
533 	 * Detects end of kernel's text in static kernel cache. It is the last text address before
534 	 * the first kext text section start.
535 	 */
536 	if (kc_format == KCFormatStatic) {
537 		if ((sec_ks = getsectbynamefromheader(mh, "__PRELINK_INFO", "__kmod_start")) == NULL) {
538 			printf("SDT: unable to find prelink info\n");
539 			return;
540 		}
541 
542 		/* find the MIN(start_address) of all kexts in this image. */
543 		const uint64_t *start_addr = (const uint64_t *)sec_ks->addr;
544 		for (int i = 0; i < sec_ks->size / sizeof(uint64_t); i++) {
545 			if (kern_end > start_addr[i]) {
546 				kern_end = start_addr[i];
547 			}
548 		}
549 	}
550 }
551 
552 /*
553  * Finds TEXT range that belongs to given module.
554  */
555 static int
sdt_find_module_text_range(struct modctl * ctl,vm_address_t * start,vm_address_t * end)556 sdt_find_module_text_range(struct modctl *ctl, vm_address_t *start, vm_address_t *end)
557 {
558 	kc_format_t                 kc_format;
559 
560 	if (!PE_get_primary_kc_format(&kc_format)) {
561 		kc_format = KCFormatUnknown;
562 	}
563 
564 	/* Adjust kernel region for static kernel cache. */
565 	*start = ctl->mod_address;
566 
567 	if (MOD_IS_MACH_KERNEL(ctl) && kc_format == KCFormatStatic) {
568 		*end = kern_end;
569 	} else {
570 		*end = ctl->mod_address + ctl->mod_size;
571 	}
572 
573 	return 1;
574 }
575 
576 /*
577  * Processes SDT section in given Mach-O header
578  */
579 void
sdt_load_machsect(struct modctl * ctl)580 sdt_load_machsect(struct modctl *ctl)
581 {
582 	kernel_mach_header_t        *mh = sdt_get_module_mh(ctl);
583 	kernel_section_t            *sec_sdt = NULL;
584 	char                        *strings = NULL;
585 	kernel_nlist_t              *sym = NULL;
586 	vm_address_t                text_start, text_end;
587 	unsigned int                len;
588 	uint32_t                    nsyms = 0;
589 
590 	if (mh == NULL) {
591 		return;
592 	}
593 
594 	/* Ignore SDT definitions if we don't know where they belong. */
595 	if (!sdt_find_module_text_range(ctl, &text_start, &text_end)) {
596 		printf("SDT: Unable to determine text range for %s\n", ctl->mod_modname);
597 		return;
598 	}
599 
600 	/* Do not load SDTs when asked to use kernel symbols but symbol table is not available. */
601 	if (MOD_HAS_KERNEL_SYMBOLS(ctl) && (nsyms = sdt_find_symbol_table(ctl, &sym, &strings)) == 0) {
602 		printf("SDT: No kernel symbols for %s\n", ctl->mod_modname);
603 		return;
604 	}
605 
606 	/* Locate DTrace SDT section in the object. */
607 	if ((sec_sdt = getsectbynamefromheader(mh, "__DATA", "__sdt")) == NULL) {
608 		return;
609 	}
610 
611 	/*
612 	 * Iterate over SDT section and establish all SDT probe descriptions.
613 	 */
614 	dtrace_sdt_def_t *sdtdef = (dtrace_sdt_def_t *)(sec_sdt->addr);
615 	for (size_t k = 0; k < sec_sdt->size / sizeof(dtrace_sdt_def_t); k++, sdtdef++) {
616 		unsigned long best = 0;
617 
618 #if defined(__arm__)
619 		/* PR8353094 - mask off thumb-bit */
620 		sdtdef->dsd_addr &= ~0x1U;
621 #elif defined(__arm64__)
622 		sdtdef->dsd_addr &= ~0x1LU;
623 #endif  /* __arm__ */
624 
625 		/*
626 		 * Static KEXTs share __sdt section with kernel after linking. It is required
627 		 * to filter out description and pick only those that belong to requested
628 		 * module or kernel itself.
629 		 */
630 		if (MOD_IS_STATIC_KEXT(ctl) || MOD_IS_MACH_KERNEL(ctl)) {
631 			if ((sdtdef->dsd_addr < text_start) || (sdtdef->dsd_addr > text_end)) {
632 				continue;
633 			}
634 		} else {
635 			/* Skip over probe descripton that do not belong to current module. */
636 			if (!dtrace_addr_in_module((void *)sdtdef->dsd_addr, ctl)) {
637 				continue;
638 			}
639 		}
640 
641 		sdt_probedesc_t *sdpd = kmem_alloc(sizeof(sdt_probedesc_t), KM_SLEEP);
642 
643 		/* Unescape probe name and keep a note of the size of original memory allocation. */
644 		sdpd->sdpd_name = sdt_strdup_name(sdtdef->dsd_name);
645 		sdpd->sdpd_namelen = strlen(sdtdef->dsd_name) + 1;
646 
647 		/* Used only for provider structure lookup so there is no need to make dynamic copy. */
648 		sdpd->sdpd_prov = sdtdef->dsd_prov;
649 
650 		/*
651 		 * Find the symbol immediately preceding the sdt probe site just discovered,
652 		 * that symbol names the function containing the sdt probe.
653 		 */
654 		sdpd->sdpd_func = NULL;
655 
656 		if (MOD_HAS_KERNEL_SYMBOLS(ctl)) {
657 			const char *funcname = SDT_UNKNOWN_FUNCNAME;
658 
659 			for (int i = 0; i < nsyms; i++) {
660 				uint8_t jn_type = sym[i].n_type & N_TYPE;
661 				char *jname = strings + sym[i].n_un.n_strx;
662 
663 				if ((N_SECT != jn_type && N_ABS != jn_type)) {
664 					continue;
665 				}
666 
667 				if (0 == sym[i].n_un.n_strx) { /* iff a null, "", name. */
668 					continue;
669 				}
670 
671 				if (*jname == '_') {
672 					jname += 1;
673 				}
674 
675 				if (sdtdef->dsd_addr <= (unsigned long)sym[i].n_value) {
676 					continue;
677 				}
678 
679 				if ((unsigned long)sym[i].n_value > best) {
680 					best = (unsigned long)sym[i].n_value;
681 					funcname = jname;
682 				}
683 			}
684 
685 			len = strlen(funcname) + 1;
686 			sdpd->sdpd_func = kmem_alloc(len, KM_SLEEP);
687 			(void) strlcpy(sdpd->sdpd_func, funcname, len);
688 		}
689 
690 		sdpd->sdpd_offset = sdtdef->dsd_addr;
691 
692 		sdpd->sdpd_next = (sdt_probedesc_t *)ctl->mod_sdtdesc;
693 		ctl->mod_sdtdesc = sdpd;
694 	}
695 }
696 
697 void
sdt_init(void)698 sdt_init( void )
699 {
700 	int majdevno = cdevsw_add(SDT_MAJOR, &sdt_cdevsw);
701 
702 	if (majdevno < 0) {
703 		printf("sdt_init: failed to allocate a major number!\n");
704 		return;
705 	}
706 
707 	if (dtrace_sdt_probes_restricted()) {
708 		return;
709 	}
710 
711 	sdt_attach((dev_info_t*)(uintptr_t)majdevno);
712 }
713 
714 #undef SDT_MAJOR
715 
716 /*
717  * Provide SDT modules with userspace symbols.
718  *
719  * A module contains only partially filled in SDT probe descriptions because symbols were
720  * not available at the time when __sdt section was loaded. Fixup descriptons before providing
721  * the probes.
722  */
723 static void
sdt_provide_module_user_syms(void * arg,struct modctl * ctl)724 sdt_provide_module_user_syms(void *arg, struct modctl *ctl)
725 {
726 	sdt_probedesc_t *sdpd;
727 	dtrace_module_symbols_t *mod_sym = ctl->mod_user_symbols;
728 
729 	if (mod_sym == NULL) {
730 		printf("DTrace missing userspace symbols for module %s\n", ctl->mod_modname);
731 		return;
732 	}
733 
734 	/* Fixup missing probe description parts. */
735 	for (sdpd = ctl->mod_sdtdesc; sdpd != NULL; sdpd = sdpd->sdpd_next) {
736 		ASSERT(sdpd->sdpd_func == NULL);
737 		const char *funcname = SDT_UNKNOWN_FUNCNAME;
738 
739 		/* Look for symbol that contains SDT probe offset. */
740 		for (int i = 0; i < mod_sym->dtmodsyms_count; i++) {
741 			dtrace_symbol_t *symbol = &mod_sym->dtmodsyms_symbols[i];
742 			char *name = symbol->dtsym_name;
743 
744 			/*
745 			 * Every function symbol gets extra '_' prepended in the Mach-O symbol table.
746 			 * Strip it away to make a probe's function name match source code.
747 			 */
748 			if (*name == '_') {
749 				name += 1;
750 			}
751 
752 			if (!symbol->dtsym_addr) {
753 				continue;
754 			}
755 
756 			/* Ignore symbols that do not belong to this module. */
757 			if (!dtrace_addr_in_module((void *)symbol->dtsym_addr, ctl)) {
758 				continue;
759 			}
760 
761 			/* Pick symbol name when we found match. */
762 			if ((symbol->dtsym_addr <= sdpd->sdpd_offset) &&
763 			    (sdpd->sdpd_offset < symbol->dtsym_addr + symbol->dtsym_size)) {
764 				funcname = name;
765 				break;
766 			}
767 		}
768 
769 		size_t len = strlen(funcname) + 1;
770 		sdpd->sdpd_func = kmem_alloc(len, KM_SLEEP);
771 		(void) strlcpy(sdpd->sdpd_func, funcname, len);
772 	}
773 
774 	/* Probe descriptionds are now fixed up.  Provide them as usual. */
775 	__sdt_provide_module(arg, ctl);
776 }
777 
778 /*ARGSUSED*/
779 void
sdt_provide_module(void * arg,struct modctl * ctl)780 sdt_provide_module(void *arg, struct modctl *ctl)
781 {
782 	ASSERT(ctl != NULL);
783 	ASSERT(dtrace_kernel_symbol_mode != DTRACE_KERNEL_SYMBOLS_NEVER);
784 	LCK_MTX_ASSERT(&mod_lock, LCK_MTX_ASSERT_OWNED);
785 
786 	if (MOD_SDT_DONE(ctl)) {
787 		return;
788 	}
789 
790 	if (MOD_HAS_KERNEL_SYMBOLS(ctl)) {
791 		__sdt_provide_module(arg, ctl);
792 		ctl->mod_flags |= MODCTL_SDT_PROBES_PROVIDED;
793 		return;
794 	}
795 
796 	if (MOD_HAS_USERSPACE_SYMBOLS(ctl)) {
797 		sdt_provide_module_user_syms(arg, ctl);
798 		ctl->mod_flags |= MODCTL_SDT_PROBES_PROVIDED;
799 		return;
800 	}
801 
802 	/*
803 	 * The SDT provider's module is not detachable so we don't have to re-provide SDT
804 	 * probes if that happens.  After succesfull providing, the probe descriptions are
805 	 * no longer required.  If module gets re-loaded it will get a new set of probe
806 	 * descriptions from its __sdt section.
807 	 */
808 	if (MOD_SDT_PROBES_PROVIDED(ctl)) {
809 		sdt_probedesc_t *sdpd = ctl->mod_sdtdesc;
810 		while (sdpd) {
811 			sdt_probedesc_t *this_sdpd = sdpd;
812 			kmem_free((void *)sdpd->sdpd_name, sdpd->sdpd_namelen);
813 			if (sdpd->sdpd_func) {
814 				kmem_free((void *)sdpd->sdpd_func, strlen(sdpd->sdpd_func) + 1);
815 			}
816 			sdpd = sdpd->sdpd_next;
817 			kmem_free((void *)this_sdpd, sizeof(sdt_probedesc_t));
818 		}
819 		ctl->mod_sdtdesc = NULL;
820 	}
821 }
822