Example #1
0
/* ARGSUSED */
static void
kdba_printaddress(kdb_machreg_t addr, disassemble_info *dip, int flag)
{
	kdb_symtab_t symtab;
	int spaces = 5;
	unsigned int offset;

	/*
	 * Print a symbol name or address as necessary.
	 */
	kdbnearsym(addr, &symtab);
	if (symtab.sym_name) {
		/* Do not use kdb_symbol_print here, it always does
		 * kdb_printf but we want dip->fprintf_func.
		 */
		dip->fprintf_func(dip->stream,
			"0x%0*lx %s",
			(int)(2*sizeof(addr)), addr, symtab.sym_name);
		if ((offset = addr - symtab.sym_start) == 0) {
			spaces += 4;
		}
		else {
			unsigned int o = offset;
			while (o >>= 4)
				--spaces;
			dip->fprintf_func(dip->stream, "+0x%x", offset);
		}

	} else {
Example #2
0
int
kdb_md(int argc, const char **argv, const char **envp, struct pt_regs *regs)
{
	char fmtchar;
	char fmtstr[64];
	int radix, count, width;
	unsigned long addr;
	unsigned long word;
	long	offset = 0;
	int	diag;
	int	nextarg;
	static unsigned long lastaddr = 0;
	static unsigned long lastcount = 0;
	static unsigned long lastradix = 0;
	char	lastbuf[50];
	int	symbolic = 0;

	/*
	 * Defaults in case the relevent environment variables are unset
	 */
	radix = 16;
	count = 8;
	width = 4;

	if (argc == 0) {
		if (lastaddr == 0)
			return KDB_ARGCOUNT;
		sprintf(lastbuf, "0x%lx", lastaddr);
		argv[1] = lastbuf;
		argc = 1;
		count = lastcount;
		radix = lastradix;
	} else {
		unsigned long val;

		if (argc >= 2) { 

			diag = kdbgetularg(argv[2], &val);
			if (!diag) 
				count = (int) val;
		} else {
			diag = kdbgetintenv("MDCOUNT", &count);
		}

		if (argc >= 3) {
			diag = kdbgetularg(argv[3], &val);
			if (!diag) 
				radix = (int) val;
		} else {
			diag = kdbgetintenv("RADIX",&radix);
		}
	}

	switch (radix) {
	case 10:
		fmtchar = 'd';
		break;
	case 16:
		fmtchar = 'x';
		break;
	case 8:
		fmtchar = 'o';
		break;
	default:
		return KDB_BADRADIX;
	}

	diag = kdbgetintenv("BYTESPERWORD", &width);

	if (strcmp(argv[0], "mds") == 0) {
		symbolic = 1;
		width = 4;
	}

	switch (width) {
	case 4:
		sprintf(fmtstr, "%%8.8%c ", fmtchar);
		break;
	case 2:
		sprintf(fmtstr, "%%4.4%c ", fmtchar);
		break;
	case 1:
		sprintf(fmtstr, "%%2.2%c ", fmtchar);
		break;
	default:
		return KDB_BADWIDTH;
	}

	
	nextarg = 1;
	diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
	if (diag)
		return diag;

	/* Round address down modulo BYTESPERWORD */
	
	addr &= ~(width-1);

	/*
	 * Remember count and radix for next 'md'
	 */
	lastcount = count;
	lastradix = radix;

	while (count--) {
		int	num = (symbolic?1 :(16 / width));
		char	cbuf[32];
		char	*c = cbuf;
		char	t;
		int     i;
	
		for(i=0; i<sizeof(cbuf); i++) {
			cbuf[i] = '\0';
		}

		kdb_printf("%8.8x: ", addr);
	
		for(i=0; i<num; i++) {
			char *name = NULL;

			word = kdbgetword(addr, width);
			if (kdb_flags & KDB_FLAG_SUPRESS) {
				kdb_flags &= ~KDB_FLAG_SUPRESS;
				return 0;  /* Error message already printed */
			}

			kdb_printf(fmtstr, word);
			if (symbolic) {
				name = kdbnearsym(word);
			}
			if (name) {
				unsigned long offset;
	
				offset = word - kdbgetsymval(name);
				kdb_printf("%s+0x%x", name, offset);
				addr += 4;
			} else {
				switch (width) {
				case 4:
					*c++ = isprint(t=kdbgetword(addr++, 1))
							?t:'.'; 
					*c++ = isprint(t=kdbgetword(addr++, 1))
							?t:'.'; 
				case 2:
					*c++ = isprint(t=kdbgetword(addr++, 1))
							?t:'.'; 
				case 1:
					*c++ = isprint(t=kdbgetword(addr++, 1))
							?t:'.'; 
					break;
				}
			}
		}
		kdb_printf(" %s\n", cbuf);
	}

	lastaddr = addr;

	return 0;
}
Example #3
0
int
kdbgetaddrarg(int argc, const char **argv, int *nextarg, 
	      unsigned long *value,  long *offset, 
	      char **name, struct pt_regs *regs)
{
	unsigned long addr;
	long	      off = 0;
	int	      positive;
	int	      diag;
	char	     *symname;
	char	      symbol = '\0';
	char	     *cp;

	/*
	 * Process arguments which follow the following syntax:
	 *
	 *  symbol | numeric-address [+/- numeric-offset]
	 *  %register
	 *  $environment-variable
	 */

	if (*nextarg > argc) {
		return KDB_ARGCOUNT;
	}

	symname = (char *)argv[*nextarg];

	/*
	 * If there is no whitespace between the symbol
	 * or address and the '+' or '-' symbols, we
	 * remember the character and replace it with a
	 * null so the symbol/value can be properly parsed
	 */
	if ((cp = strpbrk(symname, "+-")) != NULL) {
		symbol = *cp;
		*cp++ = '\0';
	}

	if (symname[0] == '$') {
		diag = kdbgetulenv(&symname[1], &addr);
		if (diag)
			return diag;
	} else if (symname[0] == '%') {
		diag = kdbgetregcontents(&symname[1], regs, &addr);
		if (diag) 
			return diag;
	} else {
		addr = kdbgetsymval(symname);
		if (addr == 0) {
			diag = kdbgetularg(argv[*nextarg], &addr);
			if (diag) 
				return diag;
		}
	}

	symname = kdbnearsym(addr);

	(*nextarg)++;

	if (name)
		*name = symname; 
	if (value) 
		*value = addr;
	if (offset && name && *name)
		*offset = addr - kdbgetsymval(*name);
	
	if ((*nextarg > argc) 
	 && (symbol == '\0'))
		return 0;

	/*
	 * check for +/- and offset
	 */

	if (symbol == '\0') {
		if ((argv[*nextarg][0] != '+')
	  	 && (argv[*nextarg][0] != '-')) {
			/*
			 * Not our argument.  Return.
			 */
			return 0;
		} else {
			positive = (argv[*nextarg][0] == '+');
			(*nextarg)++;
		}
	} else
		positive = (symbol == '+');

	/*
	 * Now there must be an offset!
	 */
	if ((*nextarg > argc) 
	 && (symbol == '\0')) {
		return KDB_INVADDRFMT;
	}

	if (!symbol) {
		cp = (char *)argv[*nextarg];
		(*nextarg)++;
	}

	diag = kdbgetularg(cp, &off);
	if (diag)
		return diag;

	if (!positive) 
		off = -off;

	if (offset) 
		*offset += off;

	if (value) 
		*value += off;

	return 0;
}