/* 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 {
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; }
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; }