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)); } }
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])); }
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])); }
const char * conv_cap_val_sf1(Xword val, Half mach, Conv_fmt_flags_t fmt_flags, Conv_cap_val_sf1_buf_t *cap_val_sf1_buf) { if (val == 0) return (MSG_ORIG(MSG_GBL_ZERO)); if (conv_cap(val, cap_val_sf1_buf->buf, sizeof (cap_val_sf1_buf->buf), mach, fmt_flags, elfcap_sf1_to_str) == 0) return (conv_invalid_val(&cap_val_sf1_buf->inv_buf, val, 0)); return ((const char *)cap_val_sf1_buf->buf); }
const char * conv_sym_info_bind(uchar_t bind, int fmt_flags) { static char string[CONV_INV_STRSIZE]; static const Msg binds[] = { MSG_STB_LOCAL, MSG_STB_GLOBAL, MSG_STB_WEAK }; if (bind >= STB_NUM) return (conv_invalid_val(string, CONV_INV_STRSIZE, bind, fmt_flags)); else return (MSG_ORIG(binds[bind])); }
void Dbg_unused_lcinterface(Rt_map *nlmp, Rt_map *olmp, int tag) { const char *str; static char string[CONV_INV_STRSIZE]; if (DBG_NOTCLASS(DBG_C_UNUSED)) return; if (tag < CI_MAX) str = MSG_ORIG(tags[tag]); else str = conv_invalid_val(string, CONV_INV_STRSIZE, tag, 0); dbg_print(LIST(nlmp), MSG_INTL(MSG_USD_LCINTERFACE), NAME(nlmp), str, NAME(olmp)); }
void Dbg_util_lcinterface(Rt_map *lmp, int tag, char *val) { const char *str; static char string[CONV_INV_STRSIZE]; if (DBG_NOTDETAIL()) return; if (tag < CI_MAX) str = MSG_ORIG(tags[tag]); else str = conv_invalid_val(string, CONV_INV_STRSIZE, tag, 0); dbg_print(LIST(lmp), MSG_INTL(MSG_UTL_LCINTERFACE), NAME(lmp), str, EC_NATPTR(val)); }
const char * conv_cap_tag(Xword tag, Conv_fmt_flags_t fmt_flags, Conv_inv_buf_t *inv_buf) { #ifdef _ELF64 /* * Valid tags all fit in 32-bits, so a value larger than that * is garbage. conv_map_ds() sees 32-bit values, so test for garbage * here before passing it on. * * Since there are no valid tags with a value > 32-bits, there * is no reason to expend effort decoding the low order bits. */ if (tag & 0xffffffff00000000) return (conv_invalid_val(inv_buf, tag, fmt_flags)); #endif return (conv_map_ds(ELFOSABI_NONE, EM_NONE, tag, conv_cap_tag_strings(fmt_flags), fmt_flags, inv_buf)); }
/* * Generic front-end that determines machine specific relocations. */ const char * conv_reloc_type(Half mach, Word type, Conv_fmt_flags_t fmt_flags, Conv_inv_buf_t *inv_buf) { switch (mach) { case EM_386: return (conv_reloc_386_type(type, fmt_flags, inv_buf)); case EM_SPARC: case EM_SPARC32PLUS: case EM_SPARCV9: return (conv_reloc_SPARC_type(type, fmt_flags, inv_buf)); case EM_AMD64: return (conv_reloc_amd64_type(type, fmt_flags, inv_buf)); } /* If didn't match a machine type, use integer value */ return (conv_invalid_val(inv_buf, type, fmt_flags)); }
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)); } }
const char * conv_cap_val(Xword tag, Xword val, Half mach, Conv_fmt_flags_t fmt_flags, Conv_cap_val_buf_t *cap_val_buf) { switch (tag) { case CA_SUNW_HW_1: return (conv_cap_val_hw1(val, mach, fmt_flags, &cap_val_buf->cap_val_hw1_buf)); case CA_SUNW_SF_1: return (conv_cap_val_sf1(val, mach, fmt_flags, &cap_val_buf->cap_val_sf1_buf)); case CA_SUNW_HW_2: return (conv_cap_val_hw2(val, mach, fmt_flags, &cap_val_buf->cap_val_hw2_buf)); default: return (conv_invalid_val(&cap_val_buf->inv_buf, val, 0)); } }
const char * conv_elfdata_type(Elf_Type type) { static char string[CONV_INV_STRSIZE]; static const Msg types[] = { MSG_DATA_BYTE, MSG_DATA_ADDR, MSG_DATA_DYN, MSG_DATA_EHDR, MSG_DATA_HALF, MSG_DATA_OFF, MSG_DATA_PHDR, MSG_DATA_RELA, MSG_DATA_REL, MSG_DATA_SHDR, MSG_DATA_SWORD, MSG_DATA_SYM, MSG_DATA_WORD, MSG_DATA_VDEF, MSG_DATA_VNEED, MSG_DATA_SXWORD, MSG_DATA_XWORD, MSG_DATA_SYMINFO, MSG_DATA_NOTE, MSG_DATA_MOVE, MSG_DATA_MOVEP, MSG_DATA_CAP }; if (type >= ELF_T_NUM) return (conv_invalid_val(string, CONV_INV_STRSIZE, type, 0)); else return (MSG_ORIG(types[type])); }
static int cef_cp(CONV_EXPN_FIELD_ARG *arg, CONV_EXPN_FIELD_STATE *state, int list_item, const char *str) { int n; if (list_item) { /* This is a list item */ /* * If list is non-empty, and the buffer has room, * then insert the separator. */ if (state->list_cnt != 0) { if (state->sep_str_len < state->room) { (void) memcpy(state->cur, state->sep_str, state->sep_str_len); state->cur += state->sep_str_len; state->room -= state->sep_str_len; } else { /* Ensure code below will catch lack of room */ state->room = 0; } } state->list_cnt++; } n = strlen(str); if (n < state->room) { (void) memcpy(state->cur, str, n); state->cur += n; state->room -= n; return (TRUE); } /* Buffer too small. Fill in the numeric value and report failure */ (void) conv_invalid_val(arg->buf, arg->bufsize, arg->oflags, 0); return (FALSE); }
/* * Provide a focal point for expanding bit-fields values into * their corresponding strings. * * entry: * arg - Specifies the operation to be carried out. See the * definition of CONV_EXPN_FIELD_ARG in conv.h for details. * * exit: * arg->buf contains the formatted result. True (1) is returned if there * was no error, and False (0) if the buffer was too small. In the failure * case, arg->buf contains a numeric representation of the value. */ int conv_expn_field(CONV_EXPN_FIELD_ARG *arg) { const Val_desc *vde; CONV_EXPN_FIELD_STATE state; Xword rflags = arg->rflags; const char **lead_str; /* Initialize buffer state */ state.cur = arg->buf; state.room = arg->bufsize; state.list_cnt = 0; state.sep_str = arg->sep ? arg->sep : MSG_ORIG(MSG_GBL_SEP); state.sep_str_len = strlen(state.sep_str); /* Prefix string */ if (!cef_cp(arg, &state, FALSE, (arg->prefix ? arg->prefix : MSG_ORIG(MSG_GBL_OSQBRKT)))) return (FALSE); /* Any strings in the lead_str array go at the head of the list */ lead_str = arg->lead_str; if (lead_str) { while (*lead_str) { if (!cef_cp(arg, &state, TRUE, *lead_str++)) return (FALSE); } } /* * Traverse the callers Val_desc array and determine if the value * corresponds to any array item and add those that are to the list. */ for (vde = arg->vdp; vde->v_msg; vde++) { if (arg->oflags & vde->v_val) { if (!cef_cp(arg, &state, TRUE, vde->v_msg)) return (FALSE); /* Indicate this item has been collected */ rflags &= ~(vde->v_val); } } /* * If any flags remain, then they are unidentified. Add the numeric * representation of these flags to the users output buffer. */ if (rflags) { char ibuf[CONV_INV_STRSIZE]; (void) conv_invalid_val(ibuf, sizeof (ibuf), rflags, 0); if (!cef_cp(arg, &state, TRUE, ibuf)) return (FALSE); } /* Suffix string */ if (!cef_cp(arg, &state, FALSE, (arg->suffix ? arg->suffix : MSG_ORIG(MSG_GBL_CSQBRKT)))) return (FALSE); /* Terminate the buffer */ *state.cur = '\0'; return (TRUE); }