Home | History | Annotate | Line # | Download | only in common
      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 /*
     23  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
     24  */
     25 /*
     26  * Copyright (c) 2013, Joyent, Inc.  All rights reserved.
     27  * Copyright (c) 2016, Pedro Giffuni.  All rights reserved.
     28  */
     29 
     30 #include <sys/types.h>
     31 #ifdef illumos
     32 #include <sys/modctl.h>
     33 #include <sys/kobj.h>
     34 #include <sys/kobj_impl.h>
     35 #include <sys/sysmacros.h>
     36 #include <sys/elf.h>
     37 #include <sys/task.h>
     38 #else
     39 #include <sys/param.h>
     40 //#include <sys/linker.h>
     41 #include <sys/module.h>
     42 #include <sys/stat.h>
     43 #endif
     44 #ifdef __NetBSD__
     45 #include <sys/sysctl.h>
     46 #include <paths.h>
     47 #endif
     48 
     49 #include <unistd.h>
     50 #ifdef illumos
     51 #include <project.h>
     52 #endif
     53 #include <strings.h>
     54 #include <stdlib.h>
     55 #include <libelf.h>
     56 #include <limits.h>
     57 #include <assert.h>
     58 #include <errno.h>
     59 #include <dirent.h>
     60 #ifndef illumos
     61 #include <fcntl.h>
     62 #include <libproc_compat.h>
     63 #endif
     64 
     65 #include <dt_strtab.h>
     66 #include <dt_module.h>
     67 #include <dt_impl.h>
     68 
     69 static const char *dt_module_strtab; /* active strtab for qsort callbacks */
     70 
     71 static void
     72 dt_module_symhash_insert(dt_module_t *dmp, const char *name, uint_t id)
     73 {
     74 	dt_sym_t *dsp = &dmp->dm_symchains[dmp->dm_symfree];
     75 	uint_t h;
     76 
     77 	assert(dmp->dm_symfree < dmp->dm_nsymelems + 1);
     78 
     79 	dsp->ds_symid = id;
     80 	h = dt_strtab_hash(name, NULL) % dmp->dm_nsymbuckets;
     81 	dsp->ds_next = dmp->dm_symbuckets[h];
     82 	dmp->dm_symbuckets[h] = dmp->dm_symfree++;
     83 }
     84 
     85 static uint_t
     86 dt_module_syminit32(dt_module_t *dmp)
     87 {
     88 #if STT_NUM != (STT_TLS + 1)
     89 #error "STT_NUM has grown. update dt_module_syminit32()"
     90 #endif
     91 
     92 	Elf32_Sym *sym = dmp->dm_symtab.cts_data;
     93 	const char *base = dmp->dm_strtab.cts_data;
     94 	size_t ss_size = dmp->dm_strtab.cts_size;
     95 	uint_t i, n = dmp->dm_nsymelems;
     96 	uint_t asrsv = 0;
     97 
     98 #if defined(__FreeBSD__)
     99 	GElf_Ehdr ehdr;
    100 	int is_elf_obj;
    101 
    102 	gelf_getehdr(dmp->dm_elf, &ehdr);
    103 	is_elf_obj = (ehdr.e_type == ET_REL);
    104 #endif
    105 
    106 	for (i = 0; i < n; i++, sym++) {
    107 		const char *name = base + sym->st_name;
    108 		uchar_t type = ELF32_ST_TYPE(sym->st_info);
    109 
    110 		if (type >= STT_NUM || type == STT_SECTION)
    111 			continue; /* skip sections and unknown types */
    112 
    113 		if (sym->st_name == 0 || sym->st_name >= ss_size)
    114 			continue; /* skip null or invalid names */
    115 
    116 		if (sym->st_value != 0 &&
    117 		    (ELF32_ST_BIND(sym->st_info) != STB_LOCAL || sym->st_size)) {
    118 			asrsv++; /* reserve space in the address map */
    119 
    120 #if defined(__FreeBSD__)
    121 			sym->st_value += (Elf_Addr) dmp->dm_reloc_offset;
    122 			if (is_elf_obj && sym->st_shndx != SHN_UNDEF &&
    123 			    sym->st_shndx < ehdr.e_shnum)
    124 				sym->st_value +=
    125 				    dmp->dm_sec_offsets[sym->st_shndx];
    126 #endif
    127 #ifdef __NetBSD__
    128 			sym->st_value += (uintptr_t) dmp->dm_reloc_offset;
    129 #endif
    130 		}
    131 
    132 		dt_module_symhash_insert(dmp, name, i);
    133 	}
    134 
    135 	return (asrsv);
    136 }
    137 
    138 static uint_t
    139 dt_module_syminit64(dt_module_t *dmp)
    140 {
    141 #if STT_NUM != (STT_TLS + 1)
    142 #error "STT_NUM has grown. update dt_module_syminit64()"
    143 #endif
    144 
    145 	Elf64_Sym *sym = dmp->dm_symtab.cts_data;
    146 	const char *base = dmp->dm_strtab.cts_data;
    147 	size_t ss_size = dmp->dm_strtab.cts_size;
    148 	uint_t i, n = dmp->dm_nsymelems;
    149 	uint_t asrsv = 0;
    150 
    151 #if defined(__FreeBSD__)
    152 	GElf_Ehdr ehdr;
    153 	int is_elf_obj;
    154 
    155 	gelf_getehdr(dmp->dm_elf, &ehdr);
    156 	is_elf_obj = (ehdr.e_type == ET_REL);
    157 #endif
    158 
    159 	for (i = 0; i < n; i++, sym++) {
    160 		const char *name = base + sym->st_name;
    161 		uchar_t type = ELF64_ST_TYPE(sym->st_info);
    162 
    163 		if (type >= STT_NUM || type == STT_SECTION)
    164 			continue; /* skip sections and unknown types */
    165 
    166 		if (sym->st_name == 0 || sym->st_name >= ss_size)
    167 			continue; /* skip null or invalid names */
    168 
    169 		if (sym->st_value != 0 &&
    170 		    (ELF64_ST_BIND(sym->st_info) != STB_LOCAL || sym->st_size)) {
    171 			asrsv++; /* reserve space in the address map */
    172 #if defined(__FreeBSD__)
    173 			sym->st_value += (Elf_Addr) dmp->dm_reloc_offset;
    174 			if (is_elf_obj && sym->st_shndx != SHN_UNDEF &&
    175 			    sym->st_shndx < ehdr.e_shnum)
    176 				sym->st_value +=
    177 				    dmp->dm_sec_offsets[sym->st_shndx];
    178 #endif
    179 #ifdef __NetBSD__
    180 			sym->st_value += (uintptr_t) dmp->dm_reloc_offset;
    181 #endif
    182 		}
    183 
    184 		dt_module_symhash_insert(dmp, name, i);
    185 	}
    186 
    187 	return (asrsv);
    188 }
    189 
    190 /*
    191  * Sort comparison function for 32-bit symbol address-to-name lookups.  We sort
    192  * symbols by value.  If values are equal, we prefer the symbol that is
    193  * non-zero sized, typed, not weak, or lexically first, in that order.
    194  */
    195 static int
    196 dt_module_symcomp32(const void *lp, const void *rp)
    197 {
    198 	Elf32_Sym *lhs = *((Elf32_Sym **)lp);
    199 	Elf32_Sym *rhs = *((Elf32_Sym **)rp);
    200 
    201 	if (lhs->st_value != rhs->st_value)
    202 		return (lhs->st_value > rhs->st_value ? 1 : -1);
    203 
    204 	if ((lhs->st_size == 0) != (rhs->st_size == 0))
    205 		return (lhs->st_size == 0 ? 1 : -1);
    206 
    207 	if ((ELF32_ST_TYPE(lhs->st_info) == STT_NOTYPE) !=
    208 	    (ELF32_ST_TYPE(rhs->st_info) == STT_NOTYPE))
    209 		return (ELF32_ST_TYPE(lhs->st_info) == STT_NOTYPE ? 1 : -1);
    210 
    211 	if ((ELF32_ST_BIND(lhs->st_info) == STB_WEAK) !=
    212 	    (ELF32_ST_BIND(rhs->st_info) == STB_WEAK))
    213 		return (ELF32_ST_BIND(lhs->st_info) == STB_WEAK ? 1 : -1);
    214 
    215 	return (strcmp(dt_module_strtab + lhs->st_name,
    216 	    dt_module_strtab + rhs->st_name));
    217 }
    218 
    219 /*
    220  * Sort comparison function for 64-bit symbol address-to-name lookups.  We sort
    221  * symbols by value.  If values are equal, we prefer the symbol that is
    222  * non-zero sized, typed, not weak, or lexically first, in that order.
    223  */
    224 static int
    225 dt_module_symcomp64(const void *lp, const void *rp)
    226 {
    227 	Elf64_Sym *lhs = *((Elf64_Sym **)lp);
    228 	Elf64_Sym *rhs = *((Elf64_Sym **)rp);
    229 
    230 	if (lhs->st_value != rhs->st_value)
    231 		return (lhs->st_value > rhs->st_value ? 1 : -1);
    232 
    233 	if ((lhs->st_size == 0) != (rhs->st_size == 0))
    234 		return (lhs->st_size == 0 ? 1 : -1);
    235 
    236 	if ((ELF64_ST_TYPE(lhs->st_info) == STT_NOTYPE) !=
    237 	    (ELF64_ST_TYPE(rhs->st_info) == STT_NOTYPE))
    238 		return (ELF64_ST_TYPE(lhs->st_info) == STT_NOTYPE ? 1 : -1);
    239 
    240 	if ((ELF64_ST_BIND(lhs->st_info) == STB_WEAK) !=
    241 	    (ELF64_ST_BIND(rhs->st_info) == STB_WEAK))
    242 		return (ELF64_ST_BIND(lhs->st_info) == STB_WEAK ? 1 : -1);
    243 
    244 	return (strcmp(dt_module_strtab + lhs->st_name,
    245 	    dt_module_strtab + rhs->st_name));
    246 }
    247 
    248 static void
    249 dt_module_symsort32(dt_module_t *dmp)
    250 {
    251 	Elf32_Sym *symtab = (Elf32_Sym *)dmp->dm_symtab.cts_data;
    252 	Elf32_Sym **sympp = (Elf32_Sym **)dmp->dm_asmap;
    253 	const dt_sym_t *dsp = dmp->dm_symchains + 1;
    254 	uint_t i, n = dmp->dm_symfree;
    255 
    256 	for (i = 1; i < n; i++, dsp++) {
    257 		Elf32_Sym *sym = symtab + dsp->ds_symid;
    258 		if (sym->st_value != 0 &&
    259 		    (ELF32_ST_BIND(sym->st_info) != STB_LOCAL || sym->st_size))
    260 			*sympp++ = sym;
    261 	}
    262 
    263 	dmp->dm_aslen = (uint_t)(sympp - (Elf32_Sym **)dmp->dm_asmap);
    264 	assert(dmp->dm_aslen <= dmp->dm_asrsv);
    265 
    266 	dt_module_strtab = dmp->dm_strtab.cts_data;
    267 	qsort(dmp->dm_asmap, dmp->dm_aslen,
    268 	    sizeof (Elf32_Sym *), dt_module_symcomp32);
    269 	dt_module_strtab = NULL;
    270 }
    271 
    272 static void
    273 dt_module_symsort64(dt_module_t *dmp)
    274 {
    275 	Elf64_Sym *symtab = (Elf64_Sym *)dmp->dm_symtab.cts_data;
    276 	Elf64_Sym **sympp = (Elf64_Sym **)dmp->dm_asmap;
    277 	const dt_sym_t *dsp = dmp->dm_symchains + 1;
    278 	uint_t i, n = dmp->dm_symfree;
    279 
    280 	for (i = 1; i < n; i++, dsp++) {
    281 		Elf64_Sym *sym = symtab + dsp->ds_symid;
    282 		if (sym->st_value != 0 &&
    283 		    (ELF64_ST_BIND(sym->st_info) != STB_LOCAL || sym->st_size))
    284 			*sympp++ = sym;
    285 	}
    286 
    287 	dmp->dm_aslen = (uint_t)(sympp - (Elf64_Sym **)dmp->dm_asmap);
    288 	assert(dmp->dm_aslen <= dmp->dm_asrsv);
    289 
    290 	dt_module_strtab = dmp->dm_strtab.cts_data;
    291 	qsort(dmp->dm_asmap, dmp->dm_aslen,
    292 	    sizeof (Elf64_Sym *), dt_module_symcomp64);
    293 	dt_module_strtab = NULL;
    294 }
    295 
    296 static GElf_Sym *
    297 dt_module_symgelf32(const Elf32_Sym *src, GElf_Sym *dst)
    298 {
    299 	if (dst != NULL) {
    300 		dst->st_name = src->st_name;
    301 		dst->st_info = src->st_info;
    302 		dst->st_other = src->st_other;
    303 		dst->st_shndx = src->st_shndx;
    304 		dst->st_value = src->st_value;
    305 		dst->st_size = src->st_size;
    306 	}
    307 
    308 	return (dst);
    309 }
    310 
    311 static GElf_Sym *
    312 dt_module_symgelf64(const Elf64_Sym *src, GElf_Sym *dst)
    313 {
    314 	if (dst != NULL)
    315 		bcopy(src, dst, sizeof (GElf_Sym));
    316 
    317 	return (dst);
    318 }
    319 
    320 static GElf_Sym *
    321 dt_module_symname32(dt_module_t *dmp, const char *name,
    322     GElf_Sym *symp, uint_t *idp)
    323 {
    324 	const Elf32_Sym *symtab = dmp->dm_symtab.cts_data;
    325 	const char *strtab = dmp->dm_strtab.cts_data;
    326 
    327 	const Elf32_Sym *sym;
    328 	const dt_sym_t *dsp;
    329 	uint_t i, h;
    330 
    331 	if (dmp->dm_nsymelems == 0)
    332 		return (NULL);
    333 
    334 	h = dt_strtab_hash(name, NULL) % dmp->dm_nsymbuckets;
    335 
    336 	for (i = dmp->dm_symbuckets[h]; i != 0; i = dsp->ds_next) {
    337 		dsp = &dmp->dm_symchains[i];
    338 		sym = symtab + dsp->ds_symid;
    339 
    340 		if (strcmp(name, strtab + sym->st_name) == 0) {
    341 			if (idp != NULL)
    342 				*idp = dsp->ds_symid;
    343 			return (dt_module_symgelf32(sym, symp));
    344 		}
    345 	}
    346 
    347 	return (NULL);
    348 }
    349 
    350 static GElf_Sym *
    351 dt_module_symname64(dt_module_t *dmp, const char *name,
    352     GElf_Sym *symp, uint_t *idp)
    353 {
    354 	const Elf64_Sym *symtab = dmp->dm_symtab.cts_data;
    355 	const char *strtab = dmp->dm_strtab.cts_data;
    356 
    357 	const Elf64_Sym *sym;
    358 	const dt_sym_t *dsp;
    359 	uint_t i, h;
    360 
    361 	if (dmp->dm_nsymelems == 0)
    362 		return (NULL);
    363 
    364 	h = dt_strtab_hash(name, NULL) % dmp->dm_nsymbuckets;
    365 
    366 	for (i = dmp->dm_symbuckets[h]; i != 0; i = dsp->ds_next) {
    367 		dsp = &dmp->dm_symchains[i];
    368 		sym = symtab + dsp->ds_symid;
    369 
    370 		if (strcmp(name, strtab + sym->st_name) == 0) {
    371 			if (idp != NULL)
    372 				*idp = dsp->ds_symid;
    373 			return (dt_module_symgelf64(sym, symp));
    374 		}
    375 	}
    376 
    377 	return (NULL);
    378 }
    379 
    380 static GElf_Sym *
    381 dt_module_symaddr32(dt_module_t *dmp, GElf_Addr addr,
    382     GElf_Sym *symp, uint_t *idp)
    383 {
    384 	const Elf32_Sym **asmap = (const Elf32_Sym **)dmp->dm_asmap;
    385 	const Elf32_Sym *symtab = dmp->dm_symtab.cts_data;
    386 	const Elf32_Sym *sym;
    387 
    388 	uint_t i, mid, lo = 0, hi = dmp->dm_aslen - 1;
    389 	Elf32_Addr v;
    390 
    391 	if (dmp->dm_aslen == 0)
    392 		return (NULL);
    393 
    394 	while (hi - lo > 1) {
    395 		mid = (lo + hi) / 2;
    396 		if (addr >= asmap[mid]->st_value)
    397 			lo = mid;
    398 		else
    399 			hi = mid;
    400 	}
    401 
    402 	i = addr < asmap[hi]->st_value ? lo : hi;
    403 	sym = asmap[i];
    404 	v = sym->st_value;
    405 
    406 	/*
    407 	 * If the previous entry has the same value, improve our choice.  The
    408 	 * order of equal-valued symbols is determined by the comparison func.
    409 	 */
    410 	while (i-- != 0 && asmap[i]->st_value == v)
    411 		sym = asmap[i];
    412 
    413 	if (addr - sym->st_value < MAX(sym->st_size, 1)) {
    414 		if (idp != NULL)
    415 			*idp = (uint_t)(sym - symtab);
    416 		return (dt_module_symgelf32(sym, symp));
    417 	}
    418 
    419 	return (NULL);
    420 }
    421 
    422 static GElf_Sym *
    423 dt_module_symaddr64(dt_module_t *dmp, GElf_Addr addr,
    424     GElf_Sym *symp, uint_t *idp)
    425 {
    426 	const Elf64_Sym **asmap = (const Elf64_Sym **)dmp->dm_asmap;
    427 	const Elf64_Sym *symtab = dmp->dm_symtab.cts_data;
    428 	const Elf64_Sym *sym;
    429 
    430 	uint_t i, mid, lo = 0, hi = dmp->dm_aslen - 1;
    431 	Elf64_Addr v;
    432 
    433 	if (dmp->dm_aslen == 0)
    434 		return (NULL);
    435 
    436 	while (hi - lo > 1) {
    437 		mid = (lo + hi) / 2;
    438 		if (addr >= asmap[mid]->st_value)
    439 			lo = mid;
    440 		else
    441 			hi = mid;
    442 	}
    443 
    444 	i = addr < asmap[hi]->st_value ? lo : hi;
    445 	sym = asmap[i];
    446 	v = sym->st_value;
    447 
    448 	/*
    449 	 * If the previous entry has the same value, improve our choice.  The
    450 	 * order of equal-valued symbols is determined by the comparison func.
    451 	 */
    452 	while (i-- != 0 && asmap[i]->st_value == v)
    453 		sym = asmap[i];
    454 
    455 	if (addr - sym->st_value < MAX(sym->st_size, 1)) {
    456 		if (idp != NULL)
    457 			*idp = (uint_t)(sym - symtab);
    458 		return (dt_module_symgelf64(sym, symp));
    459 	}
    460 
    461 	return (NULL);
    462 }
    463 
    464 static const dt_modops_t dt_modops_32 = {
    465 	dt_module_syminit32,
    466 	dt_module_symsort32,
    467 	dt_module_symname32,
    468 	dt_module_symaddr32
    469 };
    470 
    471 static const dt_modops_t dt_modops_64 = {
    472 	dt_module_syminit64,
    473 	dt_module_symsort64,
    474 	dt_module_symname64,
    475 	dt_module_symaddr64
    476 };
    477 
    478 dt_module_t *
    479 dt_module_create(dtrace_hdl_t *dtp, const char *name)
    480 {
    481 	long pid;
    482 	char *eptr;
    483 	dt_ident_t *idp;
    484 	uint_t h = dt_strtab_hash(name, NULL) % dtp->dt_modbuckets;
    485 	dt_module_t *dmp;
    486 
    487 	for (dmp = dtp->dt_mods[h]; dmp != NULL; dmp = dmp->dm_next) {
    488 		if (strcmp(dmp->dm_name, name) == 0)
    489 			return (dmp);
    490 	}
    491 
    492 	if ((dmp = malloc(sizeof (dt_module_t))) == NULL)
    493 		return (NULL); /* caller must handle allocation failure */
    494 
    495 	bzero(dmp, sizeof (dt_module_t));
    496 	(void) strlcpy(dmp->dm_name, name, sizeof (dmp->dm_name));
    497 	dt_list_append(&dtp->dt_modlist, dmp);
    498 	dmp->dm_next = dtp->dt_mods[h];
    499 	dtp->dt_mods[h] = dmp;
    500 	dtp->dt_nmods++;
    501 
    502 	if (dtp->dt_conf.dtc_ctfmodel == CTF_MODEL_LP64)
    503 		dmp->dm_ops = &dt_modops_64;
    504 	else
    505 		dmp->dm_ops = &dt_modops_32;
    506 
    507 	/*
    508 	 * Modules for userland processes are special. They always refer to a
    509 	 * specific process and have a copy of their CTF data from a specific
    510 	 * instant in time. Any dt_module_t that begins with 'pid' is a module
    511 	 * for a specific process, much like how any probe description that
    512 	 * begins with 'pid' is special. pid123 refers to process 123. A module
    513 	 * that is just 'pid' refers specifically to pid$target. This is
    514 	 * generally done as D does not currently allow for macros to be
    515 	 * evaluated when working with types.
    516 	 */
    517 	if (strncmp(dmp->dm_name, "pid", 3) == 0) {
    518 		errno = 0;
    519 		if (dmp->dm_name[3] == '\0') {
    520 			idp = dt_idhash_lookup(dtp->dt_macros, "target");
    521 			if (idp != NULL && idp->di_id != 0)
    522 				dmp->dm_pid = idp->di_id;
    523 		} else {
    524 			pid = strtol(dmp->dm_name + 3, &eptr, 10);
    525 			if (errno == 0 && *eptr == '\0')
    526 				dmp->dm_pid = (pid_t)pid;
    527 			else
    528 				dt_dprintf("encountered malformed pid "
    529 				    "module: %s\n", dmp->dm_name);
    530 		}
    531 	}
    532 
    533 	return (dmp);
    534 }
    535 
    536 dt_module_t *
    537 dt_module_lookup_by_name(dtrace_hdl_t *dtp, const char *name)
    538 {
    539 	uint_t h = dt_strtab_hash(name, NULL) % dtp->dt_modbuckets;
    540 	dt_module_t *dmp;
    541 
    542 	for (dmp = dtp->dt_mods[h]; dmp != NULL; dmp = dmp->dm_next) {
    543 		if (strcmp(dmp->dm_name, name) == 0)
    544 			return (dmp);
    545 	}
    546 
    547 	return (NULL);
    548 }
    549 
    550 /*ARGSUSED*/
    551 dt_module_t *
    552 dt_module_lookup_by_ctf(dtrace_hdl_t *dtp, ctf_file_t *ctfp)
    553 {
    554 	return (ctfp ? ctf_getspecific(ctfp) : NULL);
    555 }
    556 
    557 #if defined(__FreeBSD__) || defined(__NetBSD__)
    558 dt_kmodule_t *
    559 dt_kmodule_lookup(dtrace_hdl_t *dtp, const char *name)
    560 {
    561 	uint_t h = dt_strtab_hash(name, NULL) % dtp->dt_modbuckets;
    562 	dt_kmodule_t *dkmp;
    563 
    564 	for (dkmp = dtp->dt_kmods[h]; dkmp != NULL; dkmp = dkmp->dkm_next) {
    565 		if (strcmp(dkmp->dkm_name, name) == 0)
    566 			return (dkmp);
    567 	}
    568 
    569 	return (NULL);
    570 }
    571 #endif
    572 
    573 static int
    574 dt_module_load_sect(dtrace_hdl_t *dtp, dt_module_t *dmp, ctf_sect_t *ctsp)
    575 {
    576 	const char *s;
    577 	size_t shstrs;
    578 	GElf_Shdr sh;
    579 	Elf_Data *dp;
    580 	Elf_Scn *sp;
    581 
    582 	if (elf_getshdrstrndx(dmp->dm_elf, &shstrs) == -1)
    583 		return (dt_set_errno(dtp, EDT_NOTLOADED));
    584 
    585 	for (sp = NULL; (sp = elf_nextscn(dmp->dm_elf, sp)) != NULL; ) {
    586 		if (gelf_getshdr(sp, &sh) == NULL || sh.sh_type == SHT_NULL ||
    587 		    (s = elf_strptr(dmp->dm_elf, shstrs, sh.sh_name)) == NULL)
    588 			continue; /* skip any malformed sections */
    589 
    590 		if (sh.sh_type == ctsp->cts_type &&
    591 		    sh.sh_entsize == ctsp->cts_entsize &&
    592 		    strcmp(s, ctsp->cts_name) == 0)
    593 			break; /* section matches specification */
    594 	}
    595 
    596 	/*
    597 	 * If the section isn't found, return success but leave cts_data set
    598 	 * to NULL and cts_size set to zero for our caller.
    599 	 */
    600 	if (sp == NULL || (dp = elf_getdata(sp, NULL)) == NULL)
    601 		return (0);
    602 
    603 #ifdef illumos
    604 	ctsp->cts_data = dp->d_buf;
    605 #else
    606 	if ((ctsp->cts_data = malloc(dp->d_size)) == NULL)
    607 		return (0);
    608 	memcpy(ctsp->cts_data, dp->d_buf, dp->d_size);
    609 #endif
    610 	ctsp->cts_size = dp->d_size;
    611 
    612 	dt_dprintf("loaded %s [%s] (%lu bytes)\n",
    613 	    dmp->dm_name, ctsp->cts_name, (ulong_t)ctsp->cts_size);
    614 
    615 	return (0);
    616 }
    617 
    618 typedef struct dt_module_cb_arg {
    619 	struct ps_prochandle *dpa_proc;
    620 	dtrace_hdl_t *dpa_dtp;
    621 	dt_module_t *dpa_dmp;
    622 	uint_t dpa_count;
    623 } dt_module_cb_arg_t;
    624 
    625 /* ARGSUSED */
    626 static int
    627 dt_module_load_proc_count(void *arg, const prmap_t *prmap, const char *obj)
    628 {
    629 	ctf_file_t *fp;
    630 	dt_module_cb_arg_t *dcp = arg;
    631 
    632 	/* Try to grab a ctf container if it exists */
    633 	fp = Pname_to_ctf(dcp->dpa_proc, obj);
    634 	if (fp != NULL)
    635 		dcp->dpa_count++;
    636 	return (0);
    637 }
    638 
    639 /* ARGSUSED */
    640 static int
    641 dt_module_load_proc_build(void *arg, const prmap_t *prmap, const char *obj)
    642 {
    643 	ctf_file_t *fp;
    644 	char buf[MAXPATHLEN], *p;
    645 	dt_module_cb_arg_t *dcp = arg;
    646 	int count = dcp->dpa_count;
    647 	Lmid_t lmid;
    648 
    649 	fp = Pname_to_ctf(dcp->dpa_proc, obj);
    650 	if (fp == NULL)
    651 		return (0);
    652 	fp = ctf_dup(fp);
    653 	if (fp == NULL)
    654 		return (0);
    655 	dcp->dpa_dmp->dm_libctfp[count] = fp;
    656 	/*
    657 	 * While it'd be nice to simply use objname here, because of our prior
    658 	 * actions we'll always get a resolved object name to its on disk file.
    659 	 * Like the pid provider, we need to tell a bit of a lie here. The type
    660 	 * that the user thinks of is in terms of the libraries they requested,
    661 	 * eg. libc.so.1, they don't care about the fact that it's
    662 	 * libc_hwcap.so.1.
    663 	 */
    664 	(void) Pobjname(dcp->dpa_proc, prmap->pr_vaddr, buf, sizeof (buf));
    665 	if ((p = strrchr(buf, '/')) == NULL)
    666 		p = buf;
    667 	else
    668 		p++;
    669 
    670 	/*
    671 	 * If for some reason we can't find a link map id for this module, which
    672 	 * would be really quite weird. We instead just say the link map id is
    673 	 * zero.
    674 	 */
    675 	if (Plmid(dcp->dpa_proc, prmap->pr_vaddr, &lmid) != 0)
    676 		lmid = 0;
    677 
    678 	if (lmid == 0)
    679 		dcp->dpa_dmp->dm_libctfn[count] = strdup(p);
    680 	else
    681 		(void) asprintf(&dcp->dpa_dmp->dm_libctfn[count],
    682 		    "LM%x`%s", lmid, p);
    683 	if (dcp->dpa_dmp->dm_libctfn[count] == NULL)
    684 		return (1);
    685 	ctf_setspecific(fp, dcp->dpa_dmp);
    686 	dcp->dpa_count++;
    687 	return (0);
    688 }
    689 
    690 /*
    691  * We've been asked to load data that belongs to another process. As such we're
    692  * going to pgrab it at this instant, load everything that we might ever care
    693  * about, and then drive on. The reason for this is that the process that we're
    694  * interested in might be changing. As long as we have grabbed it, then this
    695  * can't be a problem for us.
    696  *
    697  * For now, we're actually going to punt on most things and just try to get CTF
    698  * data, nothing else. Basically this is only useful as a source of type
    699  * information, we can't go and do the stacktrace lookups, etc.
    700  */
    701 static int
    702 dt_module_load_proc(dtrace_hdl_t *dtp, dt_module_t *dmp)
    703 {
    704 	struct ps_prochandle *p;
    705 	dt_module_cb_arg_t arg;
    706 
    707 	/*
    708 	 * Note that on success we do not release this hold. We must hold this
    709 	 * for our life time.
    710 	 */
    711 	p = dt_proc_grab(dtp, dmp->dm_pid, 0, PGRAB_RDONLY | PGRAB_FORCE);
    712 	if (p == NULL) {
    713 		dt_dprintf("failed to grab pid: %d\n", (int)dmp->dm_pid);
    714 		return (dt_set_errno(dtp, EDT_CANTLOAD));
    715 	}
    716 	dt_proc_lock(dtp, p);
    717 
    718 	arg.dpa_proc = p;
    719 	arg.dpa_dtp = dtp;
    720 	arg.dpa_dmp = dmp;
    721 	arg.dpa_count = 0;
    722 	if (Pobject_iter_resolved(p, dt_module_load_proc_count, &arg) != 0) {
    723 		dt_dprintf("failed to iterate objects\n");
    724 		dt_proc_unlock(dtp, p);
    725 		dt_proc_release(dtp, p);
    726 		return (dt_set_errno(dtp, EDT_CANTLOAD));
    727 	}
    728 
    729 	if (arg.dpa_count == 0) {
    730 		dt_dprintf("no ctf data present\n");
    731 		dt_proc_unlock(dtp, p);
    732 		dt_proc_release(dtp, p);
    733 		return (dt_set_errno(dtp, EDT_CANTLOAD));
    734 	}
    735 
    736 	dmp->dm_libctfp = calloc(arg.dpa_count, sizeof (ctf_file_t *));
    737 	if (dmp->dm_libctfp == NULL) {
    738 		dt_proc_unlock(dtp, p);
    739 		dt_proc_release(dtp, p);
    740 		return (dt_set_errno(dtp, EDT_NOMEM));
    741 	}
    742 
    743 	dmp->dm_libctfn = calloc(arg.dpa_count, sizeof (char *));
    744 	if (dmp->dm_libctfn == NULL) {
    745 		free(dmp->dm_libctfp);
    746 		dt_proc_unlock(dtp, p);
    747 		dt_proc_release(dtp, p);
    748 		return (dt_set_errno(dtp, EDT_NOMEM));
    749 	}
    750 
    751 	dmp->dm_nctflibs = arg.dpa_count;
    752 
    753 	arg.dpa_count = 0;
    754 	if (Pobject_iter_resolved(p, dt_module_load_proc_build, &arg) != 0) {
    755 		dt_proc_unlock(dtp, p);
    756 		dt_module_unload(dtp, dmp);
    757 		dt_proc_release(dtp, p);
    758 		return (dt_set_errno(dtp, EDT_CANTLOAD));
    759 	}
    760 	assert(arg.dpa_count == dmp->dm_nctflibs);
    761 	dt_dprintf("loaded %d ctf modules for pid %d\n", arg.dpa_count,
    762 	    (int)dmp->dm_pid);
    763 
    764 	dt_proc_unlock(dtp, p);
    765 	dt_proc_release(dtp, p);
    766 	dmp->dm_flags |= DT_DM_LOADED;
    767 
    768 	return (0);
    769 }
    770 
    771 int
    772 dt_module_load(dtrace_hdl_t *dtp, dt_module_t *dmp)
    773 {
    774 	if (dmp->dm_flags & DT_DM_LOADED)
    775 		return (0); /* module is already loaded */
    776 
    777 	if (dmp->dm_pid != 0)
    778 		return (dt_module_load_proc(dtp, dmp));
    779 
    780 	dmp->dm_ctdata.cts_name = ".SUNW_ctf";
    781 	dmp->dm_ctdata.cts_type = SHT_PROGBITS;
    782 	dmp->dm_ctdata.cts_flags = 0;
    783 	dmp->dm_ctdata.cts_data = NULL;
    784 	dmp->dm_ctdata.cts_size = 0;
    785 	dmp->dm_ctdata.cts_entsize = 0;
    786 	dmp->dm_ctdata.cts_offset = 0;
    787 
    788 	dmp->dm_symtab.cts_name = ".symtab";
    789 	dmp->dm_symtab.cts_type = SHT_SYMTAB;
    790 	dmp->dm_symtab.cts_flags = 0;
    791 	dmp->dm_symtab.cts_data = NULL;
    792 	dmp->dm_symtab.cts_size = 0;
    793 	dmp->dm_symtab.cts_entsize = dmp->dm_ops == &dt_modops_64 ?
    794 	    sizeof (Elf64_Sym) : sizeof (Elf32_Sym);
    795 	dmp->dm_symtab.cts_offset = 0;
    796 
    797 	dmp->dm_strtab.cts_name = ".strtab";
    798 	dmp->dm_strtab.cts_type = SHT_STRTAB;
    799 	dmp->dm_strtab.cts_flags = 0;
    800 	dmp->dm_strtab.cts_data = NULL;
    801 	dmp->dm_strtab.cts_size = 0;
    802 	dmp->dm_strtab.cts_entsize = 0;
    803 	dmp->dm_strtab.cts_offset = 0;
    804 
    805 	/*
    806 	 * Attempt to load the module's CTF section, symbol table section, and
    807 	 * string table section.  Note that modules may not contain CTF data:
    808 	 * this will result in a successful load_sect but data of size zero.
    809 	 * We will then fail if dt_module_getctf() is called, as shown below.
    810 	 */
    811 	if (dt_module_load_sect(dtp, dmp, &dmp->dm_ctdata) == -1 ||
    812 	    dt_module_load_sect(dtp, dmp, &dmp->dm_symtab) == -1 ||
    813 	    dt_module_load_sect(dtp, dmp, &dmp->dm_strtab) == -1) {
    814 		dt_module_unload(dtp, dmp);
    815 		return (-1); /* dt_errno is set for us */
    816 	}
    817 
    818 	/*
    819 	 * Allocate the hash chains and hash buckets for symbol name lookup.
    820 	 * This is relatively simple since the symbol table is of fixed size
    821 	 * and is known in advance.  We allocate one extra element since we
    822 	 * use element indices instead of pointers and zero is our sentinel.
    823 	 */
    824 	dmp->dm_nsymelems =
    825 	    dmp->dm_symtab.cts_size / dmp->dm_symtab.cts_entsize;
    826 
    827 	dmp->dm_nsymbuckets = _dtrace_strbuckets;
    828 	dmp->dm_symfree = 1;		/* first free element is index 1 */
    829 
    830 	dmp->dm_symbuckets = calloc(dmp->dm_nsymbuckets, sizeof (uint_t));
    831 	dmp->dm_symchains = calloc(dmp->dm_nsymelems + 1, sizeof (dt_sym_t));
    832 
    833 	if (dmp->dm_symbuckets == NULL || dmp->dm_symchains == NULL) {
    834 		dt_module_unload(dtp, dmp);
    835 		return (dt_set_errno(dtp, EDT_NOMEM));
    836 	}
    837 
    838 	/*
    839 	 * Iterate over the symbol table data buffer and insert each symbol
    840 	 * name into the name hash if the name and type are valid.  Then
    841 	 * allocate the address map, fill it in, and sort it.
    842 	 */
    843 	dmp->dm_asrsv = dmp->dm_ops->do_syminit(dmp);
    844 
    845 	dt_dprintf("hashed %s [%s] (%u symbols)\n",
    846 	    dmp->dm_name, dmp->dm_symtab.cts_name, dmp->dm_symfree - 1);
    847 
    848 	if ((dmp->dm_asmap = malloc(sizeof (void *) * dmp->dm_asrsv)) == NULL) {
    849 		dt_module_unload(dtp, dmp);
    850 		return (dt_set_errno(dtp, EDT_NOMEM));
    851 	}
    852 
    853 	dmp->dm_ops->do_symsort(dmp);
    854 
    855 	dt_dprintf("sorted %s [%s] (%u symbols)\n",
    856 	    dmp->dm_name, dmp->dm_symtab.cts_name, dmp->dm_aslen);
    857 
    858 	dmp->dm_flags |= DT_DM_LOADED;
    859 	return (0);
    860 }
    861 
    862 int
    863 dt_module_hasctf(dtrace_hdl_t *dtp, dt_module_t *dmp)
    864 {
    865 	if (dmp->dm_pid != 0 && dmp->dm_nctflibs > 0)
    866 		return (1);
    867 	return (dt_module_getctf(dtp, dmp) != NULL);
    868 }
    869 
    870 ctf_file_t *
    871 dt_module_getctf(dtrace_hdl_t *dtp, dt_module_t *dmp)
    872 {
    873 	const char *parent;
    874 	dt_module_t *pmp;
    875 	ctf_file_t *pfp;
    876 	int model;
    877 
    878 	if (dmp->dm_ctfp != NULL || dt_module_load(dtp, dmp) != 0)
    879 		return (dmp->dm_ctfp);
    880 
    881 	if (dmp->dm_ops == &dt_modops_64)
    882 		model = CTF_MODEL_LP64;
    883 	else
    884 		model = CTF_MODEL_ILP32;
    885 
    886 	/*
    887 	 * If the data model of the module does not match our program data
    888 	 * model, then do not permit CTF from this module to be opened and
    889 	 * returned to the compiler.  If we support mixed data models in the
    890 	 * future for combined kernel/user tracing, this can be removed.
    891 	 */
    892 	if (dtp->dt_conf.dtc_ctfmodel != model) {
    893 		(void) dt_set_errno(dtp, EDT_DATAMODEL);
    894 		return (NULL);
    895 	}
    896 
    897 	if (dmp->dm_ctdata.cts_size == 0) {
    898 		(void) dt_set_errno(dtp, EDT_NOCTF);
    899 		return (NULL);
    900 	}
    901 
    902 	dmp->dm_ctfp = ctf_bufopen(&dmp->dm_ctdata,
    903 	    &dmp->dm_symtab, &dmp->dm_strtab, &dtp->dt_ctferr);
    904 
    905 	if (dmp->dm_ctfp == NULL) {
    906 		(void) dt_set_errno(dtp, EDT_CTF);
    907 		return (NULL);
    908 	}
    909 
    910 	(void) ctf_setmodel(dmp->dm_ctfp, model);
    911 	ctf_setspecific(dmp->dm_ctfp, dmp);
    912 
    913 	if ((parent = ctf_parent_name(dmp->dm_ctfp)) != NULL) {
    914 		if ((pmp = dt_module_create(dtp, parent)) == NULL ||
    915 		    (pfp = dt_module_getctf(dtp, pmp)) == NULL) {
    916 			if (pmp == NULL)
    917 				(void) dt_set_errno(dtp, EDT_NOMEM);
    918 			goto err;
    919 		}
    920 
    921 		if (ctf_import(dmp->dm_ctfp, pfp) == CTF_ERR) {
    922 			dtp->dt_ctferr = ctf_errno(dmp->dm_ctfp);
    923 			(void) dt_set_errno(dtp, EDT_CTF);
    924 			goto err;
    925 		}
    926 	}
    927 
    928 	dt_dprintf("loaded CTF container for %s (%p)\n",
    929 	    dmp->dm_name, (void *)dmp->dm_ctfp);
    930 
    931 	return (dmp->dm_ctfp);
    932 
    933 err:
    934 	ctf_close(dmp->dm_ctfp);
    935 	dmp->dm_ctfp = NULL;
    936 	return (NULL);
    937 }
    938 
    939 /*ARGSUSED*/
    940 void
    941 dt_module_unload(dtrace_hdl_t *dtp, dt_module_t *dmp)
    942 {
    943 	int i;
    944 
    945 	ctf_close(dmp->dm_ctfp);
    946 	dmp->dm_ctfp = NULL;
    947 
    948 #ifndef illumos
    949 	if (dmp->dm_ctdata.cts_data != NULL) {
    950 		free(dmp->dm_ctdata.cts_data);
    951 	}
    952 	if (dmp->dm_symtab.cts_data != NULL) {
    953 		free(dmp->dm_symtab.cts_data);
    954 	}
    955 	if (dmp->dm_strtab.cts_data != NULL) {
    956 		free(dmp->dm_strtab.cts_data);
    957 	}
    958 #endif
    959 
    960 	if (dmp->dm_libctfp != NULL) {
    961 		for (i = 0; i < dmp->dm_nctflibs; i++) {
    962 			ctf_close(dmp->dm_libctfp[i]);
    963 			free(dmp->dm_libctfn[i]);
    964 		}
    965 		free(dmp->dm_libctfp);
    966 		free(dmp->dm_libctfn);
    967 		dmp->dm_libctfp = NULL;
    968 		dmp->dm_nctflibs = 0;
    969 	}
    970 
    971 	bzero(&dmp->dm_ctdata, sizeof (ctf_sect_t));
    972 	bzero(&dmp->dm_symtab, sizeof (ctf_sect_t));
    973 	bzero(&dmp->dm_strtab, sizeof (ctf_sect_t));
    974 
    975 	if (dmp->dm_symbuckets != NULL) {
    976 		free(dmp->dm_symbuckets);
    977 		dmp->dm_symbuckets = NULL;
    978 	}
    979 
    980 	if (dmp->dm_symchains != NULL) {
    981 		free(dmp->dm_symchains);
    982 		dmp->dm_symchains = NULL;
    983 	}
    984 
    985 	if (dmp->dm_asmap != NULL) {
    986 		free(dmp->dm_asmap);
    987 		dmp->dm_asmap = NULL;
    988 	}
    989 #if defined(__FreeBSD__)
    990 	if (dmp->dm_sec_offsets != NULL) {
    991 		free(dmp->dm_sec_offsets);
    992 		dmp->dm_sec_offsets = NULL;
    993 	}
    994 #endif
    995 	dmp->dm_symfree = 0;
    996 	dmp->dm_nsymbuckets = 0;
    997 	dmp->dm_nsymelems = 0;
    998 	dmp->dm_asrsv = 0;
    999 	dmp->dm_aslen = 0;
   1000 
   1001 	dmp->dm_text_va = 0;
   1002 	dmp->dm_text_size = 0;
   1003 	dmp->dm_data_va = 0;
   1004 	dmp->dm_data_size = 0;
   1005 	dmp->dm_bss_va = 0;
   1006 	dmp->dm_bss_size = 0;
   1007 
   1008 	if (dmp->dm_extern != NULL) {
   1009 		dt_idhash_destroy(dmp->dm_extern);
   1010 		dmp->dm_extern = NULL;
   1011 	}
   1012 
   1013 	(void) elf_end(dmp->dm_elf);
   1014 	dmp->dm_elf = NULL;
   1015 
   1016 	dmp->dm_pid = 0;
   1017 
   1018 	dmp->dm_flags &= ~DT_DM_LOADED;
   1019 }
   1020 
   1021 void
   1022 dt_module_destroy(dtrace_hdl_t *dtp, dt_module_t *dmp)
   1023 {
   1024 	uint_t h = dt_strtab_hash(dmp->dm_name, NULL) % dtp->dt_modbuckets;
   1025 	dt_module_t **dmpp = &dtp->dt_mods[h];
   1026 
   1027 	dt_list_delete(&dtp->dt_modlist, dmp);
   1028 	assert(dtp->dt_nmods != 0);
   1029 	dtp->dt_nmods--;
   1030 
   1031 	/*
   1032 	 * Now remove this module from its hash chain.  We expect to always
   1033 	 * find the module on its hash chain, so in this loop we assert that
   1034 	 * we don't run off the end of the list.
   1035 	 */
   1036 	while (*dmpp != dmp) {
   1037 		dmpp = &((*dmpp)->dm_next);
   1038 		assert(*dmpp != NULL);
   1039 	}
   1040 
   1041 	*dmpp = dmp->dm_next;
   1042 
   1043 	dt_module_unload(dtp, dmp);
   1044 	free(dmp);
   1045 }
   1046 
   1047 /*
   1048  * Insert a new external symbol reference into the specified module.  The new
   1049  * symbol will be marked as undefined and is assigned a symbol index beyond
   1050  * any existing cached symbols from this module.  We use the ident's di_data
   1051  * field to store a pointer to a copy of the dtrace_syminfo_t for this symbol.
   1052  */
   1053 dt_ident_t *
   1054 dt_module_extern(dtrace_hdl_t *dtp, dt_module_t *dmp,
   1055     const char *name, const dtrace_typeinfo_t *tip)
   1056 {
   1057 	dtrace_syminfo_t *sip;
   1058 	dt_ident_t *idp;
   1059 	uint_t id;
   1060 
   1061 	if (dmp->dm_extern == NULL && (dmp->dm_extern = dt_idhash_create(
   1062 	    "extern", NULL, dmp->dm_nsymelems, UINT_MAX)) == NULL) {
   1063 		(void) dt_set_errno(dtp, EDT_NOMEM);
   1064 		return (NULL);
   1065 	}
   1066 
   1067 	if (dt_idhash_nextid(dmp->dm_extern, &id) == -1) {
   1068 		(void) dt_set_errno(dtp, EDT_SYMOFLOW);
   1069 		return (NULL);
   1070 	}
   1071 
   1072 	if ((sip = malloc(sizeof (dtrace_syminfo_t))) == NULL) {
   1073 		(void) dt_set_errno(dtp, EDT_NOMEM);
   1074 		return (NULL);
   1075 	}
   1076 
   1077 	idp = dt_idhash_insert(dmp->dm_extern, name, DT_IDENT_SYMBOL, 0, id,
   1078 	    _dtrace_symattr, 0, &dt_idops_thaw, NULL, dtp->dt_gen);
   1079 
   1080 	if (idp == NULL) {
   1081 		(void) dt_set_errno(dtp, EDT_NOMEM);
   1082 		free(sip);
   1083 		return (NULL);
   1084 	}
   1085 
   1086 	sip->dts_object = dmp->dm_name;
   1087 	sip->dts_name = idp->di_name;
   1088 	sip->dts_id = idp->di_id;
   1089 
   1090 	idp->di_data = sip;
   1091 	idp->di_ctfp = tip->dtt_ctfp;
   1092 	idp->di_type = tip->dtt_type;
   1093 
   1094 	return (idp);
   1095 }
   1096 
   1097 const char *
   1098 dt_module_modelname(dt_module_t *dmp)
   1099 {
   1100 	if (dmp->dm_ops == &dt_modops_64)
   1101 		return ("64-bit");
   1102 	else
   1103 		return ("32-bit");
   1104 }
   1105 
   1106 /* ARGSUSED */
   1107 int
   1108 dt_module_getlibid(dtrace_hdl_t *dtp, dt_module_t *dmp, const ctf_file_t *fp)
   1109 {
   1110 	int i;
   1111 
   1112 	for (i = 0; i < dmp->dm_nctflibs; i++) {
   1113 		if (dmp->dm_libctfp[i] == fp)
   1114 			return (i);
   1115 	}
   1116 
   1117 	return (-1);
   1118 }
   1119 
   1120 /* ARGSUSED */
   1121 ctf_file_t *
   1122 dt_module_getctflib(dtrace_hdl_t *dtp, dt_module_t *dmp, const char *name)
   1123 {
   1124 	int i;
   1125 
   1126 	for (i = 0; i < dmp->dm_nctflibs; i++) {
   1127 		if (strcmp(dmp->dm_libctfn[i], name) == 0)
   1128 			return (dmp->dm_libctfp[i]);
   1129 	}
   1130 
   1131 	return (NULL);
   1132 }
   1133 
   1134 /*
   1135  * Update our module cache by adding an entry for the specified module 'name'.
   1136  * We create the dt_module_t and populate it using /system/object/<name>/.
   1137  *
   1138  * On FreeBSD, the module name is passed as the full module file name,
   1139  * including the path.
   1140  */
   1141 static void
   1142 #if defined(illumos) || defined(__NetBSD__)
   1143 dt_module_update(dtrace_hdl_t *dtp, const char *name)
   1144 #elif defined(__FreeBSD__)
   1145 dt_module_update(dtrace_hdl_t *dtp, struct kld_file_stat *k_stat)
   1146 #endif
   1147 {
   1148 	char fname[MAXPATHLEN];
   1149 	struct stat64 st;
   1150 	int fd, err, bits;
   1151 #ifdef __FreeBSD__
   1152 	struct module_stat ms;
   1153 	dt_kmodule_t *dkmp;
   1154 	uint_t h;
   1155 	int modid;
   1156 #endif
   1157 
   1158 	dt_module_t *dmp;
   1159 	const char *s;
   1160 	size_t shstrs;
   1161 	GElf_Shdr sh;
   1162 	Elf_Data *dp;
   1163 	Elf_Scn *sp;
   1164 
   1165 #ifdef illumos
   1166 	(void) snprintf(fname, sizeof (fname),
   1167 	    "%s/%s/object", OBJFS_ROOT, name);
   1168 #elif defined(__FreeBSD__)
   1169 	GElf_Ehdr ehdr;
   1170 	GElf_Phdr ph;
   1171 	char name[MAXPATHLEN];
   1172 	uintptr_t mapbase, alignmask;
   1173 	int i = 0;
   1174 	int is_elf_obj;
   1175 
   1176 	(void) strlcpy(name, k_stat->name, sizeof(name));
   1177 	(void) strlcpy(fname, k_stat->pathname, sizeof(fname));
   1178 #elif defined(__NetBSD__)
   1179 	int mib_osrel[2] = { CTL_KERN, KERN_OSRELEASE };
   1180 	int mib_mach[2] = { CTL_HW, HW_MACHINE };
   1181 	char osrel[64];
   1182 	char machine[64];
   1183 	size_t len;
   1184 	uintptr_t mapbase;
   1185 	int i;
   1186 	bool ismod;
   1187 
   1188 	if (strcmp("netbsd", name) == 0) {
   1189 		strlcpy(fname, _PATH_KSYMS, sizeof fname);
   1190 		ismod = false;
   1191 	} else {
   1192 
   1193 		/* build stand module path from system */
   1194 		len = sizeof(osrel);
   1195 		if (sysctl(mib_osrel, 2, osrel, &len, NULL, 0) == -1) {
   1196 			dt_dprintf("sysctl osrel failed: %s\n",
   1197 				strerror(errno));
   1198 		    return;
   1199 		}
   1200 
   1201 		len = sizeof(machine);
   1202 		if (sysctl(mib_mach, 2, machine, &len, NULL, 0) == -1) {
   1203 			dt_dprintf("sysctl machine failed: %s\n",
   1204 				strerror(errno));
   1205 		    return;
   1206 		}
   1207 
   1208 		(void) snprintf(fname, sizeof (fname),
   1209 		    "/stand/%s/%s/modules/%s/%s.kmod", machine, osrel, name, name);
   1210 		ismod = true;
   1211 	}
   1212 #endif
   1213 
   1214 	if ((fd = open(fname, O_RDONLY)) == -1 || fstat64(fd, &st) == -1 ||
   1215 	    (dmp = dt_module_create(dtp, name)) == NULL) {
   1216 		dt_dprintf("failed to open %s: %s\n", fname, strerror(errno));
   1217 		(void) close(fd);
   1218 		return;
   1219 	}
   1220 
   1221 	/*
   1222 	 * Since the module can unload out from under us (and /system/object
   1223 	 * will return ENOENT), tell libelf to cook the entire file now and
   1224 	 * then close the underlying file descriptor immediately.  If this
   1225 	 * succeeds, we know that we can continue safely using dmp->dm_elf.
   1226 	 */
   1227 	dmp->dm_elf = elf_begin(fd, ELF_C_READ, NULL);
   1228 	err = elf_cntl(dmp->dm_elf, ELF_C_FDREAD);
   1229 	(void) close(fd);
   1230 
   1231 	if (dmp->dm_elf == NULL || err == -1 ||
   1232 	    elf_getshdrstrndx(dmp->dm_elf, &shstrs) == -1) {
   1233 		dt_dprintf("failed to load %s: %s\n",
   1234 		    fname, elf_errmsg(elf_errno()));
   1235 		dt_module_destroy(dtp, dmp);
   1236 		return;
   1237 	}
   1238 
   1239 	switch (gelf_getclass(dmp->dm_elf)) {
   1240 	case ELFCLASS32:
   1241 		dmp->dm_ops = &dt_modops_32;
   1242 		bits = 32;
   1243 		break;
   1244 	case ELFCLASS64:
   1245 		dmp->dm_ops = &dt_modops_64;
   1246 		bits = 64;
   1247 		break;
   1248 	default:
   1249 		dt_dprintf("failed to load %s: unknown ELF class\n", fname);
   1250 		dt_module_destroy(dtp, dmp);
   1251 		return;
   1252 	}
   1253 #if defined(__FreeBSD__)
   1254 	mapbase = (uintptr_t)k_stat->address;
   1255 	gelf_getehdr(dmp->dm_elf, &ehdr);
   1256 	is_elf_obj = (ehdr.e_type == ET_REL);
   1257 	if (is_elf_obj) {
   1258 		dmp->dm_sec_offsets =
   1259 		    malloc(ehdr.e_shnum * sizeof(*dmp->dm_sec_offsets));
   1260 		if (dmp->dm_sec_offsets == NULL) {
   1261 			dt_dprintf("failed to allocate memory\n");
   1262 			dt_module_destroy(dtp, dmp);
   1263 			return;
   1264 		}
   1265 	}
   1266 #endif
   1267 #ifdef __NetBSD__
   1268 	mapbase = 0;
   1269 	if (ismod) {
   1270 #define	MAXMODULES 512
   1271 		modstat_t modstat_buf[MAXMODULES], *ms;
   1272 		struct iovec iov = { modstat_buf, sizeof(modstat_buf) };
   1273 
   1274 		if (modctl(MODCTL_STAT, &iov) < 0) {
   1275 			dt_dprintf("failed to get list of kernel modules: %s\n",
   1276 				   strerror(errno));
   1277 			return;
   1278 		}
   1279 
   1280 		for (i = 0; i < MAXMODULES; i++) {
   1281 			ms = &modstat_buf[i];
   1282 			if (!strcmp(name, ms->ms_name)) {
   1283 				mapbase = ms->ms_addr;
   1284 				break;
   1285 			}
   1286 		}
   1287 		if (i == MAXMODULES) {
   1288 			dt_dprintf("module %s not found\n", name);
   1289 			return;
   1290 		}
   1291 		dmp->dm_reloc_offset = (void *)mapbase;
   1292 	}
   1293 #endif
   1294 
   1295 	/*
   1296 	 * Iterate over the section headers locating various sections of
   1297 	 * interest and use their attributes to flesh out the dt_module_t.
   1298 	 */
   1299 	for (sp = NULL; (sp = elf_nextscn(dmp->dm_elf, sp)) != NULL; ) {
   1300 		if (gelf_getshdr(sp, &sh) == NULL || sh.sh_type == SHT_NULL ||
   1301 		    (s = elf_strptr(dmp->dm_elf, shstrs, sh.sh_name)) == NULL)
   1302 			continue; /* skip any malformed sections */
   1303 #if defined(__FreeBSD__)
   1304 		if (sh.sh_size == 0)
   1305 			continue;
   1306 		if (sh.sh_type == SHT_PROGBITS || sh.sh_type == SHT_NOBITS) {
   1307 			alignmask = sh.sh_addralign - 1;
   1308 			mapbase += alignmask;
   1309 			mapbase &= ~alignmask;
   1310 			sh.sh_addr = mapbase;
   1311 			if (is_elf_obj)
   1312 				dmp->dm_sec_offsets[elf_ndxscn(sp)] = sh.sh_addr;
   1313 			mapbase += sh.sh_size;
   1314 		}
   1315 #endif
   1316 		if (strcmp(s, ".text") == 0) {
   1317 			dmp->dm_text_size = sh.sh_size;
   1318 			dmp->dm_text_va = sh.sh_addr;
   1319 		} else if (strcmp(s, ".data") == 0) {
   1320 			dmp->dm_data_size = sh.sh_size;
   1321 			dmp->dm_data_va = sh.sh_addr;
   1322 		} else if (strcmp(s, ".bss") == 0) {
   1323 			dmp->dm_bss_size = sh.sh_size;
   1324 			dmp->dm_bss_va = sh.sh_addr;
   1325 		} else if (strcmp(s, ".info") == 0 &&
   1326 		    (dp = elf_getdata(sp, NULL)) != NULL) {
   1327 			bcopy(dp->d_buf, &dmp->dm_info,
   1328 			    MIN(sh.sh_size, sizeof (dmp->dm_info)));
   1329 		} else if (strcmp(s, ".filename") == 0 &&
   1330 		    (dp = elf_getdata(sp, NULL)) != NULL) {
   1331 			(void) strlcpy(dmp->dm_file,
   1332 			    dp->d_buf, sizeof (dmp->dm_file));
   1333 		}
   1334 	}
   1335 
   1336 	dmp->dm_flags |= DT_DM_KERNEL;
   1337 #ifdef illumos
   1338 	dmp->dm_modid = (int)OBJFS_MODID(st.st_ino);
   1339 #endif /* illumos */
   1340 #ifdef __FreeBSD__
   1341 	/*
   1342 	 * Include .rodata and special sections into .text.
   1343 	 * This depends on default section layout produced by GNU ld
   1344 	 * for ELF objects and libraries:
   1345 	 * [Text][R/O data][R/W data][Dynamic][BSS][Non loadable]
   1346 	 */
   1347 	dmp->dm_text_size = dmp->dm_data_va - dmp->dm_text_va;
   1348 #if defined(__i386__)
   1349 	/*
   1350 	 * Find the first load section and figure out the relocation
   1351 	 * offset for the symbols. The kernel module will not need
   1352 	 * relocation, but the kernel linker modules will.
   1353 	 */
   1354 	for (i = 0; gelf_getphdr(dmp->dm_elf, i, &ph) != NULL; i++) {
   1355 		if (ph.p_type == PT_LOAD) {
   1356 			dmp->dm_reloc_offset = k_stat->address - ph.p_vaddr;
   1357 			break;
   1358 		}
   1359 	}
   1360 #endif
   1361 #endif /* __FreeBSD__ */
   1362 #ifdef __NetBSD__
   1363 	if (ismod) {
   1364 		dmp->dm_text_va = mapbase;
   1365 		dmp->dm_data_va = 0;
   1366 		dmp->dm_data_size = 0;
   1367 		dmp->dm_bss_va = 0;
   1368 		dmp->dm_bss_size = 0;
   1369 	}
   1370 #endif
   1371 
   1372 	if (dmp->dm_info.objfs_info_primary)
   1373 		dmp->dm_flags |= DT_DM_PRIMARY;
   1374 
   1375 #ifdef __FreeBSD__
   1376 	ms.version = sizeof(ms);
   1377 	for (modid = kldfirstmod(k_stat->id); modid > 0;
   1378 	    modid = modnext(modid)) {
   1379 		if (modstat(modid, &ms) != 0) {
   1380 			dt_dprintf("modstat failed for id %d in %s: %s\n",
   1381 			    modid, k_stat->name, strerror(errno));
   1382 			continue;
   1383 		}
   1384 		if (dt_kmodule_lookup(dtp, ms.name) != NULL)
   1385 			continue;
   1386 
   1387 		dkmp = malloc(sizeof (*dkmp));
   1388 		if (dkmp == NULL) {
   1389 			dt_dprintf("failed to allocate memory\n");
   1390 			dt_module_destroy(dtp, dmp);
   1391 			return;
   1392 		}
   1393 
   1394 		h = dt_strtab_hash(ms.name, NULL) % dtp->dt_modbuckets;
   1395 		dkmp->dkm_next = dtp->dt_kmods[h];
   1396 		dkmp->dkm_name = strdup(ms.name);
   1397 		dkmp->dkm_module = dmp;
   1398 		dtp->dt_kmods[h] = dkmp;
   1399 	}
   1400 #endif
   1401 
   1402 	dt_dprintf("opened %d-bit module %s (%s) [%d]\n",
   1403 	    bits, dmp->dm_name, dmp->dm_file, dmp->dm_modid);
   1404 }
   1405 
   1406 /*
   1407  * Unload all the loaded modules and then refresh the module cache with the
   1408  * latest list of loaded modules and their address ranges.
   1409  */
   1410 void
   1411 dtrace_update(dtrace_hdl_t *dtp)
   1412 {
   1413 	dt_module_t *dmp;
   1414 #ifdef illumos
   1415 	DIR *dirp;
   1416 #elif defined(__FreeBSD__)
   1417 	int fileid;
   1418 #endif
   1419 
   1420 	for (dmp = dt_list_next(&dtp->dt_modlist);
   1421 	    dmp != NULL; dmp = dt_list_next(dmp))
   1422 		dt_module_unload(dtp, dmp);
   1423 
   1424 #ifdef illumos
   1425 	/*
   1426 	 * Open /system/object and attempt to create a libdtrace module for
   1427 	 * each kernel module that is loaded on the current system.
   1428 	 */
   1429 	if (!(dtp->dt_oflags & DTRACE_O_NOSYS) &&
   1430 	    (dirp = opendir(OBJFS_ROOT)) != NULL) {
   1431 		struct dirent *dp;
   1432 
   1433 		while ((dp = readdir(dirp)) != NULL) {
   1434 			if (dp->d_name[0] != '.')
   1435 				dt_module_update(dtp, dp->d_name);
   1436 		}
   1437 
   1438 		(void) closedir(dirp);
   1439 	}
   1440 #elif defined(__FreeBSD__)
   1441 	/*
   1442 	 * Use FreeBSD's kernel loader interface to discover what kernel
   1443 	 * modules are loaded and create a libdtrace module for each one.
   1444 	 */
   1445 	for (fileid = kldnext(0); fileid > 0; fileid = kldnext(fileid)) {
   1446 		struct kld_file_stat k_stat;
   1447 		k_stat.version = sizeof(k_stat);
   1448 		if (kldstat(fileid, &k_stat) == 0)
   1449 			dt_module_update(dtp, &k_stat);
   1450 	}
   1451 #elif defined(__NetBSD__)
   1452 	size_t len;
   1453 	struct iovec iov;
   1454 	modstat_t *ms;
   1455 
   1456 	dt_module_update(dtp, "netbsd");
   1457 	for (len = 8192;;) {
   1458 		iov.iov_base = malloc(len);
   1459 		iov.iov_len = len;
   1460 		if (modctl(MODCTL_STAT, &iov)) {
   1461 			free(iov.iov_base);
   1462 			iov.iov_len = 0;
   1463 			break;
   1464 		}
   1465 		if (len >= iov.iov_len) {
   1466 			break;
   1467 		}
   1468 		free(iov.iov_base);
   1469 		len = iov.iov_len;
   1470 	}
   1471 	len = iov.iov_len / sizeof(modstat_t);
   1472 	for (ms = iov.iov_base; len != 0; ms++, len--) {
   1473 		if (ms->ms_source != MODULE_SOURCE_FILESYS)
   1474 			continue;
   1475 		dt_module_update(dtp, ms->ms_name);
   1476 	}
   1477 #endif
   1478 
   1479 	/*
   1480 	 * Look up all the macro identifiers and set di_id to the latest value.
   1481 	 * This code collaborates with dt_lex.l on the use of di_id.  We will
   1482 	 * need to implement something fancier if we need to support non-ints.
   1483 	 */
   1484 	dt_idhash_lookup(dtp->dt_macros, "egid")->di_id = getegid();
   1485 	dt_idhash_lookup(dtp->dt_macros, "euid")->di_id = geteuid();
   1486 	dt_idhash_lookup(dtp->dt_macros, "gid")->di_id = getgid();
   1487 	dt_idhash_lookup(dtp->dt_macros, "pid")->di_id = getpid();
   1488 	dt_idhash_lookup(dtp->dt_macros, "pgid")->di_id = getpgid(0);
   1489 	dt_idhash_lookup(dtp->dt_macros, "ppid")->di_id = getppid();
   1490 #ifdef illumos
   1491 	dt_idhash_lookup(dtp->dt_macros, "projid")->di_id = getprojid();
   1492 #endif
   1493 	dt_idhash_lookup(dtp->dt_macros, "sid")->di_id = getsid(0);
   1494 #ifdef illumos
   1495 	dt_idhash_lookup(dtp->dt_macros, "taskid")->di_id = gettaskid();
   1496 #endif
   1497 	dt_idhash_lookup(dtp->dt_macros, "uid")->di_id = getuid();
   1498 
   1499 	/*
   1500 	 * Cache the pointers to the modules representing the base executable
   1501 	 * and the run-time linker in the dtrace client handle. Note that on
   1502 	 * x86 krtld is folded into unix, so if we don't find it, use unix
   1503 	 * instead.
   1504 	 */
   1505 	dtp->dt_exec = dt_module_lookup_by_name(dtp, "genunix");
   1506 	dtp->dt_rtld = dt_module_lookup_by_name(dtp, "krtld");
   1507 	if (dtp->dt_rtld == NULL)
   1508 		dtp->dt_rtld = dt_module_lookup_by_name(dtp, "unix");
   1509 
   1510 	/*
   1511 	 * If this is the first time we are initializing the module list,
   1512 	 * remove the module for genunix from the module list and then move it
   1513 	 * to the front of the module list.  We do this so that type and symbol
   1514 	 * queries encounter genunix and thereby optimize for the common case
   1515 	 * in dtrace_lookup_by_name() and dtrace_lookup_by_type(), below.
   1516 	 */
   1517 	if (dtp->dt_exec != NULL &&
   1518 	    dtp->dt_cdefs == NULL && dtp->dt_ddefs == NULL) {
   1519 		dt_list_delete(&dtp->dt_modlist, dtp->dt_exec);
   1520 		dt_list_prepend(&dtp->dt_modlist, dtp->dt_exec);
   1521 	}
   1522 }
   1523 
   1524 static dt_module_t *
   1525 dt_module_from_object(dtrace_hdl_t *dtp, const char *object)
   1526 {
   1527 	int err = EDT_NOMOD;
   1528 	dt_module_t *dmp;
   1529 
   1530 	switch ((uintptr_t)object) {
   1531 	case (uintptr_t)DTRACE_OBJ_EXEC:
   1532 		dmp = dtp->dt_exec;
   1533 		break;
   1534 	case (uintptr_t)DTRACE_OBJ_RTLD:
   1535 		dmp = dtp->dt_rtld;
   1536 		break;
   1537 	case (uintptr_t)DTRACE_OBJ_CDEFS:
   1538 		dmp = dtp->dt_cdefs;
   1539 		break;
   1540 	case (uintptr_t)DTRACE_OBJ_DDEFS:
   1541 		dmp = dtp->dt_ddefs;
   1542 		break;
   1543 	default:
   1544 		dmp = dt_module_create(dtp, object);
   1545 		err = EDT_NOMEM;
   1546 	}
   1547 
   1548 	if (dmp == NULL)
   1549 		(void) dt_set_errno(dtp, err);
   1550 
   1551 	return (dmp);
   1552 }
   1553 
   1554 /*
   1555  * Exported interface to look up a symbol by name.  We return the GElf_Sym and
   1556  * complete symbol information for the matching symbol.
   1557  */
   1558 int
   1559 dtrace_lookup_by_name(dtrace_hdl_t *dtp, const char *object, const char *name,
   1560     GElf_Sym *symp, dtrace_syminfo_t *sip)
   1561 {
   1562 	dt_module_t *dmp;
   1563 	dt_ident_t *idp;
   1564 	uint_t n, id;
   1565 	GElf_Sym sym;
   1566 
   1567 	uint_t mask = 0; /* mask of dt_module flags to match */
   1568 	uint_t bits = 0; /* flag bits that must be present */
   1569 
   1570 	if (object != DTRACE_OBJ_EVERY &&
   1571 	    object != DTRACE_OBJ_KMODS &&
   1572 	    object != DTRACE_OBJ_UMODS) {
   1573 		if ((dmp = dt_module_from_object(dtp, object)) == NULL)
   1574 			return (-1); /* dt_errno is set for us */
   1575 
   1576 		if (dt_module_load(dtp, dmp) == -1)
   1577 			return (-1); /* dt_errno is set for us */
   1578 		n = 1;
   1579 
   1580 	} else {
   1581 		if (object == DTRACE_OBJ_KMODS)
   1582 			mask = bits = DT_DM_KERNEL;
   1583 		else if (object == DTRACE_OBJ_UMODS)
   1584 			mask = DT_DM_KERNEL;
   1585 
   1586 		dmp = dt_list_next(&dtp->dt_modlist);
   1587 		n = dtp->dt_nmods;
   1588 	}
   1589 
   1590 	if (symp == NULL)
   1591 		symp = &sym;
   1592 
   1593 	for (; n > 0; n--, dmp = dt_list_next(dmp)) {
   1594 		if ((dmp->dm_flags & mask) != bits)
   1595 			continue; /* failed to match required attributes */
   1596 
   1597 		if (dt_module_load(dtp, dmp) == -1)
   1598 			continue; /* failed to load symbol table */
   1599 
   1600 		if (dmp->dm_ops->do_symname(dmp, name, symp, &id) != NULL) {
   1601 			if (sip != NULL) {
   1602 				sip->dts_object = dmp->dm_name;
   1603 				sip->dts_name = (const char *)
   1604 				    dmp->dm_strtab.cts_data + symp->st_name;
   1605 				sip->dts_id = id;
   1606 			}
   1607 			return (0);
   1608 		}
   1609 
   1610 		if (dmp->dm_extern != NULL &&
   1611 		    (idp = dt_idhash_lookup(dmp->dm_extern, name)) != NULL) {
   1612 			if (symp != &sym) {
   1613 				symp->st_name = (uintptr_t)idp->di_name;
   1614 				symp->st_info =
   1615 				    GELF_ST_INFO(STB_GLOBAL, STT_NOTYPE);
   1616 				symp->st_other = 0;
   1617 				symp->st_shndx = SHN_UNDEF;
   1618 				symp->st_value = 0;
   1619 				symp->st_size =
   1620 				    ctf_type_size(idp->di_ctfp, idp->di_type);
   1621 			}
   1622 
   1623 			if (sip != NULL) {
   1624 				sip->dts_object = dmp->dm_name;
   1625 				sip->dts_name = idp->di_name;
   1626 				sip->dts_id = idp->di_id;
   1627 			}
   1628 
   1629 			return (0);
   1630 		}
   1631 	}
   1632 
   1633 	return (dt_set_errno(dtp, EDT_NOSYM));
   1634 }
   1635 
   1636 /*
   1637  * Exported interface to look up a symbol by address.  We return the GElf_Sym
   1638  * and complete symbol information for the matching symbol.
   1639  */
   1640 int
   1641 dtrace_lookup_by_addr(dtrace_hdl_t *dtp, GElf_Addr addr,
   1642     GElf_Sym *symp, dtrace_syminfo_t *sip)
   1643 {
   1644 	dt_module_t *dmp;
   1645 	uint_t id;
   1646 	const dtrace_vector_t *v = dtp->dt_vector;
   1647 
   1648 	if (v != NULL)
   1649 		return (v->dtv_lookup_by_addr(dtp->dt_varg, addr, symp, sip));
   1650 
   1651 	for (dmp = dt_list_next(&dtp->dt_modlist); dmp != NULL;
   1652 	    dmp = dt_list_next(dmp)) {
   1653 
   1654 		if (addr - dmp->dm_text_va < dmp->dm_text_size ||
   1655 		    addr - dmp->dm_data_va < dmp->dm_data_size ||
   1656 		    addr - dmp->dm_bss_va < dmp->dm_bss_size)
   1657 			break;
   1658 	}
   1659 
   1660 	if (dmp == NULL)
   1661 		return (dt_set_errno(dtp, EDT_NOSYMADDR));
   1662 
   1663 	if (dt_module_load(dtp, dmp) == -1)
   1664 		return (-1); /* dt_errno is set for us */
   1665 
   1666 	if (symp != NULL) {
   1667 		if (dmp->dm_ops->do_symaddr(dmp, addr, symp, &id) == NULL)
   1668 			return (dt_set_errno(dtp, EDT_NOSYMADDR));
   1669 	}
   1670 
   1671 	if (sip != NULL) {
   1672 		sip->dts_object = dmp->dm_name;
   1673 
   1674 		if (symp != NULL) {
   1675 			sip->dts_name = (const char *)
   1676 			    dmp->dm_strtab.cts_data + symp->st_name;
   1677 			sip->dts_id = id;
   1678 		} else {
   1679 			sip->dts_name = NULL;
   1680 			sip->dts_id = 0;
   1681 		}
   1682 	}
   1683 
   1684 	return (0);
   1685 }
   1686 
   1687 int
   1688 dtrace_lookup_by_type(dtrace_hdl_t *dtp, const char *object, const char *name,
   1689     dtrace_typeinfo_t *tip)
   1690 {
   1691 	dtrace_typeinfo_t ti;
   1692 	dt_module_t *dmp;
   1693 	int found = 0;
   1694 	ctf_id_t id = CTF_ERR;	// XXX: gcc
   1695 	uint_t n, i;
   1696 	int justone;
   1697 	ctf_file_t *fp = NULL;	// XXX: gcc
   1698 	char *buf, *p, *q;
   1699 
   1700 	uint_t mask = 0; /* mask of dt_module flags to match */
   1701 	uint_t bits = 0; /* flag bits that must be present */
   1702 
   1703 	if (object != DTRACE_OBJ_EVERY &&
   1704 	    object != DTRACE_OBJ_KMODS &&
   1705 	    object != DTRACE_OBJ_UMODS) {
   1706 		if ((dmp = dt_module_from_object(dtp, object)) == NULL)
   1707 			return (-1); /* dt_errno is set for us */
   1708 
   1709 		if (dt_module_load(dtp, dmp) == -1)
   1710 			return (-1); /* dt_errno is set for us */
   1711 		n = 1;
   1712 		justone = 1;
   1713 	} else {
   1714 		if (object == DTRACE_OBJ_KMODS)
   1715 			mask = bits = DT_DM_KERNEL;
   1716 		else if (object == DTRACE_OBJ_UMODS)
   1717 			mask = DT_DM_KERNEL;
   1718 
   1719 		dmp = dt_list_next(&dtp->dt_modlist);
   1720 		n = dtp->dt_nmods;
   1721 		justone = 0;
   1722 	}
   1723 
   1724 	if (tip == NULL)
   1725 		tip = &ti;
   1726 
   1727 	for (; n > 0; n--, dmp = dt_list_next(dmp)) {
   1728 		if ((dmp->dm_flags & mask) != bits)
   1729 			continue; /* failed to match required attributes */
   1730 
   1731 		/*
   1732 		 * If we can't load the CTF container, continue on to the next
   1733 		 * module.  If our search was scoped to only one module then
   1734 		 * return immediately leaving dt_errno unmodified.
   1735 		 */
   1736 		if (dt_module_hasctf(dtp, dmp) == 0) {
   1737 			if (justone)
   1738 				return (-1);
   1739 			continue;
   1740 		}
   1741 
   1742 		/*
   1743 		 * Look up the type in the module's CTF container.  If our
   1744 		 * match is a forward declaration tag, save this choice in
   1745 		 * 'tip' and keep going in the hope that we will locate the
   1746 		 * underlying structure definition.  Otherwise just return.
   1747 		 */
   1748 		if (dmp->dm_pid == 0) {
   1749 			id = ctf_lookup_by_name(dmp->dm_ctfp, name);
   1750 			fp = dmp->dm_ctfp;
   1751 		} else {
   1752 			if ((p = strchr(name, '`')) != NULL) {
   1753 				buf = strdup(name);
   1754 				if (buf == NULL)
   1755 					return (dt_set_errno(dtp, EDT_NOMEM));
   1756 				p = strchr(buf, '`');
   1757 				if ((q = strchr(p + 1, '`')) != NULL)
   1758 					p = q;
   1759 				*p = '\0';
   1760 				fp = dt_module_getctflib(dtp, dmp, buf);
   1761 				if (fp == NULL || (id = ctf_lookup_by_name(fp,
   1762 				    p + 1)) == CTF_ERR)
   1763 					id = CTF_ERR;
   1764 				free(buf);
   1765 			} else {
   1766 				for (i = 0; i < dmp->dm_nctflibs; i++) {
   1767 					fp = dmp->dm_libctfp[i];
   1768 					id = ctf_lookup_by_name(fp, name);
   1769 					if (id != CTF_ERR)
   1770 						break;
   1771 				}
   1772 			}
   1773 		}
   1774 		if (id != CTF_ERR) {
   1775 			tip->dtt_object = dmp->dm_name;
   1776 			tip->dtt_ctfp = fp;
   1777 			tip->dtt_type = id;
   1778 			if (ctf_type_kind(fp, ctf_type_resolve(fp, id)) !=
   1779 			    CTF_K_FORWARD)
   1780 				return (0);
   1781 
   1782 			found++;
   1783 		}
   1784 	}
   1785 
   1786 	if (found == 0)
   1787 		return (dt_set_errno(dtp, EDT_NOTYPE));
   1788 
   1789 	return (0);
   1790 }
   1791 
   1792 int
   1793 dtrace_symbol_type(dtrace_hdl_t *dtp, const GElf_Sym *symp,
   1794     const dtrace_syminfo_t *sip, dtrace_typeinfo_t *tip)
   1795 {
   1796 	dt_module_t *dmp;
   1797 
   1798 	tip->dtt_object = NULL;
   1799 	tip->dtt_ctfp = NULL;
   1800 	tip->dtt_type = CTF_ERR;
   1801 	tip->dtt_flags = 0;
   1802 
   1803 	if ((dmp = dt_module_lookup_by_name(dtp, sip->dts_object)) == NULL)
   1804 		return (dt_set_errno(dtp, EDT_NOMOD));
   1805 
   1806 	if (symp->st_shndx == SHN_UNDEF && dmp->dm_extern != NULL) {
   1807 		dt_ident_t *idp =
   1808 		    dt_idhash_lookup(dmp->dm_extern, sip->dts_name);
   1809 
   1810 		if (idp == NULL)
   1811 			return (dt_set_errno(dtp, EDT_NOSYM));
   1812 
   1813 		tip->dtt_ctfp = idp->di_ctfp;
   1814 		tip->dtt_type = idp->di_type;
   1815 
   1816 	} else if (GELF_ST_TYPE(symp->st_info) != STT_FUNC) {
   1817 		if (dt_module_getctf(dtp, dmp) == NULL)
   1818 			return (-1); /* errno is set for us */
   1819 
   1820 		tip->dtt_ctfp = dmp->dm_ctfp;
   1821 		tip->dtt_type = ctf_lookup_by_symbol(dmp->dm_ctfp, sip->dts_id);
   1822 
   1823 		if (tip->dtt_type == CTF_ERR) {
   1824 			dtp->dt_ctferr = ctf_errno(tip->dtt_ctfp);
   1825 			return (dt_set_errno(dtp, EDT_CTF));
   1826 		}
   1827 
   1828 	} else {
   1829 		tip->dtt_ctfp = DT_FPTR_CTFP(dtp);
   1830 		tip->dtt_type = DT_FPTR_TYPE(dtp);
   1831 	}
   1832 
   1833 	tip->dtt_object = dmp->dm_name;
   1834 	return (0);
   1835 }
   1836 
   1837 static dtrace_objinfo_t *
   1838 dt_module_info(const dt_module_t *dmp, dtrace_objinfo_t *dto)
   1839 {
   1840 	dto->dto_name = dmp->dm_name;
   1841 	dto->dto_file = dmp->dm_file;
   1842 	dto->dto_id = dmp->dm_modid;
   1843 	dto->dto_flags = 0;
   1844 
   1845 	if (dmp->dm_flags & DT_DM_KERNEL)
   1846 		dto->dto_flags |= DTRACE_OBJ_F_KERNEL;
   1847 	if (dmp->dm_flags & DT_DM_PRIMARY)
   1848 		dto->dto_flags |= DTRACE_OBJ_F_PRIMARY;
   1849 
   1850 	dto->dto_text_va = dmp->dm_text_va;
   1851 	dto->dto_text_size = dmp->dm_text_size;
   1852 	dto->dto_data_va = dmp->dm_data_va;
   1853 	dto->dto_data_size = dmp->dm_data_size;
   1854 	dto->dto_bss_va = dmp->dm_bss_va;
   1855 	dto->dto_bss_size = dmp->dm_bss_size;
   1856 
   1857 	return (dto);
   1858 }
   1859 
   1860 int
   1861 dtrace_object_iter(dtrace_hdl_t *dtp, dtrace_obj_f *func, void *data)
   1862 {
   1863 	const dt_module_t *dmp = dt_list_next(&dtp->dt_modlist);
   1864 	dtrace_objinfo_t dto;
   1865 	int rv;
   1866 
   1867 	for (; dmp != NULL; dmp = dt_list_next(dmp)) {
   1868 		if ((rv = (*func)(dtp, dt_module_info(dmp, &dto), data)) != 0)
   1869 			return (rv);
   1870 	}
   1871 
   1872 	return (0);
   1873 }
   1874 
   1875 int
   1876 dtrace_object_info(dtrace_hdl_t *dtp, const char *object, dtrace_objinfo_t *dto)
   1877 {
   1878 	dt_module_t *dmp;
   1879 
   1880 	if (object == DTRACE_OBJ_EVERY || object == DTRACE_OBJ_KMODS ||
   1881 	    object == DTRACE_OBJ_UMODS || dto == NULL)
   1882 		return (dt_set_errno(dtp, EINVAL));
   1883 
   1884 	if ((dmp = dt_module_from_object(dtp, object)) == NULL)
   1885 		return (-1); /* dt_errno is set for us */
   1886 
   1887 	if (dt_module_load(dtp, dmp) == -1)
   1888 		return (-1); /* dt_errno is set for us */
   1889 
   1890 	(void) dt_module_info(dmp, dto);
   1891 	return (0);
   1892 }
   1893