Exemplo n.º 1
0
bool
db_value_of_name(const char *name, db_expr_t *valuep)
{
	char symbol[128];
	char *mod, *sym;
#ifdef _KERNEL
	unsigned long uval;
	long val;
#endif

#ifndef _KERNEL
	if (!use_ksyms) {
		db_sym_t ssym;

		/*
		 * Cannot load symtabs in a.out kernels, so the ':'
		 * style of selecting modules is irrelevant.
		 */
		ssym = (*db_symformat->sym_lookup)(NULL, name);
		if (ssym == DB_SYM_NULL)
			return (false);
		db_symbol_values(ssym, &name, valuep);
		return (true);
	}
#endif

	(void)strlcpy(symbol, name, sizeof(symbol));
	db_symsplit(symbol, &mod, &sym);
#ifdef _KERNEL
	if (ksyms_getval_unlocked(mod, sym, &uval, KSYMS_EXTERN) == 0) {
		val = (long) uval;
		*valuep = (db_expr_t)val;
		return true;
	}
	if (ksyms_getval_unlocked(mod, sym, &uval, KSYMS_ANY) == 0) {
		val = (long) uval;
		*valuep = (db_expr_t)val;
		return true;
	}
#endif
	return false;
}
Exemplo n.º 2
0
/*
 * Find the closest symbol to val, and return its name
 * and the difference between val and the symbol found.
 */
db_sym_t
db_search_symbol(db_addr_t val, db_strategy_t strategy, db_expr_t *offp)
{
	unsigned int diff;
	db_sym_t ret = DB_SYM_NULL;
#ifdef _KERNEL
	unsigned long naddr;
	const char *mod;
	const char *sym;
#endif

#ifndef _KERNEL
	if (!use_ksyms) {
		db_expr_t newdiff;
		db_sym_t ssym;

		newdiff = diff = ~0;
		ssym = (*db_symformat->sym_search)
		    (NULL, val, strategy, &newdiff);
		if ((unsigned int) newdiff < diff) {
			diff = newdiff;
			ret = ssym;
		}
		*offp = diff;
		return ret;
	}
#endif

#ifdef _KERNEL
	if (ksyms_getname(&mod, &sym, (vaddr_t)val, strategy) == 0) {
		(void)ksyms_getval_unlocked(mod, sym, &naddr, KSYMS_ANY);
		diff = val - (db_addr_t)naddr;
		ret = (db_sym_t)naddr;
	} else
#endif
		diff = 0;
	*offp = diff;
	return ret;
}
Exemplo n.º 3
0
/*
 * kobj_checksyms:
 *
 *	Scan symbol table for duplicates or resolve references to
 *	exernal symbols.
 */
