Subversion Repositories HelenOS-historic

Compare Revisions

Ignore whitespace Rev 634 → Rev 635

/kernel/trunk/generic/src/console/kconsole.c
117,8 → 117,9
spinlock_lock(&cmd->lock);
spinlock_lock(&hlp->lock);
}
if ((strncmp(hlp->name, cmd->name, strlen(cmd->name)) == 0)) {
if ((strncmp(hlp->name,
cmd->name, max(strlen(cmd->name),
strlen(hlp->name))) == 0)) {
/* The command is already there. */
spinlock_unlock(&hlp->lock);
spinlock_unlock(&cmd->lock);
139,6 → 140,7
return 1;
}
 
/** Print count times a character */
static void rdln_print_c(char ch, int count)
{
int i;
146,6 → 148,7
putchar(ch);
}
 
/** Insert character to string */
static void insert_char(char *str, char ch, int pos)
{
int i;
155,6 → 158,7
str[pos] = ch;
}
 
/** Try to find a command begenning with prefix */
static const char * cmdtab_search_one(const char *name,link_t **startpos)
{
int namelen = strlen(name);
481,7 → 485,8
hlp = list_get_instance(cur, cmd_info_t, link);
spinlock_lock(&hlp->lock);
if (strncmp(hlp->name, &cmdline[start], strlen(hlp->name)) == 0) {
if (strncmp(hlp->name, &cmdline[start], max(strlen(hlp->name),
end-start+1)) == 0) {
cmd = hlp;
break;
}
/kernel/trunk/generic/src/lib/func.c
114,7 → 114,7
}
if (i == len || *src == *dst)
return 0;
if (*src < *dst)
if (!*src)
return -1;
return 1;
}
/kernel/trunk/arch/mips32/include/debugger.h
35,11 → 35,21
 
#define BKPOINTS_MAX 10
 
#define BKPOINT_INPROG (1 << 0) /**< Breakpoint was shot */
#define BKPOINT_ONESHOT (1 << 1) /**< One-time breakpoint,mandatory for j/b
instructions */
#define BKPOINT_REINST (1 << 2) /**< Breakpoint is set on the next
instruction, so that it could be
reinstalled on the previous one */
#define BKPOINT_FUNCCALL (1 << 3) /**< Call a predefined function */
 
typedef struct {
__address address; /**< Breakpoint address */
__native instruction; /**< Original instruction */
__native nextinstruction; /**< Original instruction following break */
bool executing; /**< If we are executing the original instruciton */
int flags; /**< Flags regarding breakpoint */
count_t counter;
void (*bkfunc)(void *b, struct exception_regdump *pstate);
} bpinfo_t;
 
extern void debugger_init(void);
/kernel/trunk/arch/mips32/src/debugger.c
72,6 → 72,65
.argv = &add_argv
};
 
static cmd_arg_t adde_argv[] = {
{ .type = ARG_TYPE_INT },
{ .type = ARG_TYPE_INT }
};
static cmd_info_t addbkpte_info = {
.name = "addbkpte",
.description = "addebkpte <&symbol> <&func> - new bkpoint. Call func(or Nothing if 0).",
.func = cmd_add_breakpoint,
.argc = 2,
.argv = adde_argv
};
 
