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