Changes in kernel/arch/amd64/src/debugger.c [49ace23:a000878c] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/arch/amd64/src/debugger.c
r49ace23 ra000878c 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 unative_t dr7 = read_dr7(); 128 dr7 &= ~(0x2 << (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 &= ~(0x3 << (16 + 4 * curidx));150 dr7 &= ~(0x3 << (18 + 4 * curidx));151 152 if (!(flags & BKPOINT_INSTR)) {153 138 #ifdef __32_BITS__ 154 139 dr7 |= ((unative_t) 0x3) << (18 + 4 * curidx); 155 140 #endif 156 141 157 142 #ifdef __64_BITS__ 158 143 dr7 |= ((unative_t) 0x2) << (18 + 4 * curidx); … … 164 149 dr7 |= ((unative_t) 0x3) << (16 + 4 * curidx); 165 150 } 166 151 167 152 /* Enable global breakpoint */ 168 153 dr7 |= 0x2 << (curidx * 2); 154 155 write_dr7(dr7); 169 156 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 */ 216 203 // ipi_broadcast(VECTOR_DEBUG_IPI); 217 204 218 205 return curidx; 219 206 } 220 207 208 #ifdef __64_BITS__ 209 #define getip(x) ((x)->rip) 210 #else 211 #define getip(x) ((x)->eip) 212 #endif 213 221 214 static void handle_exception(int slot, istate_t *istate) 222 215 { 223 ASSERT(slot >= 0);224 216 ASSERT(breakpoints[slot].address); 225 217 226 218 /* Handle zero checker */ 227 if (! (breakpoints[slot].flags & BKPOINT_INSTR)) {219 if (! (breakpoints[slot].flags & BKPOINT_INSTR)) { 228 220 if ((breakpoints[slot].flags & BKPOINT_CHECK_ZERO)) { 229 221 if (*((unative_t *) breakpoints[slot].address) != 0) 230 222 return; 231 232 printf("*** Found ZERO on address %" PRIp " (slot %d) ***\n", 223 printf("*** Found ZERO on address %lx (slot %d) ***\n", 233 224 breakpoints[slot].address, slot); 234 225 } else { 235 printf("Data watchpoint - new data: % " PRIp "\n",226 printf("Data watchpoint - new data: %lx\n", 236 227 *((unative_t *) breakpoints[slot].address)); 237 228 } 238 229 } 239 240 printf("Reached breakpoint %d:% " PRIp "(%s)\n", slot, getip(istate),230 231 printf("Reached breakpoint %d:%lx (%s)\n", slot, getip(istate), 241 232 symtab_fmt_name_lookup(getip(istate))); 242 233 243 234 #ifdef CONFIG_KCONSOLE 244 235 atomic_set(&haltstate, 1); … … 250 241 void breakpoint_del(int slot) 251 242 { 252 ASSERT(slot >= 0); 253 254 irq_spinlock_lock(&bkpoint_lock, true); 255 256 bpinfo_t *cur = &breakpoints[slot]; 243 bpinfo_t *cur; 244 ipl_t ipl; 245 246 ipl = interrupts_disable(); 247 spinlock_lock(&bkpoint_lock); 248 249 cur = &breakpoints[slot]; 257 250 if (!cur->address) { 258 irq_spinlock_unlock(&bkpoint_lock, true); 251 spinlock_unlock(&bkpoint_lock); 252 interrupts_restore(ipl); 259 253 return; 260 254 } 261 255 262 256 cur->address = NULL; 263 257 264 258 setup_dr(slot); 265 266 irq_spinlock_unlock(&bkpoint_lock, true); 259 260 spinlock_unlock(&bkpoint_lock); 261 interrupts_restore(ipl); 267 262 // ipi_broadcast(VECTOR_DEBUG_IPI); 268 263 } 269 264 270 static void debug_exception(unsigned int n __attribute__((unused)), istate_t *istate) 271 { 265 266 267 static void debug_exception(int n __attribute__((unused)), istate_t *istate) 268 { 269 unative_t dr6; 270 int i; 271 272 272 /* Set RF to restart the instruction */ 273 273 #ifdef __64_BITS__ 274 274 istate->rflags |= RFLAGS_RF; 275 #endif 276 277 #ifdef __32_BITS__ 275 #else 278 276 istate->eflags |= EFLAGS_RF; 279 277 #endif 280 281 unative_t dr6 = read_dr6(); 282 283 unsigned int i; 284 for (i = 0; i < BKPOINTS_MAX; i++) { 278 279 dr6 = read_dr6(); 280 for (i=0; i < BKPOINTS_MAX; i++) { 285 281 if (dr6 & (1 << i)) { 286 282 dr6 &= ~ (1 << i); … … 293 289 294 290 #ifdef CONFIG_SMP 295 static void debug_ipi(unsigned int n __attribute__((unused)), 291 static void 292 debug_ipi(int n __attribute__((unused)), 296 293 istate_t *istate __attribute__((unused))) 297 294 { 298 i rq_spinlock_lock(&bkpoint_lock, false);299 300 unsigned int i;295 int i; 296 297 spinlock_lock(&bkpoint_lock); 301 298 for (i = 0; i < BKPOINTS_MAX; i++) 302 299 setup_dr(i); 303 304 irq_spinlock_unlock(&bkpoint_lock, false); 305 } 306 #endif /* CONFIG_SMP */ 307 308 /** Initialize debugger 309 * 310 */ 300 spinlock_unlock(&bkpoint_lock); 301 } 302 #endif 303 304 /** Initialize debugger */ 311 305 void debugger_init() 312 306 { 313 unsigned int i; 307 int i; 308 314 309 for (i = 0; i < BKPOINTS_MAX; i++) 315 310 breakpoints[i].address = NULL; 316 311 317 312 #ifdef CONFIG_KCONSOLE 318 313 cmd_initialize(&bkpts_info); 319 314 if (!cmd_register(&bkpts_info)) 320 315 printf("Cannot register command %s\n", bkpts_info.name); 321 316 322 317 cmd_initialize(&delbkpt_info); 323 318 if (!cmd_register(&delbkpt_info)) 324 319 printf("Cannot register command %s\n", delbkpt_info.name); 325 320 326 321 cmd_initialize(&addbkpt_info); 327 322 if (!cmd_register(&addbkpt_info)) 328 323 printf("Cannot register command %s\n", addbkpt_info.name); 329 324 330 325 cmd_initialize(&addwatchp_info); 331 326 if (!cmd_register(&addwatchp_info)) … … 333 328 #endif /* CONFIG_KCONSOLE */ 334 329 335 exc_register(VECTOR_DEBUG, "debugger", true, 336 debug_exception); 337 330 exc_register(VECTOR_DEBUG, "debugger", debug_exception); 338 331 #ifdef CONFIG_SMP 339 exc_register(VECTOR_DEBUG_IPI, "debugger_smp", true, 340 debug_ipi); 341 #endif /* CONFIG_SMP */ 332 exc_register(VECTOR_DEBUG_IPI, "debugger_smp", debug_ipi); 333 #endif 342 334 } 343 335 344 336 #ifdef CONFIG_KCONSOLE 345 /** Print table of active breakpoints 346 * 347 */ 337 /** Print table of active breakpoints */ 348 338 int cmd_print_breakpoints(cmd_arg_t *argv __attribute__((unused))) 349 339 { 340 unsigned int i; 341 350 342 #ifdef __32_BITS__ 351 printf("[nr] [count] [address ] [in symbol\n"); 352 #endif 353 343 printf("# Count Address In symbol\n"); 344 printf("-- ----- ---------- ---------\n"); 345 #endif 346 354 347 #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++) {348 printf("# Count Address In symbol\n"); 349 printf("-- ----- ------------------ ---------\n"); 350 #endif 351 352 for (i = 0; i < BKPOINTS_MAX; i++) 360 353 if (breakpoints[i].address) { 361 354 const char *symbol = symtab_fmt_name_lookup( 362 355 breakpoints[i].address); 363 356 364 357 #ifdef __32_BITS__ 365 printf("%- 4u %7" PRIs " %p%s\n", i,358 printf("%-2u %-5d %#10zx %s\n", i, 366 359 breakpoints[i].counter, breakpoints[i].address, 367 360 symbol); 368 361 #endif 369 362 370 363 #ifdef __64_BITS__ 371 printf("%- 4u %7" PRIs " %p%s\n", i,364 printf("%-2u %-5d %#18zx %s\n", i, 372 365 breakpoints[i].counter, breakpoints[i].address, 373 366 symbol); 374 367 #endif 375 } 376 } 377 368 369 } 378 370 return 1; 379 371 } 380 372 381 /** Remove breakpoint from table 382 * 383 */ 373 /** Remove breakpoint from table */ 384 374 int cmd_del_breakpoint(cmd_arg_t *argv) 385 375 { … … 389 379 return 0; 390 380 } 391 392 381 breakpoint_del(argv->intval); 393 382 return 1; 394 383 } 395 384 396 /** Add new breakpoint to table 397 * 398 */ 385 /** Add new breakpoint to table */ 399 386 static int cmd_add_breakpoint(cmd_arg_t *argv) 400 387 { 401 unsigned int flags; 402 if (argv == &add_argv) 388 int flags; 389 int id; 390 391 if (argv == &add_argv) { 403 392 flags = BKPOINT_INSTR; 404 else393 } else { /* addwatchp */ 405 394 flags = BKPOINT_WRITE; 406 395 } 407 396 printf("Adding breakpoint on address: %p\n", argv->intval); 408 409 int id = breakpoint_add((void *)argv->intval, flags, -1); 397 id = breakpoint_add((void *)argv->intval, flags, -1); 410 398 if (id < 0) 411 399 printf("Add breakpoint failed.\n");
Note:
See TracChangeset
for help on using the changeset viewer.