static struct {
__u32 andmask;
__u32 value;
}jmpinstr[] = {
{0xf3ff0000, 0x41000000}, /* BCzF */
{0xf3ff0000, 0x41020000}, /* BCzFL */
{0xf3ff0000, 0x41010000}, /* BCzT */
{0xf3ff0000, 0x41030000}, /* BCzTL */
{0xfc000000, 0x10000000}, /* BEQ */
{0xfc000000, 0x50000000}, /* BEQL */
{0xfc1f0000, 0x04010000}, /* BEQL */
{0xfc1f0000, 0x04110000}, /* BGEZAL */
{0xfc1f0000, 0x04130000}, /* BGEZALL */
{0xfc1f0000, 0x04030000}, /* BGEZL */
{0xfc1f0000, 0x1c000000}, /* BGTZ */
{0xfc1f0000, 0x5c000000}, /* BGTZL */
{0xfc1f0000, 0x18000000}, /* BLEZ */
{0xfc1f0000, 0x58000000}, /* BLEZL */
{0xfc1f0000, 0x04000000}, /* BLTZ */
{0xfc1f0000, 0x04100000}, /* BLTZAL */
{0xfc1f0000, 0x04120000}, /* BLTZALL */
{0xfc1f0000, 0x04020000}, /* BLTZL */
{0xfc000000, 0x14000000}, /* BNE */
{0xfc000000, 0x54000000}, /* BNEL */
{0xfc000000, 0x08000000}, /* J */
{0xfc000000, 0x0c000000}, /* JAL */
{0xfc1f07ff, 0x00000009}, /* JALR */
{0,0} /* EndOfTable */
};
 
/** Test, if the given instruction is a jump or branch instruction
*
* @param instr Instruction code
* @return true - it is jump instruction, false otherwise
*/
static bool is_jump(__native instr)
{
int i;
 
for (i=0;jmpinstr[i].andmask;i++) {
if ((instr & jmpinstr[i].andmask) == jmpinstr[i].value)
return true;
}
 
return false;
}
 
/** Add new breakpoint to table */
int cmd_add_breakpoint(cmd_arg_t *argv)
{
116,7 → 175,15
printf("Adding breakpoint on address: %p\n", argv->intval);
cur->instruction = ((__native *)cur->address)[0];
cur->nextinstruction = ((__native *)cur->address)[1];
cur->executing = false;
if (argv == &add_argv) {
cur->flags = 0;
} else { /* We are add extended */
cur->flags = BKPOINT_FUNCCALL;
cur->bkfunc = (void (*)(void *, struct exception_regdump *)) argv[1].intval;
}
if (is_jump(cur->instruction))
cur->flags |= BKPOINT_ONESHOT;
cur->counter = 0;
 
/* Set breakpoint */
*((__native *)cur->address) = 0x0d;
127,6 → 194,8
return 1;
}
 
 
 
/** Remove breakpoint from table */
int cmd_del_breakpoint(cmd_arg_t *argv)
{
147,7 → 216,12
interrupts_restore(ipl);
return 0;
}
if ((cur->flags & BKPOINT_INPROG) && (cur->flags & BKPOINT_ONESHOT)) {
printf("Cannot remove one-shot breakpoint in-progress\n");
spinlock_unlock(&bkpoint_lock);
interrupts_restore(ipl);
return 0;
}
((__u32 *)cur->address)[0] = cur->instruction;
((__u32 *)cur->address)[1] = cur->nextinstruction;
 
170,6 → 244,14
symbol = get_symtab_entry(breakpoints[i].address);
printf("%d. 0x%p in %s\n",i,
breakpoints[i].address, symbol);
printf(" Count(%d) ", breakpoints[i].counter);
if (breakpoints[i].flags & BKPOINT_INPROG)
printf("INPROG ");
if (breakpoints[i].flags & BKPOINT_ONESHOT)
printf("ONESHOT ");
if (breakpoints[i].flags & BKPOINT_FUNCCALL)
printf("FUNCCALL ");
printf("\n");
}
return 1;
}
193,6 → 275,10
cmd_initialize(&addbkpt_info);
if (!cmd_register(&addbkpt_info))
panic("could not register command %s\n", addbkpt_info.name);
 
cmd_initialize(&addbkpte_info);
if (!cmd_register(&addbkpte_info))
panic("could not register command %s\n", addbkpte_info.name);
}
 
