Example #1
0
int
kdb_rm(int argc, const char **argv, const char **envp, struct pt_regs *regs)
{
	int diag;
	int ind = 0;
	unsigned long contents;

	if (argc != 2) {
		return KDB_ARGCOUNT;
	}

	/*
	 * Allow presence or absence of leading '%' symbol.
	 */

	if (argv[1][0] == '%')
		ind = 1;

	diag = kdbgetularg(argv[2], &contents);
	if (diag)
		return diag;

	diag = kdbsetregcontents(&argv[1][ind], regs, contents);
	if (diag)
		return diag;

	return 0;
}
Example #2
0
int
kdb_ll(int argc, const char **argv, const char **envp, struct pt_regs *regs)
{
	int diag;
	unsigned long addr, firstaddr;
	long 	      offset = 0;
	unsigned long va;
	unsigned long linkoffset;
	int nextarg;

	if (argc != 3) {
		return KDB_ARGCOUNT;
	}

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

	diag = kdbgetularg(argv[2], &linkoffset);
	if (diag)
		return diag;

	/*
	 * Using the starting address as the first element in the list,
	 * and assuming that the list ends with a null pointer or with
	 * the first element again (do the right thing for both
	 * null-terminated and circular lists).
	 */

	va = firstaddr = addr;

	while (va) {
		char buf[80];

		sprintf(buf, "%s 0x%lx\n", argv[3], va);
		diag = kdb_parse(buf, regs);
		if (diag)
			return diag;

		addr = va + linkoffset;
		va = kdbgetword(addr, sizeof(va));
		if (kdb_flags & KDB_FLAG_SUPRESS) {
			kdb_flags &= ~KDB_FLAG_SUPRESS;
			return 0;
		}
		if (va == firstaddr)
			break;
	}

	return 0;
}
Example #3
0
static int
kdbm_vm(int argc, const char **argv)
{
	unsigned long addr;
	long offset = 0;
	int nextarg;
	int diag;
	int verbose_flg = 0;

	if (argc == 2) {
		if (strcmp(argv[1], "-v") != 0) {
			return KDB_ARGCOUNT;
		}
		verbose_flg = 1;
	} else if (argc != 1) {
		return KDB_ARGCOUNT;
	}

	if (strcmp(argv[0], "vmp") == 0) {
		struct task_struct *g, *tp;
		struct vm_area_struct *vp;
		pid_t pid;

		if ((diag = kdbgetularg(argv[argc], (unsigned long *) &pid)))
			return diag;

		kdb_do_each_thread(g, tp) {
			if (tp->pid == pid) {
				if (tp->mm != NULL) {
					if (verbose_flg)
						kdb_printf
						    ("vm_area_struct       ");
					kdb_printf
					    ("vm_start            vm_end              vm_flags\n");
					vp = tp->mm->mmap;
					while (vp != NULL) {
						kdbm_print_vmp(vp, verbose_flg);
						vp = vp->vm_next;
					}
				}
				return 0;
			}
		} kdb_while_each_thread(g, tp);

		kdb_printf("No process with pid == %d found\n", pid);

	} else {
Example #4
0
static int kdb_parsebp(int argc, const char **argv, int *nextargp, kdb_bp_t *bp)
{
	int nextarg = *nextargp;
	int diag;

	bp->bph_length = 1;
	if ((argc + 1) != nextarg) {
		if (strncasecmp(argv[nextarg], "datar", sizeof("datar")) == 0)
			bp->bp_type = BP_ACCESS_WATCHPOINT;
		else if (strncasecmp(argv[nextarg], "dataw", sizeof("dataw")) == 0)
			bp->bp_type = BP_WRITE_WATCHPOINT;
		else if (strncasecmp(argv[nextarg], "inst", sizeof("inst")) == 0)
			bp->bp_type = BP_HARDWARE_BREAKPOINT;
		else
			return KDB_ARGCOUNT;

		bp->bph_length = 1;

		nextarg++;

		if ((argc + 1) != nextarg) {
			unsigned long len;

			diag = kdbgetularg((char *)argv[nextarg],
					   &len);
			if (diag)
				return diag;


			if (len > 8)
				return KDB_BADLENGTH;

			bp->bph_length = len;
			nextarg++;
		}

		if ((argc + 1) != nextarg)
			return KDB_ARGCOUNT;
	}

	*nextargp = nextarg;
	return 0;
}
Example #5
0
int
kdb_cpu(int argc, const char **argv, const char **envp, struct pt_regs *regs)
{
	unsigned long cpunum;
	int diag;

	if (argc == 0) {
		int i;

		kdb_printf("Currently on cpu %d\n", smp_processor_id());
		kdb_printf("Available cpus: ");
		for (i=0; i<NR_CPUS; i++) {
			if (test_bit(i, &cpu_online_map)) {
				if (i) kdb_printf(", ");
				kdb_printf("%d", i);
			}
		}
		kdb_printf("\n");
		return 0;
	}

	if (argc != 1) 
		return KDB_ARGCOUNT;

	diag = kdbgetularg(argv[1], &cpunum);
	if (diag)
		return diag;

	/*
	 * Validate cpunum
	 */
	if ((cpunum > NR_CPUS)
	 || !test_bit(cpunum, &cpu_online_map))
		return KDB_BADCPUNUM;

	kdb_new_cpu = cpunum;

	/*
	 * Switch to other cpu
	 */
	return KDB_CPUSWITCH;
}
Example #6
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 #7
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;
}
Example #8
0
int
kdba_parsebp(int argc, const char **argv, int *nextargp, kdb_bp_t *bp)
{
	int		nextarg = *nextargp;
	int		diag;
	kdbhard_bp_t 	*bph = &bp->bp_template;

	bph->bph_mode = 0;		/* Default to instruction breakpoint */
	bph->bph_length = 0;		/* Length must be zero for insn bp */
	if ((argc + 1) != nextarg) {
		if (strnicmp(argv[nextarg], "datar", sizeof("datar")) == 0) {
			bph->bph_mode = 3;
		} else if (strnicmp(argv[nextarg], "dataw", sizeof("dataw")) == 0) {
			bph->bph_mode = 1;
		} else if (strnicmp(argv[nextarg], "io", sizeof("io")) == 0) {
			bph->bph_mode = 2;
		} else if (strnicmp(argv[nextarg], "inst", sizeof("inst")) == 0) {
			bph->bph_mode = 0;
		} else {
			return KDB_ARGCOUNT;
		}

		bph->bph_length = 3;	/* Default to 4 byte */

		nextarg++;

		if ((argc + 1) != nextarg) {
			unsigned long len;

			diag = kdbgetularg((char *)argv[nextarg],
					   &len);
			if (diag)
				return diag;


			if ((len > 4) || (len == 3))
				return KDB_BADLENGTH;

			bph->bph_length = len;
			bph->bph_length--; /* Normalize for debug register */
			nextarg++;
		}

		if ((argc + 1) != nextarg)
			return KDB_ARGCOUNT;

		/*
		 * Indicate to architecture independent level that
		 * a hardware register assignment is required to enable
		 * this breakpoint.
		 */

		bph->bph_free = 0;
	} else {
		if (KDB_DEBUG(BP))
			kdb_printf("kdba_bp: no args, forcehw is %d\n", bp->bp_forcehw);
		if (bp->bp_forcehw) {
			/*
			 * We are forced to use a hardware register for this
			 * breakpoint because either the bph or bpha
			 * commands were used to establish this breakpoint.
			 */
			bph->bph_free = 0;
		} else {
			/*
			 * Indicate to architecture dependent level that
			 * the instruction replacement breakpoint technique
			 * should be used for this breakpoint.
			 */
			bph->bph_free = 1;
			bp->bp_adjust = 1;	/* software, int 3 is one byte */
		}
	}

	if (bph->bph_mode != 2 && kdba_verify_rw(bp->bp_addr, bph->bph_length+1)) {
		kdb_printf("Invalid address for breakpoint, ignoring bp command\n");
		return KDB_BADADDR;
	}

	*nextargp = nextarg;
	return 0;
}
Example #9
0
int
kdb_bt(int argc, const char **argv, const char **envp, struct pt_regs *regs)
{
	int done = 0;
#if !defined(CONFIG_KDB_FRAMEPTR)
	unsigned long sp;
#endif
	unsigned long base, limit, esp, ebp, eip;
	unsigned long start = 0;	/* Start address of current function */
	unsigned long addr;
	long offset = 0;
	int nextarg;
	int argcount=5;
	char	*name;
	int	diag;
	struct pt_regs	   taskregs;
	struct frame {
		unsigned long ebp;
		unsigned long eip;
	} old;
	unsigned long stackbase = (unsigned long)current;

	/*
	 * Determine how many possible arguments to print.
	 */
	diag = kdbgetintenv("BTARGS", &argcount);

	if (strcmp(argv[0], "btp") == 0){
		struct task_struct *p;
		int		   pid;
		
		diag = kdbgetularg((char *)argv[1], (unsigned long*)&pid);
		if (diag)
			return diag;

		taskregs.eax = 1;
		for_each_task(p) {
			if (p->pid == pid) {
				taskregs.eip = p->tss.eip;
				taskregs.esp = p->tss.esp;
				taskregs.ebp = p->tss.ebp;
				/*
				 * Since we don't really use the TSS
				 * to store register between task switches,
				 * attempt to locate real ebp (should be
				 * top of stack if task is in schedule)
				 */
				if (taskregs.ebp == 0) {
					taskregs.ebp = 
					 *(unsigned long *)(taskregs.esp);
				}

				taskregs.eax = 0;
				stackbase = (unsigned long)p;
				break;
			}
		}

		if (taskregs.eax == 1) {
			kdb_printf("No process with pid == %d found\n",
				   pid);
			return 0;
		}
		regs = &taskregs;
	} else {
		if (argc) {
Example #10
0
static int
kdb_bc(int argc, const char **argv)
{
	kdb_machreg_t addr;
	kdb_bp_t *bp = NULL;
	int lowbp = KDB_MAXBPT;
	int highbp = 0;
	int done = 0;
	int i;
	int diag;
	int cmd;			/* KDBCMD_B? */

	if (strcmp(argv[0], "be") == 0) {
		cmd = KDBCMD_BE;
	} else if (strcmp(argv[0], "bd") == 0) {
		cmd = KDBCMD_BD;
	} else
		cmd = KDBCMD_BC;

	if (argc != 1)
		return KDB_ARGCOUNT;

	if (strcmp(argv[1], "*") == 0) {
		lowbp = 0;
		highbp = KDB_MAXBPT;
	} else {
		diag = kdbgetularg(argv[1], &addr);
		if (diag)
			return diag;

		/*
		 * For addresses less than the maximum breakpoint number,
		 * assume that the breakpoint number is desired.
		 */
		if (addr < KDB_MAXBPT) {
			bp = &kdb_breakpoints[addr];
			lowbp = highbp = addr;
			highbp++;
		} else {
			for(i=0, bp=kdb_breakpoints; i<KDB_MAXBPT; i++, bp++) {
				if (bp->bp_addr == addr) {
					lowbp = highbp = i;
					highbp++;
					break;
				}
			}
		}
	}

	/*
	 * Now operate on the set of breakpoints matching the input
	 * criteria (either '*' for all, or an individual breakpoint).
	 */
	for(bp=&kdb_breakpoints[lowbp], i=lowbp;
	    i < highbp;
	    i++, bp++) {
		if (bp->bp_free)
			continue;

		done++;

		switch (cmd) {
		case KDBCMD_BC:
			if (bp->bp_hardtype)
				kdba_free_hwbp(bp);

			bp->bp_enabled = 0;
			bp->bp_global = 0;

			kdb_printf("Breakpoint %d at " kdb_bfd_vma_fmt " cleared\n",
				i, bp->bp_addr);

			bp->bp_addr = 0;
			bp->bp_free = 1;

			break;
		case KDBCMD_BE:
			/*
			 * Allocate a hardware breakpoint.  If one is not
			 * available, don't enable the breakpoint.
			 */
			if (!bp->bp_template.bph_free
			 && !bp->bp_hardtype) {
				kdba_alloc_hwbp(bp, &diag);
				if (diag) {
					bp->bp_enabled = 0;
					bp->bp_hardtype = 0;
					kdba_free_hwbp(bp);
					return diag;
				}
			}

			bp->bp_enabled = 1;

			kdb_printf("Breakpoint %d at " kdb_bfd_vma_fmt " enabled",
				i, bp->bp_addr);

			kdb_printf("\n");
			break;
		case KDBCMD_BD:
			if (!bp->bp_enabled)
				break;

			/*
			 * Since this breakpoint is now disabled, we can
			 * give up the hardware register which is allocated
			 * to it.
			 */
			if (bp->bp_hardtype)
				kdba_free_hwbp(bp);

			bp->bp_enabled = 0;

			kdb_printf("Breakpoint %d at " kdb_bfd_vma_fmt " disabled\n",
				i, bp->bp_addr);

			break;
		}
		if (bp->bp_delay && (cmd == KDBCMD_BC || cmd == KDBCMD_BD)) {
			bp->bp_delay = 0;
			KDB_STATE_CLEAR(SSBPT);
		}
	}

	return (!done)?KDB_BPTNOTFOUND:0;
}