/* * Format an input section descriptor name for output, in the format * [ndx]name * If possible, a user supplied fixed size buffer is used. Failing that, * dynamic memory is allocated, which must be freed by the caller. * * entry: * [dbg_fmt_isec_name2]: name, scnndx - Name and section index * [dbg_fmt_isec_name]: isp - Input section descriptor giving name * and index. * * buf - Caller supplied buffer * alloc_mem - Address of pointer to be set to address of allocated * memory, or NULL if no memory is allocated. * * exit: * A pointer to the formatted string is returned. If the supplied buffer * was sufficient, *alloc_mem is set to NULL. If memory was allocated, * *alloc_mem references it. The caller must free this memory after use. */ const char * dbg_fmt_isec_name2(const char *name, Word scnndx, dbg_isec_name_buf_t buf, char **alloc_mem) { int cnt; /* * If the section index is 0, it's not a real section. * Just use the name as is. */ if (scnndx == 0) { *alloc_mem = NULL; return (name); } /* Format into the fixed buffer */ cnt = snprintf(buf, sizeof (dbg_isec_name_buf_t), MSG_ORIG(MSG_FMT_ISEC_NAME), EC_WORD(scnndx), name); /* * If the name was too long, try to allocate a dynamic buffer. * Failing that, fall through and use the clipped one already * formatted into buf, as that's better than nothing. */ if ((cnt >= sizeof (dbg_isec_name_buf_t)) && ((*alloc_mem = malloc(cnt + 1)) != NULL)) { (void) snprintf(*alloc_mem, cnt + 1, MSG_ORIG(MSG_FMT_ISEC_NAME), EC_WORD(scnndx), name); return (*alloc_mem); } /* Return the caller supplied buffer */ *alloc_mem = NULL; return (buf); }
rd_err_e rd_event_addr(rd_agent_t *rap, rd_event_e num, rd_notify_t *np) { rd_err_e rc = RD_OK; RDAGLOCK(rap); switch (num) { case RD_NONE: break; case RD_PREINIT: np->type = RD_NOTIFY_BPT; np->u.bptaddr = rap->rd_preinit; break; case RD_POSTINIT: np->type = RD_NOTIFY_BPT; np->u.bptaddr = rap->rd_postinit; break; case RD_DLACTIVITY: np->type = RD_NOTIFY_BPT; np->u.bptaddr = rap->rd_dlact; break; default: LOG(ps_plog(MSG_ORIG(MSG_DB_UNEXPEVENT), num)); rc = RD_ERR; break; } if (rc == RD_OK) { LOG(ps_plog(MSG_ORIG(MSG_DB_RDEVENTADDR), num, EC_ADDR(np->u.bptaddr))); } RDAGUNLOCK(rap); return (rc); }
/* * If a mangled name has a __ * that is not at the very beginning * of the string, then this routine * is called to demangle that part * of the name. All overloaded functions, * and class members fall into this category. * * c should start with two underscores followed by a non-zero digit or an F. */ static char * second(char *c) { int n; if (strncmp(c, MSG_ORIG(MSG_STR_DBLUNDBAR), 2)) return (hold); c += 2; if (!(isdigit(*c) || *c == 'F')) return (hold); if (isdigit(*c)) { /* a member */ n = getint(&c); if (n == 0 || (int)strlen(c) < n) return (hold); s = prep_String(MSG_ORIG(MSG_STR_DBLCOL), s); s = nprep_String(c, s, n); c += n; } if (*c == 'F') { /* an overloaded function */ switch (*++c) { case '\0': return (hold); case 'v': s = app_String(s, MSG_ORIG(MSG_STR_OPENCLOSEPAR)); break; default: if (demangle_doargs(&s, c) < 0) return (hold); } } return (PTR(s)); }
const char * conv_dyn_posflag1(Xword flags, Conv_fmt_flags_t fmt_flags, Conv_dyn_posflag1_buf_t *dyn_posflag1_buf) { static CONV_EXPN_FIELD_ARG conv_arg = { NULL, sizeof (dyn_posflag1_buf->buf) }; static CONV_EXPN_FIELD_ARG conv_arg_alt = { NULL, sizeof (dyn_posflag1_buf->buf), NULL, 0, 0, MSG_ORIG(MSG_STR_EMPTY), NULL, MSG_ORIG(MSG_STR_EMPTY) }; CONV_EXPN_FIELD_ARG *arg; if (flags == 0) return (MSG_ORIG(MSG_GBL_ZERO)); CONV_XWORD_64TEST(flags, fmt_flags, &dyn_posflag1_buf->inv_buf); arg = (CONV_TYPE_FMT_ALT(fmt_flags) == CONV_FMT_ALT_DUMP) ? &conv_arg_alt : &conv_arg; arg->buf = dyn_posflag1_buf->buf; arg->oflags = arg->rflags = flags; (void) conv_expn_field(arg, conv_dyn_posflag1_strings(fmt_flags), fmt_flags); return ((const char *)dyn_posflag1_buf); }
void Dbg_audit_lib(Rt_map *clmp, const char *lib, int type) { Lm_list *clml = LIST(clmp); const char *str; if (DBG_NOTCLASS(DBG_C_AUDITING)) return; Dbg_util_nl(clml, DBG_NL_STD); switch (type) { case DBG_AUD_PRELOAD: str = MSG_ORIG(MSG_AUD_PRELOAD); break; case DBG_AUD_GLOBAL: str = MSG_ORIG(MSG_AUD_GLOBAL); break; case DBG_AUD_LOCAL: /* FALLTHROUGH */ default: str = MSG_ORIG(MSG_STR_EMPTY); } dbg_print(clml, MSG_INTL(MSG_AUD_LIB), lib, NAME(clmp), str); }
void Dbg_sec_group(Lm_list *lml, Is_desc *isp, Group_desc *gdp) { dbg_isec_name_buf_t buf; char *alloc_mem; const char *comdat, *isp_str; if (DBG_NOTCLASS(DBG_C_SECTIONS)) return; if (gdp->gd_data[0] & GRP_COMDAT) comdat = MSG_ORIG(MSG_STR_COMDAT); else comdat = MSG_ORIG(MSG_STR_EMPTY); isp_str = dbg_fmt_isec_name(isp, buf, &alloc_mem); if (isp->is_shdr->sh_type == SHT_GROUP) { dbg_print(lml, MSG_INTL(MSG_SEC_GRP_DEFINE), isp_str, isp->is_file->ifl_name, comdat, gdp->gd_name); } else { dbg_print(lml, MSG_INTL(MSG_SEC_GRP_MEMBER), isp_str, isp->is_file->ifl_name, comdat, gdp->gd_name); } if (gdp->gd_oisc) { dbg_print(lml, MSG_INTL(MSG_SEC_GRP_DISCARDED), isp_str, isp->is_file->ifl_name, gdp->gd_name, gdp->gd_oisc->is_file->ifl_name); } if (alloc_mem != NULL) free(alloc_mem); }
static int conv_cap(Xword val, char *str, size_t len, Half mach, Conv_fmt_flags_t fmt_flags, elfcap_to_str_func_t *fptr) { size_t _len; int do_bkt = (fmt_flags & CONV_FMT_NOBKT) == 0; /* * Note that for the purposes of this routine, I consider * CONV_FMT_NOBKT to mean no brackets, or anything that * is placed outside of them. We also drop the hex version * of the flags that are put in front of the opening bracket. */ if (do_bkt) { _len = sprintf(str, MSG_ORIG(MSG_GBL_OSQBRKT), EC_XWORD(val)); len -= _len; str += _len; } if ((*fptr)(ELFCAP_STYLE_UC, val, str, len, ELFCAP_FMT_SNGSPACE, mach) != 0) return (0); if (do_bkt) { _len = strlen(str); if ((len - _len) >= MSG_GBL_CSQBRKT_SIZE) { str += _len; (void) strcpy(str, MSG_ORIG(MSG_GBL_CSQBRKT)); } } return (1); }
void Dbg_util_edge_in(Lm_list *lml, Rt_map *clmp, uint_t flags, Rt_map *dlmp, int ndx, int flag) { const char *str; if (DBG_NOTCLASS(DBG_C_INIT)) return; if (DBG_NOTDETAIL()) return; if (flag & RT_SORT_REV) str = MSG_ORIG(MSG_SCN_INIT); else str = MSG_ORIG(MSG_SCN_FINI); if ((clmp == 0) || (ectoggle == 0)) Dbg_util_nl(lml, DBG_NL_STD); if (clmp == 0) { dbg_print(lml, MSG_INTL(MSG_UTL_EDGE_TITLE), str); dbg_print(lml, MSG_INTL(MSG_UTL_EDGE_START), ndx, NAME(dlmp)); } else dbg_print(lml, MSG_INTL(MSG_UTL_EDGE_IN), ndx, NAME(dlmp), NAME(clmp), conv_bnd_type(flags)); ectoggle = 1; }
char * rd_errstr(rd_err_e rderr) { /* * Convert an 'rd_err_e' to a string */ switch (rderr) { case RD_OK: return ((char *)MSG_ORIG(MSG_ER_OK)); case RD_ERR: return ((char *)MSG_ORIG(MSG_ER_ERR)); case RD_DBERR: return ((char *)MSG_ORIG(MSG_ER_DBERR)); case RD_NOCAPAB: return ((char *)MSG_ORIG(MSG_ER_NOCAPAB)); case RD_NODYNAM: return ((char *)MSG_ORIG(MSG_ER_NODYNAM)); case RD_NOBASE: return ((char *)MSG_ORIG(MSG_ER_NOBASE)); case RD_NOMAPS: return ((char *)MSG_ORIG(MSG_ER_NOMAPS)); default: return ((char *)MSG_ORIG(MSG_ER_DEFAULT)); } }
const char * conv_sym_shndx(Half shndx) { static char string[CONV_INV_STRSIZE]; switch (shndx) { case SHN_UNDEF: return (MSG_ORIG(MSG_SHN_UNDEF)); case SHN_SUNW_IGNORE: return (MSG_ORIG(MSG_SHN_SUNW_IGNORE)); case SHN_ABS: return (MSG_ORIG(MSG_SHN_ABS)); case SHN_COMMON: return (MSG_ORIG(MSG_SHN_COMMON)); case SHN_AMD64_LCOMMON: return (MSG_ORIG(MSG_SHN_AMD64_LCOMMON)); case SHN_AFTER: return (MSG_ORIG(MSG_SHN_AFTER)); case SHN_BEFORE: return (MSG_ORIG(MSG_SHN_BEFORE)); case SHN_XINDEX: return (MSG_ORIG(MSG_SHN_XINDEX)); default: return (conv_invalid_val(string, CONV_INV_STRSIZE, shndx, CONV_FMT_DECIMAL)); } }
void Dbg_unused_sec(Lm_list *lml, Is_desc *isp) { const char *str; if (DBG_NOTCLASS(DBG_C_UNUSED)) return; if (DBG_NOTDETAIL()) return; /* * If the file from which this section originates hasn't been referenced * at all, skip this diagnostic, as it would have been covered under * Dbg_unused_file() called from ignore_section_processing(). */ if (isp->is_file && ((isp->is_file->ifl_flags & FLG_IF_FILEREF) == 0)) return; if (isp->is_flags & FLG_IS_DISCARD) str = MSG_INTL(MSG_USD_SECDISCARD); else str = MSG_ORIG(MSG_STR_EMPTY); dbg_print(lml, MSG_INTL(MSG_USD_SEC), isp->is_basename, EC_XWORD(isp->is_shdr->sh_size), isp->is_file->ifl_name, str); }
rd_err_e rd_reset(struct rd_agent *rap) { rd_err_e err; RDAGLOCK(rap); rap->rd_flags = 0; #ifdef _LP64 /* * Determine if client is 32-bit or 64-bit. */ if (ps_pdmodel(rap->rd_psp, &rap->rd_dmodel) != PS_OK) { LOG(ps_plog(MSG_ORIG(MSG_DB_DMLOOKFAIL))); RDAGUNLOCK(rap); return (RD_DBERR); } if (rap->rd_dmodel == PR_MODEL_LP64) err = _rd_reset64(rap); else #endif err = _rd_reset32(rap); RDAGUNLOCK(rap); return (err); }
audit_symget(Audit_list * alp, int info) { Rt_map *_lmp, *lmp = alp->al_lmp; const char *sname = MSG_ORIG(aud_info[info].sname); uint_t alflag = aud_info[info].alflag; uint_t auflag = aud_info[info].auflag; uint_t binfo; Sym *sym; Slookup sl; sl.sl_name = sname; sl.sl_cmap = lml_rtld.lm_head; sl.sl_imap = lmp; sl.sl_hash = 0; sl.sl_rsymndx = 0; sl.sl_flags = LKUP_FIRST; if (sym = LM_LOOKUP_SYM(lmp)(&sl, &_lmp, &binfo)) { Addr addr = sym->st_value; if (!(FLAGS(lmp) & FLG_RT_FIXED)) addr += ADDR(lmp); if (alflag) alp->al_flags |= alflag; if (auflag) audit_flags |= auflag; DBG_CALL(Dbg_audit_interface(LIST(alp->al_lmp), alp->al_libname, sname)); return (addr); } else return (0); }
/*ARGSUSED*/ static void cpl_eltarg(elfedit_obj_state_t *obj_state, void *cpldata, int argc, const char *argv[], int num_opt) { Word i; /* -capid id_name */ if (argc <= num_opt) { cpl_capid_opt(obj_state, cpldata, argc, argv, num_opt); return; } /* Make sure it's the first argument */ if ((argc - num_opt) != 1) return; /* Is -capndx present? If so, we don't complete tag types */ for (i = 0; i < num_opt; i++) if (strcmp(argv[i], MSG_ORIG(MSG_STR_MINUS_CAPNDX)) == 0) return; /* * Supply capability tag names. There are very few of these, so * rather than worry about whether a given tag exists in the * file or not, we simply serve up all the possibilities. */ elfedit_cpl_atoconst(cpldata, ELFEDIT_CONST_CA); }
/* * -capid command completion: Supply all CA_SUNW_ID names found in the object. */ static void cpl_capid_opt(elfedit_obj_state_t *obj_state, void *cpldata, int argc, const char *argv[], int num_opt) { elfedit_section_t *cap_sec, *str_sec; Cap *cap; Word num; if (obj_state == NULL) /* No object available */ return; if ((argc > num_opt) || (argc < 2) || (strcmp(argv[argc - 2], MSG_ORIG(MSG_STR_MINUS_CAPID)) != 0)) return; cap_sec = elfedit_sec_getcap(obj_state, &cap, &num); /* If no associated string table, we have no strings to complete */ if (cap_sec->sec_shdr->sh_info == 0) return; str_sec = elfedit_sec_getstr(obj_state, cap_sec->sec_shdr->sh_info, 0); for (; num--; cap++) if (cap->c_tag == CA_SUNW_ID) elfedit_cpl_match(cpldata, elfedit_offset_to_str( str_sec, cap->c_un.c_val, ELFEDIT_MSG_ERR, 0), 0); }
void rd_log(const int on_off) { (void) mutex_lock(&glob_mutex); rtld_db_logging = on_off; (void) mutex_unlock(&glob_mutex); LOG(ps_plog(MSG_ORIG(MSG_DB_LOGENABLE))); }
const char * conv_reloc_amd64_type(Word type, Conv_fmt_flags_t fmt_flags, Conv_inv_buf_t *inv_buf) { if (type >= R_AMD64_NUM) return (conv_invalid_val(inv_buf, type, fmt_flags)); return (MSG_ORIG(rels[type])); }
/* * Variant of Elf_dyn_entry() specifically for DT_NULL. Handles the * case of multiple adjacent DT_NULL entries by displaying them on * a single line using an index range instead of a single index. */ void Elf_dyn_null_entry(Lm_list *lml, Dyn *dyn, int start_ndx, int end_ndx) { Conv_inv_buf_t inv_buf; char index[2 * INDEX_STR_SIZE]; if (start_ndx == end_ndx) { Elf_dyn_entry(lml, dyn, start_ndx, MSG_ORIG(MSG_STR_EMPTY), ELFOSABI_NONE, 0); } else { (void) snprintf(index, sizeof (index), MSG_ORIG(MSG_FMT_INDEX_RANGE), start_ndx, end_ndx); dbg_print(lml, MSG_INTL(MSG_DYN_ENTRY), index, conv_dyn_tag(DT_NULL, ELFOSABI_NONE, 0, 0, &inv_buf), EC_XWORD(dyn->d_un.d_val), MSG_ORIG(MSG_STR_EMPTY)); } }
void Elf_got_entry(Lm_list *lml, Sword ndx, Addr addr, Xword value, Half mach, uchar_t ei_target_data, uchar_t ei_host_data, Word type, void *reloc, const char *name) { Rela *rela; Rel *rel; const char *str; Conv_inv_buf_t inv_buf; char index[INDEX_STR_SIZE]; (void) snprintf(index, INDEX_STR_SIZE, MSG_ORIG(MSG_GOT_INDEX), EC_SWORD(ndx)); /* * Got sections are SHT_PROGBITS, and are therefore not xlated by * libelf. If the target system has a different byte order than * the system displaying the data, swap the bytes so they are * presented properly. */ if (ei_target_data != ei_host_data) value = BSWAP_XWORD(value); if (reloc) { if (type == SHT_RELA) { rela = (Rela *)reloc; str = conv_reloc_type(mach, ELF_R_TYPE(rela->r_info, mach), 0, &inv_buf); } else { rel = (Rel *)reloc; str = conv_reloc_type(mach, ELF_R_TYPE(rel->r_info, mach), 0, &inv_buf); } if (name) name = Elf_demangle_name(name); else name = MSG_ORIG(MSG_STR_EMPTY); dbg_print(lml, MSG_INTL(MSG_GOT_ENTRY_RE), index, EC_ADDR(addr), EC_XWORD(value), str, name); } else dbg_print(lml, MSG_INTL(MSG_GOT_ENTRY_NR), index, EC_ADDR(addr), EC_XWORD(value)); }
void Dbg_util_str(Lm_list *lml, const char *str) { Dbg_util_nl(lml, DBG_NL_STD); Dbg_util_nl(lml, DBG_NL_FRC); dbg_print(lml, MSG_ORIG(MSG_FMT_STR), str); Dbg_util_nl(lml, DBG_NL_FRC); Dbg_util_nl(lml, DBG_NL_STD); }
void Dbg_util_scc_entry(Rt_map *lmp, uint_t idx) { if (DBG_NOTCLASS(DBG_C_INIT)) return; if (DBG_NOTDETAIL()) return; dbg_print(LIST(lmp), MSG_ORIG(MSG_UTL_SCC_ENTRY), idx, NAME(lmp)); }
void rd_delete(rd_agent_t *rap) { LOG(ps_plog(MSG_ORIG(MSG_DB_RDDELETE), rap)); if (rap->rd_helper.rh_dlhandle != NULL) { rap->rd_helper.rh_ops->rho_fini(rap->rd_helper.rh_data); (void) dlclose(rap->rd_helper.rh_dlhandle); } free(rap); }
void Dbg_util_call_array(Rt_map *lmp, void *addr, int ndx, Word shtype) { Lm_list *lml = LIST(lmp); const char *str; if (DBG_NOTCLASS(DBG_C_INIT)) return; if (shtype == SHT_INIT_ARRAY) str = MSG_ORIG(MSG_SCN_INITARRAY); else if (shtype == SHT_FINI_ARRAY) str = MSG_ORIG(MSG_SCN_FINIARRAY); else str = MSG_ORIG(MSG_SCN_PREINITARRAY); dbg_print(lml, MSG_INTL(MSG_UTL_ARRAY), str, ndx, EC_NATPTR(addr), NAME(lmp)); }
int elf_copy_gen(Rt_map *lmp) { if (interp && ((ulong_t)interp->i_faddr != r_debug.rtd_rdebug.r_ldbase) && !(strcmp(interp->i_name, MSG_ORIG(MSG_PTH_LIBC)))) { DBG_CALL(Dbg_reloc_run(lmp, M_REL_SHT_TYPE, 0, DBG_REL_START)); if (_elf_copy_reloc(MSG_ORIG(MSG_SYM_CTYPE), lmp, (Rt_map *)NEXT(lmp)) == 0) return (0); if (_elf_copy_reloc(MSG_ORIG(MSG_SYM_IOB), lmp, (Rt_map *)NEXT(lmp)) == 0) return (0); } return (1); }
/* * Given an integer value, generate an ASCII representation of it. * * entry: * string - Buffer into which the resulting string is generated. * size - Size of string buffer (i.e. sizeof(string)) * value - Value to be formatted. * fmt_flags - CONV_FMT_* values, used to specify formatting details. * * exit: * The formatted string, or as much as will fit, is placed into * string. String is returned. */ const char * conv_invalid_val(char *string, size_t size, Xword value, int fmt_flags) { const char *fmt; if (fmt_flags & CONV_FMT_DECIMAL) { if (fmt_flags & CONV_FMT_SPACE) fmt = MSG_ORIG(MSG_GBL_FMT_DECS); else fmt = MSG_ORIG(MSG_GBL_FMT_DEC); } else { if (fmt_flags & CONV_FMT_SPACE) fmt = MSG_ORIG(MSG_GBL_FMT_HEXS); else fmt = MSG_ORIG(MSG_GBL_FMT_HEX); } (void) snprintf(string, size, fmt, value); return ((const char *)string); }
const char * conv_reloc_amd64_type(Word type, int fmt_flags) { static char string[CONV_INV_STRSIZE]; if (type >= R_AMD64_NUM) return (conv_invalid_val(string, CONV_INV_STRSIZE, type, fmt_flags)); return (MSG_ORIG(rels[type])); }
/* * Generic new line generator. To prevent multiple newlines from being * generated, a flag is maintained in the global debug descriptor. This flag * is cleared by the callers dbg_print() function to indicate that a newline * (actually, any line) has been printed. Multiple newlines can be generated * using the DBG_NL_FRC flag. */ void Dbg_util_nl(Lm_list *lml, int flag) { if ((flag == DBG_NL_STD) && (dbg_desc->d_extra & DBG_E_STDNL)) return; dbg_print(lml, MSG_ORIG(MSG_STR_EMPTY)); if (flag == DBG_NL_STD) dbg_desc->d_extra |= DBG_E_STDNL; }
void Dbg_sec_strtab(Lm_list *lml, Os_desc *osp, Str_tbl *stp) { uint_t cnt; if (DBG_NOTCLASS(DBG_C_STRTAB)) return; if (!osp) return; Dbg_util_nl(lml, DBG_NL_STD); if (stp->st_flags & FLG_STTAB_COMPRESS) dbg_print(lml, MSG_INTL(MSG_SEC_STRTAB_COMP), osp->os_name, EC_XWORD(stp->st_fullstrsize), EC_XWORD(stp->st_strsize)); else dbg_print(lml, MSG_INTL(MSG_SEC_STRTAB_STND), osp->os_name, EC_XWORD(stp->st_fullstrsize)); if ((DBG_NOTDETAIL()) || ((stp->st_flags & FLG_STTAB_COMPRESS) == 0)) return; dbg_print(lml, MSG_ORIG(MSG_STR_EMPTY)); dbg_print(lml, MSG_INTL(MSG_SEC_STRTAB_HD), osp->os_name, stp->st_hbckcnt); for (cnt = 0; cnt < stp->st_hbckcnt; cnt++) { Str_hash *strhash = stp->st_hashbcks[cnt]; if (strhash == NULL) continue; dbg_print(lml, MSG_INTL(MSG_SEC_STRTAB_BCKT), cnt); while (strhash) { size_t stroff = strhash->hi_mstr->sm_strlen - strhash->hi_strlen; if (stroff == 0) { dbg_print(lml, MSG_INTL(MSG_SEC_STRTAB_MSTR), EC_XWORD(strhash->hi_refcnt), strhash->hi_mstr->sm_str); } else { dbg_print(lml, MSG_INTL(MSG_SEC_STRTAB_SUFSTR), EC_XWORD(strhash->hi_refcnt), &strhash->hi_mstr->sm_str[stroff], strhash->hi_mstr->sm_str); } strhash = strhash->hi_next; } } }
/* * Versioning Notes. * * The following have been added as the versions of librtld_db * have grown: * * RD_VERSION1: * o baseline version * * RD_VERSION2: * o added support for the use of the AT_SUN_LDBASE auxvector * to find the initialial debugging (r_debug) structures * in ld.so.1 * o added the rl_dynamic field to rd_loadobj_t * o added the RD_FLG_MEM_OBJECT to be used with the * rl_dynamic->rl_flags field. * * RD_VERSION3: * o added the following fields/flags to the rd_plt_info_t * type: * pi_baddr - bound address of PLT (if bound) * pi_flags - flag field * RD_FLG_PI_PLTBOUND (flag for pi_flags) * if set - the PLT is bound and pi_baddr * is filled in with the destination of the PLT. * * RD_VERSION4: * o added the following field to the rd_loadobj_t structure: * rl_tlsmodid - module ID for TLS references */ rd_err_e rd_init(int version) { if ((version < RD_VERSION1) || (version > RD_VERSION)) return (RD_NOCAPAB); rtld_db_version = version; LOG(ps_plog(MSG_ORIG(MSG_DB_RDINIT), rtld_db_version)); return (RD_OK); }
const char * conv_sym_info_type(Half mach, uchar_t type, int fmt_flags) { static char string[CONV_INV_STRSIZE]; static const Msg types[] = { MSG_STT_NOTYPE, MSG_STT_OBJECT, MSG_STT_FUNC, MSG_STT_SECTION, MSG_STT_FILE, MSG_STT_COMMON, MSG_STT_TLS }; if (type < STT_NUM) { return (MSG_ORIG(types[type])); } else if (((mach == EM_SPARC) || (mach == EM_SPARC32PLUS) || (mach == EM_SPARCV9)) && (type == STT_SPARC_REGISTER)) { return (MSG_ORIG(MSG_STT_REGISTER)); } else { return (conv_invalid_val(string, CONV_INV_STRSIZE, type, fmt_flags)); } }