/** Handle breakpoint
205,13 → 291,10
*/
void debugger_bpoint(struct exception_regdump *pstate)
{
char *symbol;
bpinfo_t *cur = NULL;
__address fireaddr = pstate->epc;
int i;
 
symbol = get_symtab_entry(pstate->epc);
 
/* test branch delay slot */
if (cp0_cause_read() & 0x80000000)
panic("Breakpoint in branch delay slot not supported.\n");
218,45 → 301,79
 
spinlock_lock(&bkpoint_lock);
for (i=0; i<BKPOINTS_MAX; i++) {
if (pstate->epc == breakpoints[i].address || \
(pstate->epc == breakpoints[i].address+sizeof(__native) &&\
breakpoints[i].executing))
/* Normal breakpoint */
if (fireaddr == breakpoints[i].address \
&& !(breakpoints[i].flags & BKPOINT_REINST)) {
cur = &breakpoints[i];
break;
 
break;
}
/* Reinst only breakpoint */
if ((breakpoints[i].flags & BKPOINT_REINST) \
&& (fireaddr ==breakpoints[i].address+sizeof(__native))) {
cur = &breakpoints[i];
break;
}
}
if (cur) {
if ((cur->executing && pstate->epc==cur->address) ||
(!cur->executing && pstate->epc==cur->address+sizeof(__native)))
panic("Weird breakpoint state.\n");
if (!cur->executing) {
printf("***Breakpoint %d: 0x%p in %s.\n", i,
pstate->epc,symbol);
/* Return first instruction back */
((__u32 *)cur->address)[0] = cur->instruction;
/* Set Breakpoint on second */
((__u32 *)cur->address)[1] = 0x0d;
cur->executing = true;
} else {
if (cur->flags & BKPOINT_REINST) {
/* Set breakpoint on first instruction */
((__u32 *)cur->address)[0] = 0x0d;
/* Return back the second */
((__u32 *)cur->address)[1] = cur->nextinstruction;
cur->executing = false;
cur->flags &= ~BKPOINT_REINST;
spinlock_unlock(&bkpoint_lock);
return;
}
}
if (cur->flags & BKPOINT_INPROG)
printf("Warning: breakpoint recursion\n");
if (!(cur->flags & BKPOINT_FUNCCALL))
printf("***Breakpoint %d: 0x%p in %s.\n", i,
fireaddr, get_symtab_entry(pstate->epc));
 
/* Return first instruction back */
((__u32 *)cur->address)[0] = cur->instruction;
 
if (! (cur->flags & BKPOINT_ONESHOT)) {
/* Set Breakpoint on next instruction */
((__u32 *)cur->address)[1] = 0x0d;
cur->flags |= BKPOINT_REINST;
}
cur->flags |= BKPOINT_INPROG;
} else {
printf("***Breakpoint 0x%p in %s.\n", pstate->epc, symbol);
printf("***Breakpoint 0x%p in %s.\n", fireaddr,
get_symtab_entry(fireaddr));
/* Move on to next instruction */
pstate->epc += 4;
}
cur->counter++;
if (cur && (cur->flags & BKPOINT_FUNCCALL)) {
/* Allow zero bkfunc, just for counting */
if (cur->bkfunc)
cur->bkfunc(cur, pstate);
} else {
printf("***Type 'exit' to exit kconsole.\n");
/* This disables all other processors - we are not SMP,
* actually this gets us to cpu_halt, if scheduler() is run
* - we generally do not want scheduler to be run from debug,
* so this is a good idea
*/
atomic_set(&haltstate,1);
spinlock_unlock(&bkpoint_lock);
 
kconsole("debug");
 
spinlock_lock(&bkpoint_lock);
atomic_set(&haltstate,0);
}
 
if (cur && cur->address == fireaddr && (cur->flags & BKPOINT_INPROG)) {
/* Remove one-shot breakpoint */
if ((cur->flags & BKPOINT_ONESHOT))
cur->address = NULL;
/* Remove in-progress flag */
cur->flags &= ~BKPOINT_INPROG;
}
spinlock_unlock(&bkpoint_lock);
 
printf("***Type 'exit' to exit kconsole.\n");
/* Umm..we should rather set some 'debugstate' here */
atomic_set(&haltstate,1);
kconsole("debug");
atomic_set(&haltstate,0);
}