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