db_break.c (256281) | db_break.c (273265) |
---|---|
1/*- 2 * Mach Operating System 3 * Copyright (c) 1991,1990 Carnegie Mellon University 4 * All Rights Reserved. 5 * 6 * Permission to use, copy, modify and distribute this software and its 7 * documentation is hereby granted, provided that both the copyright 8 * notice and this permission notice appear in all copies of the --- 19 unchanged lines hidden (view full) --- 28 * Author: David B. Golub, Carnegie Mellon University 29 * Date: 7/90 30 */ 31/* 32 * Breakpoints. 33 */ 34 35#include <sys/cdefs.h> | 1/*- 2 * Mach Operating System 3 * Copyright (c) 1991,1990 Carnegie Mellon University 4 * All Rights Reserved. 5 * 6 * Permission to use, copy, modify and distribute this software and its 7 * documentation is hereby granted, provided that both the copyright 8 * notice and this permission notice appear in all copies of the --- 19 unchanged lines hidden (view full) --- 28 * Author: David B. Golub, Carnegie Mellon University 29 * Date: 7/90 30 */ 31/* 32 * Breakpoints. 33 */ 34 35#include <sys/cdefs.h> |
36__FBSDID("$FreeBSD: stable/10/sys/ddb/db_break.c 225214 2011-08-27 14:24:27Z rwatson $"); | 36__FBSDID("$FreeBSD: stable/10/sys/ddb/db_break.c 273265 2014-10-18 19:22:59Z pfg $"); |
37 38#include <sys/param.h> 39 40#include <vm/vm.h> 41#include <vm/vm_kern.h> 42 43#include <ddb/ddb.h> 44#include <ddb/db_break.h> --- 9 unchanged lines hidden (view full) --- 54static db_breakpoint_t db_breakpoint_alloc(void); 55static void db_breakpoint_free(db_breakpoint_t bkpt); 56static void db_delete_breakpoint(vm_map_t map, db_addr_t addr); 57static db_breakpoint_t db_find_breakpoint(vm_map_t map, db_addr_t addr); 58static void db_list_breakpoints(void); 59static void db_set_breakpoint(vm_map_t map, db_addr_t addr, int count); 60 61static db_breakpoint_t | 37 38#include <sys/param.h> 39 40#include <vm/vm.h> 41#include <vm/vm_kern.h> 42 43#include <ddb/ddb.h> 44#include <ddb/db_break.h> --- 9 unchanged lines hidden (view full) --- 54static db_breakpoint_t db_breakpoint_alloc(void); 55static void db_breakpoint_free(db_breakpoint_t bkpt); 56static void db_delete_breakpoint(vm_map_t map, db_addr_t addr); 57static db_breakpoint_t db_find_breakpoint(vm_map_t map, db_addr_t addr); 58static void db_list_breakpoints(void); 59static void db_set_breakpoint(vm_map_t map, db_addr_t addr, int count); 60 61static db_breakpoint_t |
62db_breakpoint_alloc() | 62db_breakpoint_alloc(void) |
63{ 64 register db_breakpoint_t bkpt; 65 66 if ((bkpt = db_free_breakpoints) != 0) { 67 db_free_breakpoints = bkpt->link; 68 return (bkpt); 69 } 70 if (db_next_free_breakpoint == &db_break_table[NBREAKPOINTS]) { 71 db_printf("All breakpoints used.\n"); 72 return (0); 73 } 74 bkpt = db_next_free_breakpoint; 75 db_next_free_breakpoint++; 76 77 return (bkpt); 78} 79 80static void | 63{ 64 register db_breakpoint_t bkpt; 65 66 if ((bkpt = db_free_breakpoints) != 0) { 67 db_free_breakpoints = bkpt->link; 68 return (bkpt); 69 } 70 if (db_next_free_breakpoint == &db_break_table[NBREAKPOINTS]) { 71 db_printf("All breakpoints used.\n"); 72 return (0); 73 } 74 bkpt = db_next_free_breakpoint; 75 db_next_free_breakpoint++; 76 77 return (bkpt); 78} 79 80static void |
81db_breakpoint_free(bkpt) 82 register db_breakpoint_t bkpt; | 81db_breakpoint_free(db_breakpoint_t bkpt) |
83{ 84 bkpt->link = db_free_breakpoints; 85 db_free_breakpoints = bkpt; 86} 87 88static void | 82{ 83 bkpt->link = db_free_breakpoints; 84 db_free_breakpoints = bkpt; 85} 86 87static void |
89db_set_breakpoint(map, addr, count) 90 vm_map_t map; 91 db_addr_t addr; 92 int count; | 88db_set_breakpoint(vm_map_t map, db_addr_t addr, int count) |
93{ 94 register db_breakpoint_t bkpt; 95 96 if (db_find_breakpoint(map, addr)) { 97 db_printf("Already set.\n"); 98 return; 99 } 100 --- 9 unchanged lines hidden (view full) --- 110 bkpt->init_count = count; 111 bkpt->count = count; 112 113 bkpt->link = db_breakpoint_list; 114 db_breakpoint_list = bkpt; 115} 116 117static void | 89{ 90 register db_breakpoint_t bkpt; 91 92 if (db_find_breakpoint(map, addr)) { 93 db_printf("Already set.\n"); 94 return; 95 } 96 --- 9 unchanged lines hidden (view full) --- 106 bkpt->init_count = count; 107 bkpt->count = count; 108 109 bkpt->link = db_breakpoint_list; 110 db_breakpoint_list = bkpt; 111} 112 113static void |
118db_delete_breakpoint(map, addr) 119 vm_map_t map; 120 db_addr_t addr; | 114db_delete_breakpoint(vm_map_t map, db_addr_t addr) |
121{ 122 register db_breakpoint_t bkpt; 123 register db_breakpoint_t *prev; 124 125 for (prev = &db_breakpoint_list; 126 (bkpt = *prev) != 0; 127 prev = &bkpt->link) { 128 if (db_map_equal(bkpt->map, map) && --- 6 unchanged lines hidden (view full) --- 135 db_printf("Not set.\n"); 136 return; 137 } 138 139 db_breakpoint_free(bkpt); 140} 141 142static db_breakpoint_t | 115{ 116 register db_breakpoint_t bkpt; 117 register db_breakpoint_t *prev; 118 119 for (prev = &db_breakpoint_list; 120 (bkpt = *prev) != 0; 121 prev = &bkpt->link) { 122 if (db_map_equal(bkpt->map, map) && --- 6 unchanged lines hidden (view full) --- 129 db_printf("Not set.\n"); 130 return; 131 } 132 133 db_breakpoint_free(bkpt); 134} 135 136static db_breakpoint_t |
143db_find_breakpoint(map, addr) 144 vm_map_t map; 145 db_addr_t addr; | 137db_find_breakpoint(vm_map_t map, db_addr_t addr) |
146{ 147 register db_breakpoint_t bkpt; 148 149 for (bkpt = db_breakpoint_list; 150 bkpt != 0; 151 bkpt = bkpt->link) 152 { 153 if (db_map_equal(bkpt->map, map) && 154 (bkpt->address == addr)) 155 return (bkpt); 156 } 157 return (0); 158} 159 160db_breakpoint_t | 138{ 139 register db_breakpoint_t bkpt; 140 141 for (bkpt = db_breakpoint_list; 142 bkpt != 0; 143 bkpt = bkpt->link) 144 { 145 if (db_map_equal(bkpt->map, map) && 146 (bkpt->address == addr)) 147 return (bkpt); 148 } 149 return (0); 150} 151 152db_breakpoint_t |
161db_find_breakpoint_here(addr) 162 db_addr_t addr; | 153db_find_breakpoint_here(db_addr_t addr) |
163{ | 154{ |
164 return db_find_breakpoint(db_map_addr(addr), addr); | 155 return db_find_breakpoint(db_map_addr(addr), addr); |
165} 166 167static boolean_t db_breakpoints_inserted = TRUE; 168 169#ifndef BKPT_WRITE | 156} 157 158static boolean_t db_breakpoints_inserted = TRUE; 159 160#ifndef BKPT_WRITE |
170#define BKPT_WRITE(addr, storage) \ | 161#define BKPT_WRITE(addr, storage) \ |
171do { \ 172 *storage = db_get_value(addr, BKPT_SIZE, FALSE); \ 173 db_put_value(addr, BKPT_SIZE, BKPT_SET(*storage)); \ 174} while (0) 175#endif 176 177#ifndef BKPT_CLEAR | 162do { \ 163 *storage = db_get_value(addr, BKPT_SIZE, FALSE); \ 164 db_put_value(addr, BKPT_SIZE, BKPT_SET(*storage)); \ 165} while (0) 166#endif 167 168#ifndef BKPT_CLEAR |
178#define BKPT_CLEAR(addr, storage) \ | 169#define BKPT_CLEAR(addr, storage) \ |
179 db_put_value(addr, BKPT_SIZE, *storage) 180#endif 181 182void | 170 db_put_value(addr, BKPT_SIZE, *storage) 171#endif 172 173void |
183db_set_breakpoints() | 174db_set_breakpoints(void) |
184{ 185 register db_breakpoint_t bkpt; 186 187 if (!db_breakpoints_inserted) { 188 189 for (bkpt = db_breakpoint_list; 190 bkpt != 0; 191 bkpt = bkpt->link) 192 if (db_map_current(bkpt->map)) { 193 BKPT_WRITE(bkpt->address, &bkpt->bkpt_inst); 194 } 195 db_breakpoints_inserted = TRUE; 196 } 197} 198 199void | 175{ 176 register db_breakpoint_t bkpt; 177 178 if (!db_breakpoints_inserted) { 179 180 for (bkpt = db_breakpoint_list; 181 bkpt != 0; 182 bkpt = bkpt->link) 183 if (db_map_current(bkpt->map)) { 184 BKPT_WRITE(bkpt->address, &bkpt->bkpt_inst); 185 } 186 db_breakpoints_inserted = TRUE; 187 } 188} 189 190void |
200db_clear_breakpoints() | 191db_clear_breakpoints(void) |
201{ 202 register db_breakpoint_t bkpt; 203 204 if (db_breakpoints_inserted) { 205 206 for (bkpt = db_breakpoint_list; 207 bkpt != 0; 208 bkpt = bkpt->link) --- 6 unchanged lines hidden (view full) --- 215 216#ifdef SOFTWARE_SSTEP 217/* 218 * Set a temporary breakpoint. 219 * The instruction is changed immediately, 220 * so the breakpoint does not have to be on the breakpoint list. 221 */ 222db_breakpoint_t | 192{ 193 register db_breakpoint_t bkpt; 194 195 if (db_breakpoints_inserted) { 196 197 for (bkpt = db_breakpoint_list; 198 bkpt != 0; 199 bkpt = bkpt->link) --- 6 unchanged lines hidden (view full) --- 206 207#ifdef SOFTWARE_SSTEP 208/* 209 * Set a temporary breakpoint. 210 * The instruction is changed immediately, 211 * so the breakpoint does not have to be on the breakpoint list. 212 */ 213db_breakpoint_t |
223db_set_temp_breakpoint(addr) 224 db_addr_t addr; | 214db_set_temp_breakpoint(db_addr_t addr) |
225{ 226 register db_breakpoint_t bkpt; 227 228 bkpt = db_breakpoint_alloc(); 229 if (bkpt == 0) { 230 db_printf("Too many breakpoints.\n"); 231 return 0; 232 } --- 4 unchanged lines hidden (view full) --- 237 bkpt->init_count = 1; 238 bkpt->count = 1; 239 240 BKPT_WRITE(bkpt->address, &bkpt->bkpt_inst); 241 return bkpt; 242} 243 244void | 215{ 216 register db_breakpoint_t bkpt; 217 218 bkpt = db_breakpoint_alloc(); 219 if (bkpt == 0) { 220 db_printf("Too many breakpoints.\n"); 221 return 0; 222 } --- 4 unchanged lines hidden (view full) --- 227 bkpt->init_count = 1; 228 bkpt->count = 1; 229 230 BKPT_WRITE(bkpt->address, &bkpt->bkpt_inst); 231 return bkpt; 232} 233 234void |
245db_delete_temp_breakpoint(bkpt) 246 db_breakpoint_t bkpt; | 235db_delete_temp_breakpoint(db_breakpoint_t bkpt) |
247{ 248 BKPT_CLEAR(bkpt->address, &bkpt->bkpt_inst); 249 db_breakpoint_free(bkpt); 250} 251#endif /* SOFTWARE_SSTEP */ 252 253/* 254 * List breakpoints. 255 */ 256static void | 236{ 237 BKPT_CLEAR(bkpt->address, &bkpt->bkpt_inst); 238 db_breakpoint_free(bkpt); 239} 240#endif /* SOFTWARE_SSTEP */ 241 242/* 243 * List breakpoints. 244 */ 245static void |
257db_list_breakpoints() | 246db_list_breakpoints(void) |
258{ 259 register db_breakpoint_t bkpt; 260 261 if (db_breakpoint_list == 0) { 262 db_printf("No breakpoints set\n"); 263 return; 264 } 265 --- 7 unchanged lines hidden (view full) --- 273 db_printsym(bkpt->address, DB_STGY_PROC); 274 db_printf("\n"); 275 } 276} 277 278/* Delete breakpoint */ 279/*ARGSUSED*/ 280void | 247{ 248 register db_breakpoint_t bkpt; 249 250 if (db_breakpoint_list == 0) { 251 db_printf("No breakpoints set\n"); 252 return; 253 } 254 --- 7 unchanged lines hidden (view full) --- 262 db_printsym(bkpt->address, DB_STGY_PROC); 263 db_printf("\n"); 264 } 265} 266 267/* Delete breakpoint */ 268/*ARGSUSED*/ 269void |
281db_delete_cmd(addr, have_addr, count, modif) 282 db_expr_t addr; 283 boolean_t have_addr; 284 db_expr_t count; 285 char * modif; | 270db_delete_cmd(db_expr_t addr, boolean_t have_addr, db_expr_t count, char *modif) |
286{ 287 db_delete_breakpoint(db_map_addr(addr), (db_addr_t)addr); 288} 289 290/* Set breakpoint with skip count */ 291/*ARGSUSED*/ 292void | 271{ 272 db_delete_breakpoint(db_map_addr(addr), (db_addr_t)addr); 273} 274 275/* Set breakpoint with skip count */ 276/*ARGSUSED*/ 277void |
293db_breakpoint_cmd(addr, have_addr, count, modif) 294 db_expr_t addr; 295 boolean_t have_addr; 296 db_expr_t count; 297 char * modif; | 278db_breakpoint_cmd(db_expr_t addr, boolean_t have_addr, db_expr_t count, 279 char *modif) |
298{ 299 if (count == -1) 300 count = 1; 301 302 db_set_breakpoint(db_map_addr(addr), (db_addr_t)addr, count); 303} 304 305/* list breakpoints */ 306void | 280{ 281 if (count == -1) 282 count = 1; 283 284 db_set_breakpoint(db_map_addr(addr), (db_addr_t)addr, count); 285} 286 287/* list breakpoints */ 288void |
307db_listbreak_cmd(dummy1, dummy2, dummy3, dummy4) 308 db_expr_t dummy1; 309 boolean_t dummy2; 310 db_expr_t dummy3; 311 char * dummy4; | 289db_listbreak_cmd(db_expr_t dummy1, boolean_t dummy2, db_expr_t dummy3, 290 char *dummy4) |
312{ 313 db_list_breakpoints(); 314} 315 316/* 317 * We want ddb to be usable before most of the kernel has been 318 * initialized. In particular, current_thread() or kernel_map 319 * (or both) may be null. 320 */ 321 322boolean_t | 291{ 292 db_list_breakpoints(); 293} 294 295/* 296 * We want ddb to be usable before most of the kernel has been 297 * initialized. In particular, current_thread() or kernel_map 298 * (or both) may be null. 299 */ 300 301boolean_t |
323db_map_equal(map1, map2) 324 vm_map_t map1, map2; | 302db_map_equal(vm_map_t map1, vm_map_t map2) |
325{ 326 return ((map1 == map2) || 327 ((map1 == NULL) && (map2 == kernel_map)) || 328 ((map1 == kernel_map) && (map2 == NULL))); 329} 330 331boolean_t | 303{ 304 return ((map1 == map2) || 305 ((map1 == NULL) && (map2 == kernel_map)) || 306 ((map1 == kernel_map) && (map2 == NULL))); 307} 308 309boolean_t |
332db_map_current(map) 333 vm_map_t map; | 310db_map_current(vm_map_t map) |
334{ 335#if 0 336 thread_t thread; 337 338 return ((map == NULL) || 339 (map == kernel_map) || 340 (((thread = current_thread()) != NULL) && 341 (map == thread->task->map))); 342#else 343 return (1); 344#endif 345} 346 347vm_map_t | 311{ 312#if 0 313 thread_t thread; 314 315 return ((map == NULL) || 316 (map == kernel_map) || 317 (((thread = current_thread()) != NULL) && 318 (map == thread->task->map))); 319#else 320 return (1); 321#endif 322} 323 324vm_map_t |
348db_map_addr(addr) 349 vm_offset_t addr; | 325db_map_addr(vm_offset_t addr) |
350{ 351#if 0 352 thread_t thread; 353 354 /* 355 * We want to return kernel_map for all 356 * non-user addresses, even when debugging 357 * kernel tasks with their own maps. 358 */ 359 360 if ((VM_MIN_ADDRESS <= addr) && 361 (addr < VM_MAX_ADDRESS) && 362 ((thread = current_thread()) != NULL)) 363 return thread->task->map; 364 else 365#endif 366 return kernel_map; 367} | 326{ 327#if 0 328 thread_t thread; 329 330 /* 331 * We want to return kernel_map for all 332 * non-user addresses, even when debugging 333 * kernel tasks with their own maps. 334 */ 335 336 if ((VM_MIN_ADDRESS <= addr) && 337 (addr < VM_MAX_ADDRESS) && 338 ((thread = current_thread()) != NULL)) 339 return thread->task->map; 340 else 341#endif 342 return kernel_map; 343} |