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); }
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_move_expand(Lm_list *lml, Move *mv, Addr addr) { if (DBG_NOTCLASS(DBG_C_MOVE)) return; if (DBG_NOTDETAIL()) return; dbg_print(lml, MSG_INTL(MSG_MOVE_EXPAND), EC_ADDR(addr), EC_LWORD(mv->m_value)); }
const char * conv_sym_value(Half mach, uchar_t type, Addr value) { static char string[CONV_INV_STRSIZE]; if (((mach == EM_SPARC) || (mach == EM_SPARC32PLUS) || (mach == EM_SPARCV9)) && (type == STT_SPARC_REGISTER)) return (conv_sym_SPARC_value(value, 0)); (void) sprintf(string, MSG_ORIG(MSG_SYM_FMT_VAL), EC_ADDR(value)); return (string); }
/* * -p flag specified */ static void print_with_pflag( int ndigits, Elf *elf_file, unsigned int shstrndx, SYM *sym_data, char *filename ) { const char * const fmt[] = { "%.*llu ", /* FMT_T_DEC */ "0x%.*llx ", /* FMT_T_HEX */ "0%.*llo " /* FMT_T_OCT */ }; if (is_sym_print(sym_data) != 1) return; /* * -A header */ if (A_flag != 0) (void) printf("%s", A_header); /* * Symbol Value. * (hex/octal/decimal) */ (void) printf(fmt[fmt_flag], ndigits, EC_ADDR(sym_data->value)); /* * Symbol Type. */ print_brief_sym_type(elf_file, shstrndx, sym_data); if (!r_flag) { if (R_flag) { if (archive_name != (char *)0) (void) printf("%s:%s:%s\n", archive_name, filename, sym_data->name); else (void) printf("%s:%s\n", filename, sym_data->name); } else (void) printf("%s\n", sym_data->name); } else (void) printf("%s:%s\n", filename, sym_data->name); }
/* * -P flag specified */ static void print_with_Pflag( int ndigits, Elf *elf_file, unsigned int shstrndx, SYM *sym_data ) { #define SYM_LEN 10 char sym_name[SYM_LEN+1]; size_t len; const char * const fmt[] = { "%*llu %*llu \n", /* FMT_T_DEC */ "%*llx %*llx \n", /* FMT_T_HEX */ "%*llo %*llo \n" /* FMT_T_OCT */ }; if (is_sym_print(sym_data) != 1) return; /* * -A header */ if (A_flag != 0) (void) printf("%s", A_header); /* * Symbol name */ len = strlen(sym_data->name); if (len >= SYM_LEN) (void) printf("%s ", sym_data->name); else { (void) sprintf(sym_name, "%-10s", sym_data->name); (void) printf("%s ", sym_name); } /* * Symbol Type. */ print_brief_sym_type(elf_file, shstrndx, sym_data); /* * Symbol Value & size * (hex/octal/decimal) */ (void) printf(fmt[fmt_flag], ndigits, EC_ADDR(sym_data->value), ndigits, EC_XWORD(sym_data->size)); }
/* * Warning message for bad move target. */ void elf_move_bad(Lm_list *lml, Rt_map *lmp, Sym *sym, ulong_t num, Addr addr) { const char *name; int trace; trace = (lml->lm_flags & LML_FLG_TRC_ENABLE) && (((rtld_flags & RT_FL_SILENCERR) == 0) || (lml->lm_flags & (LML_FLG_TRC_VERBOSE | LML_FLG_TRC_WARN))); if ((trace == 0) && (DBG_ENABLED == 0)) return; if (ELF_ST_BIND(sym->st_info) != STB_LOCAL) name = (const char *)(STRTAB(lmp) + sym->st_name); else name = MSG_INTL(MSG_STR_UNKNOWN); if (trace) (void) printf(MSG_INTL(MSG_LDD_MOVE_ERR), EC_XWORD(num), name, EC_ADDR(addr)); else DBG_CALL(Dbg_move_bad(lml, num, name, addr)); }
/* * other flags specified */ static void print_with_otherflags( int ndigits, Elf *elf_file, unsigned int shstrndx, SYM *sym_data, char *filename ) { const char * const fmt_value_size[] = { "%*llu|%*lld|", /* FMT_T_DEC */ "0x%.*llx|0x%.*llx|", /* FMT_T_HEX */ "0%.*llo|0%.*llo|" /* FMT_T_OCT */ }; const char * const fmt_int[] = { "%-5d", /* FMT_T_DEC */ "%#-5x", /* FMT_T_HEX */ "%#-5o" /* FMT_T_OCT */ }; if (is_sym_print(sym_data) != 1) return; (void) printf("%s", A_header); (void) printf("[%d]\t|", sym_data->indx); (void) printf(fmt_value_size[fmt_flag], ndigits, EC_ADDR(sym_data->value), ndigits, EC_XWORD(sym_data->size)); switch (sym_data->type) { case STT_NOTYPE:(void) printf("%-5s", "NOTY"); break; case STT_OBJECT:(void) printf("%-5s", "OBJT"); break; case STT_FUNC: (void) printf("%-5s", "FUNC"); break; case STT_SECTION:(void) printf("%-5s", "SECT"); break; case STT_FILE: (void) printf("%-5s", "FILE"); break; case STT_COMMON: (void) printf("%-5s", "COMM"); break; case STT_TLS: (void) printf("%-5s", "TLS "); break; case STT_SPARC_REGISTER: (void) printf("%-5s", "REGI"); break; default: (void) printf(fmt_int[fmt_flag], sym_data->type); } (void) printf("|"); switch (sym_data->bind) { case STB_LOCAL: (void) printf("%-5s", "LOCL"); break; case STB_GLOBAL:(void) printf("%-5s", "GLOB"); break; case STB_WEAK: (void) printf("%-5s", "WEAK"); break; default: (void) printf("%-5d", sym_data->bind); (void) printf(fmt_int[fmt_flag], sym_data->bind); } (void) printf("|"); (void) printf(fmt_int[fmt_flag], sym_data->other); (void) printf("|"); if (sym_data->shndx == SHN_UNDEF) { if (!s_flag) (void) printf("%-7s", "UNDEF"); else (void) printf("%-14s", "UNDEF"); } else if (sym_data->shndx == SHN_SUNW_IGNORE) { if (!s_flag) (void) printf("%-7s", "IGNORE"); else (void) printf("%-14s", "IGNORE"); } else if ((sym_data->flags & FLG_SYM_SPECSEC) && (sym_data->shndx == SHN_ABS)) { if (!s_flag) (void) printf("%-7s", "ABS"); else (void) printf("%-14s", "ABS"); } else if ((sym_data->flags & FLG_SYM_SPECSEC) && (sym_data->shndx == SHN_COMMON)) { if (!s_flag) (void) printf("%-7s", "COMMON"); else (void) printf("%-14s", "COMMON"); } else { if (s_flag) { Elf_Scn *scn = elf_getscn(elf_file, sym_data->shndx); GElf_Shdr shdr; if ((gelf_getshdr(scn, &shdr) != 0) && (shdr.sh_name != 0)) { (void) printf("%-14s", (char *)elf_strptr(elf_file, shstrndx, shdr.sh_name)); } else { (void) printf("%-14d", sym_data->shndx); } } else { (void) printf("%-7d", sym_data->shndx); } } (void) printf("|"); if (!r_flag) { if (R_flag) { if (archive_name != (char *)0) (void) printf("%s:%s:%s\n", archive_name, filename, sym_data->name); else (void) printf("%s:%s\n", filename, sym_data->name); } else (void) printf("%s\n", sym_data->name); } else (void) printf("%s:%s\n", filename, sym_data->name); }
/* ARGSUSED 3 */ rd_err_e plt64_resolution(rd_agent_t *rap, psaddr_t pc, lwpid_t lwpid, psaddr_t pltbase, rd_plt_info_t *rpi) { uint32_t pcrel; psaddr_t destaddr; psaddr_t pltoff, pltaddr; if (rtld_db_version >= RD_VERSION3) { rpi->pi_flags = 0; rpi->pi_baddr = 0; } pltoff = pc - pltbase; pltaddr = pltbase + ((pltoff / M_PLT_ENTSIZE) * M_PLT_ENTSIZE); /* * This is the target of the jmp instruction */ if (ps_pread(rap->rd_psp, pltaddr + 2, (char *)&pcrel, sizeof (pcrel)) != PS_OK) { LOG(ps_plog(MSG_ORIG(MSG_DB_READFAIL_2), EC_ADDR(pltaddr + 2))); return (RD_ERR); } /* * the offset to the GOT table entry is * PC-relative. */ destaddr = pcrel + pltaddr + 6; /* * Find out what's pointed to by @OFFSET_INTO_GOT */ if (ps_pread(rap->rd_psp, destaddr, (char *)&destaddr, sizeof (destaddr)) != PS_OK) { LOG(ps_plog(MSG_ORIG(MSG_DB_READFAIL_2), EC_ADDR(destaddr))); return (RD_ERR); } if (destaddr == (pltaddr + 6)) { rd_err_e rerr; /* * If GOT[ind] points to PLT+6 then this is the first * time through this PLT. */ if ((rerr = rd_binder_exit_addr(rap, MSG_ORIG(MSG_SYM_RTBIND), &(rpi->pi_target))) != RD_OK) { return (rerr); } rpi->pi_skip_method = RD_RESOLVE_TARGET_STEP; rpi->pi_nstep = 1; } else { /* * This is the n'th time through and GOT[ind] points * to the final destination. */ rpi->pi_skip_method = RD_RESOLVE_STEP; rpi->pi_nstep = 1; rpi->pi_target = 0; if (rtld_db_version >= RD_VERSION3) { rpi->pi_flags |= RD_FLG_PI_PLTBOUND; rpi->pi_baddr = destaddr; } } return (RD_OK); }