Example #1
0
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));
}
Example #2
0
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);
}
Example #3
0
/*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);
}
Example #4
0
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);
}