int kt_lookup_by_name(mdb_tgt_t *t, const char *obj, const char *name, GElf_Sym *symp, mdb_syminfo_t *sip) { kt_data_t *kt = t->t_data; kt_module_t *km, kmod; mdb_var_t *v; int n; /* * To simplify the implementation, we create a fake module on the stack * which is "prepended" to k_modlist and whose symtab is kt->k_symtab. */ kmod.km_symtab = kt->k_symtab; kmod.km_list.ml_next = mdb_list_next(&kt->k_modlist); switch ((uintptr_t)obj) { case (uintptr_t)MDB_TGT_OBJ_EXEC: km = &kmod; n = 1; break; case (uintptr_t)MDB_TGT_OBJ_EVERY: km = &kmod; n = mdb_nv_size(&kt->k_modules) + 1; break; case (uintptr_t)MDB_TGT_OBJ_RTLD: obj = KT_RTLD_NAME; /*FALLTHRU*/ default: if ((v = mdb_nv_lookup(&kt->k_modules, obj)) == NULL) return (set_errno(EMDB_NOOBJ)); km = mdb_nv_get_cookie(v); n = 1; if (km->km_symtab == NULL) kt_load_module(kt, t, km); } for (; n > 0; n--, km = mdb_list_next(km)) { if (mdb_gelf_symtab_lookup_by_name(km->km_symtab, name, symp, &sip->sym_id) == 0) { sip->sym_table = MDB_TGT_SYMTAB; return (0); } } return (set_errno(EMDB_NOSYM)); }
int cmd_nmadd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) { uintptr_t opt_e = 0, opt_s = 0; uint_t opt_f = FALSE, opt_o = FALSE; GElf_Sym sym; int i; if (!(flags & DCMD_ADDRSPEC)) return (DCMD_USAGE); i = mdb_getopts(argc, argv, 'f', MDB_OPT_SETBITS, TRUE, &opt_f, 'o', MDB_OPT_SETBITS, TRUE, &opt_o, 'e', MDB_OPT_UINTPTR, &opt_e, 's', MDB_OPT_UINTPTR, &opt_s, NULL); if (i != (argc - 1) || argv[i].a_type != MDB_TYPE_STRING || argv[i].a_un.a_str[0] == '-' || argv[i].a_un.a_str[0] == '+') return (DCMD_USAGE); if (opt_e && opt_e < addr) { mdb_warn("end (%p) is less than start address (%p)\n", (void *)opt_e, (void *)addr); return (DCMD_USAGE); } if (mdb_gelf_symtab_lookup_by_name(mdb.m_prsym, argv[i].a_un.a_str, &sym, NULL) == -1) { bzero(&sym, sizeof (sym)); sym.st_info = GELF_ST_INFO(STB_GLOBAL, STT_NOTYPE); } if (opt_f) sym.st_info = GELF_ST_INFO(STB_GLOBAL, STT_FUNC); if (opt_o) sym.st_info = GELF_ST_INFO(STB_GLOBAL, STT_OBJECT); if (opt_e) sym.st_size = (GElf_Xword)(opt_e - addr); if (opt_s) sym.st_size = (GElf_Xword)(opt_s); sym.st_value = (GElf_Addr)addr; mdb_gelf_symtab_insert(mdb.m_prsym, argv[i].a_un.a_str, &sym); mdb_iob_printf(mdb.m_out, "added %s, value=%llr size=%llr\n", argv[i].a_un.a_str, sym.st_value, sym.st_size); return (DCMD_OK); }
/*ARGSUSED*/ int cmd_nmdel(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) { const char *name; GElf_Sym sym; uint_t id; if (argc != 1 || argv->a_type != MDB_TYPE_STRING || argv->a_un.a_str[0] == '-' || (flags & DCMD_ADDRSPEC)) return (DCMD_USAGE); name = argv->a_un.a_str; if (mdb_gelf_symtab_lookup_by_name(mdb.m_prsym, name, &sym, &id) == 0) { mdb_gelf_symtab_delete(mdb.m_prsym, name, &sym); mdb_printf("deleted %s, value=%llr size=%llr\n", name, sym.st_value, sym.st_size); return (DCMD_OK); } mdb_warn("symbol '%s' not found in private symbol table\n", name); return (DCMD_ERR); }
static int kp_lookup_by_name(mdb_tgt_t *t, const char *object, const char *name, GElf_Sym *symp, mdb_syminfo_t *sip) { kp_data_t *kp = t->t_data; kp_file_t *kpf; int n; GElf_Sym sym; uint_t symid; int rv = -1; /* * Simplify our task: if object is EVERY, then we need to search * kp_num_files files beginning at kp_file_head; otherwise we are * searching 1 file whose file pointer is obtained via object_to_map. */ if (object != MDB_TGT_OBJ_EVERY) { kp_map_t *kpm = kp_name_to_kpmap(kp, object); if (kpm == NULL || kpm->kpm_file == NULL) return (set_errno(EMDB_NOOBJ)); kpf = kpm->kpm_file; n = 1; } else { kpf = kp->kp_file_head; n = kp->kp_num_files; } /* * Iterate through the load object files and look for the symbol name * in the .dynsym of each. If we encounter a match with SHN_UNDEF, * keep looking in hopes of finding a better match. This means that * a name such as "puts" will match the puts function in libc instead * of matching the puts PLT entry in the a.out file. */ for (; n > 0; n--, kpf = kpf->kpf_next) { if (kpf->kpf_dynsym == NULL) continue; /* No symbols for this file */ if (mdb_gelf_symtab_lookup_by_name(kpf->kpf_dynsym, name, symp, &sip->sym_id) != 0) continue; /* Symbol name not found */ symp->st_value += kpf->kpf_dyn_base; if (symp->st_shndx != SHN_UNDEF) { sip->sym_table = MDB_TGT_DYNSYM; return (0); } if (rv != 0) { sym = *symp; symid = sip->sym_id; rv = 0; } } if (rv != 0) return (set_errno(EMDB_NOSYM)); sip->sym_table = MDB_TGT_DYNSYM; sip->sym_id = symid; *symp = sym; return (0); }