static uint_t dt_module_syminit32(dt_module_t *dmp) { const Elf32_Sym *sym = dmp->dm_symtab.cts_data; const char *base = dmp->dm_strtab.cts_data; size_t ss_size = dmp->dm_strtab.cts_size; uint_t i, n = dmp->dm_nsymelems; uint_t asrsv = 0; for (i = 0; i < n; i++, sym++) { const char *name = base + sym->st_name; uchar_t type = ELF32_ST_TYPE(sym->st_info); if (type >= STT_NUM || type == STT_SECTION) continue; /* skip sections and unknown types */ if (sym->st_name == 0 || sym->st_name >= ss_size) continue; /* skip null or invalid names */ if (sym->st_value != 0 && (ELF32_ST_BIND(sym->st_info) != STB_LOCAL || sym->st_size)) asrsv++; /* reserve space in the address map */ dt_module_symhash_insert(dmp, name, i); } return (asrsv); }
static uint_t dt_module_syminit_macho_64(dt_module_t *dmp) { const struct nlist_64 *sym = (const struct nlist_64 *)(dmp->dm_symtab.cts_data); const char *base = (const char *)dmp->dm_strtab.cts_data; uint_t i, n = dmp->dm_nsymelems; uint_t asrsv = 0; for (i = 0; i < n; i++, sym++) { const char *name = base + sym->n_un.n_strx; uchar_t type = sym->n_type & (N_TYPE | N_EXT); // Check that the symbol is a global and that it has a name. if (((N_SECT | N_EXT) != type && (N_ABS | N_EXT) != type)) continue; if (STT_FUNC != sym->n_desc && STT_OBJECT != sym->n_desc) continue; if (0 == sym->n_un.n_strx) // iff a null, "", name. continue; if ('_' == name[0]) name++; // Lop off omnipresent underscore to match DWARF convention if (sym->n_value != 0) asrsv++; /* reserve space in the address map */ dt_module_symhash_insert(dmp, name, i); } return (asrsv); }
static uint_t dt_module_syminit32(dt_module_t *dmp) { #if STT_NUM != (STT_TLS + 1) #error "STT_NUM has grown. update dt_module_syminit32()" #endif Elf32_Sym *sym = dmp->dm_symtab.cts_data; const char *base = dmp->dm_strtab.cts_data; size_t ss_size = dmp->dm_strtab.cts_size; uint_t i, n = dmp->dm_nsymelems; uint_t asrsv = 0; #if defined(__FreeBSD__) GElf_Ehdr ehdr; int is_elf_obj; gelf_getehdr(dmp->dm_elf, &ehdr); is_elf_obj = (ehdr.e_type == ET_REL); #endif for (i = 0; i < n; i++, sym++) { const char *name = base + sym->st_name; uchar_t type = ELF32_ST_TYPE(sym->st_info); if (type >= STT_NUM || type == STT_SECTION) continue; /* skip sections and unknown types */ if (sym->st_name == 0 || sym->st_name >= ss_size) continue; /* skip null or invalid names */ if (sym->st_value != 0 && (ELF32_ST_BIND(sym->st_info) != STB_LOCAL || sym->st_size)) { asrsv++; /* reserve space in the address map */ #if defined(__FreeBSD__) sym->st_value += (Elf_Addr) dmp->dm_reloc_offset; if (is_elf_obj && sym->st_shndx != SHN_UNDEF && sym->st_shndx < ehdr.e_shnum) sym->st_value += dmp->dm_sec_offsets[sym->st_shndx]; #endif } dt_module_symhash_insert(dmp, name, i); } return (asrsv); }