Changes in kernel/arch/amd64/src/debugger.c [96b02eb9:e16e0d59] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/arch/amd64/src/debugger.c
r96b02eb9 re16e0d59 46 46 #include <symtab.h> 47 47 48 #ifdef __64_BITS__49 #define getip(x) ((x)->rip)50 #endif51 52 #ifdef __32_BITS__53 #define getip(x) ((x)->eip)54 #endif55 56 48 typedef struct { 57 uintptr_t address; /**< Breakpoint address */58 unsigned int flags;/**< Flags regarding breakpoint */59 size_t counter;/**< How many times the exception occured */49 uintptr_t address; /**< Breakpoint address */ 50 int flags; /**< Flags regarding breakpoint */ 51 int counter; /**< How many times the exception occured */ 60 52 } bpinfo_t; 61 53 62 54 static bpinfo_t breakpoints[BKPOINTS_MAX]; 63 IRQ_SPINLOCK_STATIC_INITIALIZE(bkpoint_lock);55 SPINLOCK_INITIALIZE(bkpoint_lock); 64 56 65 57 #ifdef CONFIG_KCONSOLE 66 58 67 static int cmd_print_breakpoints(cmd_arg_t *); 68 static int cmd_del_breakpoint(cmd_arg_t *); 69 static int cmd_add_breakpoint(cmd_arg_t *); 70 59 static int cmd_print_breakpoints(cmd_arg_t *argv); 71 60 static cmd_info_t bkpts_info = { 72 61 .name = "bkpts", … … 76 65 }; 77 66 67 static int cmd_del_breakpoint(cmd_arg_t *argv); 78 68 static cmd_arg_t del_argv = { 79 69 .type = ARG_TYPE_INT 80 70 }; 81 82 71 static cmd_info_t delbkpt_info = { 83 72 .name = "delbkpt", 84 .description = " Delete breakpoint.",73 .description = "delbkpt <number> - Delete breakpoint.", 85 74 .func = cmd_del_breakpoint, 86 75 .argc = 1, … … 88 77 }; 89 78 79 static int cmd_add_breakpoint(cmd_arg_t *argv); 90 80 static cmd_arg_t add_argv = { 91 81 .type = ARG_TYPE_INT 92 82 }; 93 94 83 static cmd_info_t addbkpt_info = { 95 84 .name = "addbkpt", 96 .description = " Addbreakpoint.",85 .description = "addbkpt <&symbol> - new breakpoint.", 97 86 .func = cmd_add_breakpoint, 98 87 .argc = 1, … … 103 92 .type = ARG_TYPE_INT 104 93 }; 105 106 94 static cmd_info_t addwatchp_info = { 107 95 .name = "addwatchp", 108 .description = " Addwrite watchpoint.",96 .description = "addbwatchp <&symbol> - new write watchpoint.", 109 97 .func = cmd_add_breakpoint, 110 98 .argc = 1, … … 114 102 #endif /* CONFIG_KCONSOLE */ 115 103 116 /** Setup DR register according to table 117 * 118 */ 104 /* Setup DR register according to table */ 119 105 static void setup_dr(int curidx) 120 106 { 121 ASSERT(curidx >= 0); 122 107 unative_t dr7; 123 108 bpinfo_t *cur = &breakpoints[curidx]; 124 unsignedint flags = breakpoints[curidx].flags;125 109 int flags = breakpoints[curidx].flags; 110 126 111 /* Disable breakpoint in DR7 */ 127 sysarg_t dr7 = read_dr7(); 128 dr7 &= ~(0x02U << (curidx * 2)); 129 130 /* Setup DR register */ 131 if (cur->address) { 112 dr7 = read_dr7(); 113 dr7 &= ~(0x2 << (curidx*2)); 114 115 if (cur->address) { /* Setup DR register */ 132 116 /* Set breakpoint to debug registers */ 133 117 switch (curidx) { … … 145 129 break; 146 130 } 131 /* Set type to requested breakpoint & length*/ 132 dr7 &= ~ (0x3 << (16 + 4*curidx)); 133 dr7 &= ~ (0x3 << (18 + 4*curidx)); 134 if ((flags & BKPOINT_INSTR)) { 135 ; 136 } else { 147 137 148 /* Set type to requested breakpoint & length*/149 dr7 &= ~(0x03U << (16 + 4 * curidx));150 dr7 &= ~(0x03U << (18 + 4 * curidx));151 152 if (!(flags & BKPOINT_INSTR)) {153 138 #ifdef __32_BITS__ 154 dr7 |= (( sysarg_t) 0x03U) << (18 + 4 * curidx);155 #endif 156 139 dr7 |= ((unative_t) 0x3) << (18 + 4 * curidx); 140 #endif 141 157 142 #ifdef __64_BITS__ 158 dr7 |= (( sysarg_t) 0x02U) << (18 + 4 * curidx);143 dr7 |= ((unative_t) 0x2) << (18 + 4 * curidx); 159 144 #endif 160 145 161 146 if ((flags & BKPOINT_WRITE)) 162 dr7 |= (( sysarg_t) 0x01U) << (16 + 4 * curidx);147 dr7 |= ((unative_t) 0x1) << (16 + 4 * curidx); 163 148 else if ((flags & BKPOINT_READ_WRITE)) 164 dr7 |= ((sysarg_t) 0x03U) << (16 + 4 * curidx); 165 } 149 dr7 |= ((unative_t) 0x3) << (16 + 4 * curidx); 150 } 151 152 /* Enable global breakpoint */ 153 dr7 |= 0x2 << (curidx * 2); 154 155 write_dr7(dr7); 166 156 167 /* Enable global breakpoint */ 168 dr7 |= 0x02U << (curidx * 2); 169 170 write_dr7(dr7); 171 } 172 } 173 157 } 158 } 159 174 160 /** Enable hardware breakpoint 175 161 * 176 162 * @param where Address of HW breakpoint 177 163 * @param flags Type of breakpoint (EXECUTE, WRITE) 178 *179 164 * @return Debug slot on success, -1 - no available HW breakpoint 180 *181 165 */ 182 int breakpoint_add(const void *where, const unsigned int flags, int curidx) 183 { 166 int breakpoint_add(const void *where, const int flags, int curidx) 167 { 168 ipl_t ipl; 169 int i; 170 bpinfo_t *cur; 171 184 172 ASSERT(flags & (BKPOINT_INSTR | BKPOINT_WRITE | BKPOINT_READ_WRITE)); 185 186 irq_spinlock_lock(&bkpoint_lock, true); 173 174 ipl = interrupts_disable(); 175 spinlock_lock(&bkpoint_lock); 187 176 188 177 if (curidx == -1) { 189 178 /* Find free space in slots */ 190 unsigned int i; 191 for (i = 0; i < BKPOINTS_MAX; i++) { 179 for (i = 0; i < BKPOINTS_MAX; i++) 192 180 if (!breakpoints[i].address) { 193 181 curidx = i; 194 182 break; 195 183 } 196 }197 198 184 if (curidx == -1) { 199 185 /* Too many breakpoints */ 200 irq_spinlock_unlock(&bkpoint_lock, true); 186 spinlock_unlock(&bkpoint_lock); 187 interrupts_restore(ipl); 201 188 return -1; 202 189 } 203 190 } 204 205 bpinfo_t *cur = &breakpoints[curidx]; 206 191 cur = &breakpoints[curidx]; 192 207 193 cur->address = (uintptr_t) where; 208 194 cur->flags = flags; 209 195 cur->counter = 0; 210 196 211 197 setup_dr(curidx); 212 213 irq_spinlock_unlock(&bkpoint_lock, true); 214 198 199 spinlock_unlock(&bkpoint_lock); 200 interrupts_restore(ipl); 201 215 202 /* Send IPI */ 203 #ifdef CONFIG_SMP 216 204 // ipi_broadcast(VECTOR_DEBUG_IPI); 217 205 #endif 206 218 207 return curidx; 219 208 } 220 209 210 #ifdef __64_BITS__ 211 #define getip(x) ((x)->rip) 212 #else 213 #define getip(x) ((x)->eip) 214 #endif 215 221 216 static void handle_exception(int slot, istate_t *istate) 222 217 { 223 ASSERT(slot >= 0);224 218 ASSERT(breakpoints[slot].address); 225 219 226 220 /* Handle zero checker */ 227 if (! (breakpoints[slot].flags & BKPOINT_INSTR)) {221 if (! (breakpoints[slot].flags & BKPOINT_INSTR)) { 228 222 if ((breakpoints[slot].flags & BKPOINT_CHECK_ZERO)) { 229 if (*(( sysarg_t *) breakpoints[slot].address) != 0)223 if (*((unative_t *) breakpoints[slot].address) != 0) 230 224 return; 231 232 printf("*** Found ZERO on address %p (slot %d) ***\n", 233 (void *) breakpoints[slot].address, slot); 225 printf("*** Found ZERO on address %lx (slot %d) ***\n", 226 breakpoints[slot].address, slot); 234 227 } else { 235 printf("Data watchpoint - new data: % #" PRIxn "\n",236 *(( sysarg_t *) breakpoints[slot].address));237 } 238 } 239 240 printf("Reached breakpoint %d:% p (%s)\n", slot,241 (void *) getip(istate),symtab_fmt_name_lookup(getip(istate)));242 228 printf("Data watchpoint - new data: %lx\n", 229 *((unative_t *) breakpoints[slot].address)); 230 } 231 } 232 233 printf("Reached breakpoint %d:%lx (%s)\n", slot, getip(istate), 234 symtab_fmt_name_lookup(getip(istate))); 235 243 236 #ifdef CONFIG_KCONSOLE 244 237 atomic_set(&haltstate, 1); … … 250 243 void breakpoint_del(int slot) 251 244 { 252 ASSERT(slot >= 0); 253 254 irq_spinlock_lock(&bkpoint_lock, true); 255 256 bpinfo_t *cur = &breakpoints[slot]; 245 bpinfo_t *cur; 246 ipl_t ipl; 247 248 ipl = interrupts_disable(); 249 spinlock_lock(&bkpoint_lock); 250 251 cur = &breakpoints[slot]; 257 252 if (!cur->address) { 258 irq_spinlock_unlock(&bkpoint_lock, true); 253 spinlock_unlock(&bkpoint_lock); 254 interrupts_restore(ipl); 259 255 return; 260 256 } 261 262 cur->address = (uintptr_t)NULL;263 257 258 cur->address = NULL; 259 264 260 setup_dr(slot); 265 266 irq_spinlock_unlock(&bkpoint_lock, true); 267 // ipi_broadcast(VECTOR_DEBUG_IPI); 268 } 269 270 static void debug_exception(unsigned int n __attribute__((unused)), istate_t *istate) 271 { 261 262 spinlock_unlock(&bkpoint_lock); 263 interrupts_restore(ipl); 264 #ifdef CONFIG_SMP 265 // ipi_broadcast(VECTOR_DEBUG_IPI); 266 #endif 267 } 268 269 270 271 static void debug_exception(int n __attribute__((unused)), istate_t *istate) 272 { 273 unative_t dr6; 274 int i; 275 272 276 /* Set RF to restart the instruction */ 273 277 #ifdef __64_BITS__ 274 278 istate->rflags |= RFLAGS_RF; 275 #endif 276 277 #ifdef __32_BITS__ 279 #else 278 280 istate->eflags |= EFLAGS_RF; 279 281 #endif 280 281 sysarg_t dr6 = read_dr6(); 282 283 unsigned int i; 284 for (i = 0; i < BKPOINTS_MAX; i++) { 282 283 dr6 = read_dr6(); 284 for (i=0; i < BKPOINTS_MAX; i++) { 285 285 if (dr6 & (1 << i)) { 286 286 dr6 &= ~ (1 << i); … … 293 293 294 294 #ifdef CONFIG_SMP 295 static void debug_ipi(unsigned int n __attribute__((unused)), 295 static void 296 debug_ipi(int n __attribute__((unused)), 296 297 istate_t *istate __attribute__((unused))) 297 298 { 298 i rq_spinlock_lock(&bkpoint_lock, false);299 300 unsigned int i;299 int i; 300 301 spinlock_lock(&bkpoint_lock); 301 302 for (i = 0; i < BKPOINTS_MAX; i++) 302 303 setup_dr(i); 303 304 irq_spinlock_unlock(&bkpoint_lock, false); 305 } 306 #endif /* CONFIG_SMP */ 307 308 /** Initialize debugger 309 * 310 */ 304 spinlock_unlock(&bkpoint_lock); 305 } 306 #endif 307 308 /** Initialize debugger */ 311 309 void debugger_init() 312 310 { 313 unsigned int i; 311 int i; 312 314 313 for (i = 0; i < BKPOINTS_MAX; i++) 315 breakpoints[i].address = (uintptr_t)NULL;316 314 breakpoints[i].address = NULL; 315 317 316 #ifdef CONFIG_KCONSOLE 318 317 cmd_initialize(&bkpts_info); 319 318 if (!cmd_register(&bkpts_info)) 320 319 printf("Cannot register command %s\n", bkpts_info.name); 321 320 322 321 cmd_initialize(&delbkpt_info); 323 322 if (!cmd_register(&delbkpt_info)) 324 323 printf("Cannot register command %s\n", delbkpt_info.name); 325 324 326 325 cmd_initialize(&addbkpt_info); 327 326 if (!cmd_register(&addbkpt_info)) 328 327 printf("Cannot register command %s\n", addbkpt_info.name); 329 328 330 329 cmd_initialize(&addwatchp_info); 331 330 if (!cmd_register(&addwatchp_info)) … … 333 332 #endif /* CONFIG_KCONSOLE */ 334 333 335 exc_register(VECTOR_DEBUG, "debugger", true, 336 debug_exception); 337 334 exc_register(VECTOR_DEBUG, "debugger", debug_exception); 338 335 #ifdef CONFIG_SMP 339 exc_register(VECTOR_DEBUG_IPI, "debugger_smp", true, 340 debug_ipi); 341 #endif /* CONFIG_SMP */ 336 exc_register(VECTOR_DEBUG_IPI, "debugger_smp", debug_ipi); 337 #endif 342 338 } 343 339 344 340 #ifdef CONFIG_KCONSOLE 345 /** Print table of active breakpoints 346 * 347 */ 341 /** Print table of active breakpoints */ 348 342 int cmd_print_breakpoints(cmd_arg_t *argv __attribute__((unused))) 349 343 { 344 unsigned int i; 345 char *symbol; 346 350 347 #ifdef __32_BITS__ 351 printf("[nr] [count] [address ] [in symbol\n"); 352 #endif 353 348 printf("# Count Address In symbol\n"); 349 printf("-- ----- ---------- ---------\n"); 350 #endif 351 354 352 #ifdef __64_BITS__ 355 printf(" [nr] [count] [address ] [in symbol\n");356 #endif 357 358 unsigned int i;359 for (i = 0; i < BKPOINTS_MAX; i++) {353 printf("# Count Address In symbol\n"); 354 printf("-- ----- ------------------ ---------\n"); 355 #endif 356 357 for (i = 0; i < BKPOINTS_MAX; i++) 360 358 if (breakpoints[i].address) { 361 const char *symbol = symtab_fmt_name_lookup(359 symbol = symtab_fmt_name_lookup( 362 360 breakpoints[i].address); 363 361 364 362 #ifdef __32_BITS__ 365 printf("%- 4u %7zu %p%s\n", i,366 breakpoints[i].counter, (void *)breakpoints[i].address,363 printf("%-2u %-5d %#10zx %s\n", i, 364 breakpoints[i].counter, breakpoints[i].address, 367 365 symbol); 368 366 #endif 369 367 370 368 #ifdef __64_BITS__ 371 printf("%- 4u %7zu %p%s\n", i,372 breakpoints[i].counter, (void *)breakpoints[i].address,369 printf("%-2u %-5d %#18zx %s\n", i, 370 breakpoints[i].counter, breakpoints[i].address, 373 371 symbol); 374 372 #endif 375 } 376 } 377 373 374 } 378 375 return 1; 379 376 } 380 377 381 /** Remove breakpoint from table 382 * 383 */ 378 /** Remove breakpoint from table */ 384 379 int cmd_del_breakpoint(cmd_arg_t *argv) 385 380 { 386 sysarg_t bpno = argv->intval;381 unative_t bpno = argv->intval; 387 382 if (bpno > BKPOINTS_MAX) { 388 383 printf("Invalid breakpoint number.\n"); 389 384 return 0; 390 385 } 391 392 386 breakpoint_del(argv->intval); 393 387 return 1; 394 388 } 395 389 396 /** Add new breakpoint to table 397 * 398 */ 390 /** Add new breakpoint to table */ 399 391 static int cmd_add_breakpoint(cmd_arg_t *argv) 400 392 { 401 unsigned int flags; 402 if (argv == &add_argv) 393 int flags; 394 int id; 395 396 if (argv == &add_argv) { 403 397 flags = BKPOINT_INSTR; 404 else398 } else { /* addwatchp */ 405 399 flags = BKPOINT_WRITE; 406 407 printf("Adding breakpoint on address: %p\n", 408 (void *) argv->intval); 409 410 int id = breakpoint_add((void *) argv->intval, flags, -1); 400 } 401 printf("Adding breakpoint on address: %p\n", argv->intval); 402 id = breakpoint_add((void *)argv->intval, flags, -1); 411 403 if (id < 0) 412 404 printf("Add breakpoint failed.\n");
Note:
See TracChangeset
for help on using the changeset viewer.