static int
kobj_checksyms(kobj_t ko, bool undefined)
{
	unsigned long rval;
	Elf_Sym *sym, *ms;
	const char *name;
	int error;

	error = 0;

	for (ms = (sym = ko->ko_symtab) + ko->ko_symcnt; sym < ms; sym++) {
		/* Check validity of the symbol. */
		if (ELF_ST_BIND(sym->st_info) != STB_GLOBAL ||
		    sym->st_name == 0)
			continue;
		if (undefined != (sym->st_shndx == SHN_UNDEF)) {
			continue;
		}

		/*
		 * Look it up.  Don't need to lock, as it is known that
		 * the symbol tables aren't going to change (we hold
		 * module_lock).
		 */
		name = ko->ko_strtab + sym->st_name;
		if (ksyms_getval_unlocked(NULL, name, &rval,
		    KSYMS_EXTERN) != 0) {
			if (undefined) {
				kobj_error(__func__, __LINE__, ko,
				    "symbol `%s' not found", name);
				error = ENOEXEC;
			}
			continue;
		}

		/* Save values of undefined globals. */
		if (undefined) {
			sym->st_value = (Elf_Addr)rval;
			continue;
		}

		/* Check (and complain) about differing values. */
		if (sym->st_value == rval) {
			continue;
		}
		if (strcmp(name, "_bss_start") == 0 ||
		    strcmp(name, "__bss_start") == 0 ||
		    strcmp(name, "_bss_end__") == 0 ||
		    strcmp(name, "__bss_end__") == 0 ||
		    strcmp(name, "_edata") == 0 ||
		    strcmp(name, "_end") == 0 ||
		    strcmp(name, "__end") == 0 ||
		    strcmp(name, "__end__") == 0 ||
		    strncmp(name, "__start_link_set_", 17) == 0 ||
		    strncmp(name, "__stop_link_set_", 16)) {
		    	continue;
		}
		kobj_error(__func__, __LINE__, ko,
		    "global symbol `%s' redefined", name);
		error = ENOEXEC;
	}

	return error;
}
Exemplo n.º 4
0
void
db_printsym(db_expr_t off, db_strategy_t strategy,
    void (*pr)(const char *, ...))
{
	const char  *name;
#ifdef _KERNEL
	const char *mod;
	unsigned long uval;
	long val;
#endif
#ifdef notyet
	char *filename;
	int  linenum;
#endif

#ifndef _KERNEL
	if (!use_ksyms) {
		db_expr_t	d;
		char 		*filename;
		db_expr_t	value;
		int 		linenum;
		db_sym_t	cursym;

		cursym = db_search_symbol(off, strategy, &d);
		db_symbol_values(cursym, &name, &value);
		if (name != NULL && ((unsigned int)d < db_maxoff) &&
		    value != 0) {
			(*pr)("%s", name);
			if (d) {
				char tbuf[24];

				db_format_radix(tbuf, 24, d, true);
				(*pr)("+%s", tbuf);
			}
			if (strategy == DB_STGY_PROC) {
				if ((*db_symformat->sym_line_at_pc)
				    (NULL, cursym, &filename, &linenum, off))
					(*pr)(" [%s:%d]", filename, linenum);
			}
			return;
		}
		(*pr)("%s", db_num_to_str(off));
		return;
	}
#endif
#ifdef _KERNEL
	if (ksyms_getname(&mod, &name, (vaddr_t)off,
	    strategy|KSYMS_CLOSEST) == 0) {
		(void)ksyms_getval_unlocked(mod, name, &uval, KSYMS_ANY);
		val = (long) uval;
		if (((off - val) < db_maxoff) && val) {
			(*pr)("%s:%s", mod, name);
			if (off - val) {
				char tbuf[24];

				db_format_radix(tbuf, 24, off - val, true);
				(*pr)("+%s", tbuf);
			}
#ifdef notyet
			if (strategy & KSYMS_PROC) {
				if (ksyms_fmaddr(off, &filename, &linenum) == 0)
					(*pr)(" [%s:%d]", filename, linenum);
			}
#endif
			return;
		}
	}
#endif
	(*pr)("%s", db_num_to_str(off));
	return;
}
Exemplo n.º 5
0
void
db_symstr(char *buf, size_t buflen, db_expr_t off, db_strategy_t strategy)
{
	const char  *name;
#ifdef _KERNEL
	const char *mod;
	unsigned long val;
#endif

#ifndef _KERNEL
	if (!use_ksyms) {
		db_expr_t	d;
		char 		*filename;
		db_expr_t	value;
		int 		linenum;
		db_sym_t	cursym;

		cursym = db_search_symbol(off, strategy, &d);
		db_symbol_values(cursym, &name, &value);
		if (name != NULL && ((unsigned int)d < db_maxoff) &&
		    value != 0) {
			strlcpy(buf, name, buflen);
			if (d) {
				strlcat(buf, "+", buflen);
				db_format_radix(buf + strlen(buf), 24, d, true);
			}
			if (strategy == DB_STGY_PROC) {
				if ((*db_symformat->sym_line_at_pc)
				    (NULL, cursym, &filename, &linenum, off)) {
					size_t len = strlen(buf);
					snprintf(buf + len, buflen - len,
					    " [%s:%d]", filename, linenum);
				}
			}
			return;
		}
		strlcpy(buf, db_num_to_str(off), buflen);
		return;
	}
#endif
#ifdef _KERNEL
	if (ksyms_getname(&mod, &name, (vaddr_t)off,
	    strategy|KSYMS_CLOSEST) == 0) {
		(void)ksyms_getval_unlocked(mod, name, &val, KSYMS_ANY);
		if (((off - val) < db_maxoff) && val) {
			snprintf(buf, buflen, "%s:%s", mod, name);
			if (off - val) {
				strlcat(buf, "+", buflen);
				db_format_radix(buf+strlen(buf),
				    24, off - val, true);
			}
#ifdef notyet
			if (strategy & KSYMS_PROC) {
				if (ksyms_fmaddr(off, &filename, &linenum) == 0)
					snprintf(buf + strlen(buf),
					    buflen - strlen(buf),
					    " [%s:%d]", filename, linenum);
			}
#endif
			return;
		}
	}
	strlcpy(buf, db_num_to_str(off), buflen);
#endif
}